From 8d06d63fe3c065a919d8470e97b8b6be4979bbad Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Mon, 21 Jun 2021 23:33:17 +0100 Subject: [PATCH 01/28] Remove credential management app Settings * Update string and icon * Flip icon if languate is RTL e.g. Arabic * Add dialog when 'Remove app' is selected * Add Material Next theme to dialog * Update string terminology when removing a CA or user certificate to from 'remove' to 'uninstall' * Final UI tweaks to RequestManageCredentials screen Screenshots * Light mode: https://screenshot.googleplex.com/66QKFLhtn6ZueZQ * Dark mode: https://screenshot.googleplex.com/9kkTaaDV6CiHudF * RTL: https://screenshot.googleplex.com/AkwSibXakARYM8H * Request light mode: https://screenshot.googleplex.com/6n6raBQ8drXRHcU * Request dark mode: https://screenshot.googleplex.com/3bmWNoTwE6JBqAX Bug: 189416800 Test: atest CredentialManagementAppButtonsControllerTest manual testing with TestDPC Change-Id: I5450d33603418930e92b03c4447aaa1095afe9a3 --- AndroidManifest.xml | 1 + res/drawable/ic_redo_24.xml | 25 ++++++ .../request_manage_credentials.xml | 3 +- .../request_manage_credentials.xml | 3 +- res/layout/request_manage_credentials.xml | 3 +- res/values/strings.xml | 8 +- res/values/styles.xml | 5 +- ...dentialManagementAppButtonsController.java | 81 +++++++++++++++---- .../security/RequestManageCredentials.java | 2 +- 9 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 res/drawable/ic_redo_24.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index aa2a1422e3e..d86a6d80cb7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1485,6 +1485,7 @@ diff --git a/res/drawable/ic_redo_24.xml b/res/drawable/ic_redo_24.xml new file mode 100644 index 00000000000..21a2020f90a --- /dev/null +++ b/res/drawable/ic_redo_24.xml @@ -0,0 +1,25 @@ + + + + \ No newline at end of file diff --git a/res/layout-land/request_manage_credentials.xml b/res/layout-land/request_manage_credentials.xml index 0c7bded8a99..fbe0bd0fbad 100644 --- a/res/layout-land/request_manage_credentials.xml +++ b/res/layout-land/request_manage_credentials.xml @@ -123,11 +123,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/request_manage_credentials_more" + android:textColor="?android:attr/colorBackground" android:theme="@style/Theme.CollapsingToolbar.Settings" app:backgroundTint="?android:attr/colorAccent" app:elevation="3dp" app:icon="@drawable/ic_arrow_downward" - app:iconTint="?android:attr/textColorPrimary" + app:iconTint="?android:attr/colorBackground" app:layout_anchor="@id/apps_list" app:layout_anchorGravity="bottom|center" /> diff --git a/res/layout-sw600dp/request_manage_credentials.xml b/res/layout-sw600dp/request_manage_credentials.xml index f8cf5596f03..42facd3e13f 100644 --- a/res/layout-sw600dp/request_manage_credentials.xml +++ b/res/layout-sw600dp/request_manage_credentials.xml @@ -97,11 +97,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/request_manage_credentials_more" + android:textColor="?android:attr/colorBackground" android:theme="@style/Theme.CollapsingToolbar.Settings" app:backgroundTint="?android:attr/colorAccent" app:elevation="3dp" app:icon="@drawable/ic_arrow_downward" - app:iconTint="?android:attr/textColorPrimary" + app:iconTint="?android:attr/colorBackground" app:layout_anchor="@id/apps_list" app:layout_anchorGravity="bottom|center" /> diff --git a/res/layout/request_manage_credentials.xml b/res/layout/request_manage_credentials.xml index c8167b6ac1d..ee697f7c2e3 100644 --- a/res/layout/request_manage_credentials.xml +++ b/res/layout/request_manage_credentials.xml @@ -67,11 +67,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/request_manage_credentials_more" + android:textColor="?android:attr/colorBackground" app:layout_anchor="@id/apps_list" app:layout_anchorGravity="bottom|center" app:elevation="3dp" app:icon="@drawable/ic_arrow_downward" - app:iconTint="?android:attr/textColorPrimary" + app:iconTint="?android:attr/colorBackground" app:backgroundTint="?android:attr/colorAccent" android:theme="@style/Theme.CollapsingToolbar.Settings"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index 0d88aaef4ff..99a06314242 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6869,7 +6869,11 @@ Uninstall certificates - Remove + Remove app + + Remove this app? + + This app won\u2019t manage certificates, but it will stay on your device. Any certificates installed by the app will be uninstalled. %d URL @@ -7491,7 +7495,7 @@ Enable - Remove + Uninstall Trust diff --git a/res/values/styles.xml b/res/values/styles.xml index 63ea86ebe3b..34456273b4c 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -806,21 +806,18 @@ google-sans-medium 14sp false - ?android:attr/textColorPrimary diff --git a/src/com/android/settings/security/CredentialManagementAppButtonsController.java b/src/com/android/settings/security/CredentialManagementAppButtonsController.java index b296f379a55..250dd133e81 100644 --- a/src/com/android/settings/security/CredentialManagementAppButtonsController.java +++ b/src/com/android/settings/security/CredentialManagementAppButtonsController.java @@ -16,8 +16,11 @@ package com.android.settings.security; +import android.app.Dialog; import android.app.admin.DevicePolicyEventLogger; +import android.app.settings.SettingsEnums; import android.content.Context; +import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; @@ -25,12 +28,15 @@ import android.security.IKeyChainService; import android.security.KeyChain; import android.stats.devicepolicy.DevicePolicyEnums; import android.util.Log; +import android.view.View; +import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settingslib.widget.ActionButtonsPreference; import java.util.concurrent.ExecutorService; @@ -48,9 +54,16 @@ public class CredentialManagementAppButtonsController extends BasePreferenceCont private final Handler mHandler = new Handler(Looper.getMainLooper()); private boolean mHasCredentialManagerPackage; private Fragment mFragment; + private final int mRemoveIcon; public CredentialManagementAppButtonsController(Context context, String preferenceKey) { super(context, preferenceKey); + if (context.getResources().getConfiguration().getLayoutDirection() + == View.LAYOUT_DIRECTION_RTL) { + mRemoveIcon = R.drawable.ic_redo_24; + } else { + mRemoveIcon = R.drawable.ic_undo_24; + } } public void setParentFragment(Fragment fragment) { @@ -84,8 +97,8 @@ public class CredentialManagementAppButtonsController extends BasePreferenceCont .setButton1Icon(R.drawable.ic_upload) .setButton1OnClickListener(view -> uninstallCertificates()) .setButton2Text(R.string.remove_credential_management_app) - .setButton2Icon(R.drawable.ic_delete) - .setButton2OnClickListener(view -> removeCredentialManagementApp()); + .setButton2Icon(mRemoveIcon) + .setButton2OnClickListener(view -> showRemoveCredentialManagementAppDialog()); } } @@ -103,18 +116,54 @@ public class CredentialManagementAppButtonsController extends BasePreferenceCont }); } - private void removeCredentialManagementApp() { - mExecutor.execute(() -> { - try { - IKeyChainService service = KeyChain.bind(mContext).getService(); - service.removeCredentialManagementApp(); - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.CREDENTIAL_MANAGEMENT_APP_REMOVED) - .write(); - mFragment.getActivity().finish(); - } catch (InterruptedException | RemoteException e) { - Log.e(TAG, "Unable to remove the credential management app"); - } - }); + private void showRemoveCredentialManagementAppDialog() { + final RemoveCredentialManagementAppDialog dialog = + RemoveCredentialManagementAppDialog.newInstance(); + dialog.show(mFragment.getParentFragmentManager(), + RemoveCredentialManagementAppDialog.class.getName()); } -} + + /** + * Implements an AlertDialog for confirming that a user wants to remove the credential + * management app. The app will no longer be able to manage certificates, but it will stay on + * the device. All certificates installed by the credential management app will be uninstalled. + */ + public static class RemoveCredentialManagementAppDialog extends InstrumentedDialogFragment { + + public static RemoveCredentialManagementAppDialog newInstance() { + return new RemoveCredentialManagementAppDialog(); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return new AlertDialog.Builder(getContext(), R.style.Theme_AlertDialog) + .setTitle(R.string.remove_credential_management_app_dialog_title) + .setMessage(R.string.remove_credential_management_app_dialog_message) + .setPositiveButton(R.string.remove_credential_management_app, + (dialog, which) -> removeCredentialManagementApp()) + .setNegativeButton(R.string.cancel, (dialog, which) -> dismiss()) + .create(); + } + + private void removeCredentialManagementApp() { + final ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + try { + IKeyChainService service = KeyChain.bind(getContext()).getService(); + service.removeCredentialManagementApp(); + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.CREDENTIAL_MANAGEMENT_APP_REMOVED) + .write(); + getParentFragment().getActivity().finish(); + } catch (InterruptedException | RemoteException e) { + Log.e(TAG, "Unable to remove the credential management app"); + } + }); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.CREDENTIAL_MANAGEMENT_APP_REMOVE_APP; + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/security/RequestManageCredentials.java b/src/com/android/settings/security/RequestManageCredentials.java index cda97da17d3..1a8da671a2c 100644 --- a/src/com/android/settings/security/RequestManageCredentials.java +++ b/src/com/android/settings/security/RequestManageCredentials.java @@ -288,7 +288,7 @@ public class RequestManageCredentials extends Activity { // On down scroll, hide text in floating action button by setting // extended to false. if (dy > 0 && mExtendedFab.getVisibility() == View.VISIBLE) { - mExtendedFab.setExtended(false); + mExtendedFab.shrink(); } if (isRecyclerScrollable()) { mExtendedFab.show(); From b182a4fb5c1027d754f9cc54d0f3dee4fbaad6dc Mon Sep 17 00:00:00 2001 From: Joshua Mccloskey Date: Wed, 30 Jun 2021 09:16:20 -0700 Subject: [PATCH 02/28] Refactored bad_calibration string Test: Manual Bug: 192105305 Change-Id: I82b0965459537c940b269636b8277af89b5ad284 --- .../settings/biometrics/fingerprint/FingerprintErrorDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java b/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java index e4d86a199e7..fa929514173 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java @@ -45,7 +45,7 @@ public class FingerprintErrorDialog extends BiometricErrorDialog { // This message happens when the underlying crypto layer decides to revoke the // enrollment auth token. return R.string.security_settings_fingerprint_enroll_error_timeout_dialog_message; - case FingerprintManager.FINGERPRINT_ERROR_BAD_CALIBARTION: + case FingerprintManager.FINGERPRINT_ERROR_BAD_CALIBRATION: return R.string.security_settings_fingerprint_bad_calibration; default: // There's nothing specific to tell the user about. Ask them to try again. From d4ce558f3350c04a1a6542337c30502235e891de Mon Sep 17 00:00:00 2001 From: Ahaan Ugale Date: Wed, 30 Jun 2021 00:21:40 -0700 Subject: [PATCH 03/28] Password settings: Fix work profile Currently, the work profile password settings just point to the personal profile app. This change fixes this using the forWork metadata tag, that sets the work profile user in BasePreferenceController. Also fixes and re-enables the displayPreference_withPasswords_addsPreference test. Fix: 192417100 Test: manual - work profile link works, password count is accurate Test: atest PasswordsPreferenceControllerTest Change-Id: I6345b69b9c03ff13b8e2784e69dc0188abc436e3 --- res/xml/accounts_work_dashboard_settings.xml | 1 + .../PasswordsPreferenceController.java | 49 ++++++++++++------- .../PasswordsPreferenceControllerTest.java | 38 +++++++++++--- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/res/xml/accounts_work_dashboard_settings.xml b/res/xml/accounts_work_dashboard_settings.xml index 1c4c6aa3f3d..32699338434 100644 --- a/res/xml/accounts_work_dashboard_settings.xml +++ b/res/xml/accounts_work_dashboard_settings.xml @@ -28,6 +28,7 @@ android:persistent="false" android:title="@string/autofill_passwords" settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController" + settings:forWork="true" settings:keywords="@string/autofill_keywords" /> availableServices) { super(context, preferenceKey); mPm = context.getPackageManager(); mIconFactory = IconDrawableFactory.newInstance(mContext); + mServices = new ArrayList<>(); + } + + @OnLifecycleEvent(ON_CREATE) + void onCreate(LifecycleOwner lifecycleOwner) { + init(lifecycleOwner, AutofillServiceInfo.getAvailableServices(mContext, getUser())); + } + + @VisibleForTesting + void init(LifecycleOwner lifecycleOwner, List availableServices) { + mLifecycleOwner = lifecycleOwner; + for (int i = availableServices.size() - 1; i >= 0; i--) { final String passwordsActivity = availableServices.get(i).getPasswordsActivity(); if (TextUtils.isEmpty(passwordsActivity)) { availableServices.remove(i); } } - mServices = availableServices; - } - - @OnLifecycleEvent(ON_CREATE) - void onCreate(LifecycleOwner lifecycleOwner) { - mLifecycleOwner = lifecycleOwner; + // TODO: Reverse the loop above and add to mServices directly. + mServices.clear(); + mServices.addAll(availableServices); } @Override @@ -109,8 +112,7 @@ public class PasswordsPreferenceController extends BasePreferenceController public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); final PreferenceGroup group = screen.findPreference(getPreferenceKey()); - // TODO(b/169455298): Show work profile passwords too. - addPasswordPreferences(screen.getContext(), UserHandle.myUserId(), group); + addPasswordPreferences(screen.getContext(), getUser(), group); } private void addPasswordPreferences( @@ -126,9 +128,15 @@ public class PasswordsPreferenceController extends BasePreferenceController serviceInfo.applicationInfo, user); pref.setIcon(Utils.getSafeIcon(icon)); - pref.setIntent( - new Intent(Intent.ACTION_MAIN) - .setClassName(serviceInfo.packageName, service.getPasswordsActivity())); + pref.setOnPreferenceClickListener(p -> { + final Intent intent = + new Intent(Intent.ACTION_MAIN) + .setClassName( + serviceInfo.packageName, + service.getPasswordsActivity()); + prefContext.startActivityAsUser(intent, UserHandle.of(user)); + return true; + }); // Set an empty summary to avoid a UI flicker when the value loads. pref.setSummary(R.string.summary_placeholder); @@ -213,4 +221,9 @@ public class PasswordsPreferenceController extends BasePreferenceController } } } + + private int getUser() { + UserHandle workUser = getWorkProfileUser(); + return workUser != null ? workUser.getIdentifier() : UserHandle.myUserId(); + } } diff --git a/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java index 25d989385d3..da860ecb539 100644 --- a/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java @@ -21,11 +21,19 @@ import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_U import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.os.Looper; +import android.os.UserHandle; import android.service.autofill.AutofillServiceInfo; import androidx.lifecycle.Lifecycle; @@ -40,9 +48,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.collect.Lists; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import java.util.Collections; import java.util.List; @@ -56,7 +64,7 @@ public class PasswordsPreferenceControllerTest { @Before public void setUp() { - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); if (Looper.myLooper() == null) { Looper.prepare(); // needed to create the preference screen } @@ -66,6 +74,15 @@ public class PasswordsPreferenceControllerTest { mScreen.addPreference(mPasswordsPreferenceCategory); } + @Test + // Tests that getAvailabilityStatus() does not throw an exception if it's called before the + // Controller is initialized (this can happen during indexing). + public void getAvailabilityStatus_withoutInit_returnsUnavailable() { + PasswordsPreferenceController controller = + new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey()); + assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); + } + @Test public void getAvailabilityStatus_noServices_returnsUnavailable() { PasswordsPreferenceController controller = @@ -105,21 +122,26 @@ public class PasswordsPreferenceControllerTest { assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(0); } - @Ignore("TODO: Fix the test to handle the service binding.") @Test @UiThreadTest public void displayPreference_withPasswords_addsPreference() { AutofillServiceInfo service = createServiceWithPasswords(); + service.getServiceInfo().packageName = ""; + service.getServiceInfo().name = ""; PasswordsPreferenceController controller = createControllerWithServices(Lists.newArrayList(service)); - controller.onCreate(() -> mock(Lifecycle.class)); + doReturn(false).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any()); controller.displayPreference(mScreen); assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(1); Preference pref = mPasswordsPreferenceCategory.getPreference(0); assertThat(pref.getIcon()).isNotNull(); - assertThat(pref.getIntent().getComponent()) + pref.performClick(); + ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + UserHandle user = mContext.getUser(); + verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(user)); + assertThat(intentCaptor.getValue().getComponent()) .isEqualTo( new ComponentName( service.getServiceInfo().packageName, @@ -128,8 +150,10 @@ public class PasswordsPreferenceControllerTest { private PasswordsPreferenceController createControllerWithServices( List availableServices) { - return new PasswordsPreferenceController( - mContext, mPasswordsPreferenceCategory.getKey(), availableServices); + PasswordsPreferenceController controller = + new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey()); + controller.init(() -> mock(Lifecycle.class), availableServices); + return controller; } private AutofillServiceInfo createServiceWithPasswords() { From 60758f3eb6792ebccf6c88c825ccd95ffbdd2c6d Mon Sep 17 00:00:00 2001 From: Joy Babafemi Date: Wed, 30 Jun 2021 23:26:18 +0000 Subject: [PATCH 04/28] Remove UWB Toggle temporarily. Test: Manual Bug: 192499944 Change-Id: I48b8190d9e10d95f261bb13b92c899093283bfac --- res/xml/connected_devices_advanced.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml index 85e4a762429..3ff7d9975f8 100644 --- a/res/xml/connected_devices_advanced.xml +++ b/res/xml/connected_devices_advanced.xml @@ -65,13 +65,6 @@ android:icon="@drawable/ic_folder_vd_theme_24" android:title="@string/bluetooth_show_files_received_via_bluetooth"/> - - From e24255fe7e395d73af3f868785a4afc9ba246feb Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Thu, 1 Jul 2021 14:17:52 +0800 Subject: [PATCH 05/28] Fix multiple biometrics enrollment flow Suppose both face auth and fingerprint auth exist in a device, the setup flow will skip fingerprint enrollment when a user skips to register face data on the face enrollment education page. Updated the skip button method and make the flow move on to fingerprint enrollment if a use doesn't want to register face data. Fix: 186084024 Test: manual verified 1) Reset device and start from SUW 2) Press skip button on the face unlock education page 3) The next flow should be fingerprint enrollment intro page Change-Id: I037ae68f39f5fdbf62ea95b998621c7f7df31b43 --- .../settings/biometrics/face/FaceEnrollEducation.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index 65ab2e7c783..f915059407c 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -215,8 +215,10 @@ public class FaceEnrollEducation extends BiometricEnrollBase { } protected void onSkipButtonClick(View view) { - setResult(RESULT_SKIP); - finish(); + if (!BiometricUtils.tryStartingNextBiometricEnroll(this, ENROLL_NEXT_BIOMETRIC_REQUEST)) { + setResult(RESULT_SKIP); + finish(); + } } @Override From 566d06af22e0f349f90482260d928dfd14f99d38 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Thu, 1 Jul 2021 11:53:09 +0800 Subject: [PATCH 06/28] Fix profile tab text contrast problem Spec specify textColorSecondary of default state, however, TabLayout uses a not expected state of the color. This change sets default state color of textColorSecondary instead of textColorSecondary. Bug: 189793243 Test: manual visual Change-Id: I025ffac68505016f4c4ffb7e1c0b2ff86308d3be --- .../ProfileSelectFragment.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java index 1e0a8dde1b3..82d524d9f06 100644 --- a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java +++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java @@ -21,6 +21,7 @@ import static android.content.Intent.EXTRA_USER_ID; import android.annotation.IntDef; import android.app.Activity; import android.content.Context; +import android.content.res.ColorStateList; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; @@ -113,6 +114,7 @@ public abstract class ProfileSelectFragment extends DashboardFragment { viewPager.setAdapter(new ProfileSelectFragment.ViewPagerAdapter(this)); final TabLayout tabs = tabContainer.findViewById(R.id.tabs); tabs.setupWithViewPager(viewPager); + setupTabTextColor(tabs); tabContainer.setVisibility(View.VISIBLE); final TabLayout.Tab tab = tabs.getTabAt(selectedTab); tab.select(); @@ -129,6 +131,30 @@ public abstract class ProfileSelectFragment extends DashboardFragment { return mContentView; } + /** + * TabLayout uses ColorStateList of 2 states, selected state and empty state. + * It's expected to use textColorSecondary default state color as empty state tabTextColor. + * + * However, TabLayout uses textColorSecondary by a not expected state. + * This method sets tabTextColor with the color of expected textColorSecondary state. + */ + private void setupTabTextColor(TabLayout tabLayout) { + final ColorStateList defaultColorStateList = tabLayout.getTabTextColors(); + final ColorStateList resultColorStateList = new ColorStateList( + new int[][]{ + new int[]{android.R.attr.state_selected}, + new int[]{} + }, + new int[] { + defaultColorStateList.getColorForState(new int[]{android.R.attr.state_selected}, + Utils.getColorAttrDefaultColor(getContext(), + com.android.internal.R.attr.colorAccentPrimaryVariant)), + Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorSecondary) + } + ); + tabLayout.setTabTextColors(resultColorStateList); + } + @Override public int getMetricsCategory() { return METRICS_CATEGORY_UNKNOWN; From aaa031bd71f784d6a38f1a19ab88a5924c9060ba Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Thu, 1 Jul 2021 16:54:00 +0800 Subject: [PATCH 07/28] Correct the choose screen lock page The choose screen lock page didn't apply the right theme during the enterprise flow. That is because an intent extra of setup wizard wasn't properly passed to the next page. In this change we made sure the intent extra is able to properly pass to the next page. We also removed the wrong theme for setup choose a screen lock page since the wrong theme made this page broken. The setup choose a screen lock is a sub setting page that wasn't implemented by using SUW library, so it should not use GlifLayout theme. With this update, the choose a screen lock page still keeps the background color of Settings, that is different from the one of setup flow. Bug: 190499041 Test: manual test Change-Id: I9dceee6a398c7e7b487dd8e4046f71f76cc50e36 --- AndroidManifest.xml | 1 - src/com/android/settings/password/SetNewPasswordActivity.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 60dbb246044..4a37e2b41e1 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1910,7 +1910,6 @@ diff --git a/src/com/android/settings/password/SetNewPasswordActivity.java b/src/com/android/settings/password/SetNewPasswordActivity.java index 87411751bff..22825872128 100644 --- a/src/com/android/settings/password/SetNewPasswordActivity.java +++ b/src/com/android/settings/password/SetNewPasswordActivity.java @@ -134,6 +134,8 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true); } intent.putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, mDevicePasswordRequirementOnly); + // Copy the setup wizard intent extra to the intent. + WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent); startActivity(intent); finish(); } From 239b58e60af13090d713dc811cc1227e1d6c7c86 Mon Sep 17 00:00:00 2001 From: Ahaan Ugale Date: Thu, 1 Jul 2021 01:38:39 -0700 Subject: [PATCH 08/28] Autofill settings: Fix search Ia012232ba2856e0757289982bc3045d948ff4aa8 replace the "Autofill service" preference title with the earlier summary string. The change in title causes search to not find the preference anymore. This change adds back the title in xml, which makes search find it again. The Controller code still overwrites the title with the application name. Also fixes DefaultAutofillPreferenceControllerTest. Bug: 192403526 Test: manual - clear Settings Services storage -> search "fill" -> click link Test: make -j64 RunSettingsRoboTests \ ROBOTEST_FILTER="com.android.settings.applications.defaultapps.DefaultAutofillPreferenceControllerTest" Change-Id: I9714b3efd2a5a7d9ee7eef345415fa020ef0dc61 --- res/xml/accounts_dashboard_settings.xml | 1 + res/xml/accounts_personal_dashboard_settings.xml | 1 + res/xml/accounts_work_dashboard_settings.xml | 1 + .../defaultapps/DefaultAutofillPreferenceControllerTest.java | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/res/xml/accounts_dashboard_settings.xml b/res/xml/accounts_dashboard_settings.xml index 71bfc189609..c8627e7e9e7 100644 --- a/res/xml/accounts_dashboard_settings.xml +++ b/res/xml/accounts_dashboard_settings.xml @@ -37,6 +37,7 @@ Date: Wed, 30 Jun 2021 11:25:42 +0800 Subject: [PATCH 09/28] Update the illustrations of camera gestures. - Add the new illustrations of quickly open camera. - Add the new illustrations of flip camera for selfie. - Remove the old illustration of quickly open camera. - Remove the old illustration of flip camera for selfie. Bug: 190807662 Test: robotest and see the UI Change-Id: I72030731c6d2fe23ff4b21d366151ac4770c656f --- res/drawable/flip_camera_for_selfie.xml | 3 +++ res/drawable/quickly_open_camera.xml | 3 +++ res/raw/lottie_flip_camera_for_selfie.json | 0 res/raw/lottie_quick_open_camera.json | 0 res/xml/double_tap_power_settings.xml | 2 +- res/xml/double_twist_gesture_settings.xml | 2 +- 6 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 res/drawable/flip_camera_for_selfie.xml create mode 100644 res/drawable/quickly_open_camera.xml delete mode 100644 res/raw/lottie_flip_camera_for_selfie.json delete mode 100644 res/raw/lottie_quick_open_camera.json diff --git a/res/drawable/flip_camera_for_selfie.xml b/res/drawable/flip_camera_for_selfie.xml new file mode 100644 index 00000000000..dcbf9f4dc68 --- /dev/null +++ b/res/drawable/flip_camera_for_selfie.xml @@ -0,0 +1,3 @@ + + + diff --git a/res/drawable/quickly_open_camera.xml b/res/drawable/quickly_open_camera.xml new file mode 100644 index 00000000000..dcbf9f4dc68 --- /dev/null +++ b/res/drawable/quickly_open_camera.xml @@ -0,0 +1,3 @@ + + + diff --git a/res/raw/lottie_flip_camera_for_selfie.json b/res/raw/lottie_flip_camera_for_selfie.json deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/res/raw/lottie_quick_open_camera.json b/res/raw/lottie_quick_open_camera.json deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/res/xml/double_tap_power_settings.xml b/res/xml/double_tap_power_settings.xml index cbe2e0fea22..f4d7607c85e 100644 --- a/res/xml/double_tap_power_settings.xml +++ b/res/xml/double_tap_power_settings.xml @@ -24,7 +24,7 @@ + app:lottie_rawRes="@drawable/quickly_open_camera"/> + app:lottie_rawRes="@drawable/flip_camera_for_selfie"/> Date: Thu, 1 Jul 2021 20:15:44 +0800 Subject: [PATCH 10/28] Remove stale search result about "Recent location requests" page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on the new design, RecentLocationRequestSeeAllFragment was no longer used on Location, but it still implemented the indexable interface to provide stale search result “Recent location requests” to Settings Search. Remove the indexable interface from RecentLocationRequestSeeAllFragment as a quick fix and also correct the related test method name. Fixes: 192542283 Test: visual Change-Id: I1a3df5d7319b8831db2f3d3abba19a11b5a83c81 --- .../RecentLocationRequestSeeAllFragment.java | 12 ++---------- .../settings/search/CustomSiteMapRegistryTest.java | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java index 3f0defd1ac6..7fd66435c7a 100644 --- a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java +++ b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java @@ -24,11 +24,9 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settingslib.search.SearchIndexable; -/** Dashboard Fragment to display all recent location requests, sorted by recency. */ -@SearchIndexable +/** @deprecated Use {@link RecentLocationAccessSeeAllFragment} instead. */ +@Deprecated public class RecentLocationRequestSeeAllFragment extends DashboardFragment { private static final String TAG = "RecentLocationReqAll"; public static final String PATH = @@ -99,10 +97,4 @@ public class RecentLocationRequestSeeAllFragment extends DashboardFragment { R.string.menu_hide_system); updateMenu(); } - - /** - * For Search. - */ - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.location_recent_requests_see_all); } diff --git a/tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java b/tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java index 3848fe446b0..5eb3b336ede 100644 --- a/tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java +++ b/tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java @@ -62,7 +62,7 @@ public class CustomSiteMapRegistryTest { } @Test - public void shouldContainRecentLocationRequestSeeAllFragmentPairs() { + public void shouldContainRecentLocationAccessSeeAllFragmentPairs() { assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get( RecentLocationAccessSeeAllFragment.class.getName())).isEqualTo( LocationSettings.class.getName()); From 282b67b1c00910fccd4a145fa401d4cc47df240f Mon Sep 17 00:00:00 2001 From: tom hsu Date: Thu, 1 Jul 2021 22:32:26 +0800 Subject: [PATCH 11/28] [Settings] Prevent NPE from getting MobileIconGroup instance. Bug: 187812523 Test: Maunal test. Change-Id: Ief06c683c1c8a99d4ce2765cd802be221e55820e --- .../settings/network/SubscriptionsPreferenceController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java index e88cded175e..7c0fc29736a 100644 --- a/src/com/android/settings/network/SubscriptionsPreferenceController.java +++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java @@ -603,7 +603,11 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl public String getNetworkType(Context context, Config config, TelephonyDisplayInfo telephonyDisplayInfo, int subId) { String iconKey = getIconKey(telephonyDisplayInfo); - int resId = mapIconSets(config).get(iconKey).dataContentDescription; + MobileIconGroup iconGroup = mapIconSets(config).get(iconKey); + int resId = 0; + if (iconGroup != null) { + resId = iconGroup.dataContentDescription; + } return resId != 0 ? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : ""; From 0e898acd4a5b7dcd5e960d232c59bd381e47f33d Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Thu, 1 Jul 2021 16:20:23 +0100 Subject: [PATCH 12/28] Add bottom padding to 'Choose a new lock screen' * Add 24dp padding Before: https://screenshot.googleplex.com/64sTaMhwqMKQ4CE After: https://screenshot.googleplex.com/As33LmkLXG7duV5 Bug: 192541032 Test: manual testing (see screenshots) Change-Id: I4e29e4f776e7be1c42301c39c4844d7ee948eaaa --- res/values/styles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values/styles.xml b/res/values/styles.xml index 63ea86ebe3b..e25c7fa5bed 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -394,6 +394,7 @@ From bce875ee2a0bb17597fffff5064974598d991a6d Mon Sep 17 00:00:00 2001 From: Jernej Virag Date: Thu, 1 Jul 2021 16:36:58 +0000 Subject: [PATCH 13/28] Move Prevent Ringing gesture underneath power menu Bug: 191971326 Test: Configuration change Change-Id: I0696e96f196ce862288d2d2e752aeefa4d3aa1fd --- res/xml/gestures.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml index 175a826f108..f4e21fa5f51 100644 --- a/res/xml/gestures.xml +++ b/res/xml/gestures.xml @@ -81,15 +81,15 @@ settings:searchable="false" settings:controller="com.android.settings.gestures.PickupGesturePreferenceController" /> - - + + From bb75bb911edf67ac32169dfdb1ea473f635282a3 Mon Sep 17 00:00:00 2001 From: Jernej Virag Date: Thu, 1 Jul 2021 15:35:56 +0000 Subject: [PATCH 14/28] Update Prevent Ringing setting to avoid conflict with long press power Long press power setting overrides Prevent ringing setting key chord. This updates the Prevent Ringing setting to disable it when LPP setting conflicts and adds a string describing why this setting is disabled. Bug: 191971326 Test: Manually on device Unit tests in PreventRingingParentPreferenceController Change-Id: If9fc8318381def7e4bbd71a0f5db3f38c474cb3d --- res/values/strings.xml | 2 + ...ventRingingParentPreferenceController.java | 78 +++++++++++++++---- ...RingingParentPreferenceControllerTest.java | 64 +++++++++++++-- 3 files changed, 125 insertions(+), 19 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 26fbd795575..a5294103167 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12454,6 +12454,8 @@ Vibrate Mute + + To enable, first change \"Press and hold power button\" to the power menu. Network details diff --git a/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java b/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java index b67943817ee..b3b39fbd7e5 100644 --- a/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java +++ b/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java @@ -37,10 +37,15 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; +import com.google.common.annotations.VisibleForTesting; + /** The controller manages the behaviour of the Prevent Ringing gesture setting. */ public class PreventRingingParentPreferenceController extends TogglePreferenceController implements LifecycleObserver, OnStart, OnStop { + @VisibleForTesting + static final int KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE = 1; + final String SECURE_KEY = VOLUME_HUSH_GESTURE; private PrimarySwitchPreference mPreference; @@ -59,6 +64,10 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo @Override public boolean isChecked() { + if (!isVolumePowerKeyChordSetToHush()) { + return false; + } + final int preventRinging = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE); @@ -85,25 +94,47 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo final int value = Settings.Secure.getInt( mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE); CharSequence summary; - switch (value) { - case VOLUME_HUSH_VIBRATE: - summary = mContext.getText(R.string.prevent_ringing_option_vibrate_summary); - break; - case VOLUME_HUSH_MUTE: - summary = mContext.getText(R.string.prevent_ringing_option_mute_summary); - break; - // VOLUME_HUSH_OFF - default: - summary = mContext.getText(R.string.switch_off_text); + if (isVolumePowerKeyChordSetToHush()) { + switch (value) { + case VOLUME_HUSH_VIBRATE: + summary = mContext.getText(R.string.prevent_ringing_option_vibrate_summary); + break; + case VOLUME_HUSH_MUTE: + summary = mContext.getText(R.string.prevent_ringing_option_mute_summary); + break; + // VOLUME_HUSH_OFF + default: + summary = mContext.getText(R.string.switch_off_text); + } + preference.setEnabled(true); + mPreference.setSwitchEnabled(true); + } else { + summary = mContext.getText(R.string.prevent_ringing_option_unavailable_lpp_summary); + preference.setEnabled(false); + mPreference.setSwitchEnabled(false); } + preference.setSummary(summary); } @Override public int getAvailabilityStatus() { - return mContext.getResources().getBoolean( - com.android.internal.R.bool.config_volumeHushGestureEnabled) - ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + if (!mContext.getResources().getBoolean( + com.android.internal.R.bool.config_volumeHushGestureEnabled)) { + return UNSUPPORTED_ON_DEVICE; + } + if (isVolumePowerKeyChordSetToHush()) { + return AVAILABLE; + } + if (mContext.getResources().getBoolean( + com.android.internal + .R.bool.config_longPressOnPowerForAssistantSettingAvailable)) { + // The power + volume key chord is not set to hush gesture - it's been disabled + // by long press power for Assistant. + return DISABLED_DEPENDENT_SETTING; + } + + return UNSUPPORTED_ON_DEVICE; } @Override @@ -121,9 +152,26 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo } } + /** + * Returns true if power + volume up key chord is actually set to "mute toggle". If not, + * this setting will have no effect and should be disabled. + * + * This handles the condition when long press on power for Assistant changes power + volume + * chord to power menu and this setting needs to be disabled. + */ + private boolean isVolumePowerKeyChordSetToHush() { + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.KEY_CHORD_POWER_VOLUME_UP, + mContext.getResources().getInteger( + com.android.internal.R.integer.config_keyChordPowerVolumeUp)) + == KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE; + } + private class SettingObserver extends ContentObserver { private final Uri mVolumeHushGestureUri = Settings.Secure.getUriFor( Settings.Secure.VOLUME_HUSH_GESTURE); + private final Uri mKeyChordVolumePowerUpUri = Settings.Global.getUriFor( + Settings.Global.KEY_CHORD_POWER_VOLUME_UP); private final Preference mPreference; @@ -133,6 +181,7 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo } public void register(ContentResolver cr) { + cr.registerContentObserver(mKeyChordVolumePowerUpUri, false, this); cr.registerContentObserver(mVolumeHushGestureUri, false, this); } @@ -143,7 +192,8 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); - if (uri == null || mVolumeHushGestureUri.equals(uri)) { + if (uri == null || mVolumeHushGestureUri.equals(uri) + || mKeyChordVolumePowerUpUri.equals(uri)) { updateState(mPreference); } } diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java index 4844a1cb0a7..48a047f2da8 100644 --- a/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java @@ -22,6 +22,8 @@ import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; import static com.google.common.truth.Truth.assertThat; @@ -33,8 +35,10 @@ import android.content.res.Resources; import android.provider.Settings; import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.widget.PrimarySwitchPreference; import org.junit.Before; import org.junit.Test; @@ -50,6 +54,9 @@ public class PreventRingingParentPreferenceControllerTest { @Mock private Resources mResources; + @Mock + PreferenceScreen mScreen; + private Context mContext; private PreventRingingParentPreferenceController mController; private Preference mPreference; @@ -58,21 +65,53 @@ public class PreventRingingParentPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application.getApplicationContext()); + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getInteger( + com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn( + PreventRingingParentPreferenceController.KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE); mController = new PreventRingingParentPreferenceController(mContext, "test_key"); - mPreference = new Preference(mContext); + mPreference = new PrimarySwitchPreference(mContext); + when(mScreen.findPreference("test_key")).thenReturn(mPreference); + mController.displayPreference(mScreen); } @Test - public void testIsAvailable_configIsTrue_shouldAvailableUnSearchable() { - when(mContext.getResources()).thenReturn(mResources); + public void isAvailable_configIsTrueAndKeyChordMute_shouldAvailableUnSearchable() { when(mResources.getBoolean( com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true); - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @Test - public void testIsAvailable_configIsFalse_shouldReturnFalse() { + public void getAvailabilityStatus_configIsTrueAndKeyNotMute_shouldReturnDisabledDependent() { + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getBoolean( + com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true); + when(mResources.getBoolean( + com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable)) + .thenReturn(true); + when(mResources.getInteger( + com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(2); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_configIsTrueLppDisabled_shouldReturnUnsupportedOnDevice() { + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getBoolean( + com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true); + when(mResources.getBoolean( + com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable)) + .thenReturn(false); + when(mResources.getInteger( + com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(2); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } + + @Test + public void isAvailable_configIsFalse_shouldReturnFalse() { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean( com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false); @@ -101,6 +140,21 @@ public class PreventRingingParentPreferenceControllerTest { R.string.switch_off_text)); } + @Test + public void updateState_keyChordDisabled_summaryUpdated() { + when(mResources.getInteger( + com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(2); + // Ensure that the state displays unchecked even if the underlying field is set. + Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE, + VOLUME_HUSH_MUTE); + mController.updateState(mPreference); + + assertThat(mPreference.isEnabled()).isFalse(); + assertThat(mPreference.getSummary()).isEqualTo(mContext.getResources().getText( + R.string.prevent_ringing_option_unavailable_lpp_summary)); + assertThat(mController.isChecked()).isFalse(); + } + @Test public void isChecked_vibrate_shouldReturnTrue() { Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE, From 494c68e3cf0a214b7b3fdcfbaba9a91b2be8abf9 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 1 Jul 2021 05:11:41 +0000 Subject: [PATCH 15/28] Revert "Add a cancel string for ToggleSubscriptionDialog to handle Tamil" This reverts commit eba8857094c0a1deabaedba92f9713fddb7b0781. Reason for revert: Issue not urgent enough to go in S, will resubmit to master Bug: 185553806 Change-Id: Id7f6042e0f7c70a3a8ca951fb80bb7f30acedcb9 --- res/values/strings.xml | 2 -- .../telephony/ToggleSubscriptionDialogActivity.java | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 0f98a5a3e23..aeaea6116b8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12892,8 +12892,6 @@ Restart No thanks - - Cancel Switch diff --git a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java index e67ac42af47..0064e6ccfd2 100644 --- a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java +++ b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java @@ -338,7 +338,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc getString(R.string.sim_action_restart_title), getString(R.string.sim_action_enable_dsds_text), getString(R.string.sim_action_reboot), - getString(R.string.sim_action_cancel)); + getString(R.string.cancel)); } /* Displays the SIM toggling confirmation dialog. */ @@ -359,7 +359,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc title, null, getString(R.string.yes), - getString(R.string.sim_action_cancel)); + getString(R.string.cancel)); } private void showEnableSimConfirmDialog() { @@ -384,7 +384,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc getSwitchSubscriptionTitle(), getSwitchDialogBodyMsg(activeSub, isBetweenEsim), getSwitchDialogPosBtnText(), - getString(R.string.sim_action_cancel)); + getString(android.R.string.cancel)); } private void showNonSwitchSimConfirmDialog() { @@ -395,7 +395,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc getEnableSubscriptionTitle(), null /* msg */, getString(R.string.yes), - getString(R.string.sim_action_cancel)); + getString(android.R.string.cancel)); } private String getSwitchDialogPosBtnText() { From 4cf13de04d133c1c70a44358f1935aac1e071a32 Mon Sep 17 00:00:00 2001 From: Curtis Belmonte Date: Thu, 1 Jul 2021 10:38:25 -0700 Subject: [PATCH 16/28] Adjust UI of face and fingerprint enroll intro pages Changes the appearance and spacing of the face and fingerprint unlock intro/consent pages to be consistent with one another and more closely match the latest mocks. Test: Manually tested face and fingerprint enrollment Fixes: 192475206 Change-Id: I4d41ddc15dc1a6be818762a286f06470344cf819 --- res/layout/face_enroll_introduction.xml | 53 +++++------------ .../fingerprint_enroll_introduction.xml | 57 ++++++------------- res/values/styles.xml | 14 +++++ 3 files changed, 45 insertions(+), 79 deletions(-) diff --git a/res/layout/face_enroll_introduction.xml b/res/layout/face_enroll_introduction.xml index 2887bcac277..c9c4d23f578 100644 --- a/res/layout/face_enroll_introduction.xml +++ b/res/layout/face_enroll_introduction.xml @@ -43,9 +43,7 @@ + android:layout_height="wrap_content"> + style="@style/BiometricEnrollIntroTitle" + android:text="@string/security_settings_face_enroll_introduction_info_title" /> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" /> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" /> - - - - + style="@style/BiometricEnrollIntroTitle" + android:text="@string/security_settings_face_enroll_introduction_how_title" /> - - + style="@style/BiometricEnrollIntroMessage" /> - - + style="@style/BiometricEnrollIntroTitle" /> + style="@style/BiometricEnrollIntroMessage" + android:paddingBottom="0dp" /> diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml index 5f828799269..d4914e64bbb 100644 --- a/res/layout/fingerprint_enroll_introduction.xml +++ b/res/layout/fingerprint_enroll_introduction.xml @@ -42,8 +42,7 @@ + android:layout_height="wrap_content"> + style="@style/BiometricEnrollIntroTitle" + android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_title_2" /> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" /> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" /> - - + style="@style/BiometricEnrollIntroTitle" /> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" /> - - + style="@style/BiometricEnrollIntroTitle" + android:text="@string/security_settings_face_enroll_introduction_info_title"/> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" /> + android:orientation="horizontal"> + style="@style/BiometricEnrollIntroMessage" + android:paddingBottom="0dp" + android:text="@string/security_settings_fingerprint_v2_enroll_introduction_message_learn_more" /> diff --git a/res/values/styles.xml b/res/values/styles.xml index 63ea86ebe3b..979632e57db 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -397,6 +397,20 @@ 1.2 + + + + From b757a6e9f21047fe828d569fe988592a464d27fe Mon Sep 17 00:00:00 2001 From: Stanley Wang Date: Thu, 1 Jul 2021 22:47:55 +0800 Subject: [PATCH 25/28] Fix the problem that when the MainSwitchPreference is gone, there will be a blank area. - Disable the visibility of preference when the the hide() method is invoked. Fix: 192332931 Test: robotest and see the UI Change-Id: Iec5a06ca689843ebb692b1b7040f1d2be9f45bc2 --- .../settings/widget/SettingsMainSwitchPreference.java | 8 +++----- .../settings/widget/SettingsMainSwitchPreferenceTest.java | 2 ++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/widget/SettingsMainSwitchPreference.java b/src/com/android/settings/widget/SettingsMainSwitchPreference.java index f0e8d95b899..f1eb603a719 100644 --- a/src/com/android/settings/widget/SettingsMainSwitchPreference.java +++ b/src/com/android/settings/widget/SettingsMainSwitchPreference.java @@ -50,7 +50,6 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements private SettingsMainSwitchBar mMainSwitchBar; private CharSequence mTitle; - private boolean mIsVisible; private EnforcedAdmin mEnforcedAdmin; private RestrictedPreferenceHelper mRestrictedHelper; @@ -87,7 +86,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements } mMainSwitchBar = (SettingsMainSwitchBar) holder.findViewById(R.id.main_switch_bar); initMainSwitchBar(); - if (mIsVisible) { + if (isVisible()) { mMainSwitchBar.show(); if (mMainSwitchBar.isChecked() != isChecked()) { setChecked(isChecked()); @@ -101,7 +100,6 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements private void init(Context context, AttributeSet attrs) { setLayoutResource(R.layout.preference_widget_main_switch); mSwitchChangeListeners.add(this); - mIsVisible = true; if (attrs != null) { final TypedArray a = context.obtainStyledAttributes(attrs, @@ -151,7 +149,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements * Show the MainSwitchBar */ public void show() { - mIsVisible = true; + setVisible(true); if (mMainSwitchBar != null) { mMainSwitchBar.show(); } @@ -161,7 +159,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements * Hide the MainSwitchBar */ public void hide() { - mIsVisible = false; + setVisible(false); if (mMainSwitchBar != null) { mMainSwitchBar.hide(); } diff --git a/tests/robotests/src/com/android/settings/widget/SettingsMainSwitchPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/SettingsMainSwitchPreferenceTest.java index 31d10d925ad..c079029ffe0 100644 --- a/tests/robotests/src/com/android/settings/widget/SettingsMainSwitchPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/widget/SettingsMainSwitchPreferenceTest.java @@ -76,6 +76,7 @@ public class SettingsMainSwitchPreferenceTest { mPreference.onBindViewHolder(mHolder); assertThat(mPreference.isShowing()).isTrue(); + assertThat(mPreference.isVisible()).isTrue(); } @Test @@ -85,5 +86,6 @@ public class SettingsMainSwitchPreferenceTest { mPreference.onBindViewHolder(mHolder); assertThat(mPreference.isShowing()).isFalse(); + assertThat(mPreference.isVisible()).isFalse(); } } From 7b8eea386c7883171e989df4a8433d0326660eb7 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Fri, 2 Jul 2021 12:45:20 +0800 Subject: [PATCH 26/28] Refine the ripple effect and text style of ActionPrimaryButton - The background color of the button is inverted, which has to be applied to inverse ripple colors. - Update the font size and family. Fixes: 190338973 Test: visual, manual Change-Id: Ia7447b5e2f64546e0f011cca904d1317d6a38cf1 --- res/values-night/colors.xml | 3 +++ res/values/colors.xml | 3 +++ res/values/styles.xml | 6 ++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml index c63b7c1191b..4e4ee5ddb22 100644 --- a/res/values-night/colors.xml +++ b/res/values-night/colors.xml @@ -49,5 +49,8 @@ #669df6 #5e5e5e #669df6 + + + @*android:color/ripple_material_light diff --git a/res/values/colors.xml b/res/values/colors.xml index a3a7d03d762..0fe4975550e 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -207,4 +207,7 @@ #1A73E8 + + + @*android:color/ripple_material_dark diff --git a/res/values/styles.xml b/res/values/styles.xml index 63ea86ebe3b..64ae202e594 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -407,13 +407,15 @@