From 8d06d63fe3c065a919d8470e97b8b6be4979bbad Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Mon, 21 Jun 2021 23:33:17 +0100 Subject: [PATCH 01/32] 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/32] 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/32] 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/32] 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/32] 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/32] 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/32] 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/32] 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/32] 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/32] 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/32] [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 bce875ee2a0bb17597fffff5064974598d991a6d Mon Sep 17 00:00:00 2001 From: Jernej Virag Date: Thu, 1 Jul 2021 16:36:58 +0000 Subject: [PATCH 12/32] 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 13/32] 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 94ffc288bd19b82135fbfecb18e11352f06337fb Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 1 Jul 2021 14:08:39 -0400 Subject: [PATCH 14/32] Move selectability to switch from container To better work with SwitchAcccess Test: manual with Switch Access (with labels on) and Talkback Fixes: 189074205 Change-Id: Iafbc4eca9bce8c979ec16a743509b46727cd9eb6 --- .../applications/manageapplications/ApplicationViewHolder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java b/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java index 5dd1e43b77c..9ef66010070 100644 --- a/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java +++ b/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java @@ -159,6 +159,9 @@ public class ApplicationViewHolder extends RecyclerView.ViewHolder { if (mSwitch != null && mWidgetContainer != null) { mWidgetContainer.setOnClickListener(listener); mWidgetContainer.setFocusable(false); + mWidgetContainer.setClickable(false); + mSwitch.setFocusable(true); + mSwitch.setClickable(true); mSwitch.setChecked(checked); mSwitch.setEnabled(enabled); } From f60885a040d2cbb9a1900f07992998474188db08 Mon Sep 17 00:00:00 2001 From: Abel Tesfaye Date: Thu, 24 Jun 2021 02:10:13 +0000 Subject: [PATCH 15/32] Hide battery saver warning and camera privacy lock on devices that do not support smart-auto-rotate Bug: 191924078 Test: locally on crosshatch Change-Id: I8464860c3d1d59c5d4549e7c488457e92054dbba --- .../settings/display/SmartAutoRotateBatterySaverController.java | 2 +- .../settings/display/SmartAutoRotateCameraStateController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java b/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java index 4e083029ce9..9d4645e1fd0 100644 --- a/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java +++ b/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java @@ -50,7 +50,7 @@ public class SmartAutoRotateBatterySaverController extends BasePreferenceControl if (mPreference == null) { return; } - mPreference.setVisible(isPowerSaveMode()); + mPreference.setVisible(isAvailable()); updateState(mPreference); } }; diff --git a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java index a17a903532e..39576a9dfee 100644 --- a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java +++ b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java @@ -45,7 +45,7 @@ public class SmartAutoRotateCameraStateController extends BasePreferenceControll mPrivacyManager = SensorPrivacyManager.getInstance(context); mPrivacyManager.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> { if (mPreference != null) { - mPreference.setVisible(enabled); + mPreference.setVisible(isAvailable()); } updateState(mPreference); }); From 25880d0d0e10e376fcca219fe9c69a4cc0dbeed8 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Fri, 2 Jul 2021 10:39:25 +0800 Subject: [PATCH 16/32] Fix incorrect storage size in Storage Settings From Android S, Storage Settings queries file sizes from MediaProvider, it's not necessary to count size data from getExternalStorageStats when calculating size data. Bug: 185542752 Test: make RunSettingsRoboTests ROBOTEST_FILTER=testMeasurementCompletedUpdatesPreferences manual 1. Connect device to PC via USB File transfer. 2. Copy large files from PC to device. 3. Observe size information in Storage Settings. Change-Id: I43cbec764e97f5003a4ec981717c9f213a21b614 --- .../storage/StorageItemPreferenceController.java | 2 -- .../storage/StorageItemPreferenceControllerTest.java | 7 ------- 2 files changed, 9 deletions(-) diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index 22ea98fda3e..fd9ae8c5d8f 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -386,8 +386,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle + otherData.documentsAndOtherSize + otherData.trashSize + otherData.allAppsExceptGamesSize; - attributedSize += otherData.externalStats.totalBytes - - otherData.externalStats.appBytes; attributedSize -= otherData.duplicateCodeSize; } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java index 3eab600d841..5fcb9c1e8ef 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java @@ -54,7 +54,6 @@ import com.android.settings.applications.manageapplications.ManageApplications; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settings.deviceinfo.StorageItemPreference; import com.android.settings.testutils.shadow.ShadowUserManager; -import com.android.settingslib.applications.StorageStatsSource; import com.android.settingslib.deviceinfo.StorageVolumeProvider; import org.junit.Before; @@ -340,12 +339,6 @@ public class StorageItemPreferenceControllerTest { result.documentsAndOtherSize = MEGABYTE_IN_BYTES * 50; result.trashSize = KILOBYTE_IN_BYTES * 100; result.allAppsExceptGamesSize = MEGABYTE_IN_BYTES * 90; - result.externalStats = - new StorageStatsSource.ExternalStorageStats( - MEGABYTE_IN_BYTES * 500, // total - MEGABYTE_IN_BYTES * 100, // audio - MEGABYTE_IN_BYTES * 150, // video - MEGABYTE_IN_BYTES * 200, 0); // image final SparseArray results = new SparseArray<>(); results.put(0, result); From 96b5af7e397ede1d09681811d382e8ee82501a4c Mon Sep 17 00:00:00 2001 From: George Chang Date: Fri, 2 Jul 2021 11:00:55 +0800 Subject: [PATCH 17/32] Separate NFC on/off strings For pt-BR, it needs a different gender when we are referring to "NFC". Bug: 189314407 Test: check On/Off strings Change-Id: I87da43c66a65b3ef2fcd9c57632b36302d9920e8 --- res/values/strings.xml | 4 ++++ .../connecteddevice/NfcAndPaymentFragmentController.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 62c59e1d013..ac06f735143 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10030,6 +10030,10 @@ On Off + + On + + Off On diff --git a/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java b/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java index 17958c96010..ee0021ec951 100644 --- a/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java +++ b/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java @@ -54,9 +54,9 @@ public class NfcAndPaymentFragmentController extends BasePreferenceController { public CharSequence getSummary() { if (mNfcAdapter != null) { if (mNfcAdapter.isEnabled()) { - return mContext.getText(R.string.switch_on_text); + return mContext.getText(R.string.nfc_setting_on); } else { - return mContext.getText(R.string.switch_off_text); + return mContext.getText(R.string.nfc_setting_off); } } return null; From a78e1f51fe243ac202383b5e33ed2383272f41e6 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 1 Jul 2021 21:24:02 -0700 Subject: [PATCH 18/32] Switch back to sync IInputMethodManager This logically reverts two recent CLs [1][2] to submit a corresponding logical revert [3] into frameworks/base to address Bug 190486491. [1]: I767069892c713023b064525105ef2b55946b7bb8 8279b8ee5a6cd36cbfbdda084115658ffb5e17d5 [2]: I6733e8b500f5e02d4e14cde4ab7a46f4f716f5d0 fa01bf30ba0affcca01e537c704e0c96ee3e1fbc [3]: If16ac0de536d9089eb04f6e07b1ee47378124658 Bug: 163453493 Bug: 190486491 Test: make RunSettingsRoboTests ROBOTEST_FILTER="WinscopeTraceTest" Change-Id: Idea98bd36935a27d886ca337154112e7dd293080 Merged-In: Idea98bd36935a27d886ca337154112e7dd293080 --- .../development/qstile/DevelopmentTiles.java | 19 +++++----------- .../development/qstile/WinscopeTraceTest.java | 22 ++++++++----------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java index c55d0cb354d..764c83ef64a 100644 --- a/src/com/android/settings/development/qstile/DevelopmentTiles.java +++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java @@ -48,8 +48,6 @@ import android.widget.Toast; import androidx.annotation.VisibleForTesting; import com.android.internal.app.LocalePicker; -import com.android.internal.inputmethod.Completable; -import com.android.internal.inputmethod.ResultCallbacks; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.view.IInputMethodManager; import com.android.settings.R; @@ -262,13 +260,9 @@ public abstract class DevelopmentTiles extends TileService { return false; } - @VisibleForTesting - boolean isImeTraceEnabled() { + private boolean isImeTraceEnabled() { try { - // TODO(b/175742251): Get rid of dependency on IInputMethodManager - final Completable.Boolean value = Completable.createBoolean(); - mInputMethodManager.isImeTraceEnabled(ResultCallbacks.of(value)); - return Completable.getResult(value); + return mInputMethodManager.isImeTraceEnabled(); } catch (RemoteException e) { Log.e(TAG, "Could not get ime trace status, defaulting to false.", e); } @@ -328,16 +322,13 @@ public abstract class DevelopmentTiles extends TileService { } } - protected void setImeTraceEnabled(boolean isEnabled) { + private void setImeTraceEnabled(boolean isEnabled) { try { - // TODO(b/175742251): Get rid of dependency on IInputMethodManager - final Completable.Void value = Completable.createVoid(); if (isEnabled) { - mInputMethodManager.startImeTrace(ResultCallbacks.of(value)); + mInputMethodManager.startImeTrace(); } else { - mInputMethodManager.stopImeTrace(ResultCallbacks.of(value)); + mInputMethodManager.stopImeTrace(); } - Completable.getResult(value); } catch (RemoteException e) { Log.e(TAG, "Could not set ime trace status." + e.toString()); } diff --git a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java index 52ba7a7f696..b4dab0d7cbd 100644 --- a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java +++ b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java @@ -24,10 +24,8 @@ import static com.android.settings.development.qstile.DevelopmentTiles.WinscopeT import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.spy; @@ -39,7 +37,6 @@ import android.os.RemoteException; import android.view.IWindowManager; import android.widget.Toast; -import com.android.internal.inputmethod.IBooleanResultCallback; import com.android.internal.view.IInputMethodManager; import com.android.settings.testutils.shadow.ShadowParcel; @@ -71,10 +68,6 @@ public class WinscopeTraceTest { public void setUp() { MockitoAnnotations.initMocks(this); mWinscopeTrace = spy(new DevelopmentTiles.WinscopeTrace()); - // default ImeTraceEnabled value, prevent tests from actually calling into IMM and - // await the result forever. - doReturn(false).when(mWinscopeTrace).isImeTraceEnabled(); - doNothing().when(mWinscopeTrace).setImeTraceEnabled(anyBoolean()); ReflectionHelpers.setField(mWinscopeTrace, "mWindowManager", mWindowManager); ReflectionHelpers.setField(mWinscopeTrace, "mInputMethodManager", mInputMethodManager); ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", mSurfaceFlinger); @@ -100,6 +93,7 @@ public class WinscopeTraceTest { public void sfReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException { // Assume Window Trace and Input Method Manager are disabled. doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); ShadowParcel.sReadBoolResult = true; assertThat(mWinscopeTrace.isEnabled()).isTrue(); verify(mSurfaceFlinger) @@ -120,6 +114,7 @@ public class WinscopeTraceTest { public void wmAndSfAndImmReturnTraceDisabled_shouldReturnDisabled() throws RemoteException { ShadowParcel.sReadBoolResult = false; doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); assertThat(mWinscopeTrace.isEnabled()).isFalse(); verify(mSurfaceFlinger) .transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(), @@ -132,7 +127,7 @@ public class WinscopeTraceTest { throws RemoteException { ShadowParcel.sReadBoolResult = false; doReturn(false).when(mWindowManager).isWindowTraceEnabled(); - doReturn(true).when(mWinscopeTrace).isImeTraceEnabled(); + doReturn(true).when(mInputMethodManager).isImeTraceEnabled(); assertThat(mWinscopeTrace.isEnabled()).isTrue(); verify(mSurfaceFlinger) .transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(), @@ -145,7 +140,7 @@ public class WinscopeTraceTest { public void immReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException { // Assume Window Manager and Surface Trace are disabled. ShadowParcel.sReadBoolResult = false; - doReturn(true).when(mWinscopeTrace).isImeTraceEnabled(); + doReturn(true).when(mInputMethodManager).isImeTraceEnabled(); assertThat(mWinscopeTrace.isEnabled()).isTrue(); } @@ -154,6 +149,7 @@ public class WinscopeTraceTest { public void immReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException { // Assume Window Manager and Surface Trace are disabled. ShadowParcel.sReadBoolResult = false; + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); assertThat(mWinscopeTrace.isEnabled()).isFalse(); } @@ -171,6 +167,7 @@ public class WinscopeTraceTest { public void sfUnavailableAndWmAndImmReturnTraceDisabled_shouldReturnDisabled() throws RemoteException { doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", null); assertThat(mWinscopeTrace.isEnabled()).isFalse(); } @@ -185,7 +182,7 @@ public class WinscopeTraceTest { @Test public void setIsEnableTrue_shouldEnableImeTrace() throws RemoteException { mWinscopeTrace.setIsEnabled(true); - verify(mWinscopeTrace).setImeTraceEnabled(eq(true)); + verify(mInputMethodManager).startImeTrace(); verifyNoMoreInteractions(mInputMethodManager); } @@ -213,7 +210,7 @@ public class WinscopeTraceTest { @Config(shadows = ShadowParcel.class) public void setIsEnableFalse_shouldDisableImeTrace() throws RemoteException { mWinscopeTrace.setIsEnabled(false); - verify(mWinscopeTrace).setImeTraceEnabled(eq(false)); + verify(mInputMethodManager).stopImeTrace(); verifyNoMoreInteractions(mInputMethodManager); verify(mToast).show(); } @@ -254,8 +251,7 @@ public class WinscopeTraceTest { @Test public void setIsEnableAndImmThrowsRemoteException_shouldFailGracefully() throws RemoteException { - doThrow(new RemoteException("Unknown")).when(mInputMethodManager) - .isImeTraceEnabled(any(IBooleanResultCallback.Stub.class)); + doThrow(new RemoteException("Unknown")).when(mInputMethodManager).isImeTraceEnabled(); mWinscopeTrace.setIsEnabled(true); } From 634f3d66559e89cba9478fc753c4b51f6eac9cbf Mon Sep 17 00:00:00 2001 From: Stanley Wang Date: Fri, 2 Jul 2021 15:39:29 +0800 Subject: [PATCH 19/32] Update the illustration of NFC page. - NFC uses the old component to display the illustration. Use the IllustrationPreference to display the illustration. Fix: 192630194 Test: robotest and see the UI Change-Id: Idcae247e0af039749dca072dd7fa44839b0b787d --- res/xml/nfc_and_payment_settings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/xml/nfc_and_payment_settings.xml b/res/xml/nfc_and_payment_settings.xml index 09ce27769ab..b7900f84b65 100644 --- a/res/xml/nfc_and_payment_settings.xml +++ b/res/xml/nfc_and_payment_settings.xml @@ -24,10 +24,10 @@ android:title="@string/nfc_main_switch_title" settings:controller="com.android.settings.nfc.NfcPreferenceController"/> - Date: Fri, 2 Jul 2021 16:17:49 +0800 Subject: [PATCH 20/32] Fix "notification" should be "notifications" in One-handed mode settings page Change "notification" to "notifications" for wrong string. Bug: 192345310 Test: manual verified on System > Gestures > One-handed mode page Change-Id: I9cf49a2a037483b118027488f36669b9db26a21e --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 32914b8c0f6..e026e9395d4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11763,7 +11763,7 @@ Show notifications - Notification and settings will appear. + Notifications and settings will appear. From 18e88b86b127da881087a235f47af340575ff7f1 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Fri, 2 Jul 2021 16:20:36 +0800 Subject: [PATCH 21/32] Update the dialog of SIM status and IMEI in About phone page - Update label font size to 20sp and fontFamily - Update value font size to 14sp and fontFamily Fixes: 182092163 Test: visual verify Change-Id: Ieb3cb9e834592e88fe40ba62fe3210754eb928a3 --- res/values/styles.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/res/values/styles.xml b/res/values/styles.xml index 63ea86ebe3b..1f589347755 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -453,13 +453,16 @@ From b757a6e9f21047fe828d569fe988592a464d27fe Mon Sep 17 00:00:00 2001 From: Stanley Wang Date: Thu, 1 Jul 2021 22:47:55 +0800 Subject: [PATCH 22/32] 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 23/32] 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 @@