Settings for NFC Unlock

Change-Id: Ifaa2717da6c364daa7af073e42fc8f6a097c14bb
This commit is contained in:
Andres Morales
2013-11-25 17:26:13 -08:00
parent aadd6e516a
commit fd2b629335
24 changed files with 445 additions and 0 deletions

View File

@@ -1716,6 +1716,16 @@
</intent-filter>
</activity>
<activity android:name=".PairNfcDevice"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings$SecuritySettingsActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.settings.PAIR_NFC_DEVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="Settings$NotificationAccessSettingsActivity"
android:label="@string/manage_notification_access"
android:taskAffinity=""

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<ImageView
android:id="@+id/status_image"
android:src="@drawable/no_ring_detected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:scaleType="center"/>
<TextView
android:id="@+id/status_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:textSize="24sp"
android:textAlignment="center"
android:paddingTop="16dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"/>
</LinearLayout>

View File

@@ -700,6 +700,10 @@
<string name="security_enable_widgets_title">Enable widgets</string>
<!-- Summary for settings checkbox to disable widgets when the setting has been disabled by an installed device admin [CHAR LIMIT=50] -->
<string name="security_enable_widgets_disabled_summary">Disabled by administrator</string>
<!-- Text shown for title of settings to setup/change NFC unlock [CHAR LIMIT=20]-->
<string name="nfc_unlock_title">NFC unlock</string>
<!-- Text shown for summary of owner info setting [CHAR LIMIT=40]-->
<string name="owner_info_settings_summary"></string>
<!-- Hint text shown in owner info edit text [CHAR LIMIT=50] -->
@@ -4946,4 +4950,21 @@
<!-- Text to display in regulatory info screen (from device overlay). -->
<string name="regulatory_info_text"></string>
<!-- NFC unlock -->
<string name="lock_settings_nfc_title">NFC Screen Lock Settings</string>
<string name="nfc_unlock_paired_tags_title">Paired Tags</string>
<string name="nfc_unlock_enabled">Enabled</string>
<string name="start_nfc_pairing">Pair with a tag</string>
<!-- Nfc pair activity strings -->
<string name="title_activity_nfc_pairing">NfcPairingActivity</string>
<string name="pairing_button_title">Pair now</string>
<string name="status_no_ring_detected">Set the tag flat on a table and place the phone on top</string>
<string name="status_device_paired">Tag and phone successfully paired, you are done!</string>
<string name="status_error_invalid_device">The tag provided cannot be used to unlock your phone</string>
<string name="status_error_pairing_failed">The pairing with your tag failed, please try again</string>
<string name="enable_nfc">NFC is not enabled and is required for NFC Unlock. Please turn on NFC.</string>
<string name="ok">NFC Settings</string>
</resources>

View File

@@ -61,6 +61,11 @@
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<PreferenceScreen
android:key="nfc_unlock_set_or_change"
android:title="@string/nfc_unlock_title"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -36,6 +36,11 @@
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<PreferenceScreen
android:key="nfc_unlock_set_or_change"
android:title="@string/nfc_unlock_title"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="security_category"
android:title="@string/lock_settings_nfc_title">
<CheckBoxPreference
android:key="nfc_unlock_enabled"
android:title="@string/nfc_unlock_enabled"
android:persistent="false" />
<Preference
android:title="@string/start_nfc_pairing"
android:key="nfc_pairing"
android:persistent="false"
android:dependency="nfc_unlock_enabled" >
<intent android:action="android.settings.PAIR_NFC_DEVICE"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:key="nfc_unlock_tags_category"
android:title="@string/nfc_unlock_paired_tags_title">
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -48,6 +48,11 @@
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<PreferenceScreen
android:key="nfc_unlock_set_or_change"
android:title="@string/nfc_unlock_title"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -52,6 +52,11 @@
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<PreferenceScreen
android:key="nfc_unlock_set_or_change"
android:title="@string/nfc_unlock_title"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -48,6 +48,11 @@
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<PreferenceScreen
android:key="nfc_unlock_set_or_change"
android:title="@string/nfc_unlock_title"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.nfc.NfcAdapter;
import android.nfc.NfcUnlock;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.util.Log;
import com.android.internal.widget.LockPatternUtils;
import java.text.DateFormat;
import java.util.Date;
import static android.preference.Preference.OnPreferenceClickListener;
public class NfcLockFragment extends SettingsPreferenceFragment {
private static final String NFC_PAIRING = "nfc_pairing";
private static final String NFC_UNLOCK_ENABLED = "nfc_unlock_enabled";
private static final String TAGS_CATEGORY = "nfc_unlock_tags_category";
private static final String TAG_FORMAT = "Tag # %d";
private NfcUnlock mNfcUnlock;
private LockPatternUtils mLockPatternUtils;
private NfcAdapter mNfcAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNfcUnlock = NfcUnlock.getInstance(NfcAdapter.getDefaultAdapter(getActivity()));
mLockPatternUtils = new LockPatternUtils(getActivity());
mNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
addPreferencesFromResource(R.xml.security_settings_nfc_unlock);
}
@Override
public void onResume() {
super.onResume();
boolean prefsEnabled = (mLockPatternUtils.isLockPasswordEnabled() ||
mLockPatternUtils.isLockPatternEnabled()) && mNfcAdapter.isEnabled();
CheckBoxPreference unlockPref = (CheckBoxPreference) findPreference(NFC_UNLOCK_ENABLED);
unlockPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
mNfcUnlock.setNfcUnlockEnabled((Boolean) newValue);
return true;
}
});
Preference pairingPref = findPreference(NFC_PAIRING);
unlockPref.setEnabled(prefsEnabled);
pairingPref.setEnabled(prefsEnabled);
long[] tagRegistryTimes = mNfcUnlock.getTagRegistryTimes();
unlockPref.setChecked(mNfcUnlock.getNfcUnlockEnabled());
final PreferenceCategory pairedTags = (PreferenceCategory) findPreference(TAGS_CATEGORY);
pairedTags.setEnabled(prefsEnabled);
loadTagList(tagRegistryTimes, pairedTags);
}
private void loadTagList(long[] tagRegistryTimes, final PreferenceCategory pairedTags) {
pairedTags.removeAll();
for (int i = 0; i < tagRegistryTimes.length; i++) {
final Preference thisPreference = new Preference(getActivity());
final long timestamp = tagRegistryTimes[i];
thisPreference.setTitle(String.format(TAG_FORMAT, i));
thisPreference.setSummary(
DateFormat.getDateTimeInstance().format(new Date(tagRegistryTimes[i])));
thisPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
AlertDialog.Builder deleteDialogBuilder = new AlertDialog.Builder(getActivity());
deleteDialogBuilder.setTitle(thisPreference.getTitle());
deleteDialogBuilder.setItems(new String[] {"Delete"},
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
if (mNfcUnlock.deregisterTag(timestamp)) {
loadTagList(mNfcUnlock.getTagRegistryTimes(),
pairedTags);
}
}
}
});
deleteDialogBuilder.show();
return true;
}
});
pairedTags.addPreference(thisPreference);
}
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.NfcUnlock;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.provider.Settings;
import android.view.Menu;
import android.widget.ImageView;
import android.widget.TextView;
public class PairNfcDevice extends Activity {
private static String TAG = PairNfcDevice.class.getName();
private TextView mStatusText;
private ImageView mStatusImage;
private PendingIntent mPendingIntent;
private NfcAdapter mAdapter;
private Handler mHandler = new Handler();
private PowerManager.WakeLock mWakeLock;
private NfcUnlock mNfcUnlock;
// If pairing fails, we immediately get a new intent that would not leave time for the user to
// read the error message. So we'll just drop it and the user has to try again.
// TEST
private boolean mWaitingForDeviceDelayed;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfc_pairing);
mStatusText = (TextView) findViewById(R.id.status_text);
mStatusImage = (ImageView) findViewById(R.id.status_image);
mAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNfcUnlock = NfcUnlock.getInstance(mAdapter);
setWaitingForDeviceMode();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return false;
}
public void onPause() {
super.onPause();
mAdapter.disableForegroundDispatch(this);
if (mWakeLock != null) {
mWakeLock.release();
}
}
public void onResume() {
super.onResume();
if (!mAdapter.isEnabled()) {
// We need the user to start NFC.
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setMessage(R.string.enable_nfc);
dialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
}
});
dialogBuilder.show();
}
mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
if (mWakeLock == null) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG);
}
mWakeLock.acquire();
}
@Override
public void onNewIntent(Intent intent) {
Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (!mWaitingForDeviceDelayed) {
processTag(tag);
}
}
private void processTag(Tag tag) {
if (mNfcUnlock.registerTag(tag)) {
setPairingSucceededMode();
} else {
setPairingFailedMode();
}
}
private void setWaitingForDeviceModeDelayed(int delayInMs) {
mWaitingForDeviceDelayed = true;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mWaitingForDeviceDelayed = false;
setWaitingForDeviceMode();
}
}, delayInMs);
}
private void setWaitingForDeviceMode() {
mStatusImage.setImageResource(R.drawable.no_ring_detected);
mStatusText.setText(R.string.status_no_ring_detected);
}
private void setPairingFailedMode() {
setErrorMode(R.string.status_error_pairing_failed);
}
private void setPairingSucceededMode() {
mStatusImage.setImageResource(R.drawable.ring_paired);
mStatusText.setText(R.string.status_device_paired);
// Automatically quit.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
finish();
}
}, 4000);
}
private void setErrorMode(int errorMsgResourceId) {
mStatusText.setText(errorMsgResourceId);
setWaitingForDeviceModeDelayed(2500);
}
}

View File

@@ -29,7 +29,9 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.nfc.NfcUnlock;
import android.os.Bundle;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.CheckBoxPreference;
@@ -57,6 +59,7 @@ public class SecuritySettings extends RestrictedSettingsFragment
// Lock Settings
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
private static final String KEY_NFC_UNLOCK_SET_OR_CHANGE = "nfc_unlock_set_or_change";
private static final String KEY_BIOMETRIC_WEAK_IMPROVE_MATCHING =
"biometric_weak_improve_matching";
private static final String KEY_BIOMETRIC_WEAK_LIVELINESS = "biometric_weak_liveliness";
@@ -225,6 +228,17 @@ public class SecuritySettings extends RestrictedSettingsFragment
}
}
// don't display NFC unlock settings if the prop is not enabled
if (!NfcUnlock.getPropertyEnabled()) {
PreferenceGroup securityCategory =
(PreferenceGroup) root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null) {
securityCategory.removePreference(
root.findPreference(KEY_NFC_UNLOCK_SET_OR_CHANGE));
}
}
// Append the rest of the settings
addPreferencesFromResource(R.xml.security_settings_misc);
@@ -520,6 +534,9 @@ public class SecuritySettings extends RestrictedSettingsFragment
if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
} else if (KEY_NFC_UNLOCK_SET_OR_CHANGE.equals(key)) {
startFragment(this, "com.android.settings.NfcLockFragment",
SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
} else if (KEY_BIOMETRIC_WEAK_IMPROVE_MATCHING.equals(key)) {
ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(this.getActivity(), this);