diff options
Diffstat (limited to 'src')
18 files changed, 396 insertions, 104 deletions
diff --git a/src/com/android/settings/AppHeader.java b/src/com/android/settings/AppHeader.java index 5cd126a..cd76e80 100644 --- a/src/com/android/settings/AppHeader.java +++ b/src/com/android/settings/AppHeader.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.settings; import android.app.Activity; diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java index bfb328d..aeb3827 100644 --- a/src/com/android/settings/ChooseLockGeneric.java +++ b/src/com/android/settings/ChooseLockGeneric.java @@ -35,6 +35,8 @@ import android.os.UserManager; import android.preference.Preference; import android.preference.PreferenceScreen; import android.security.KeyStore; +import android.service.fingerprint.FingerprintManager; +import android.service.fingerprint.FingerprintManagerReceiver; import android.util.EventLog; import android.util.Log; import android.util.MutableBoolean; @@ -72,26 +74,24 @@ public class ChooseLockGeneric extends SettingsActivity { } public static class ChooseLockGenericFragment extends SettingsPreferenceFragment { + private static final String TAG = "ChooseLockGenericFragment"; private static final int MIN_PASSWORD_LENGTH = 4; - private static final String KEY_UNLOCK_BACKUP_INFO = "unlock_backup_info"; private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off"; private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none"; private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin"; private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password"; private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern"; - private static final int CONFIRM_EXISTING_REQUEST = 100; - private static final int ENABLE_ENCRYPTION_REQUEST = 102; - private static final int CHOOSE_LOCK_REQUEST = 103; private static final String PASSWORD_CONFIRMED = "password_confirmed"; - private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation"; - private static final String TAG = "ChooseLockGenericFragment"; public static final String MINIMUM_QUALITY_KEY = "minimum_quality"; + public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs"; public static final String ENCRYPT_REQUESTED_QUALITY = "encrypt_requested_quality"; public static final String ENCRYPT_REQUESTED_DISABLED = "encrypt_requested_disabled"; public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog"; - private static final boolean ALWAY_SHOW_TUTORIAL = true; + private static final int CONFIRM_EXISTING_REQUEST = 100; + private static final int ENABLE_ENCRYPTION_REQUEST = 101; + private static final int CHOOSE_LOCK_REQUEST = 102; private ChooseLockSettingsHelper mChooseLockSettingsHelper; private DevicePolicyManager mDPM; @@ -102,11 +102,14 @@ public class ChooseLockGeneric extends SettingsActivity { private boolean mEncryptionRequestDisabled; private boolean mRequirePassword; private LockPatternUtils mLockPatternUtils; + private FingerprintManager mFingerprintManager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mFingerprintManager = + (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE); mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); mKeyStore = KeyStore.getInstance(); mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity()); @@ -219,12 +222,14 @@ public class ChooseLockGeneric extends SettingsActivity { // If caller didn't specify password quality, show UI and allow the user to choose. quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1); quality = upgradeQuality(quality); + final boolean hideDisabledPrefs = intent.getBooleanExtra( + HIDE_DISABLED_PREFS, false); final PreferenceScreen prefScreen = getPreferenceScreen(); if (prefScreen != null) { prefScreen.removeAll(); } addPreferencesFromResource(R.xml.security_settings_picker); - disableUnusablePreferences(quality); + disableUnusablePreferences(quality, hideDisabledPrefs); updatePreferenceSummaryIfNeeded(); } else { updateUnlockMethodAndFinish(quality, false); @@ -261,9 +266,11 @@ public class ChooseLockGeneric extends SettingsActivity { * implementation is in disableUnusablePreferenceImpl. * * @param quality the requested quality. + * @param hideDisabledPrefs if false preferences show why they were disabled; otherwise + * they're not shown at all. */ - protected void disableUnusablePreferences(final int quality) { - disableUnusablePreferencesImpl(quality, false /* hideDisabled */); + protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) { + disableUnusablePreferencesImpl(quality, hideDisabledPrefs); } /*** @@ -391,13 +398,36 @@ public class ChooseLockGeneric extends SettingsActivity { } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { mChooseLockSettingsHelper.utils().clearLock(); mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled); + removeAllFingerprintTemplates(); getActivity().setResult(Activity.RESULT_OK); finish(); } else { + removeAllFingerprintTemplates(); finish(); } } + // TODO: This is only required because we used to enforce clients have a listener, + // which is no longer required in the new API. Remove when that happens. + FingerprintManagerReceiver mReceiver = new FingerprintManagerReceiver() { + public void onRemoved(int fingerprintId) { + Log.v(TAG, "onRemoved(id=" + fingerprintId + ")"); + } + }; + + private void removeAllFingerprintTemplates() { + if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) { + mFingerprintManager.startListening(mReceiver); + mFingerprintManager.remove(0 /* all fingerprint templates */); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + mFingerprintManager.stopListening(); + } + @Override protected int getHelpResource() { return R.string.help_url_choose_lockscreen; diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java index b85daa7..0a0aebd 100644 --- a/src/com/android/settings/ChooseLockPassword.java +++ b/src/com/android/settings/ChooseLockPassword.java @@ -432,7 +432,6 @@ public class ChooseLockPassword extends SettingsActivity { } else if (mUiStage == Stage.NeedToConfirm) { if (mFirstPin.equals(pin)) { boolean wasSecureBefore = mLockPatternUtils.isSecure(); - mLockPatternUtils.clearLock(); final boolean required = getActivity().getIntent().getBooleanExtra( EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); mLockPatternUtils.setCredentialRequiredToDecrypt(required); diff --git a/src/com/android/settings/FingerprintEnroll.java b/src/com/android/settings/FingerprintEnroll.java index 24f479e..865fcdc 100644 --- a/src/com/android/settings/FingerprintEnroll.java +++ b/src/com/android/settings/FingerprintEnroll.java @@ -21,10 +21,12 @@ import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; import android.app.Activity; import android.app.Fragment; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.drawable.AnimationDrawable; +import android.graphics.drawable.Drawable; import android.media.AudioAttributes; import android.os.Bundle; import android.os.PowerManager; @@ -80,11 +82,13 @@ public class FingerprintEnroll extends SettingsActivity { } public static class FingerprintEnrollFragment extends Fragment implements View.OnClickListener { + private static final int PROGRESS_BAR_MAX = 10000; private static final String TAG = "FingerprintEnroll"; private static final boolean DEBUG = true; private static final int CONFIRM_REQUEST = 101; private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102; private static final long ENROLL_TIMEOUT = 300*1000; + private static final int FINISH_DELAY = 250; private PowerManager mPowerManager; private FingerprintManager mFingerprintManager; @@ -98,6 +102,15 @@ public class FingerprintEnroll extends SettingsActivity { private ProgressBar mProgressBar; private ImageView mFingerprintAnimator; private ObjectAnimator mProgressAnim; + + // Give the user a chance to see progress completed before jumping to the next stage. + Runnable mDelayedFinishRunnable = new Runnable() { + @Override + public void run() { + updateStage(Stage.EnrollingFinish); + } + }; + private final AnimatorListener mProgressAnimationListener = new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @@ -107,8 +120,8 @@ public class FingerprintEnroll extends SettingsActivity { @Override public void onAnimationEnd(Animator animation) { - if (mProgressBar.getProgress() >= 100) { - updateStage(Stage.EnrollingFinish); + if (mProgressBar.getProgress() >= PROGRESS_BAR_MAX) { + mContentView.postDelayed(mDelayedFinishRunnable, FINISH_DELAY); } } @@ -133,12 +146,17 @@ public class FingerprintEnroll extends SettingsActivity { R.id.fingerprint_enroll_button_next }; - private static final int VIEWS_ENROLL_START[] = { + private static final int VIEWS_ENROLL_FIND_SENSOR[] = { R.id.fingerprint_sensor_location, - R.id.fingerprint_progress_bar + R.id.fingerprint_enroll_button_area, + R.id.fingerprint_enroll_button_next }; - private static final int VIEWS_ENROLL_PROGRESS[] = { + private static final int VIEWS_ENROLL_START[] = { + R.id.fingerprint_animator, + }; + + private static final int VIEWS_ENROLL_REPEAT[] = { R.id.fingerprint_animator, R.id.fingerprint_progress_bar }; @@ -149,17 +167,21 @@ public class FingerprintEnroll extends SettingsActivity { R.id.fingerprint_enroll_button_add, R.id.fingerprint_enroll_button_next }; + private static final boolean ALWAYS_SHOW_FIND_SCREEN = true; - enum Stage { - EnrollingOnboarding(R.string.security_settings_fingerprint_enroll_onboard_title, + private enum Stage { + EnrollingOnboard(R.string.security_settings_fingerprint_enroll_onboard_title, R.string.security_settings_fingerprint_enroll_onboard_message, VIEWS_ENROLL_ONBOARD), + EnrollingFindSensor(R.string.security_settings_fingerprint_enroll_find_sensor_title, + R.string.security_settings_fingerprint_enroll_find_sensor_message, + VIEWS_ENROLL_FIND_SENSOR), EnrollingStart(R.string.security_settings_fingerprint_enroll_start_title, R.string.security_settings_fingerprint_enroll_start_message, VIEWS_ENROLL_START), EnrollingRepeat(R.string.security_settings_fingerprint_enroll_repeat_title, R.string.security_settings_fingerprint_enroll_repeat_message, - VIEWS_ENROLL_PROGRESS), + VIEWS_ENROLL_REPEAT), EnrollingFinish(R.string.security_settings_fingerprint_enroll_finish_title, R.string.security_settings_fingerprint_enroll_finish_message, VIEWS_ENROLL_FINISH); @@ -196,22 +218,29 @@ public class FingerprintEnroll extends SettingsActivity { } private void startFingerprintAnimator() { - AnimationDrawable drawable = (AnimationDrawable) mFingerprintAnimator.getDrawable(); - drawable.start(); + final Drawable d = mFingerprintAnimator.getDrawable(); + if (d instanceof AnimationDrawable) { + ((AnimationDrawable) d).start(); + } } private void stopFingerprintAnimator() { - AnimationDrawable drawable = (AnimationDrawable) mFingerprintAnimator.getDrawable(); - drawable.stop(); - drawable.setLevel(0); + final Drawable d = mFingerprintAnimator.getDrawable(); + if (d instanceof AnimationDrawable) { + final AnimationDrawable drawable = (AnimationDrawable) d; + drawable.stop(); + drawable.setLevel(0); + } } private void onStageChanged(Stage stage) { // Update state switch (stage) { - case EnrollingOnboarding: + case EnrollingOnboard: // pass through + case EnrollingFindSensor: mEnrollmentSteps = -1; mEnrolling = false; + mFingerprintManager.stopListening(); break; case EnrollingStart: @@ -288,7 +317,7 @@ public class FingerprintEnroll extends SettingsActivity { } if (remaining >= 0) { int progress = Math.max(0, mEnrollmentSteps + 1 - remaining); - updateProgress(100*progress / (mEnrollmentSteps + 1)); + updateProgress(PROGRESS_BAR_MAX * progress / (mEnrollmentSteps + 1)); // Treat fingerprint like a touch event mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_OTHER, @@ -371,7 +400,7 @@ public class FingerprintEnroll extends SettingsActivity { if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { if (resultCode == RESULT_FINISHED) { // The lock pin/pattern/password was set. Start enrolling! - updateStage(Stage.EnrollingStart); + updateStage(Stage.EnrollingFindSensor); } } } @@ -401,7 +430,10 @@ public class FingerprintEnroll extends SettingsActivity { LockPatternUtils utils = new LockPatternUtils(activity); if (!utils.isSecure()) { // Device doesn't have any security. Set that up first. - updateStage(Stage.EnrollingOnboarding); + updateStage(Stage.EnrollingOnboard); + } else if (ALWAYS_SHOW_FIND_SCREEN + || mFingerprintManager.getEnrolledFingerprints().size() == 0) { + updateStage(Stage.EnrollingFindSensor); } else { updateStage(Stage.EnrollingStart); } @@ -415,8 +447,10 @@ public class FingerprintEnroll extends SettingsActivity { updateStage(Stage.EnrollingStart); break; case R.id.fingerprint_enroll_button_next: - if (mStage == Stage.EnrollingOnboarding) { + if (mStage == Stage.EnrollingOnboard) { launchChooseLock(); + } else if (mStage == Stage.EnrollingFindSensor) { + updateStage(Stage.EnrollingStart); } else if (mStage == Stage.EnrollingFinish) { getActivity().finish(); } else { @@ -429,6 +463,9 @@ public class FingerprintEnroll extends SettingsActivity { private void launchChooseLock() { Intent intent = new Intent(); intent.setClassName("com.android.settings", ChooseLockGeneric.class.getName()); + intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, + DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); + intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST); } } diff --git a/src/com/android/settings/FingerprintSettings.java b/src/com/android/settings/FingerprintSettings.java new file mode 100644 index 0000000..f91fcfa --- /dev/null +++ b/src/com/android/settings/FingerprintSettings.java @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2015 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.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceGroup; +import android.preference.PreferenceScreen; +import android.service.fingerprint.FingerprintManager; +import android.service.fingerprint.FingerprintManagerReceiver; +import android.service.fingerprint.FingerprintManager.FingerprintItem; +import android.util.Log; +import android.widget.EditText; + +import com.android.settings.search.Indexable; + +import java.util.HashMap; +import java.util.List; + +/** + * Settings screen for fingerprints + */ +public class FingerprintSettings extends SettingsActivity { + + @Override + public Intent getIntent() { + Intent modIntent = new Intent(super.getIntent()); + modIntent.putExtra(EXTRA_SHOW_FRAGMENT, FingerprintSettingsFragment.class.getName()); + return modIntent; + } + + @Override + protected boolean isValidFragment(String fragmentName) { + if (FingerprintSettingsFragment.class.getName().equals(fragmentName)) return true; + return false; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + CharSequence msg = getText(R.string.security_settings_fingerprint_preference_title); + setTitle(msg); + } + + public static class FingerprintSettingsFragment extends SettingsPreferenceFragment + implements OnPreferenceChangeListener, Indexable { + private static final String TAG = "FingerprintSettings"; + private static final String KEY_FINGERPRINT_ITEM = "key_fingerprint_item"; + private static final String KEY_USAGE_CATEGORY = "fingerprint_usage_category"; + private static final String KEY_FINGERPRINT_ADD = "key_fingerprint_add"; + private static final String KEY_MANAGE_CATEGORY = "fingerprint_manage_category"; + private static final String KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE = + "fingerprint_enable_keyguard_toggle"; + + private static final int ADD_FINGERPRINT_REQUEST = 10; + + private static final boolean ENABLE_USAGE_CATEGORY = false; + + private FingerprintManager mFingerprintManager; + private HashMap<Preference, FingerprintItem> mFingerprintMap + = new HashMap<Preference, FingerprintManager.FingerprintItem>(); + private EditText mDialogTextField; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mFingerprintManager = (FingerprintManager) getActivity().getSystemService( + Context.FINGERPRINT_SERVICE); + mFingerprintManager.startListening(new FingerprintManagerReceiver() { + @Override + public void onRemoved(int fingerprintId) { + Log.v(TAG, "Fingerprint template " + fingerprintId + " removed"); + // TODO: this is a bit wasteful; just remove the fingerprint id item + createPreferenceHierarchy(); + } + @Override + public void onProcessed(int fingerprintId) { + Log.v(TAG, "Fingerprint " + fingerprintId + " detected"); + } + }); + } + + /** + * Important! + * + * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the + * logic or adding/removing preferences here. + */ + private PreferenceScreen createPreferenceHierarchy() { + PreferenceScreen root = getPreferenceScreen(); + if (root != null) { + root.removeAll(); + } + addPreferencesFromResource(R.xml.security_settings_fingerprint); + root = getPreferenceScreen(); + + // Fingerprint items + PreferenceGroup manageCategory = (PreferenceGroup) root.findPreference( + KEY_MANAGE_CATEGORY); + if (manageCategory != null) { + addFingerprintItemPreferences(manageCategory); + } + + // Fingerprint usage options + PreferenceGroup usageCategory = (PreferenceGroup) root.findPreference( + KEY_USAGE_CATEGORY); + if (usageCategory != null) { + Preference toggle = root.findPreference(KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE); + toggle.setOnPreferenceChangeListener(this); + if (!ENABLE_USAGE_CATEGORY) { + root.removePreference(usageCategory); + } else { + toggle.setOnPreferenceChangeListener(this); + } + } + + return root; + } + + private void addFingerprintItemPreferences(PreferenceGroup manageFingerprintCategory) { + manageFingerprintCategory.removeAll(); + List<FingerprintItem> items = mFingerprintManager.getEnrolledFingerprints(); + final int fingerprintCount = items.size(); + mFingerprintMap.clear(); + for (int i = 0; i < fingerprintCount; i++) { + Preference pref = new Preference(manageFingerprintCategory.getContext()); + pref.setKey(KEY_FINGERPRINT_ITEM); + FingerprintItem item = items.get(i); + pref.setTitle(item.name); + manageFingerprintCategory.addPreference(pref); + pref.setOnPreferenceChangeListener(this); + mFingerprintMap.put(pref, item); + } + Preference addPreference = new Preference(manageFingerprintCategory.getContext()); + addPreference.setKey(KEY_FINGERPRINT_ADD); + addPreference.setTitle(R.string.fingerprint_add_title); + manageFingerprintCategory.addPreference(addPreference); + addPreference.setOnPreferenceChangeListener(this); + } + + @Override + public void onResume() { + super.onResume(); + // Make sure we reload the preference hierarchy since fingerprints may be added, + // deleted or renamed. + createPreferenceHierarchy(); + } + + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) { + final String key = pref.getKey(); + if (KEY_FINGERPRINT_ADD.equals(key)) { + Intent intent = new Intent(); + intent.setClassName("com.android.settings", FingerprintEnroll.class.getName()); + startActivityForResult(intent, ADD_FINGERPRINT_REQUEST); + } else if (KEY_FINGERPRINT_ITEM.equals(key)) { + final FingerprintItem item = mFingerprintMap.get(pref); + showRenameDeleteDialog(item.name, pref, item.id); + return super.onPreferenceTreeClick(preferenceScreen, pref); + } + return true; + } + + private void showRenameDeleteDialog(final CharSequence name, Preference pref, + final int fpId) { + final Activity activity = getActivity(); + AlertDialog dialog = new AlertDialog.Builder(activity) + .setView(R.layout.fingerprint_rename_dialog) + .setPositiveButton(R.string.security_settings_fingerprint_enroll_dialog_ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String newName = mDialogTextField.getText().toString(); + if (!newName.equals(name)) { + Log.v(TAG, "Would rename " + name + " to " + newName); + mFingerprintManager.rename(fpId, newName); + } + dialog.dismiss(); + } + }) + .setNegativeButton(R.string.security_settings_fingerprint_enroll_dialog_delete, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Log.v(TAG, "Removing fpId " + fpId); + mFingerprintManager.remove(fpId); + dialog.dismiss(); + } + }) + .create(); + dialog.show(); + mDialogTextField = (EditText) dialog.findViewById(R.id.fingerprint_rename_field); + mDialogTextField.setText(name); + mDialogTextField.selectAll(); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + boolean result = true; + final String key = preference.getKey(); + if (KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE.equals(key)) { + // TODO + } else { + Log.v(TAG, "Unknown key:" + key); + } + return result; + } + + @Override + protected int getHelpResource() { + return R.string.help_url_security; + } + } +} diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 95826e4..053e7f0 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -67,8 +67,9 @@ import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; */ public class SecuritySettings extends SettingsPreferenceFragment implements OnPreferenceChangeListener, DialogInterface.OnClickListener, Indexable { + + private static final String TAG = "SecuritySettings"; private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent"; - static final String TAG = "SecuritySettings"; private static final Intent TRUST_AGENT_INTENT = new Intent(TrustAgentService.SERVICE_INTERFACE); @@ -81,6 +82,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private static final String KEY_OWNER_INFO_SETTINGS = "owner_info_settings"; private static final String KEY_ADVANCED_SECURITY = "advanced_security"; private static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents"; + private static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings"; private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123; private static final int CHANGE_TRUST_AGENT_SETTINGS = 126; @@ -337,21 +339,22 @@ public class SecuritySettings extends SettingsPreferenceFragment return; } Preference fingerprintPreference = new Preference(securityCategory.getContext()); - fingerprintPreference.setKey(KEY_TRUST_AGENT); + fingerprintPreference.setKey(KEY_FINGERPRINT_SETTINGS); fingerprintPreference.setTitle(R.string.security_settings_fingerprint_preference_title); Intent intent = new Intent(); List<FingerprintItem> items = fpm.getEnrolledFingerprints(); int fingerprintCount = items.size(); + final String clazz; if (fingerprintCount > 0) { fingerprintPreference.setSummary(getResources().getQuantityString( R.plurals.security_settings_fingerprint_preference_summary, fingerprintCount, fingerprintCount)); - // TODO: Launch fingerprintSettings instead... - intent.setClassName("com.android.settings", FingerprintEnroll.class.getName()); + clazz = FingerprintSettings.class.getName(); } else { - // No fingerprints registered, launch directly into fingerprint enrollment wizard - intent.setClassName("com.android.settings", FingerprintEnroll.class.getName()); + // No fingerprints registered, launch directly into enrollment wizard + clazz = FingerprintEnroll.class.getName(); } + intent.setClassName("com.android.settings", clazz); fingerprintPreference.setIntent(intent); securityCategory.addPreference(fingerprintPreference); } diff --git a/src/com/android/settings/SetupChooseLockGeneric.java b/src/com/android/settings/SetupChooseLockGeneric.java index 94ff8d6..f29f08a 100644 --- a/src/com/android/settings/SetupChooseLockGeneric.java +++ b/src/com/android/settings/SetupChooseLockGeneric.java @@ -110,7 +110,7 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric * @param quality the requested quality. */ @Override - protected void disableUnusablePreferences(final int quality) { + protected void disableUnusablePreferences(final int quality, boolean hideDisabled) { // At this part of the flow, the user has already indicated they want to add a pin, // pattern or password, so don't show "None" or "Slide". We disable them here and set // the HIDE_DISABLED flag to true to hide them. This only happens for setup wizard. diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 5a2618e..16037c5 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -67,6 +67,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -133,6 +134,8 @@ public final class Utils { private static final int SECONDS_PER_HOUR = 60 * 60; private static final int SECONDS_PER_DAY = 24 * 60 * 60; + private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<Bitmap>(); + /** * Finds a matching activity for a preference's intent. If a matching * activity is not found, it will remove the preference. @@ -1083,4 +1086,22 @@ public final class Utils { return (sm.getStorageBytesUntilLow(context.getFilesDir()) < 0); } + + /** + * Returns a default user icon (as a {@link Bitmap}) for the given user. + * + * Note that for guest users, you should pass in {@code UserHandle.USER_NULL}. + * @param userId the user id or {@code UserHandle.USER_NULL} for a non-user specific icon + */ + public static Bitmap getDefaultUserIconAsBitmap(int userId) { + Bitmap bitmap = null; + // Try finding the corresponding bitmap in the dark bitmap cache + bitmap = sDarkDefaultUserBitmapCache.get(userId); + if (bitmap == null) { + bitmap = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(userId, false)); + // Save it to cache + sDarkDefaultUserBitmapCache.put(userId, bitmap); + } + return bitmap; + } } diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java index 2203a21..81edde2 100644 --- a/src/com/android/settings/applications/AppInfoBase.java +++ b/src/com/android/settings/applications/AppInfoBase.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.settings.applications; import android.app.Activity; @@ -151,15 +152,29 @@ public abstract class AppInfoBase extends PreferenceFragment protected abstract AlertDialog createDialog(int id, int errorCode); @Override - public void onRunningStateChanged(boolean running) { } + public void onRunningStateChanged(boolean running) { + // No op. + } + @Override - public void onRebuildComplete(ArrayList<AppEntry> apps) { } + public void onRebuildComplete(ArrayList<AppEntry> apps) { + // No op. + } + @Override - public void onPackageIconChanged() { } + public void onPackageIconChanged() { + // No op. + } + @Override - public void onPackageSizeChanged(String packageName) { } + public void onPackageSizeChanged(String packageName) { + // No op. + } + @Override - public void onAllSizesComputed() { } + public void onAllSizesComputed() { + // No op. + } @Override public void onPackageListChanged() { diff --git a/src/com/android/settings/applications/AppLaunchSettings.java b/src/com/android/settings/applications/AppLaunchSettings.java index 6379102..24a6fe0 100644 --- a/src/com/android/settings/applications/AppLaunchSettings.java +++ b/src/com/android/settings/applications/AppLaunchSettings.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.settings.applications; import android.app.AlertDialog; diff --git a/src/com/android/settings/applications/AppPermissionSettings.java b/src/com/android/settings/applications/AppPermissionSettings.java index a5b4895..496faf5 100644 --- a/src/com/android/settings/applications/AppPermissionSettings.java +++ b/src/com/android/settings/applications/AppPermissionSettings.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.settings.applications; import android.app.AlertDialog; diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java index 5ae5e8f..3df01ed 100644 --- a/src/com/android/settings/applications/AppStorageSettings.java +++ b/src/com/android/settings/applications/AppStorageSettings.java @@ -45,7 +45,7 @@ import com.android.settings.applications.ApplicationsState.AppEntry; import com.android.settings.applications.ApplicationsState.Callbacks; public class AppStorageSettings extends AppInfoWithHeader implements OnClickListener, Callbacks { - private static final String TAG = "AppStorageSettings"; + private static final String TAG = AppStorageSettings.class.getSimpleName(); //internal constants used in Handler private static final int OP_SUCCESSFUL = 1; diff --git a/src/com/android/settings/applications/HeaderPreference.java b/src/com/android/settings/applications/HeaderPreference.java index 57fe9f3..a3d4bde 100644 --- a/src/com/android/settings/applications/HeaderPreference.java +++ b/src/com/android/settings/applications/HeaderPreference.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.settings.applications; import android.content.Context; diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index 67c026b..0bb54b2 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -112,7 +112,7 @@ public final class BluetoothDevicePreference extends Preference implements */ setTitle(mCachedDevice.getName()); - int summaryResId = getConnectionSummary(); + int summaryResId = mCachedDevice.getConnectionSummary(); if (summaryResId != 0) { setSummary(summaryResId); } else { @@ -232,60 +232,6 @@ public final class BluetoothDevicePreference extends Preference implements } } - private int getConnectionSummary() { - final CachedBluetoothDevice cachedDevice = mCachedDevice; - - boolean profileConnected = false; // at least one profile is connected - boolean a2dpNotConnected = false; // A2DP is preferred but not connected - boolean headsetNotConnected = false; // Headset is preferred but not connected - - for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) { - int connectionStatus = cachedDevice.getProfileConnectionState(profile); - - switch (connectionStatus) { - case BluetoothProfile.STATE_CONNECTING: - case BluetoothProfile.STATE_DISCONNECTING: - return Utils.getConnectionStateSummary(connectionStatus); - - case BluetoothProfile.STATE_CONNECTED: - profileConnected = true; - break; - - case BluetoothProfile.STATE_DISCONNECTED: - if (profile.isProfileReady()) { - if (profile instanceof A2dpProfile) { - a2dpNotConnected = true; - } else if (profile instanceof HeadsetProfile) { - headsetNotConnected = true; - } - } - break; - } - } - - if (profileConnected) { - if (a2dpNotConnected && headsetNotConnected) { - return R.string.bluetooth_connected_no_headset_no_a2dp; - } else if (a2dpNotConnected) { - return R.string.bluetooth_connected_no_a2dp; - } else if (headsetNotConnected) { - return R.string.bluetooth_connected_no_headset; - } else { - return R.string.bluetooth_connected; - } - } - - switch (cachedDevice.getBondState()) { - case BluetoothDevice.BOND_BONDING: - return R.string.bluetooth_pairing; - - case BluetoothDevice.BOND_BONDED: - case BluetoothDevice.BOND_NONE: - default: - return 0; - } - } - private int getBtClassDrawable() { BluetoothClass btClass = mCachedDevice.getBtClass(); if (btClass != null) { diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java index b2a703d..f07a9f2 100644 --- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java +++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java @@ -220,4 +220,6 @@ public abstract class DeviceListPreferenceFragment extends updateProgressUi(false); } } + + public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { } } diff --git a/src/com/android/settings/bluetooth/DockService.java b/src/com/android/settings/bluetooth/DockService.java index c4f6485..020ca0c 100644 --- a/src/com/android/settings/bluetooth/DockService.java +++ b/src/com/android/settings/bluetooth/DockService.java @@ -937,6 +937,7 @@ public final class DockService extends Service implements ServiceListener { public void onBluetoothStateChanged(int bluetoothState) { } public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { } public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { } + public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { } @Override public void onScanningStateChanged(boolean started) { diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java index dbd0481..e54ea9f 100644 --- a/src/com/android/settings/users/UserSettings.java +++ b/src/com/android/settings/users/UserSettings.java @@ -872,8 +872,7 @@ public class UserSettings extends SettingsPreferenceFragment for (int userId : values[0]) { Bitmap bitmap = mUserManager.getUserIcon(userId); if (bitmap == null) { - bitmap = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(userId, - /* light= */ false)); + bitmap = Utils.getDefaultUserIconAsBitmap(userId); } mUserIcons.append(userId, bitmap); } @@ -889,15 +888,13 @@ public class UserSettings extends SettingsPreferenceFragment } private void assignDefaultPhoto(UserInfo user) { - Bitmap bitmap = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(user.id, - /* light= */ false)); + Bitmap bitmap = Utils.getDefaultUserIconAsBitmap(user.id); mUserManager.setUserIcon(user.id, bitmap); } private Drawable getEncircledDefaultIcon() { if (mDefaultIconDrawable == null) { - mDefaultIconDrawable = encircle(UserIcons.convertToBitmap( - UserIcons.getDefaultUserIcon(UserHandle.USER_NULL, /* light= */ false))); + mDefaultIconDrawable = encircle(Utils.getDefaultUserIconAsBitmap(UserHandle.USER_NULL)); } return mDefaultIconDrawable; } diff --git a/src/com/android/settings/wifi/WifiSettingsForSetupWizard.java b/src/com/android/settings/wifi/WifiSettingsForSetupWizard.java index efa56d7..5716bec 100644 --- a/src/com/android/settings/wifi/WifiSettingsForSetupWizard.java +++ b/src/com/android/settings/wifi/WifiSettingsForSetupWizard.java @@ -73,7 +73,9 @@ public class WifiSettingsForSetupWizard extends WifiSettings { final Intent intent = getActivity().getIntent(); if (intent.getBooleanExtra(EXTRA_SHOW_WIFI_REQUIRED_INFO, false)) { - view.findViewById(R.id.wifi_required_info).setVisibility(View.VISIBLE); + final View requiredInfo = + inflater.inflate(R.layout.setup_wifi_required_info, list, false); + list.addHeaderView(requiredInfo, null, false); } return view; |