Merge "Tablet Settings Layout is no longer stretched" into nyc-mr1-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e09a9d4..ddfbf60 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1713,6 +1713,11 @@
<activity android:name="ChooseLockGeneric"
android:label="@string/lockpassword_choose_lock_generic_header"
+ android:excludeFromRecents="true"
+ android:exported="false" />
+
+ <activity android:name=".password.SetNewPasswordActivity"
+ android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true" >
<intent-filter android:priority="1">
<action android:name="android.app.action.SET_NEW_PASSWORD" />
diff --git a/res/layout/choose_lock_generic_fingerprint_header.xml b/res/layout/choose_lock_generic_fingerprint_header.xml
index 5ad3004..6a107bf 100644
--- a/res/layout/choose_lock_generic_fingerprint_header.xml
+++ b/res/layout/choose_lock_generic_fingerprint_header.xml
@@ -15,6 +15,7 @@
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/fingerprint_header_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
@@ -22,4 +23,4 @@
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:text="@string/lock_settings_picker_fingerprint_message"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+ style="@style/FingerprintHeaderStyle" />
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index ceb7201..ba1f6fc 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -287,11 +287,14 @@
android:layout_height="wrap_content"
style="@style/wifi_item"
android:paddingBottom="4dp"
+ android:importantForAccessibility="yes"
+ android:contentDescription="@string/wifi_advanced_toggle_description_collapsed"
android:visibility="gone">
<CheckBox android:id="@+id/wifi_advanced_togglebox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/wifi_advanced_toggle"
+ android:importantForAccessibility="noHideDescendants"
android:text="@string/wifi_show_advanced" />
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 299ef24..3864591 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1083,6 +1083,12 @@
<!-- Title for preference that guides the user through creating a backup unlock password for fingerprint [CHAR LIMIT=45]-->
<string name="fingerprint_unlock_set_unlock_password">Fingerprint + Password</string>
+ <!-- Title for preference that guides the user to skip fingerprint setup [CHAR LIMIT=60]-->
+ <string name="fingerprint_unlock_skip_fingerprint">Continue without fingerprint</string>
+
+ <!-- Message shown in screen lock picker while setting up the new screen lock with fingerprint option. [CHAR LIMIT=NONE]-->
+ <string name="fingerprint_unlock_title">You can unlock your phone using your fingerprint. For security, this option requires a backup screen lock.</string>
+
<!-- Summary for preference that has been disabled by because of the DevicePolicyAdmin, or because device encryption is enabled, or because there are credentials in the credential storage [CHAR LIMIT=50] -->
<string name="unlock_set_unlock_disabled_summary">Disabled by administrator, encryption policy, or credential storage</string>
@@ -1987,15 +1993,26 @@
<string name="wifi_calling_suggestion_title">Turn on Wi-Fi Calling</string>
<!-- Summary of suggestion to turn on wifi calling [CHAR LIMIT=60] -->
<string name="wifi_calling_suggestion_summary">Use Wi-Fi instead of mobile network</string>
- <!-- WFC mode [CHAR LIMIT=30] -->
+ <!-- Title of WFC preference item [CHAR LIMIT=30] -->
<string name="wifi_calling_mode_title">Calling preference</string>
- <!-- WFC mode dialog [CHAR LIMIT=30] -->
+ <!-- Title of WFC preference selection dialog [CHAR LIMIT=30] -->
<string name="wifi_calling_mode_dialog_title">Wi-Fi calling mode</string>
+ <!-- Title of WFC roaming preference item [CHAR LIMIT=45] -->
+ <string name="wifi_calling_roaming_mode_title">Roaming preference</string>
+ <!-- Summary of WFC roaming preference item [CHAR LIMIT=NONE]-->
+ <string name="wifi_calling_roaming_mode_summary"><xliff:g id="wfc_roaming_preference" example="Wi-Fi">%1$s</xliff:g></string>
+ <!-- WFC mode dialog [CHAR LIMIT=45] -->
+ <string name="wifi_calling_roaming_mode_dialog_title">Roaming preference</string>
<string-array name="wifi_calling_mode_choices">
<item>Wi-Fi preferred</item>
<item>Cellular preferred</item>
<item>Wi-Fi only</item>
</string-array>
+ <string-array name="wifi_calling_mode_choices_v2">
+ <item>Wi-Fi</item>
+ <item>Cellular</item>
+ <item>Wi-Fi only</item>
+ </string-array>
<string-array name="wifi_calling_mode_values">
<item>"2"</item>
<item>"1"</item>
@@ -2005,13 +2022,19 @@
<item>Wi-Fi preferred</item>
<item>Cellular preferred</item>
</string-array>
+ <string-array name="wifi_calling_mode_choices_v2_without_wifi_only">
+ <item>Wi-Fi</item>
+ <item>Cellular</item>
+ </string-array>
<string-array name="wifi_calling_mode_values_without_wifi_only">
<item>"2"</item>
<item>"1"</item>
</string-array>
<!-- Wi-Fi Calling settings. Text displayed when Wi-Fi Calling is off -->
<string name="wifi_calling_off_explanation">When Wi-Fi calling is on, your phone can route calls via Wi-Fi networks or your carrier\u2019s network, depending on your preference and which signal is stronger. Before turning on this feature, check with your carrier regarding fees and other details.</string>
+ <!-- Title of a preference for updating emergency address [CHAR LIMIT=40] -->
<string name="emergency_address_title">Update Emergency Address</string>
+ <!-- Summary of Update Emergency Address preference, explaining usage of emergency address [CHAR LIMIT=NONE] -->
<string name="emergency_address_summary">Address used by emergency services as your location if you make a 911 call using WiFi</string>
@@ -5864,6 +5887,12 @@
<!--Dashboard strings-->
<!-- Text to describe the dashboard fragment title [CHAR LIMIT=16] -->
<string name="dashboard_title">Settings</string>
+ <!-- Text to describe the items to be expanded as suggested settings [CHAR LIMIT=none] -->
+ <plurals name="settings_suggestion_header_summary_hidden_items">
+ <item quantity="one">Show %d hidden item</item>
+ <item quantity="other">Show %d hidden items</item>
+ </plurals>
+
<!-- Search strings -->
<!-- Text to describe the search results fragment title [CHAR LIMIT=16] -->
@@ -7828,4 +7857,7 @@
<!-- Section title for the Domain URL app preference list [CHAR LIMIT=60]-->
<string name="domain_url_section_title">Installed apps</string>
+
+ <!-- Warning when activating the automatic storage manager on legacy devices. [CHAR LIMIT=NONE] -->
+ <string name="automatic_storage_manager_activation_warning">Your storage is now being managed by the storage manager</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 12b794a..11e4afb 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -435,4 +435,10 @@
<item name="android:paddingEnd">56dp</item>
</style>
+ <style name="FingerprintHeaderStyle" parent="android:style/TextAppearance.Material.Subhead">
+ <item name="android:paddingTop">16dp</item>
+ <item name="android:textColor">@color/primary_dark_material_light</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ </style>
+
</resources>
diff --git a/res/xml/security_settings_picker.xml b/res/xml/security_settings_picker.xml
index 7b6069d..6b52156 100644
--- a/res/xml/security_settings_picker.xml
+++ b/res/xml/security_settings_picker.xml
@@ -47,4 +47,9 @@
android:key="unlock_set_managed"
android:persistent="false"/>
+ <com.android.settingslib.RestrictedPreference
+ android:key="unlock_skip_fingerprint"
+ android:title="@string/fingerprint_unlock_skip_fingerprint"
+ android:persistent="false"/>
+
</PreferenceScreen>
diff --git a/res/xml/wifi_calling_settings.xml b/res/xml/wifi_calling_settings.xml
index c32582c..0adb1e8 100644
--- a/res/xml/wifi_calling_settings.xml
+++ b/res/xml/wifi_calling_settings.xml
@@ -26,10 +26,17 @@
android:entryValues="@array/wifi_calling_mode_values"
android:dialogTitle="@string/wifi_calling_mode_dialog_title" />
+ <ListPreference
+ android:key="wifi_calling_roaming_mode"
+ android:title="@string/wifi_calling_roaming_mode_title"
+ android:summary="@string/wifi_calling_roaming_mode_summary"
+ android:entries="@array/wifi_calling_mode_choices_v2"
+ android:entryValues="@array/wifi_calling_mode_values"
+ android:dialogTitle="@string/wifi_calling_roaming_mode_dialog_title" />
+
<Preference
- android:key="emergency_address_key"
- android:title="@string/emergency_address_title"
- android:summary="@string/emergency_address_summary">
- </Preference>
+ android:key="emergency_address_key"
+ android:title="@string/emergency_address_title"
+ android:summary="@string/emergency_address_summary" />
</PreferenceScreen>
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 8d39e6b..ffc9abc 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -16,6 +16,11 @@
package com.android.settings;
+import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD;
+import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
+import static com.android.settings.ChooseLockPassword.ChooseLockPasswordFragment.RESULT_FINISHED;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.AlertDialog;
@@ -42,16 +47,17 @@
import android.util.EventLog;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;
+import android.widget.TextView;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.fingerprint.FingerprintEnrollBase;
+import com.android.settings.fingerprint.FingerprintEnrollFindSensor;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import java.util.List;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
public class ChooseLockGeneric extends SettingsActivity {
public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
@@ -61,8 +67,8 @@
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
String action = modIntent.getAction();
- if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD.equals(action)
- || DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
+ if (ACTION_SET_NEW_PASSWORD.equals(action)
+ || ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
}
return modIntent;
@@ -90,6 +96,7 @@
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 String KEY_UNLOCK_SET_MANAGED = "unlock_set_managed";
+ private static final String KEY_SKIP_FINGERPRINT = "unlock_skip_fingerprint";
private static final String PASSWORD_CONFIRMED = "password_confirmed";
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
@@ -101,6 +108,8 @@
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 static final int CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST = 103;
+ private static final int SKIP_FINGERPRINT_REQUEST = 104;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private DevicePolicyManager mDPM;
@@ -119,6 +128,7 @@
private int mUserId;
private boolean mHideDrawer = false;
private ManagedLockPasswordProvider mManagedPasswordProvider;
+ private boolean mIsSetNewPassword = false;
protected boolean mForFingerprint = false;
@@ -131,12 +141,15 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ String chooseLockAction = getActivity().getIntent().getAction();
mFingerprintManager =
(FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mKeyStore = KeyStore.getInstance();
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
mLockPatternUtils = new LockPatternUtils(getActivity());
+ mIsSetNewPassword = ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
+ || ACTION_SET_NEW_PASSWORD.equals(chooseLockAction);
// Defaults to needing to confirm credentials
final boolean confirmCredentials = getActivity().getIntent()
@@ -154,6 +167,16 @@
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
+ if (mIsSetNewPassword) {
+ // In ACTION_SET_NEW_PARENT_PROFILE_PASSWORD or ACTION_SET_NEW_PASSWORD, the user
+ // will be asked to confirm the password if one has been set.
+ // On fingerprint supported device, fingerprint options are represented in the
+ // options. If the user chooses to skip fingerprint setup, ChooseLockGeneric is
+ // relaunched to only show options without fingerprint. In this case, we shouldn't
+ // ask the user to confirm the password again.
+ mPasswordConfirmed = getActivity().getIntent().getBooleanExtra(
+ PASSWORD_CONFIRMED, false);
+ }
if (savedInstanceState != null) {
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
@@ -168,9 +191,8 @@
UserManager.get(getActivity()),
null,
getActivity().getIntent().getExtras()).getIdentifier();
- if (DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(
- getActivity().getIntent().getAction()) ||
- !mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
+ if (ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
+ || !mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
// Always use parent if explicitely requested or if profile challenge is not
// supported
Bundle arguments = getArguments();
@@ -180,8 +202,7 @@
mUserId = targetUser;
}
- if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD
- .equals(getActivity().getIntent().getAction())
+ if (ACTION_SET_NEW_PASSWORD.equals(chooseLockAction)
&& Utils.isManagedProfile(UserManager.get(getActivity()), mUserId)
&& mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
getActivity().setTitle(R.string.lock_settings_picker_title_profile);
@@ -216,6 +237,10 @@
protected void addHeaderView() {
if (mForFingerprint) {
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
+ if (mIsSetNewPassword) {
+ ((TextView) getHeaderView().findViewById(R.id.fingerprint_header_description))
+ .setText(R.string.fingerprint_unlock_title);
+ }
}
}
@@ -228,6 +253,12 @@
// unlock method to an insecure one
showFactoryResetProtectionWarningDialog(key);
return true;
+ } else if (KEY_SKIP_FINGERPRINT.equals(key)) {
+ Intent chooseLockGenericIntent = new Intent(getActivity(), ChooseLockGeneric.class);
+ chooseLockGenericIntent.setAction(getIntent().getAction());
+ chooseLockGenericIntent.putExtra(PASSWORD_CONFIRMED, mPasswordConfirmed);
+ startActivityForResult(chooseLockGenericIntent, SKIP_FINGERPRINT_REQUEST);
+ return true;
} else {
return setUnlockMethod(key);
}
@@ -302,6 +333,20 @@
getActivity().setResult(resultCode, data);
finish();
}
+ } else if (requestCode == CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
+ && resultCode == FingerprintEnrollBase.RESULT_FINISHED) {
+ Intent intent = new Intent(getActivity(), FingerprintEnrollFindSensor.class);
+ if (data != null) {
+ intent.putExtras(data.getExtras());
+ }
+ startActivity(intent);
+ finish();
+ } else if (requestCode == SKIP_FINGERPRINT_REQUEST) {
+ if (resultCode != RESULT_CANCELED) {
+ getActivity().setResult(
+ resultCode == RESULT_FINISHED ? RESULT_OK : resultCode, data);
+ finish();
+ }
} else {
getActivity().setResult(Activity.RESULT_CANCELED);
finish();
@@ -375,6 +420,10 @@
} else {
removePreference(KEY_UNLOCK_SET_MANAGED);
}
+
+ if (!(mForFingerprint && mIsSetNewPassword)) {
+ removePreference(KEY_SKIP_FINGERPRINT);
+ }
}
private void updateCurrentPreference() {
@@ -607,7 +656,10 @@
quality = upgradeQuality(quality);
Intent intent = getIntentForUnlockMethod(quality, disabled);
if (intent != null) {
- startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
+ startActivityForResult(intent,
+ mIsSetNewPassword && mHasChallenge
+ ? CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
+ : CHOOSE_LOCK_REQUEST);
return;
}
@@ -615,8 +667,8 @@
mLockPatternUtils.setSeparateProfileChallengeEnabled(mUserId, true, mUserPassword);
mChooseLockSettingsHelper.utils().clearLock(mUserId);
mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
- removeAllFingerprintForUserAndFinish(mUserId);
getActivity().setResult(Activity.RESULT_OK);
+ removeAllFingerprintForUserAndFinish(mUserId);
} else {
removeAllFingerprintForUserAndFinish(mUserId);
}
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index b071cc3..54ff4db 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -29,7 +29,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.os.SystemProperties;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
@@ -343,6 +342,11 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ if (!android.os.Process.myUserHandle().isSystem()) {
+ Log.e(TAG, "Not run from system user, don't do anything.");
+ finish();
+ return;
+ }
setContentView(R.layout.radio_info);
diff --git a/src/com/android/settings/WifiCallingSettings.java b/src/com/android/settings/WifiCallingSettings.java
index 0af6ffa..3e9da17 100644
--- a/src/com/android/settings/WifiCallingSettings.java
+++ b/src/com/android/settings/WifiCallingSettings.java
@@ -56,6 +56,7 @@
//String keys for preference lookup
private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
+ private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
private static final String PREFERENCE_EMERGENCY_ADDRESS = "emergency_address_key";
private static final int REQUEST_CHECK_WFC_EMERGENCY_ADDRESS = 1;
@@ -69,11 +70,13 @@
private SwitchBar mSwitchBar;
private Switch mSwitch;
private ListPreference mButtonWfcMode;
+ private ListPreference mButtonWfcRoamingMode;
private Preference mUpdateAddress;
private TextView mEmptyView;
private boolean mValidListener = false;
private boolean mEditableWfcMode = true;
+ private boolean mEditableWfcRoamingMode = true;
private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
/*
@@ -94,26 +97,33 @@
switchBar.setEnabled((state == TelephonyManager.CALL_STATE_IDLE)
&& isNonTtyOrTtyOnVolteEnabled);
+ boolean isWfcModeEditable = true;
+ boolean isWfcRoamingModeEditable = false;
+ final CarrierConfigManager configManager = (CarrierConfigManager)
+ activity.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle b = configManager.getConfig();
+ if (b != null) {
+ isWfcModeEditable = b.getBoolean(
+ CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
+ isWfcRoamingModeEditable = b.getBoolean(
+ CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL);
+ }
+ }
+
Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE);
if (pref != null) {
- pref.setEnabled(isWfcEnabled && getEditableWfcMode(activity)
+ pref.setEnabled(isWfcEnabled && isWfcModeEditable
+ && (state == TelephonyManager.CALL_STATE_IDLE));
+ }
+ Preference pref_roam = getPreferenceScreen().findPreference(BUTTON_WFC_ROAMING_MODE);
+ if (pref_roam != null) {
+ pref_roam.setEnabled(isWfcEnabled && isWfcRoamingModeEditable
&& (state == TelephonyManager.CALL_STATE_IDLE));
}
}
};
- private static boolean getEditableWfcMode(Context context) {
- CarrierConfigManager configManager = (CarrierConfigManager)
- context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- PersistableBundle b = configManager.getConfig();
- if (b != null) {
- return b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
- }
- }
- return true;
- }
-
private final OnPreferenceClickListener mUpdateAddressListener =
new OnPreferenceClickListener() {
/*
@@ -204,6 +214,9 @@
mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE);
mButtonWfcMode.setOnPreferenceChangeListener(this);
+ mButtonWfcRoamingMode = (ListPreference) findPreference(BUTTON_WFC_ROAMING_MODE);
+ mButtonWfcRoamingMode.setOnPreferenceChangeListener(this);
+
mUpdateAddress = (Preference) findPreference(PREFERENCE_EMERGENCY_ADDRESS);
mUpdateAddress.setOnPreferenceClickListener(mUpdateAddressListener);
@@ -217,6 +230,8 @@
PersistableBundle b = configManager.getConfig();
if (b != null) {
mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
+ mEditableWfcRoamingMode = b.getBoolean(
+ CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL);
isWifiOnlySupported = b.getBoolean(
CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true);
}
@@ -225,6 +240,10 @@
if (!isWifiOnlySupported) {
mButtonWfcMode.setEntries(R.array.wifi_calling_mode_choices_without_wifi_only);
mButtonWfcMode.setEntryValues(R.array.wifi_calling_mode_values_without_wifi_only);
+ mButtonWfcRoamingMode.setEntries(
+ R.array.wifi_calling_mode_choices_v2_without_wifi_only);
+ mButtonWfcRoamingMode.setEntryValues(
+ R.array.wifi_calling_mode_values_without_wifi_only);
}
}
@@ -247,9 +266,11 @@
boolean wfcEnabled = ImsManager.isWfcEnabledByUser(context)
&& ImsManager.isNonTtyOrTtyOnVolteEnabled(context);
mSwitch.setChecked(wfcEnabled);
- int wfcMode = ImsManager.getWfcMode(context);
+ int wfcMode = ImsManager.getWfcMode(context, false);
+ int wfcRoamingMode = ImsManager.getWfcMode(context, true);
mButtonWfcMode.setValue(Integer.toString(wfcMode));
- updateButtonWfcMode(context, wfcEnabled, wfcMode);
+ mButtonWfcRoamingMode.setValue(Integer.toString(wfcRoamingMode));
+ updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode);
context.registerReceiver(mIntentReceiver, mIntentFilter);
@@ -332,8 +353,9 @@
Log.i(TAG, "updateWfcMode(" + wfcEnabled + ")");
ImsManager.setWfcSetting(context, wfcEnabled);
- int wfcMode = ImsManager.getWfcMode(context);
- updateButtonWfcMode(context, wfcEnabled, wfcMode);
+ int wfcMode = ImsManager.getWfcMode(context, false);
+ int wfcRoamingMode = ImsManager.getWfcMode(context, true);
+ updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode);
if (wfcEnabled) {
MetricsLogger.action(getActivity(), getMetricsCategory(), wfcMode);
} else {
@@ -356,9 +378,12 @@
}
}
- private void updateButtonWfcMode(Context context, boolean wfcEnabled, int wfcMode) {
+ private void updateButtonWfcMode(Context context, boolean wfcEnabled,
+ int wfcMode, int wfcRoamingMode) {
mButtonWfcMode.setSummary(getWfcModeSummary(context, wfcMode));
mButtonWfcMode.setEnabled(wfcEnabled && mEditableWfcMode);
+ // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value.
+ mButtonWfcRoamingMode.setEnabled(wfcEnabled && mEditableWfcRoamingMode);
final PreferenceScreen preferenceScreen = getPreferenceScreen();
boolean updateAddressEnabled = (getCarrierActivityIntent(context) != null);
@@ -366,9 +391,15 @@
if (mEditableWfcMode) {
preferenceScreen.addPreference(mButtonWfcMode);
} else {
- // Don't show WFC mode preference if it's not editable.
+ // Don't show WFC (home) preference if it's not editable.
preferenceScreen.removePreference(mButtonWfcMode);
}
+ if (mEditableWfcRoamingMode) {
+ preferenceScreen.addPreference(mButtonWfcRoamingMode);
+ } else {
+ // Don't show WFC roaming preference if it's not editable.
+ preferenceScreen.removePreference(mButtonWfcRoamingMode);
+ }
if (updateAddressEnabled) {
preferenceScreen.addPreference(mUpdateAddress);
} else {
@@ -376,6 +407,7 @@
}
} else {
preferenceScreen.removePreference(mButtonWfcMode);
+ preferenceScreen.removePreference(mButtonWfcRoamingMode);
preferenceScreen.removePreference(mUpdateAddress);
}
}
@@ -386,12 +418,28 @@
if (preference == mButtonWfcMode) {
mButtonWfcMode.setValue((String) newValue);
int buttonMode = Integer.valueOf((String) newValue);
- int currentMode = ImsManager.getWfcMode(context);
- if (buttonMode != currentMode) {
- ImsManager.setWfcMode(context, buttonMode);
+ int currentWfcMode = ImsManager.getWfcMode(context, false);
+ if (buttonMode != currentWfcMode) {
+ ImsManager.setWfcMode(context, buttonMode, false);
mButtonWfcMode.setSummary(getWfcModeSummary(context, buttonMode));
MetricsLogger.action(getActivity(), getMetricsCategory(), buttonMode);
}
+ if (!mEditableWfcRoamingMode) {
+ int currentWfcRoamingMode = ImsManager.getWfcMode(context, true);
+ if (buttonMode != currentWfcRoamingMode) {
+ ImsManager.setWfcMode(context, buttonMode, true);
+ // mButtonWfcRoamingMode.setSummary is not needed; summary is selected value
+ }
+ }
+ } else if (preference == mButtonWfcRoamingMode) {
+ mButtonWfcRoamingMode.setValue((String) newValue);
+ int buttonMode = Integer.valueOf((String) newValue);
+ int currentMode = ImsManager.getWfcMode(context, true);
+ if (buttonMode != currentMode) {
+ ImsManager.setWfcMode(context, buttonMode, true);
+ // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value.
+ MetricsLogger.action(getActivity(), getMetricsCategory(), buttonMode);
+ }
}
return true;
}
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index 7e3b8d8..7434e67 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -362,7 +362,7 @@
getPreferenceScreen().addPreference(mButtonWfc);
mButtonWfc.setSummary(WifiCallingSettings.getWfcModeSummary(
- context, ImsManager.getWfcMode(context)));
+ context, ImsManager.getWfcMode(context, mTm.isNetworkRoaming())));
} else {
removePreference(KEY_WFC_SETTINGS);
}
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index 81614e0..d45bea4 100755
--- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -116,7 +116,7 @@
EditText deviceName = (EditText) mRootView.findViewById(R.id.name);
mCachedDevice.setName(deviceName.getText().toString());
break;
- case DialogInterface.BUTTON_NEGATIVE:
+ case DialogInterface.BUTTON_NEUTRAL:
mCachedDevice.unpair();
com.android.settings.bluetooth.Utils.updateSearchIndex(getContext(),
BluetoothSettings.class.getName(), mCachedDevice.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index ca68a74..6b2e145 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -301,11 +301,22 @@
}
private void onBindSuggestionHeader(final DashboardItemHolder holder) {
- holder.icon.setImageResource(hasMoreSuggestions() ? R.drawable.ic_expand_more
- : R.drawable.ic_expand_less);
- holder.title.setText(mContext.getString(R.string.suggestions_title, mSuggestions.size()));
+ final boolean moreSuggestions = hasMoreSuggestions();
final int undisplayedSuggestionCount =
mSuggestions.size() - getDisplayableSuggestionCount();
+ holder.icon.setImageResource(moreSuggestions ? R.drawable.ic_expand_more
+ : R.drawable.ic_expand_less);
+ holder.title.setText(mContext.getString(R.string.suggestions_title, mSuggestions.size()));
+ String summaryContentDescription;
+ if (moreSuggestions) {
+ summaryContentDescription = mContext.getResources().getQuantityString(
+ R.plurals.settings_suggestion_header_summary_hidden_items,
+ undisplayedSuggestionCount, undisplayedSuggestionCount);
+ } else {
+ summaryContentDescription = mContext.getString(R.string.condition_expand_hide);
+ }
+ holder.summary.setContentDescription(summaryContentDescription);
+
if (undisplayedSuggestionCount == 0) {
holder.summary.setText(null);
} else {
diff --git a/src/com/android/settings/deletionhelper/ActivationWarningFragment.java b/src/com/android/settings/deletionhelper/ActivationWarningFragment.java
new file mode 100644
index 0000000..f7d46d1
--- /dev/null
+++ b/src/com/android/settings/deletionhelper/ActivationWarningFragment.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.deletionhelper;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import com.android.settings.R;
+
+/**
+ * Fragment to warn the user about activating the storage manager.
+ */
+public class ActivationWarningFragment extends DialogFragment {
+ public static final String TAG = "ActivationWarningFragment";
+
+ public static ActivationWarningFragment newInstance() {
+ return new ActivationWarningFragment();
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(R.string.automatic_storage_manager_activation_warning)
+ .setPositiveButton(android.R.string.ok, null)
+ .create();
+ }
+
+}
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
index 20efdda..f9b1a57 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
@@ -17,11 +17,13 @@
package com.android.settings.deletionhelper;
import android.app.Activity;
+import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
+import android.os.SystemProperties;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.format.DateUtils;
@@ -55,6 +57,8 @@
private static final String KEY_DELETION_HELPER = "deletion_helper";
private static final String KEY_FREED = "freed_bytes";
private static final String KEY_STORAGE_MANAGER_SWITCH = "storage_manager_active";
+ private static final String STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY =
+ "ro.storage_manager.enabled";
private DropDownPreference mDaysToRetain;
private Preference mFreedBytes;
@@ -126,6 +130,10 @@
mDaysToRetain.setEnabled(checked);
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, checked ? 1 : 0);
+ // Only show a warning if enabling.
+ if (checked) {
+ maybeShowWarning();
+ }
break;
case KEY_DAYS:
Settings.Secure.putInt(getContentResolver(),
@@ -164,4 +172,15 @@
}
return indices.length - 1;
}
+
+ private void maybeShowWarning() {
+ // If the storage manager is on by default, we can use the normal message.
+ boolean warningUnneeded = SystemProperties.getBoolean(
+ STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, false);
+ if (warningUnneeded) {
+ return;
+ }
+ ActivationWarningFragment fragment = ActivationWarningFragment.newInstance();
+ fragment.show(getFragmentManager(), ActivationWarningFragment.TAG);
+ }
}
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollBase.java b/src/com/android/settings/fingerprint/FingerprintEnrollBase.java
index 2aef37b..f36321d 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollBase.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollBase.java
@@ -36,7 +36,7 @@
*/
public abstract class FingerprintEnrollBase extends InstrumentedActivity
implements View.OnClickListener {
- static final int RESULT_FINISHED = FingerprintSettings.RESULT_FINISHED;
+ public static final int RESULT_FINISHED = FingerprintSettings.RESULT_FINISHED;
static final int RESULT_SKIP = FingerprintSettings.RESULT_SKIP;
static final int RESULT_TIMEOUT = FingerprintSettings.RESULT_TIMEOUT;
diff --git a/src/com/android/settings/password/SetNewPasswordActivity.java b/src/com/android/settings/password/SetNewPasswordActivity.java
new file mode 100644
index 0000000..7cdf006
--- /dev/null
+++ b/src/com/android/settings/password/SetNewPasswordActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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.password;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.settings.ChooseLockGeneric;
+
+/**
+ * Trampolines {@link DevicePolicyManager#ACTION_SET_NEW_PASSWORD} and
+ * {@link DevicePolicyManager#ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} intent to the appropriate UI
+ * activity for handling set new password.
+ */
+public class SetNewPasswordActivity extends Activity implements SetNewPasswordController.Ui {
+ private String mNewPasswordAction;
+ private SetNewPasswordController mSetNewPasswordController;
+
+ @Override
+ protected void onCreate(Bundle savedState) {
+ super.onCreate(savedState);
+
+ mNewPasswordAction = getIntent().getAction();
+ mSetNewPasswordController = new SetNewPasswordController(this, this);
+ mSetNewPasswordController.dispatchSetNewPasswordIntent();
+ }
+
+ @Override
+ public void launchChooseLock(@Nullable Bundle chooseLockFingerprintExtras) {
+ Intent intent = new Intent(this, ChooseLockGeneric.class)
+ .setAction(mNewPasswordAction);
+ if (chooseLockFingerprintExtras != null) {
+ intent.putExtras(chooseLockFingerprintExtras);
+ }
+ startActivity(intent);
+ finish();
+ }
+}
diff --git a/src/com/android/settings/password/SetNewPasswordController.java b/src/com/android/settings/password/SetNewPasswordController.java
new file mode 100644
index 0000000..470723b
--- /dev/null
+++ b/src/com/android/settings/password/SetNewPasswordController.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 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.password;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.ChooseLockGeneric;
+import com.android.settings.ChooseLockSettingsHelper;
+
+/**
+ * Business logic for {@link SetNewPasswordActivity}.
+ *
+ * <p>On devices that supports fingerprint, this controller directs the user to configure
+ * fingerprint + a backup password if the device admin allows fingerprint for keyguard and
+ * the user has never configured a fingerprint before.
+ */
+final class SetNewPasswordController {
+
+ interface Ui {
+ /** Starts the {@link ChooseLockGeneric} activity with the given extras. */
+ void launchChooseLock(@Nullable Bundle chooseLockFingerprintExtras);
+ }
+
+ private final int mCurrentUserId;
+ private final PackageManager mPackageManager;
+ @Nullable private final FingerprintManager mFingerprintManager;
+ private final DevicePolicyManager mDevicePolicyManager;
+ private final Ui mUi;
+
+ public SetNewPasswordController(Context context, Ui ui) {
+ this(context.getUserId(),
+ context.getPackageManager(),
+ (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE),
+ (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE),
+ ui);
+ }
+
+ @VisibleForTesting
+ SetNewPasswordController(
+ int currentUserId,
+ PackageManager packageManager,
+ FingerprintManager fingerprintManager,
+ DevicePolicyManager devicePolicyManager,
+ Ui ui) {
+ mCurrentUserId = currentUserId;
+ mPackageManager = checkNotNull(packageManager);
+ mFingerprintManager = fingerprintManager;
+ mDevicePolicyManager = checkNotNull(devicePolicyManager);
+ mUi = checkNotNull(ui);
+ }
+
+ /**
+ * Dispatches the set new password intent to the correct activity that handles it.
+ */
+ public void dispatchSetNewPasswordIntent() {
+ if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
+ && mFingerprintManager != null
+ && mFingerprintManager.isHardwareDetected()
+ && !mFingerprintManager.hasEnrolledFingerprints()
+ && !isFingerprintDisabledByAdmin()) {
+ mUi.launchChooseLock(getFingerprintChooseLockExtras());
+ } else {
+ mUi.launchChooseLock(null);
+ }
+ }
+
+ private Bundle getFingerprintChooseLockExtras() {
+ Bundle chooseLockExtras = new Bundle();
+ if (mFingerprintManager != null) {
+ long challenge = mFingerprintManager.preEnroll();
+ chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
+ DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ chooseLockExtras.putBoolean(
+ ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
+ chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
+ chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+ chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
+ if (mCurrentUserId != UserHandle.USER_NULL) {
+ chooseLockExtras.putInt(Intent.EXTRA_USER_ID, mCurrentUserId);
+ }
+ }
+ return chooseLockExtras;
+ }
+
+ private boolean isFingerprintDisabledByAdmin() {
+ int disabledFeatures = mDevicePolicyManager.getKeyguardDisabledFeatures(
+ null, mCurrentUserId);
+ return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
+ }
+}
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index ee6b503..dd2e7df 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -54,6 +54,7 @@
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
+import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
@@ -262,13 +263,13 @@
showSecurityFields();
showIpConfigFields();
showProxyFields();
+ final CheckBox advancedTogglebox =
+ (CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox);
mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(View.VISIBLE);
- ((CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox))
- .setOnCheckedChangeListener(this);
- if (showAdvancedFields) {
- ((CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox)).setChecked(true);
- mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.VISIBLE);
- }
+ advancedTogglebox.setOnCheckedChangeListener(this);
+ advancedTogglebox.setChecked(showAdvancedFields);
+ mView.findViewById(R.id.wifi_advanced_fields)
+ .setVisibility(showAdvancedFields ? View.VISIBLE : View.GONE);
}
if (mMode == WifiConfigUiBase.MODE_MODIFY) {
@@ -1210,11 +1211,18 @@
((EditText) mPasswordView).setSelection(pos);
}
} else if (view.getId() == R.id.wifi_advanced_togglebox) {
+ final View advancedToggle = mView.findViewById(R.id.wifi_advanced_toggle);
+ final int toggleVisibility;
+ final int stringID;
if (isChecked) {
- mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.VISIBLE);
+ toggleVisibility = View.VISIBLE;
+ stringID = R.string.wifi_advanced_toggle_description_expanded;
} else {
- mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.GONE);
+ toggleVisibility = View.GONE;
+ stringID = R.string.wifi_advanced_toggle_description_collapsed;
}
+ mView.findViewById(R.id.wifi_advanced_fields).setVisibility(toggleVisibility);
+ advancedToggle.setContentDescription(mContext.getString(stringID));
}
}
diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
new file mode 100644
index 0000000..61dbe08
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2016 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.password;
+
+import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
+import static com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS;
+import static com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY;
+import static com.android.settings.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE;
+import static com.android.settings.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
+import static com.android.settings.ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+/**
+ * Tests for {@link SetNewPasswordController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public final class SetNewPasswordControllerTest {
+ private static final int CURRENT_UID = 101;
+ private static final long FINGERPRINT_CHALLENGE = -9876512313131L;
+
+ @Mock PackageManager mPackageManager;
+ @Mock FingerprintManager mFingerprintManager;
+ @Mock DevicePolicyManager mDevicePolicyManager;
+
+ @Mock private SetNewPasswordController.Ui mUi;
+ private SetNewPasswordController mSetNewPasswordController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mSetNewPasswordController = new SetNewPasswordController(
+ CURRENT_UID, mPackageManager, mFingerprintManager, mDevicePolicyManager, mUi);
+
+ when(mFingerprintManager.preEnroll()).thenReturn(FINGERPRINT_CHALLENGE);
+ when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(true);
+ }
+
+ @Test
+ public void launchChooseLockWithFingerprint() {
+ // GIVEN the device supports fingerprint.
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+ // GIVEN there are no enrolled fingerprints.
+ when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false);
+ // GIVEN DPC does not disallow fingerprint for keyguard usage.
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
+ .thenReturn(0);
+
+ // WHEN the controller dispatches a set new password intent.
+ mSetNewPasswordController.dispatchSetNewPasswordIntent();
+
+ // THEN the choose lock activity is launched with fingerprint extras.
+ ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mUi).launchChooseLock(bundleArgumentCaptor.capture());
+ // THEN the extras have all values for fingerprint setup.
+ compareFingerprintExtras(bundleArgumentCaptor.getValue());
+ }
+
+ @Test
+ public void launchChooseLockWithoutFingerprint_noFingerprintFeature() {
+ // GIVEN the device does NOT support fingerprint feature.
+ when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(false);
+
+ // WHEN the controller dispatches a set new password intent.
+ mSetNewPasswordController.dispatchSetNewPasswordIntent();
+
+ // THEN the choose lock activity is launched without fingerprint extras.
+ verify(mUi).launchChooseLock(null);
+ }
+
+ @Test
+ public void launchChooseLockWithoutFingerprint_noFingerprintSensor() {
+ // GIVEN the device does NOT support fingerprint.
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
+ // GIVEN there are no enrolled fingerprints.
+ when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false);
+ // GIVEN DPC does not disallow fingerprint for keyguard usage.
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
+ .thenReturn(0);
+
+ // WHEN the controller dispatches a set new password intent.
+ mSetNewPasswordController.dispatchSetNewPasswordIntent();
+
+ // THEN the choose lock activity is launched without fingerprint extras.
+ verify(mUi).launchChooseLock(null);
+ }
+
+ @Test
+ public void launchChooseLockWithoutFingerprint_hasFingerprintEnrolled() {
+ // GIVEN the device supports fingerprint.
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+ // GIVEN there are no enrolled fingerprints.
+ when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(true);
+ // GIVEN DPC does not disallow fingerprint for keyguard usage.
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
+ .thenReturn(0);
+
+ // WHEN the controller dispatches a set new password intent.
+ mSetNewPasswordController.dispatchSetNewPasswordIntent();
+
+ // THEN the choose lock activity is launched without fingerprint extras.
+ verify(mUi).launchChooseLock(null);
+ }
+
+ @Test
+ public void launchChooseLockWithoutFingerprint_deviceAdminDisallowFingerprintForKeyguard() {
+ // GIVEN the device supports fingerprint.
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+ // GIVEN there is an enrolled fingerprint.
+ when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(true);
+ // GIVEN DPC disallows fingerprint for keyguard usage.
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
+ .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
+
+ // WHEN the controller dispatches a set new password intent.
+ mSetNewPasswordController.dispatchSetNewPasswordIntent();
+
+ // THEN the choose lock activity is launched without fingerprint extras.
+ verify(mUi).launchChooseLock(null);
+ }
+
+ private void compareFingerprintExtras(Bundle actualBundle) {
+ assertEquals(
+ "Password quality must be something in order to config fingerprint.",
+ DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
+ actualBundle.getInt(MINIMUM_QUALITY_KEY));
+ assertTrue(
+ "All disabled preference should be removed.",
+ actualBundle.getBoolean(HIDE_DISABLED_PREFS));
+ assertTrue(
+ "There must be a fingerprint challenge.",
+ actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE));
+ assertEquals(
+ "The fingerprint challenge must come from the FingerprintManager",
+ FINGERPRINT_CHALLENGE,
+ actualBundle.getLong(EXTRA_KEY_CHALLENGE));
+ assertTrue(
+ "The request must be a fingerprint set up request.",
+ actualBundle.getBoolean(EXTRA_KEY_FOR_FINGERPRINT));
+ assertEquals(
+ "User id must be equaled to the input one.",
+ CURRENT_UID,
+ actualBundle.getInt(Intent.EXTRA_USER_ID));
+ }
+}