From bf5686e5f55b4af130ff3999554a97893581eb11 Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Thu, 16 May 2019 16:19:02 -0700 Subject: [PATCH 01/12] Help URI for USB contaminant dialog Bug: 132737150 Test: build test. Change-Id: If6ac3b086edaee18cd982ef12220b480d12f5228 --- res/values/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 54d3df82559..4526665b1e3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10486,6 +10486,9 @@ + + + From 81d15f029a31036a8f8dfa8a18200b99c7ed0f75 Mon Sep 17 00:00:00 2001 From: Lei Yu Date: Fri, 17 May 2019 14:47:01 -0700 Subject: [PATCH 02/12] Set some BT icon background to white Fixes: 132992480 Test: Manual Change-Id: I22aad1ab327dd34ad67b9bbac10f6f2e3c9ec139 --- res/drawable/circle_outline.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/drawable/circle_outline.xml b/res/drawable/circle_outline.xml index 1b2631d522d..829d6b9f0a4 100644 --- a/res/drawable/circle_outline.xml +++ b/res/drawable/circle_outline.xml @@ -16,6 +16,7 @@ --> + From 386318dbea2aa8860f27863b0ca987174d405fae Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 20 May 2019 13:17:14 +0800 Subject: [PATCH 03/12] Fix view overlap in landscape wifi dpp enrollment. Bug: 132813855 Test: manual Change-Id: I961dcc88e044dc1ba6dc3d87d9820a2ced5196ee --- res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml index 51c8c96a008..cfe6cc039ed 100644 --- a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml +++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml @@ -45,7 +45,8 @@ + android:layout_height="@dimen/qrcode_preview_size" + android:clipChildren="true"> Date: Fri, 17 May 2019 15:36:28 +0100 Subject: [PATCH 04/12] Don't display footer text when calling app is DPC. If the calling app has admin rights (DA/DO/PO), don't display footer text that the calling app is 'recommending' that a password is set. Fixes: 131888973 Test: atest com.android.settings.password.SetNewPasswordActivityTest --verbose Test: atest com.android.settings.password.ChooseLockGenericTest --verbose Test: manual Change-Id: I32785d33e6425416fc1dbba24540ece8917b58f3 --- .../settings/password/ChooseLockGeneric.java | 11 +++- .../password/ChooseLockSettingsHelper.java | 6 ++ .../password/SetNewPasswordActivity.java | 23 +++++++ .../password/ChooseLockGenericTest.java | 13 +++- .../password/SetNewPasswordActivityTest.java | 62 ++++++++++++++++--- 5 files changed, 105 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java index 7eb8dc23818..2a7de057193 100644 --- a/src/com/android/settings/password/ChooseLockGeneric.java +++ b/src/com/android/settings/password/ChooseLockGeneric.java @@ -25,6 +25,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment.RESULT_FINISHED; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import android.accessibilityservice.AccessibilityServiceInfo; @@ -169,6 +170,12 @@ public class ChooseLockGeneric extends SettingsActivity { /** From intent extra {@link ChooseLockSettingsHelper#EXTRA_KEY_CALLER_APP_NAME}. */ private String mCallerAppName = null; + /** + * The value from the intent extra {@link + * ChooseLockSettingsHelper#EXTRA_KEY_IS_CALLING_APP_ADMIN}. + */ + private boolean mIsCallingAppAdmin; + protected boolean mForFingerprint = false; protected boolean mForFace = false; @@ -217,6 +224,8 @@ public class ChooseLockGeneric extends SettingsActivity { .getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE); mCallerAppName = getActivity().getIntent().getStringExtra(EXTRA_KEY_CALLER_APP_NAME); + mIsCallingAppAdmin = getActivity().getIntent() + .getBooleanExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, /* defValue= */ false); mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean( ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT); mUserManager = UserManager.get(getActivity()); @@ -490,7 +499,7 @@ public class ChooseLockGeneric extends SettingsActivity { protected void addPreferences() { addPreferencesFromResource(R.xml.security_settings_picker); - if (!TextUtils.isEmpty(mCallerAppName)) { + if (!TextUtils.isEmpty(mCallerAppName) && !mIsCallingAppAdmin) { FooterPreferenceMixinCompat footerMixin = new FooterPreferenceMixinCompat(this, getSettingsLifecycle()); FooterPreference footer = footerMixin.createFooterPreference(); diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java index db125986c95..28ded2d8bf9 100644 --- a/src/com/android/settings/password/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java @@ -60,6 +60,12 @@ public final class ChooseLockSettingsHelper { */ public static final String EXTRA_KEY_CALLER_APP_NAME = "caller_app_name"; + /** + * Intent extra indicating that the calling app is an admin, such as a Device Adimn, Device + * Owner, or Profile Owner. + */ + public static final String EXTRA_KEY_IS_CALLING_APP_ADMIN = "is_calling_app_admin"; + /** * When invoked via {@link ConfirmLockPassword.InternalActivity}, this flag * controls if we relax the enforcement of diff --git a/src/com/android/settings/password/SetNewPasswordActivity.java b/src/com/android/settings/password/SetNewPasswordActivity.java index 4722c56c537..055e5bedf8d 100644 --- a/src/com/android/settings/password/SetNewPasswordActivity.java +++ b/src/com/android/settings/password/SetNewPasswordActivity.java @@ -23,6 +23,7 @@ import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import android.app.Activity; @@ -30,6 +31,8 @@ import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.PasswordMetrics; import android.app.settings.SettingsEnums; +import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; @@ -39,6 +42,8 @@ import com.android.settings.Utils; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import java.util.List; + /** * Trampolines {@link DevicePolicyManager#ACTION_SET_NEW_PASSWORD} and * {@link DevicePolicyManager#ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} intent to the appropriate UI @@ -116,10 +121,28 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo if (mRequestedMinComplexity != PASSWORD_COMPLEXITY_NONE) { intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, mRequestedMinComplexity); } + if (isCallingAppAdmin()) { + intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true); + } startActivity(intent); finish(); } + private boolean isCallingAppAdmin() { + DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName(getActivityToken()); + List admins = devicePolicyManager.getActiveAdmins(); + if (admins == null) { + return false; + } + for (ComponentName componentName : admins) { + if (componentName.getPackageName().equals(callingAppPackageName)) { + return true; + } + } + return false; + } + private void logSetNewPasswordIntent() { final String callingAppPackageName = PasswordUtils.getCallingAppPackageName(getActivityToken()); diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java index c692f55390d..673c33415cf 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java @@ -23,6 +23,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import static com.google.common.truth.Truth.assertThat; @@ -182,12 +183,22 @@ public class ChooseLockGenericTest { CharSequence expectedTitle = mActivity.getString(R.string.unlock_footer_none_complexity_requested, "app name"); - mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */); + mFragment.updatePreferencesOrFinish(/* isRecreatingActivity= */ false); FooterPreference footer = mFragment.findPreference(FooterPreference.KEY_FOOTER); assertThat(footer.getTitle()).isEqualTo(expectedTitle); } + @Test + public void updatePreferencesOrFinish_callingAppIsAdmin_noFooter() { + initActivity(new Intent().putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true)); + + mFragment.updatePreferencesOrFinish(/* isRecreatingActivity= */ false); + + FooterPreference footer = mFragment.findPreference(FooterPreference.KEY_FOOTER); + assertThat(footer).isNull(); + } + @Test public void onActivityResult_requestcode0_shouldNotFinish() { initActivity(null); diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java index bed09cb5d37..04a2157aeee 100644 --- a/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java +++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java @@ -24,6 +24,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import static com.google.common.truth.Truth.assertThat; @@ -32,8 +33,10 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.provider.Settings; @@ -54,6 +57,8 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowActivity; +import org.robolectric.shadows.ShadowDevicePolicyManager; +import org.robolectric.shadows.ShadowLog; @RunWith(RobolectricTestRunner.class) public class SetNewPasswordActivityTest { @@ -91,7 +96,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class).get(); activity.launchChooseLock(new Bundle()); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent intent = shadowActivity.getNextStartedActivityForResult().intent; + Intent intent = getLaunchChooseLockIntent(shadowActivity); assertThat(intent.getComponent()) .isEqualTo(new ComponentName(activity, ChooseLockGeneric.class)); @@ -105,7 +110,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class).get(); activity.launchChooseLock(new Bundle()); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent intent = shadowActivity.getNextStartedActivityForResult().intent; + Intent intent = getLaunchChooseLockIntent(shadowActivity); assertThat(intent.getComponent()) .isEqualTo(new ComponentName(activity, SetupChooseLockGeneric.class)); @@ -149,7 +154,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent; + Intent actualIntent = getLaunchChooseLockIntent(shadowActivity); assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD); assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue(); assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE)) @@ -179,7 +184,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent; + Intent actualIntent = getLaunchChooseLockIntent(shadowActivity); assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD); assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse(); assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue(); @@ -207,7 +212,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent; + Intent actualIntent = getLaunchChooseLockIntent(shadowActivity); assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD); assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse(); assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue(); @@ -234,7 +239,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent; + Intent actualIntent = getLaunchChooseLockIntent(shadowActivity); assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD); assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse(); assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue(); @@ -262,7 +267,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent; + Intent actualIntent = getLaunchChooseLockIntent(shadowActivity); assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD); assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse(); assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue(); @@ -289,7 +294,7 @@ public class SetNewPasswordActivityTest { Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); - Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent; + Intent actualIntent = getLaunchChooseLockIntent(shadowActivity); assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD); assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse(); assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue(); @@ -301,4 +306,45 @@ public class SetNewPasswordActivityTest { PKG_NAME, Integer.MIN_VALUE); } + + @Test + @Config(shadows = {ShadowPasswordUtils.class}) + public void launchChooseLock_callingAppIsAdmin_setsAdminExtra() { + SetNewPasswordActivity activity = + Robolectric.buildActivity(SetNewPasswordActivity.class).get(); + DevicePolicyManager devicePolicyManager = + (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); + Shadows.shadowOf(devicePolicyManager).setActiveAdmin(buildTestComponentName(PKG_NAME)); + ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME); + + activity.launchChooseLock(new Bundle()); + + Intent intent = getLaunchChooseLockIntent(Shadows.shadowOf(activity)); + assertThat(intent.hasExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN)).isTrue(); + } + + @Test + @Config(shadows = {ShadowPasswordUtils.class}) + public void launchChooseLock_callingAppIsNotAdmin_doesNotSetAdminExtra() { + SetNewPasswordActivity activity = + Robolectric.buildActivity(SetNewPasswordActivity.class).get(); + DevicePolicyManager devicePolicyManager = + (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); + Shadows.shadowOf(devicePolicyManager) + .setActiveAdmin(buildTestComponentName("other_pkg_name")); + ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME); + + activity.launchChooseLock(new Bundle()); + + Intent intent = getLaunchChooseLockIntent(Shadows.shadowOf(activity)); + assertThat(intent.hasExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN)).isFalse(); + } + + private ComponentName buildTestComponentName(String packageName) { + return new ComponentName(packageName, "clazz"); + } + + private Intent getLaunchChooseLockIntent(ShadowActivity shadowActivity) { + return shadowActivity.getNextStartedActivityForResult().intent; + } } From 72bdef07816db010393c78ac367fd45bd154730e Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Mon, 20 May 2019 14:03:07 -0400 Subject: [PATCH 05/12] Fix hiding of channel fields When channel is off Test: atest Bug: 132971502 Change-Id: I5772266e022e5ebb5dbf20f231ca30fad95e3db7 --- .../notification/NotificationPreferenceController.java | 4 +++- .../notification/NotificationPreferenceControllerTest.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java index d09ea4dc3dc..2ae7019ea3c 100644 --- a/src/com/android/settings/notification/NotificationPreferenceController.java +++ b/src/com/android/settings/notification/NotificationPreferenceController.java @@ -74,7 +74,9 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc return false; } if (mChannelGroup != null) { - return !mChannelGroup.isBlocked(); + if (mChannelGroup.isBlocked()) { + return false; + } } if (mChannel != null) { return mChannel.getImportance() != IMPORTANCE_NONE; diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java index cde5b900cf1..b024cee3632 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java @@ -105,10 +105,12 @@ public class NotificationPreferenceControllerTest { @Test public void isAvailable_notIfChannelBlocked() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannelGroup group = mock(NotificationChannelGroup.class); + when(group.isBlocked()).thenReturn(false); NotificationChannel channel = mock(NotificationChannel.class); when(channel.getImportance()).thenReturn(IMPORTANCE_NONE); - mController.onResume(appRow, channel, null, null); + mController.onResume(appRow, channel, group, null); assertFalse(mController.isAvailable()); } From 26306c749872f6020d710435b14ec3d54e6ce6bd Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 20 May 2019 14:10:42 -0700 Subject: [PATCH 06/12] Update strings Bug: 132787143 Test: Builds Change-Id: I382c84fbeb6ca2c151d6a4fa2f7a3d29d7c72505 --- res/values/strings.xml | 68 +++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index c5fbf5336e8..3a3a5191821 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -882,17 +882,17 @@ Screen lock - + Face added - - Tap to set up face authentication + + Tap to set up face unlock - Face authentication + Face unlock - How to set up Face unlock + How to set up face unlock - Set up Face unlock - + Set up face unlock + Use your face to authenticate @@ -910,7 +910,7 @@ Cancel Unlock with your face - + Use your face to authenticate Use your face to unlock your phone, authorize purchases, or sign in to apps. @@ -952,13 +952,13 @@ Use face unlock for Unlocking your phone - + App sign-in \u0026 payments Require for face unlock - + Open eyes looking at screen - + To unlock the phone, always require looking at the screen with your eyes open Confirm button @@ -969,7 +969,7 @@ Set up new face unlock - Use Face unlock to unlock your device, sign in to apps, and confirm payments.\n\nKeep in mind:\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face while your eyes are open.\n\nYour phone can be unlocked by someone who looks a lot like you, say, an identical sibling. + Use face unlock to unlock your device, sign in to apps, and confirm payments.\n\nKeep in mind:\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face while your eyes are open.\n\nYour phone can be unlocked by someone who looks a lot like you, say, an identical sibling. Delete face data? @@ -1074,12 +1074,12 @@ Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN, pattern, or password. Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN, pattern, or password. - - Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN, pattern, or password. - - Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN, pattern, or password. - - Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN, pattern, or password. + + Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. Tap Cancel, then set a PIN, pattern, or password. + + Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. Tap Cancel, then set a PIN, pattern, or password. + + Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. Tap Cancel, then set a PIN, pattern, or password. Skip PIN setup? @@ -1323,7 +1323,7 @@ Choose your backup screen lock method - + Choose your backup screen lock method @@ -1401,19 +1401,19 @@ You can unlock your phone using your fingerprint. For security, this option requires a backup screen lock. - - Face authentication + Pattern + + Face unlock + Pattern - - Face authentication + PIN + + Face unlock + PIN - - Face authentication + Password + + Face unlock + Password - - Continue without face authentication + + Continue without face unlock - + You can unlock your phone using your face. For security, this option requires a backup screen lock. @@ -4049,12 +4049,12 @@ PIN has been set Pattern has been set - - To use face authentication, set password - - To use face authentication, set pattern - - To use face authentication, set PIN + + To use face unlock, set password + + To use face unlock, set pattern + + To use face unlock, set PIN From 4feab60a3037064d7b885cd37d8f813b4faddbf1 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 20 May 2019 15:23:05 -0700 Subject: [PATCH 07/12] Remove SmsDefaultDialog which has been replaced by role. Bug: 131204827 Test: presubmit Change-Id: If436d4f0777838dc490fa45901005008bb57315b --- AndroidManifest.xml | 10 - .../android/settings/SmsDefaultDialog.java | 289 ------------------ 2 files changed, 299 deletions(-) delete mode 100644 src/com/android/settings/SmsDefaultDialog.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index cb63df92a3f..311840336dc 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2403,16 +2403,6 @@ android:excludeFromRecents="true"> - - - - - - - = 0) { - AppListAdapter adapter = (AppListAdapter) mAlertParams.mAdapter; - if (!adapter.isSelected(which)) { - String packageName = adapter.getPackageName(which); - if (!TextUtils.isEmpty(packageName)) { - SmsApplication.setDefaultApplication(packageName, this); - setResult(RESULT_OK); - } - } - } - break; - } - } - - private boolean buildDialog(String packageName) { - TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); - if (!tm.isSmsCapable()) { - // No phone, no SMS - return false; - } - final AlertController.AlertParams p = mAlertParams; - p.mTitle = getString(R.string.sms_change_default_dialog_title); - mNewSmsApplicationData = SmsApplication.getSmsApplicationData(packageName, this); - if (mNewSmsApplicationData != null) { - // New default SMS app specified, change to that directly after the confirmation - // dialog. - SmsApplicationData oldSmsApplicationData = null; - ComponentName oldSmsComponent = SmsApplication.getDefaultSmsApplication(this, true); - if (oldSmsComponent != null) { - oldSmsApplicationData = SmsApplication.getSmsApplicationData( - oldSmsComponent.getPackageName(), this); - if (oldSmsApplicationData.mPackageName.equals( - mNewSmsApplicationData.mPackageName)) { - return false; - } - } - - // Compose dialog; get - if (oldSmsApplicationData != null) { - p.mMessage = getString(R.string.sms_change_default_dialog_text, - mNewSmsApplicationData.getApplicationName(this), - oldSmsApplicationData.getApplicationName(this)); - } else { - p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text, - mNewSmsApplicationData.getApplicationName(this)); - } - p.mPositiveButtonText = getString(R.string.yes); - p.mNegativeButtonText = getString(R.string.no); - p.mPositiveButtonListener = this; - p.mNegativeButtonListener = this; - } else { - // No new default SMS app specified, show a list of all SMS apps and let user to pick - p.mAdapter = new AppListAdapter(); - p.mOnClickListener = this; - p.mNegativeButtonText = getString(R.string.cancel); - p.mNegativeButtonListener = this; - if (p.mAdapter.isEmpty()) { - // If there is nothing to choose from, don't build the dialog. - return false; - } - } - setupAlert(); - - return true; - } - - /** - * The list of SMS apps with label, icon. Current default SMS app is marked as "default". - */ - private class AppListAdapter extends BaseAdapter { - /** - * SMS app item in the list - */ - private class Item { - final String label; // app label - final Drawable icon; // app icon - final String packgeName; // full app package name - - public Item(String label, Drawable icon, String packageName) { - this.label = label; - this.icon = icon; - this.packgeName = packageName; - } - } - - // The list - private final List mItems; - // The index of selected - private final int mSelectedIndex; - - public AppListAdapter() { - mItems = getItems(); - int selected = getSelectedIndex(); - // Move selected up to the top so it is easy to find - if (selected > 0) { - Item item = mItems.remove(selected); - mItems.add(0, item); - selected = 0; - } - mSelectedIndex = selected; - } - - @Override - public int getCount() { - return mItems != null ? mItems.size() : 0; - } - - @Override - public Object getItem(int position) { - return mItems != null && position < mItems.size() ? mItems.get(position) : null; - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - Item item = ((Item) getItem(position)); - LayoutInflater inflater = getLayoutInflater(); - View view = inflater.inflate(R.layout.app_preference_item, parent, false); - TextView textView = (TextView) view.findViewById(android.R.id.title); - textView.setText(item.label); - if (position == mSelectedIndex) { - view.findViewById(R.id.default_label).setVisibility(View.VISIBLE); - } else { - view.findViewById(R.id.default_label).setVisibility(View.GONE); - } - ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); - imageView.setImageDrawable(item.icon); - return view; - } - - /** - * Get the selected package name by - * - * @param position the index of the item in the list - * @return the package name of selected item - */ - public String getPackageName(int position) { - Item item = (Item) getItem(position); - if (item != null) { - return item.packgeName; - } - return null; - } - - /** - * Check if an item at a position is already selected - * - * @param position the index of the item in the list - * @return true if the item at the position is already selected, false otherwise - */ - public boolean isSelected(int position) { - return position == mSelectedIndex; - } - - // Get the list items by looking for SMS apps - private List getItems() { - PackageManager pm = getPackageManager(); - List items = new ArrayList<>(); - for (SmsApplication.SmsApplicationData app : - SmsApplication.getApplicationCollection(SmsDefaultDialog.this)) { - try { - String packageName = app.mPackageName; - ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0/*flags*/); - if (appInfo != null) { - items.add(new Item( - appInfo.loadLabel(pm).toString(), - appInfo.loadIcon(pm), - packageName)); - } - } catch (PackageManager.NameNotFoundException e) { - // Ignore package can't be found - } - } - return items; - } - - // Get the selected item index by looking for the current default SMS app - private int getSelectedIndex() { - ComponentName appName = SmsApplication.getDefaultSmsApplication( - SmsDefaultDialog.this, true); - if (appName != null) { - String defaultSmsAppPackageName = appName.getPackageName(); - if (!TextUtils.isEmpty(defaultSmsAppPackageName)) { - for (int i = 0; i < mItems.size(); i++) { - if (TextUtils.equals(mItems.get(i).packgeName, defaultSmsAppPackageName)) { - return i; - } - } - } - } - return -1; - } - } -} From 8c6098e5cf671122edd196be1582fa97575ceb25 Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Mon, 20 May 2019 17:20:31 -0700 Subject: [PATCH 08/12] Fix signal strength display in 'Choose network' list For GSM networks, the "Choose network" page allows you to manually pick from among different cell networks, and shows signal strength and network type (LTE, 3g, etc.) for available ones. The signal strength wedges were transparent and not visible to the user - this CL fixes that. Bug: 132895135 Test: visual (Insert SIM with GSM service, then go to Settings -> Network & internet -> Mobile network -> Advanced -> Automatically select network) Change-Id: Ibbbc60b590b09e4b4f5e31b49fe578769dcdbc4d --- .../settings/network/telephony/NetworkOperatorPreference.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java index a334aeb72fb..2359399478e 100644 --- a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java +++ b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java @@ -30,6 +30,7 @@ import android.view.Gravity; import androidx.preference.Preference; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settingslib.graph.SignalDrawable; import java.util.List; @@ -144,6 +145,7 @@ public class NetworkOperatorPreference extends Preference { // Set the signal strength icon at the bottom right icons.setLayerGravity(1 /* index of SignalDrawable */, Gravity.BOTTOM | Gravity.RIGHT); icons.setLayerSize(1 /* index of SignalDrawable */, iconSize, iconSize); + icons.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal)); setIcon(icons); } } From 81b9f5083d70ae0ea71376df05d7394c4c27ad99 Mon Sep 17 00:00:00 2001 From: Raff Tsai Date: Tue, 21 May 2019 11:30:13 +0800 Subject: [PATCH 09/12] Make SeekBarPreference to be selectable Fixes: 132983200 Test: make RunSettingsRoboTests, manual Change-Id: I3d4bc59d948236ff2482945a4fc976ee61c37c27 --- .../settings/widget/SeekBarPreference.java | 13 +++++- .../res/xml-mcc998/seekbar_preference.xml | 23 ++++++++++ .../res/xml-mcc999/seekbar_preference.xml | 24 ++++++++++ .../widget/SeekBarPreferenceTest.java | 44 +++++++++++++++++-- 4 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 tests/robotests/res/xml-mcc998/seekbar_preference.xml create mode 100644 tests/robotests/res/xml-mcc999/seekbar_preference.xml diff --git a/src/com/android/settings/widget/SeekBarPreference.java b/src/com/android/settings/widget/SeekBarPreference.java index 44def119ea2..bdd1ba94474 100644 --- a/src/com/android/settings/widget/SeekBarPreference.java +++ b/src/com/android/settings/widget/SeekBarPreference.java @@ -69,6 +69,13 @@ public class SeekBarPreference extends RestrictedPreference com.android.internal.R.layout.preference_widget_seekbar); a.recycle(); + a = context.obtainStyledAttributes( + attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes); + final boolean isSelectable = a.getBoolean( + com.android.settings.R.styleable.Preference_android_selectable, false); + setSelectable(isSelectable); + a.recycle(); + setLayoutResource(layoutResId); } @@ -93,7 +100,11 @@ public class SeekBarPreference extends RestrictedPreference @Override public boolean isSelectable() { - return isDisabledByAdmin(); + if(isDisabledByAdmin()) { + return true; + } else { + return super.isSelectable(); + } } @Override diff --git a/tests/robotests/res/xml-mcc998/seekbar_preference.xml b/tests/robotests/res/xml-mcc998/seekbar_preference.xml new file mode 100644 index 00000000000..e474c1e06bb --- /dev/null +++ b/tests/robotests/res/xml-mcc998/seekbar_preference.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/tests/robotests/res/xml-mcc999/seekbar_preference.xml b/tests/robotests/res/xml-mcc999/seekbar_preference.xml new file mode 100644 index 00000000000..77435e8d198 --- /dev/null +++ b/tests/robotests/res/xml-mcc999/seekbar_preference.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java index 0a1d5d80de5..f7dea225236 100644 --- a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java @@ -22,16 +22,24 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.os.Bundle; import android.os.Parcelable; +import androidx.preference.PreferenceFragmentCompat; + +import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.androidx.fragment.FragmentController; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowRestrictedLockUtilsInternal.class) public class SeekBarPreferenceTest { private static final int MAX = 75; @@ -73,9 +81,39 @@ public class SeekBarPreferenceTest { } @Test - public void isSelectable_notDisabledByAdmin_returnFalse() { - when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(false); + @Config(qualifiers = "mcc998") + public void isSelectable_default_returnFalse() { + final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(), + new Bundle()) + .create() + .start() + .resume() + .get(); - assertThat(mSeekBarPreference.isSelectable()).isFalse(); + final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar"); + + assertThat(seekBarPreference.isSelectable()).isFalse(); + } + + @Test + @Config(qualifiers = "mcc999") + public void isSelectable_selectableInXml_returnTrue() { + final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(), + new Bundle()) + .create() + .start() + .resume() + .get(); + + final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar"); + + assertThat(seekBarPreference.isSelectable()).isTrue(); + } + + public static class TestFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(com.android.settings.R.xml.seekbar_preference); + } } } From 91c7f77fe8c81b9408517511773acaa6884c59ff Mon Sep 17 00:00:00 2001 From: Raff Tsai Date: Tue, 21 May 2019 15:12:46 +0800 Subject: [PATCH 10/12] Fix gray lines appear in animation video Fixes: 133076740 Fixes: 132991217 Test: manual Change-Id: I3ab740ede12bf768176691e513bcaff4349eb76e --- res/layout/video_preference.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/layout/video_preference.xml b/res/layout/video_preference.xml index 17b867fcbc1..064596cc458 100644 --- a/res/layout/video_preference.xml +++ b/res/layout/video_preference.xml @@ -21,6 +21,7 @@ android:layout_height="wrap_content" android:background="@color/gestures_setting_background_color" android:clipToPadding="false" + android:clipChildren="true" android:gravity="center" android:minHeight="?android:attr/listPreferredItemHeightSmall" android:orientation="horizontal" From 66dba9479749b8dcdf16627ac2fcab65652e783e Mon Sep 17 00:00:00 2001 From: Amin Shaikh Date: Mon, 20 May 2019 21:36:57 +0000 Subject: [PATCH 11/12] Remove unnecessary STOPSHIP. THEME_CUSTOMIZATION_OVERLAY_PACKAGES will no be set in Q. When it is set, these developer settings will be removed entirely. Change-Id: Ic33bb68a4e4a0fabc6731169ef96ecd386dc441e Fixes: 122308197 Test: presubmit --- .../development/OverlayCategoryPreferenceController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/development/OverlayCategoryPreferenceController.java b/src/com/android/settings/development/OverlayCategoryPreferenceController.java index 7a2ee08020f..6e0b2d00f6b 100644 --- a/src/com/android/settings/development/OverlayCategoryPreferenceController.java +++ b/src/com/android/settings/development/OverlayCategoryPreferenceController.java @@ -198,8 +198,8 @@ public class OverlayCategoryPreferenceController extends DeveloperOptionsPrefere @Override protected void onDeveloperOptionsSwitchDisabled() { super.onDeveloperOptionsSwitchDisabled(); - // STOPSHIP b/122308197: reset the overlays to the set in - // Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES + // TODO b/133222035: remove these developer settings when the + // Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES setting is used setOverlay(PACKAGE_DEVICE_DEFAULT); updateState(mPreference); } From 5c46d93bd8121e5681beaef0b6344471dde6980b Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Tue, 21 May 2019 09:45:26 -0700 Subject: [PATCH 12/12] Prevent NullPointerException in SimStatusDialogController In rare cases the SignalStrength we get for a SIM can be null, which wasn't checked for in this code. This CL adds a null check and fixes the tests so it's possible to verify the fix (one of the methods that would have crashed was being spy'd over unnecessarily). Fixes: 132570076 Test: make RunSettingsRobotests Change-Id: Ifdec24f184ee2d93e5e242eb2c20695249992fc6 --- .../simstatus/SimStatusDialogController.java | 9 ++++---- .../SimStatusDialogControllerTest.java | 22 ++++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java index c18ec787b91..3fafd14f625 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java @@ -297,6 +297,9 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O } private void updateSignalStrength(SignalStrength signalStrength) { + if (signalStrength == null) { + return; + } final int subscriptionId = mSubscriptionInfo.getSubscriptionId(); final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subscriptionId); @@ -430,13 +433,11 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O mSubscriptionInfo.getSubscriptionId()); } - @VisibleForTesting - int getDbm(SignalStrength signalStrength) { + private int getDbm(SignalStrength signalStrength) { return signalStrength.getDbm(); } - @VisibleForTesting - int getAsuLevel(SignalStrength signalStrength) { + private int getAsuLevel(SignalStrength signalStrength) { return signalStrength.getAsuLevel(); } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java index 76c444e2c1a..0f39fc9a520 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java @@ -121,8 +121,8 @@ public class SimStatusDialogControllerTest { mLifecycle = new Lifecycle(mLifecycleOwner); mController = spy(new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */)); doReturn(mServiceState).when(mController).getCurrentServiceState(); - doReturn(0).when(mController).getDbm(any()); - doReturn(0).when(mController).getAsuLevel(any()); + doReturn(0).when(mSignalStrength).getDbm(); + doReturn(0).when(mSignalStrength).getAsuLevel(); doReturn(mPhoneStateListener).when(mController).getPhoneStateListener(); doReturn("").when(mController).getPhoneNumber(); doReturn(mSignalStrength).when(mController).getSignalStrength(); @@ -136,6 +136,9 @@ public class SimStatusDialogControllerTest { ReflectionHelpers.setField(mController, "mEuiccManager", mEuiccManager); ReflectionHelpers.setField(mController, "mSubscriptionManager", mSubscriptionManager); when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mPersistableBundle); + when(mPersistableBundle.getBoolean( + CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL)) + .thenReturn(true); final ShadowPackageManager shadowPackageManager = Shadows.shadowOf(RuntimeEnvironment.application.getPackageManager()); @@ -228,8 +231,8 @@ public class SimStatusDialogControllerTest { public void initialize_updateSignalStrengthWith50_shouldUpdateSignalStrengthTo50() { final int signalDbm = 50; final int signalAsu = 50; - doReturn(signalDbm).when(mController).getDbm(mSignalStrength); - doReturn(signalAsu).when(mController).getAsuLevel(mSignalStrength); + doReturn(signalDbm).when(mSignalStrength).getDbm(); + doReturn(signalAsu).when(mSignalStrength).getAsuLevel(); when(mPersistableBundle.getBoolean( CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL)).thenReturn(true); @@ -249,8 +252,8 @@ public class SimStatusDialogControllerTest { final int signalDbm = 50; final int signalAsu = 50; - doReturn(signalDbm).when(mController).getDbm(mSignalStrength); - doReturn(signalAsu).when(mController).getAsuLevel(mSignalStrength); + doReturn(signalDbm).when(mSignalStrength).getDbm(); + doReturn(signalAsu).when(mSignalStrength).getAsuLevel(); when(mPersistableBundle.getBoolean( CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL)).thenReturn(true); @@ -415,4 +418,11 @@ public class SimStatusDialogControllerTest { verify(mDialog).removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID); verify(mDialog).removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID); } + + @Test + public void initialize_nullSignalStrength_noCrash() { + doReturn(null).when(mController).getSignalStrength(); + // we should not crash when running the following line + mController.initialize(); + } }