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

@@ -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);