From 8ac1e4d49df835d1484636b2682d2a4ebf85be2d Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 11 May 2020 16:13:47 +0800 Subject: [PATCH 1/8] Update icon tint color when the user toggles Dark theme - Reload theme in slice provider when Dark theme mode changes for slices - Reload theme in onCreate of Panel activity for its non-slice header - Remove applyTheme from individual slices Test: robotest Fixes: 153700819 Change-Id: I40a7d2817c4b9100d7b2f2962a69c8a9ce6f7906 --- src/com/android/settings/Utils.java | 10 ++++ .../slices/BluetoothDevicesSlice.java | 3 -- .../slices/DarkThemeSlice.java | 12 +---- .../settings/media/MediaOutputGroupSlice.java | 2 - .../settings/media/MediaOutputSlice.java | 3 -- .../settings/panel/SettingsPanelActivity.java | 1 + .../slices/SettingsSliceProvider.java | 12 +++++ .../settings/slices/SliceBuilderUtils.java | 2 - .../settings/wifi/slice/WifiSlice.java | 3 -- .../slices/SettingsSliceProviderTest.java | 48 ++++++++++++++++++- .../settings/testutils/SliceTester.java | 19 ++++---- 11 files changed, 83 insertions(+), 32 deletions(-) diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 2391fe8cc40..d34dbcfea76 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -42,6 +42,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; +import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.database.Cursor; @@ -1101,4 +1102,13 @@ public final class Utils extends com.android.settingslib.Utils { context.getString(R.string.config_settingsintelligence_package_name)); return isSettingsIntelligence; } + + /** + * Returns true if the night mode is enabled. + */ + public static boolean isNightMode(Context context) { + final int currentNightMode = + context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + return currentNightMode == Configuration.UI_MODE_NIGHT_YES; + } } diff --git a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java index 25a6841fbb7..79be26decd3 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java @@ -105,9 +105,6 @@ public class BluetoothDevicesSlice implements CustomSliceable { return null; } - // Reload theme for switching dark mode on/off - mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); - final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) .setAccentColor(COLOR_NOT_TINTED); diff --git a/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java b/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java index 1c1bedc40d1..f934d587eda 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java @@ -24,7 +24,6 @@ import android.app.PendingIntent; import android.app.UiModeManager; import android.content.Context; import android.content.Intent; -import android.content.res.Configuration; import android.database.ContentObserver; import android.net.Uri; import android.os.BatteryManager; @@ -107,7 +106,7 @@ public class DarkThemeSlice implements CustomSliceable { final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.dark_theme); - final boolean isChecked = isDarkThemeMode(mContext); + final boolean isChecked = Utils.isNightMode(mContext); if (sPreChecked != isChecked) { // Dark(Night) mode changed and reset the sSliceClicked. resetValue(isChecked, false); @@ -157,7 +156,7 @@ public class DarkThemeSlice implements CustomSliceable { @VisibleForTesting boolean isAvailable(Context context) { // check if dark theme mode is enabled or if dark theme scheduling is on. - if (isDarkThemeMode(context) || isNightModeScheduled()) { + if (Utils.isNightMode(context) || isNightModeScheduled()) { return false; } // checking the current battery level @@ -167,13 +166,6 @@ public class DarkThemeSlice implements CustomSliceable { return level <= BATTERY_LEVEL_THRESHOLD; } - @VisibleForTesting - static boolean isDarkThemeMode(Context context) { - final int currentNightMode = - context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - return currentNightMode == Configuration.UI_MODE_NIGHT_YES; - } - private void resetValue(boolean preChecked, boolean clicked) { sPreChecked = preChecked; sSliceClicked = clicked; diff --git a/src/com/android/settings/media/MediaOutputGroupSlice.java b/src/com/android/settings/media/MediaOutputGroupSlice.java index be6c2984867..d75ec74cb76 100644 --- a/src/com/android/settings/media/MediaOutputGroupSlice.java +++ b/src/com/android/settings/media/MediaOutputGroupSlice.java @@ -75,8 +75,6 @@ public class MediaOutputGroupSlice implements CustomSliceable { @Override public Slice getSlice() { - // Reload theme for switching dark mode on/off - mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) .setAccentColor(COLOR_NOT_TINTED); // Add "Group" row diff --git a/src/com/android/settings/media/MediaOutputSlice.java b/src/com/android/settings/media/MediaOutputSlice.java index df9538b5773..773013e4d9e 100644 --- a/src/com/android/settings/media/MediaOutputSlice.java +++ b/src/com/android/settings/media/MediaOutputSlice.java @@ -81,9 +81,6 @@ public class MediaOutputSlice implements CustomSliceable { @Override public Slice getSlice() { - // Reload theme for switching dark mode on/off - mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); - final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) .setAccentColor(COLOR_NOT_TINTED); if (!isVisible()) { diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java index 6bf016e0cc7..68cb8d5163a 100644 --- a/src/com/android/settings/panel/SettingsPanelActivity.java +++ b/src/com/android/settings/panel/SettingsPanelActivity.java @@ -66,6 +66,7 @@ public class SettingsPanelActivity extends FragmentActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getApplicationContext().getTheme().rebase(); createOrUpdatePanel(true /* shouldForceCreation */); getLifecycle().addObserver(new HideNonSystemOverlayMixin(this)); } diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 0aaf85d143a..6c245ce80b4 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -140,8 +140,11 @@ public class SettingsSliceProvider extends SliceProvider { @VisibleForTesting Map mSliceWeakDataCache; + @VisibleForTesting final Map mPinnedWorkers = new ArrayMap<>(); + private boolean mNightMode; + public SettingsSliceProvider() { super(READ_SEARCH_INDEXABLES); } @@ -150,6 +153,8 @@ public class SettingsSliceProvider extends SliceProvider { public boolean onCreateSliceProvider() { mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext()); mSliceWeakDataCache = new WeakHashMap<>(); + mNightMode = Utils.isNightMode(getContext()); + getContext().setTheme(R.style.Theme_SettingsBase); return true; } @@ -201,6 +206,13 @@ public class SettingsSliceProvider extends SliceProvider { return null; } + final boolean nightMode = Utils.isNightMode(getContext()); + if (mNightMode != nightMode) { + Log.d(TAG, "Night mode changed, reload theme"); + mNightMode = nightMode; + getContext().getTheme().rebase(); + } + // Before adding a slice to {@link CustomSliceManager}, please get approval // from the Settings team. if (CustomSliceRegistry.isValidUri(sliceUri)) { diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index 2d5b4aa39a2..391e9fdf741 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -73,8 +73,6 @@ public class SliceBuilderUtils { * {@param sliceData} is an inline controller. */ public static Slice buildSlice(Context context, SliceData sliceData) { - // Reload theme for switching dark mode on/off - context.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); Log.d(TAG, "Creating slice for: " + sliceData.getPreferenceController()); final BasePreferenceController controller = getPreferenceController(context, sliceData); FeatureFactory.getFactory(context).getMetricsFeatureProvider() diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java index fd279705a4d..a489b05e2e4 100644 --- a/src/com/android/settings/wifi/slice/WifiSlice.java +++ b/src/com/android/settings/wifi/slice/WifiSlice.java @@ -86,9 +86,6 @@ public class WifiSlice implements CustomSliceable { @Override public Slice getSlice() { - // Reload theme for switching dark mode on/off - mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */); - final boolean isWifiEnabled = isWifiEnabled(); ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* accessPoint */); if (!isWifiEnabled) { diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 0a9d8cbe83d..0fa249d8fb7 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -20,6 +20,8 @@ package com.android.settings.slices; import static android.content.ContentResolver.SCHEME_CONTENT; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.content.res.Configuration.UI_MODE_NIGHT_NO; +import static android.content.res.Configuration.UI_MODE_NIGHT_YES; import static com.google.common.truth.Truth.assertThat; @@ -39,6 +41,7 @@ import android.app.slice.SliceManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.res.Resources.Theme; import android.net.Uri; import android.os.StrictMode; import android.provider.Settings; @@ -96,7 +99,8 @@ import java.util.Set; @Config(shadows = {ShadowUserManager.class, ShadowUtils.class, SlicesDatabaseAccessorTest.ShadowApplicationPackageManager.class, ShadowBluetoothAdapter.class, ShadowLockPatternUtils.class, - SettingsSliceProviderTest.ShadowWifiScanWorker.class}) + SettingsSliceProviderTest.ShadowWifiScanWorker.class, + SettingsSliceProviderTest.ShadowTheme.class}) public class SettingsSliceProviderTest { private static final String KEY = "KEY"; @@ -162,6 +166,7 @@ public class SettingsSliceProviderTest { @After public void cleanUp() { ShadowThreadUtils.reset(); + ShadowTheme.reset(); DatabaseTestUtils.clearDb(mContext); } @@ -263,6 +268,28 @@ public class SettingsSliceProviderTest { assertThat(slice).isNull(); } + @Test + public void onBindSlice_nightModeChanged_shouldReloadTheme() { + mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_YES; + + final SliceData data = getDummyData(); + mProvider.mSliceWeakDataCache.put(data.getUri(), data); + mProvider.onBindSlice(data.getUri()); + + assertThat(ShadowTheme.isThemeRebased()).isTrue(); + } + + @Test + public void onBindSlice_nightModeNotChanged_shouldNotReloadTheme() { + mContext.getResources().getConfiguration().uiMode = UI_MODE_NIGHT_NO; + + SliceData data = getDummyData(); + mProvider.mSliceWeakDataCache.put(data.getUri(), data); + mProvider.onBindSlice(data.getUri()); + + assertThat(ShadowTheme.isThemeRebased()).isFalse(); + } + @Test public void getDescendantUris_fullActionUri_returnsSelf() { final Collection descendants = mProvider.onGetSliceDescendants(ACTION_SLICE_URI); @@ -722,4 +749,23 @@ public class SettingsSliceProviderTest { return sSetThreadPolicyCount != 0; } } + + @Implements(Theme.class) + public static class ShadowTheme { + private static boolean sThemeRebased; + + @Resetter + public static void reset() { + sThemeRebased = false; + } + + @Implementation + public void rebase() { + sThemeRebased = true; + } + + static boolean isThemeRebased() { + return sThemeRebased; + } + } } diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java index 6fb2c49ba4c..f2cce3cdf65 100644 --- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java +++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java @@ -137,16 +137,19 @@ public class SliceTester { */ public static void testSettingsSliderSlice(Context context, Slice slice, SliceData sliceData) { final SliceMetadata metadata = SliceMetadata.from(context, slice); - - final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); - final int color = colorItem.getInt(); - assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); - final SliceAction primaryAction = metadata.getPrimaryAction(); - final IconCompat expectedIcon = IconCompat.createWithResource(context, - sliceData.getIconResource()); - assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString()); + final IconCompat icon = primaryAction.getIcon(); + if (icon == null) { + final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); + final int color = colorItem.getInt(); + assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); + + } else { + final IconCompat expectedIcon = IconCompat.createWithResource(context, + sliceData.getIconResource()); + assertThat(expectedIcon.toString()).isEqualTo(icon.toString()); + } final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); From d6d8f988449617d757a5d7439314198d10d6ee78 Mon Sep 17 00:00:00 2001 From: Sunny Shao Date: Mon, 11 May 2020 22:55:05 +0800 Subject: [PATCH 2/8] Allows to launch only authenticator owned activities - 3rd party developers can define himself-authenticator and use the accountPreferences attribute to load the predefined preference UI. - If a developer defines an action intent to launch the other activity in xml and it would return true due to the true exported attribute and no permission. - To avoid launching arbitrary activity. Here allows to launch only authenticator owned activities. Bug: 150946634 Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.accounts Test: PoC app Change-Id: I5ce1a0b3838db7b3fbe48c6ea23d5f093d625cdb --- .../settings/accounts/AccountTypePreferenceLoader.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/com/android/settings/accounts/AccountTypePreferenceLoader.java b/src/com/android/settings/accounts/AccountTypePreferenceLoader.java index d32b63013fc..c639d1df2eb 100644 --- a/src/com/android/settings/accounts/AccountTypePreferenceLoader.java +++ b/src/com/android/settings/accounts/AccountTypePreferenceLoader.java @@ -197,14 +197,7 @@ public class AccountTypePreferenceLoader { ActivityInfo resolvedActivityInfo = resolveInfo.activityInfo; ApplicationInfo resolvedAppInfo = resolvedActivityInfo.applicationInfo; try { - if (resolvedActivityInfo.exported) { - if (resolvedActivityInfo.permission == null) { - return true; // exported activity without permission. - } else if (pm.checkPermission(resolvedActivityInfo.permission, - authDesc.packageName) == PackageManager.PERMISSION_GRANTED) { - return true; - } - } + // Allows to launch only authenticator owned activities. ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0); return resolvedAppInfo.uid == authenticatorAppInf.uid; } catch (NameNotFoundException e) { From 7e70ef64d482766b1803dc78f5e1f234718c5487 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Wed, 13 May 2020 03:45:39 +0000 Subject: [PATCH 3/8] Revert "Add the settings content observer for shortcut preference." This reverts commit 785af0c15ab9e2177da43ecf081498877243e558. Bug: 155837154 Reason for revert: robolectric test fail at com.android.settings.accessibility.ToggleFeaturePreferenceFragmentTest Change-Id: If8e5681b044171ad6941307489526cc3834f66b2 --- .../ToggleFeaturePreferenceFragment.java | 19 ++----------------- ...ScreenMagnificationPreferenceFragment.java | 6 ++---- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index f8b64fb7949..6b0759a92e1 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -30,7 +30,6 @@ import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.text.Html; @@ -97,7 +96,6 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference private int mUserShortcutTypes = UserShortcutType.EMPTY; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; - private SettingsContentObserver mSettingsContentObserver; // For html description of accessibility service, must follow the rule, such as // , a11y settings will get the resources successfully. @@ -135,17 +133,6 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference removeDialog(DialogEnums.EDIT_SHORTCUT); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); }; - - final List shortcutFeatureKeys = new ArrayList<>(); - shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); - shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); - mSettingsContentObserver = new SettingsContentObserver(new Handler(), shortcutFeatureKeys) { - @Override - public void onChange(boolean selfChange, Uri uri) { - updateShortcutPreferenceData(); - updateShortcutPreference(); - } - }; return super.onCreateView(inflater, container, savedInstanceState); } @@ -242,7 +229,6 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference final AccessibilityManager am = getPrefContext().getSystemService( AccessibilityManager.class); am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener); - mSettingsContentObserver.register(getContentResolver()); updateShortcutPreferenceData(); updateShortcutPreference(); } @@ -252,7 +238,6 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference final AccessibilityManager am = getPrefContext().getSystemService( AccessibilityManager.class); am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener); - mSettingsContentObserver.unregister(getContentResolver()); super.onPause(); } @@ -633,7 +618,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference getShortcutTypeSummary(getPrefContext())); } - protected void updateShortcutPreferenceData() { + private void updateShortcutPreferenceData() { if (mComponentName == null) { return; } @@ -666,7 +651,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference mShortcutPreference.setTitle(title); } - protected void updateShortcutPreference() { + private void updateShortcutPreference() { if (mComponentName == null) { return; } diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index 52f8f71d57c..23fb153b5bf 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -467,8 +467,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends showDialog(DialogEnums.MAGNIFICATION_EDIT_SHORTCUT); } - @Override - protected void updateShortcutPreferenceData() { + private void updateShortcutPreferenceData() { // Get the user shortcut type from settings provider. mUserShortcutType = getUserShortcutTypeFromSettings(getPrefContext()); if (mUserShortcutType != UserShortcutType.EMPTY) { @@ -490,8 +489,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends mShortcutPreference.setTitle(title); } - @Override - protected void updateShortcutPreference() { + private void updateShortcutPreference() { final int shortcutTypes = getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE); mShortcutPreference.setChecked( hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes)); From 782438347bdc0ecdf0f0e27ece27cadd5525ada1 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Wed, 13 May 2020 03:58:36 +0000 Subject: [PATCH 4/8] Revert "Unable to select twilight scheduling after enabling location" This reverts commit 9073b2f96802ce793aa312c0773836de51253da7. Bug: 153115261 Reason for revert: this CL make Settings robolectric test fail at com.android.settings.display.darkmode.DarkModeScheduleSelectorControllerTest Change-Id: I3f1ba35f55f2905b10ca97149268be6074780eda --- ...NightDisplayAutoModePreferenceController.java | 2 +- .../DarkModeScheduleSelectorController.java | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java index ef11e00cebb..fb2dbc3b903 100644 --- a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java +++ b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java @@ -74,7 +74,7 @@ public class NightDisplayAutoModePreferenceController extends BasePreferenceCont if (String.valueOf(ColorDisplayManager.AUTO_MODE_TWILIGHT).equals(newValue) && !mLocationManager.isLocationEnabled()) { TwilightLocationDialog.show(mContext); - return true; + return false; } return mColorDisplayManager.setNightDisplayAutoMode(Integer.parseInt((String) newValue)); } diff --git a/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java b/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java index 2ac9a9f8638..6acaf8292a4 100644 --- a/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java +++ b/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java @@ -33,7 +33,7 @@ import com.android.settings.display.TwilightLocationDialog; */ public class DarkModeScheduleSelectorController extends BasePreferenceController implements Preference.OnPreferenceChangeListener { - private static final String TAG = DarkModeScheduleSelectorController.class.getSimpleName(); + private final UiModeManager mUiModeManager; private PowerManager mPowerManager; private DropDownPreference mPreference; @@ -51,6 +51,7 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mPreference = screen.findPreference(getPreferenceKey()); + init(); } @Override @@ -58,8 +59,7 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController return BasePreferenceController.AVAILABLE; } - @Override - public final void updateState(Preference preference) { + private void init() { final boolean batterySaver = mPowerManager.isPowerSaveMode(); mPreference.setEnabled(!batterySaver); mCurrentMode = getCurrentMode(); @@ -87,25 +87,25 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController if (newMode == mCurrentMode) { return false; } - if (newMode == mPreference.findIndexOfValue( + mCurrentMode = newMode; + if (mCurrentMode == mPreference.findIndexOfValue( mContext.getString(R.string.dark_ui_auto_mode_never))) { boolean active = (mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; int mode = active ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; mUiModeManager.setNightMode(mode); - } else if (newMode == mPreference.findIndexOfValue( + } else if (mCurrentMode == mPreference.findIndexOfValue( mContext.getString(R.string.dark_ui_auto_mode_auto))) { if (!mLocationManager.isLocationEnabled()) { TwilightLocationDialog.show(mContext); - return true; + return false; } mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_AUTO); - } else if (newMode == mPreference.findIndexOfValue( + } else if (mCurrentMode == mPreference.findIndexOfValue( mContext.getString(R.string.dark_ui_auto_mode_custom))) { mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_CUSTOM); } - mCurrentMode = newMode; return true; } } From b3d5df49894a7e5cb4d82ba5c62584027f7fa79b Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Wed, 13 May 2020 14:43:20 +0800 Subject: [PATCH 5/8] Add the settings content observer for shortcut preference. Root cause: Didn't update the UI when settings value chagned. Next: Add the settings content observer. Bug: 155837154 Test: manual test & Robo test & atest Change-Id: I7be952a3a8824d00d3903d4a69beb8f992d638a1 --- .../ToggleFeaturePreferenceFragment.java | 19 +++++++++++++++++-- ...ScreenMagnificationPreferenceFragment.java | 6 ++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index 6b0759a92e1..23869110c68 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -30,6 +30,7 @@ import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.text.Html; @@ -96,6 +97,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference private int mUserShortcutTypes = UserShortcutType.EMPTY; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; + private SettingsContentObserver mSettingsContentObserver; // For html description of accessibility service, must follow the rule, such as // , a11y settings will get the resources successfully. @@ -124,6 +126,17 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference getPrefContext()); setPreferenceScreen(preferenceScreen); } + + final List shortcutFeatureKeys = new ArrayList<>(); + shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); + shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + mSettingsContentObserver = new SettingsContentObserver(new Handler(), shortcutFeatureKeys) { + @Override + public void onChange(boolean selfChange, Uri uri) { + updateShortcutPreferenceData(); + updateShortcutPreference(); + } + }; } @Override @@ -229,6 +242,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference final AccessibilityManager am = getPrefContext().getSystemService( AccessibilityManager.class); am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener); + mSettingsContentObserver.register(getContentResolver()); updateShortcutPreferenceData(); updateShortcutPreference(); } @@ -238,6 +252,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference final AccessibilityManager am = getPrefContext().getSystemService( AccessibilityManager.class); am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener); + mSettingsContentObserver.unregister(getContentResolver()); super.onPause(); } @@ -618,7 +633,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference getShortcutTypeSummary(getPrefContext())); } - private void updateShortcutPreferenceData() { + protected void updateShortcutPreferenceData() { if (mComponentName == null) { return; } @@ -651,7 +666,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference mShortcutPreference.setTitle(title); } - private void updateShortcutPreference() { + protected void updateShortcutPreference() { if (mComponentName == null) { return; } diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index 23fb153b5bf..52f8f71d57c 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -467,7 +467,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends showDialog(DialogEnums.MAGNIFICATION_EDIT_SHORTCUT); } - private void updateShortcutPreferenceData() { + @Override + protected void updateShortcutPreferenceData() { // Get the user shortcut type from settings provider. mUserShortcutType = getUserShortcutTypeFromSettings(getPrefContext()); if (mUserShortcutType != UserShortcutType.EMPTY) { @@ -489,7 +490,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends mShortcutPreference.setTitle(title); } - private void updateShortcutPreference() { + @Override + protected void updateShortcutPreference() { final int shortcutTypes = getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE); mShortcutPreference.setChecked( hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes)); From 232cfc4e760d2c8dae90a82b10e7b090d44ff93f Mon Sep 17 00:00:00 2001 From: Tsung-Mao Fang Date: Wed, 13 May 2020 14:43:23 +0800 Subject: [PATCH 6/8] Show the app pinning description after user enables it By design, we still need to show app pinning description after user enables feature. Test: Rebuilt rom, and see description. Fix: 151332926 Change-Id: Ic9a2d7baec865358471ac0210648642ebd9fd65a --- src/com/android/settings/security/ScreenPinningSettings.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/com/android/settings/security/ScreenPinningSettings.java b/src/com/android/settings/security/ScreenPinningSettings.java index ca7590b202c..c53236656be 100644 --- a/src/com/android/settings/security/ScreenPinningSettings.java +++ b/src/com/android/settings/security/ScreenPinningSettings.java @@ -215,7 +215,6 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment private void updateDisplay() { if (isLockToAppEnabled(getActivity())) { - mFooterPreference.setVisible(false); mUseScreenLock.setVisible(true); mUseScreenLock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override @@ -226,7 +225,6 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment mUseScreenLock.setChecked(isScreenLockUsed()); mUseScreenLock.setTitle(getCurrentSecurityTitle()); } else { - mFooterPreference.setVisible(true); mFooterPreference.setSummary(getAppPinningContent()); mUseScreenLock.setVisible(false); } From 17ad56b3fcc082ededc7d1bc218b2b9c2dd4ffb3 Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Wed, 13 May 2020 18:36:23 +0800 Subject: [PATCH 7/8] [Settings] Avoid from redraw UI when first time onResume Registration of subscription change lead to redraw. However, entire UI is newly created where redraw is not required when fragment first time created. Therefore, remove first callback from SubscriptionManager to reduce some time. Bug: 141833767 Test: manual Change-Id: I54a58dd8271bb2cd8cd531cc02ff7d64b3e4328c --- .../network/telephony/MobileNetworkSettings.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index 49f7981c28b..528e5c7788b 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -73,7 +73,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings { private String mClickedPrefKey; private ActiveSubsciptionsListener mActiveSubsciptionsListener; - private boolean mActiveSubsciptionsListenerStarting; + private boolean mDropFirstSubscriptionChangeNotify; private int mActiveSubsciptionsListenerCount; public MobileNetworkSettings() { @@ -207,20 +207,20 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings { public void onResume() { super.onResume(); if (mActiveSubsciptionsListener == null) { - mActiveSubsciptionsListenerStarting = true; mActiveSubsciptionsListener = new ActiveSubsciptionsListener( getContext().getMainLooper(), getContext(), mSubId) { public void onChanged() { onSubscriptionDetailChanged(); } }; - mActiveSubsciptionsListenerStarting = false; + mDropFirstSubscriptionChangeNotify = true; } mActiveSubsciptionsListener.start(); } private void onSubscriptionDetailChanged() { - if (mActiveSubsciptionsListenerStarting) { + if (mDropFirstSubscriptionChangeNotify) { + mDropFirstSubscriptionChangeNotify = false; Log.d(LOG_TAG, "Callback during onResume()"); return; } @@ -235,6 +235,14 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings { }); } + @Override + public void onDestroy() { + if (mActiveSubsciptionsListener != null) { + mActiveSubsciptionsListener.stop(); + } + super.onDestroy(); + } + @VisibleForTesting void onRestoreInstance(Bundle icicle) { if (icicle != null) { From 9a6e7329be0fd4dc68c4167898a876c9ade3a68a Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 13 May 2020 14:03:40 -0400 Subject: [PATCH 8/8] Remove divider after last items Fixes: 155890866 Test: manual Change-Id: Ie0e3f7ad8c1868bda7623718dd60926c300fa353 --- res/layout/notification_sbn_log_row.xml | 221 +++++++++--------- .../history/NotificationHistoryActivity.java | 6 - .../history/NotificationSbnAdapter.java | 1 + .../history/NotificationSbnViewHolder.java | 6 + 4 files changed, 124 insertions(+), 110 deletions(-) diff --git a/res/layout/notification_sbn_log_row.xml b/res/layout/notification_sbn_log_row.xml index 3b731ac4f8f..049e940532c 100644 --- a/res/layout/notification_sbn_log_row.xml +++ b/res/layout/notification_sbn_log_row.xml @@ -14,119 +14,132 @@ limitations under the License. --> - - - - - - - - - - - - - - - + - + android:minHeight="@*android:dimen/status_bar_icon_size" + android:paddingBottom="6dp"> - + + + + + + + + + + + + android:orientation="vertical" + android:layout_marginStart="30dp" + android:layout_marginBottom="6dp" + > + + + + + + - + + \ No newline at end of file diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java index c45242ece25..8b4bc9d8368 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java +++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java @@ -266,9 +266,6 @@ public class NotificationHistoryActivity extends Activity { mSnoozedRv.setLayoutManager(lm); mSnoozedRv.setAdapter( new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm)); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration( - mSnoozedRv.getContext(), lm.getOrientation()); - mSnoozedRv.addItemDecoration(dividerItemDecoration); mSnoozedRv.setNestedScrollingEnabled(false); if (snoozed == null || snoozed.length == 0) { @@ -284,9 +281,6 @@ public class NotificationHistoryActivity extends Activity { mDismissedRv.setLayoutManager(dismissLm); mDismissedRv.setAdapter( new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm)); - DividerItemDecoration dismissDivider = new DividerItemDecoration( - mDismissedRv.getContext(), dismissLm.getOrientation()); - mDismissedRv.addItemDecoration(dismissDivider); mDismissedRv.setNestedScrollingEnabled(false); if (dismissed == null || dismissed.length == 0) { diff --git a/src/com/android/settings/notification/history/NotificationSbnAdapter.java b/src/com/android/settings/notification/history/NotificationSbnAdapter.java index c7f68abac14..5d4e7166710 100644 --- a/src/com/android/settings/notification/history/NotificationSbnAdapter.java +++ b/src/com/android/settings/notification/history/NotificationSbnAdapter.java @@ -94,6 +94,7 @@ public class NotificationSbnAdapter extends holder.setTitle(getTitleString(sbn.getNotification())); holder.setSummary(getTextString(mContext, sbn.getNotification())); holder.setPostedTime(sbn.getPostTime()); + holder.setDividerVisible(position < (mValues.size() -1)); int userId = normalizeUserId(sbn); if (!mUserBadgeCache.containsKey(userId)) { Drawable profile = mContext.getPackageManager().getUserBadgeForDensity( diff --git a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java index 42a210057a8..3f1197d7b95 100644 --- a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java +++ b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java @@ -45,6 +45,7 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { private final TextView mTitle; private final TextView mSummary; private final ImageView mProfileBadge; + private final View mDivider; NotificationSbnViewHolder(View itemView) { super(itemView); @@ -54,6 +55,7 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { mTitle = itemView.findViewById(R.id.title); mSummary = itemView.findViewById(R.id.text); mProfileBadge = itemView.findViewById(R.id.profile_badge); + mDivider = itemView.findViewById(R.id.divider); } void setSummary(CharSequence summary) { @@ -85,6 +87,10 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { mProfileBadge.setVisibility(badge != null ? View.VISIBLE : View.GONE); } + void setDividerVisible(boolean visible) { + mDivider.setVisibility(visible ? View.VISIBLE : View.GONE); + } + void addOnClick(String pkg, int userId, PendingIntent pi) { Intent appIntent = itemView.getContext().getPackageManager() .getLaunchIntentForPackage(pkg);