Loading core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +7 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,13 @@ public final class SystemUiDeviceConfigFlags { */ public static final String ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS = "assist_handles_shown_frequency_threshold_ms"; // Flag related to clock face /** * (String) Contains the clock plugin service names that are not allow to be shown. * Each service name is seperated by a comma(",") in the string. */ public static final String CLOCK_FACE_BLACKLIST = "clock_face_blacklist"; /** * (long) How long, in milliseconds, for teaching behaviors to wait before considering the user Loading packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +64 −16 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.keyguard.clock; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLOCK_FACE_BLACKLIST; import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; Loading @@ -24,9 +26,12 @@ import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import androidx.annotation.VisibleForTesting; Loading @@ -42,10 +47,12 @@ import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Supplier; import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; Loading @@ -67,6 +74,8 @@ public final class ClockManager { private final Handler mMainHandler = new Handler(Looper.getMainLooper()); private final CurrentUserObservable mCurrentUserObservable; private final ArraySet<String> mBlacklistedClockPlugins = new ArraySet<>(); /** * Observe settings changes to know when to switch the clock face. */ Loading Loading @@ -155,6 +164,41 @@ public final class ClockManager { DisplayMetrics dm = res.getDisplayMetrics(); mWidth = dm.widthPixels; mHeight = dm.heightPixels; updateBlackList(); registerDeviceConfigListener(); } private void updateBlackList() { String blacklist = getBlackListFromConfig(); mBlacklistedClockPlugins.clear(); if (blacklist != null && !blacklist.isEmpty()) { mBlacklistedClockPlugins.addAll(Arrays.asList(blacklist.split(","))); } } String getBlackListFromConfig() { return DeviceConfig.getString( DeviceConfig.NAMESPACE_SYSTEMUI, CLOCK_FACE_BLACKLIST, null); } private void registerDeviceConfigListener() { DeviceConfig.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_SYSTEMUI, r -> mMainHandler.post(r), properties -> onDeviceConfigPropertiesChanged(properties.getNamespace())); } void onDeviceConfigPropertiesChanged(String namespace) { if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) { Log.e(TAG, "Received update from DeviceConfig for unrelated namespace: " + namespace); return; } updateBlackList(); reload(); } /** Loading Loading @@ -240,9 +284,9 @@ public final class ClockManager { } private void reload() { mPreviewClocks.reload(); mPreviewClocks.reloadCurrentClock(); mListeners.forEach((listener, clocks) -> { clocks.reload(); clocks.reloadCurrentClock(); ClockPlugin clock = clocks.getCurrentClock(); if (clock instanceof DefaultClockController) { listener.onClockChanged(null); Loading Loading @@ -287,20 +331,13 @@ public final class ClockManager { @Override public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { addClockPlugin(plugin); reload(); if (plugin == mCurrentClock) { ClockManager.this.reload(); } reloadIfNeeded(plugin); } @Override public void onPluginDisconnected(ClockPlugin plugin) { boolean isCurrentClock = plugin == mCurrentClock; removeClockPlugin(plugin); reload(); if (isCurrentClock) { ClockManager.this.reload(); } reloadIfNeeded(plugin); } /** Loading @@ -313,10 +350,12 @@ public final class ClockManager { } /** * Get information about available clock faces. * Get information about clock faces which are available and not in blacklist. */ List<ClockInfo> getInfo() { return mClockInfo; return mClockInfo.stream() .filter(info -> !mBlacklistedClockPlugins.contains(info.getId())) .collect(Collectors.toList()); } /** Loading Loading @@ -347,10 +386,19 @@ public final class ClockManager { } } private void reloadIfNeeded(ClockPlugin plugin) { final boolean wasCurrentClock = plugin == mCurrentClock; reloadCurrentClock(); final boolean isCurrentClock = plugin == mCurrentClock; if (wasCurrentClock || isCurrentClock) { ClockManager.this.reload(); } } /** * Update the current clock. */ void reload() { void reloadCurrentClock() { mCurrentClock = getClockPlugin(); } Loading @@ -359,7 +407,7 @@ public final class ClockManager { if (ClockManager.this.isDocked()) { final String name = mSettingsWrapper.getDockedClockFace( mCurrentUserObservable.getCurrentUser().getValue()); if (name != null) { if (name != null && !mBlacklistedClockPlugins.contains(name)) { plugin = mClocks.get(name); if (plugin != null) { return plugin; Loading @@ -368,7 +416,7 @@ public final class ClockManager { } final String name = mSettingsWrapper.getLockScreenCustomClockFace( mCurrentUserObservable.getCurrentUser().getValue()); if (name != null) { if (name != null && !mBlacklistedClockPlugins.contains(name)) { plugin = mClocks.get(name); } return plugin; Loading packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java +32 −1 Original line number Diff line number Diff line Loading @@ -20,12 +20,14 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.database.ContentObserver; import android.net.Uri; import android.provider.DeviceConfig; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; Loading @@ -50,6 +52,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.List; @SmallTest @RunWith(AndroidTestingRunner.class) // Need to run tests on main looper because LiveData operations such as setData, observe, Loading @@ -63,7 +67,7 @@ public final class ClockManagerTest extends SysuiTestCase { private static final int SECONDARY_USER_ID = 11; private static final Uri SETTINGS_URI = null; private ClockManager mClockManager; ClockManager mClockManager; private ContentObserver mContentObserver; private DockManagerFake mFakeDockManager; private MutableLiveData<Integer> mCurrentUser; Loading Loading @@ -139,6 +143,33 @@ public final class ClockManagerTest extends SysuiTestCase { assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS); } @Test public void getCurrentClock_inBlackList() { mClockManager = spy(mClockManager); // GIVEN that settings is set to the bubble clock face when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(BUBBLE_CLOCK); // WHEN settings change event is fired mContentObserver.onChange(false, SETTINGS_URI, MAIN_USER_ID); // GIVEN that bubble clock is in blacklist when(mClockManager.getBlackListFromConfig()).thenReturn(BUBBLE_CLOCK); // WHEN device config change of systemui is fired mClockManager.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI); // THEN the result is null, indicated the current clock should be reset to the default one. assertThat(mClockManager.getCurrentClock()).isNull(); } @Test public void getClockInfo_inBlackList() { mClockManager = spy(mClockManager); // GIVEN that bubble clock is in blacklist when(mClockManager.getBlackListFromConfig()).thenReturn(BUBBLE_CLOCK); // WHEN device config change of systemui is fired mClockManager.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI); // THEN the ClockInfo should not contain bubble clock List<ClockInfo> clocks = mClockManager.getClockInfos(); assertThat(clocks.stream().anyMatch(info -> BUBBLE_CLOCK.equals(info.getId()))).isFalse(); } @Test public void onClockChanged_customClock() { // GIVEN that settings is set to the bubble clock face Loading Loading
core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +7 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,13 @@ public final class SystemUiDeviceConfigFlags { */ public static final String ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS = "assist_handles_shown_frequency_threshold_ms"; // Flag related to clock face /** * (String) Contains the clock plugin service names that are not allow to be shown. * Each service name is seperated by a comma(",") in the string. */ public static final String CLOCK_FACE_BLACKLIST = "clock_face_blacklist"; /** * (long) How long, in milliseconds, for teaching behaviors to wait before considering the user Loading
packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +64 −16 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.keyguard.clock; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLOCK_FACE_BLACKLIST; import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; Loading @@ -24,9 +26,12 @@ import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import androidx.annotation.VisibleForTesting; Loading @@ -42,10 +47,12 @@ import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Supplier; import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; Loading @@ -67,6 +74,8 @@ public final class ClockManager { private final Handler mMainHandler = new Handler(Looper.getMainLooper()); private final CurrentUserObservable mCurrentUserObservable; private final ArraySet<String> mBlacklistedClockPlugins = new ArraySet<>(); /** * Observe settings changes to know when to switch the clock face. */ Loading Loading @@ -155,6 +164,41 @@ public final class ClockManager { DisplayMetrics dm = res.getDisplayMetrics(); mWidth = dm.widthPixels; mHeight = dm.heightPixels; updateBlackList(); registerDeviceConfigListener(); } private void updateBlackList() { String blacklist = getBlackListFromConfig(); mBlacklistedClockPlugins.clear(); if (blacklist != null && !blacklist.isEmpty()) { mBlacklistedClockPlugins.addAll(Arrays.asList(blacklist.split(","))); } } String getBlackListFromConfig() { return DeviceConfig.getString( DeviceConfig.NAMESPACE_SYSTEMUI, CLOCK_FACE_BLACKLIST, null); } private void registerDeviceConfigListener() { DeviceConfig.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_SYSTEMUI, r -> mMainHandler.post(r), properties -> onDeviceConfigPropertiesChanged(properties.getNamespace())); } void onDeviceConfigPropertiesChanged(String namespace) { if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) { Log.e(TAG, "Received update from DeviceConfig for unrelated namespace: " + namespace); return; } updateBlackList(); reload(); } /** Loading Loading @@ -240,9 +284,9 @@ public final class ClockManager { } private void reload() { mPreviewClocks.reload(); mPreviewClocks.reloadCurrentClock(); mListeners.forEach((listener, clocks) -> { clocks.reload(); clocks.reloadCurrentClock(); ClockPlugin clock = clocks.getCurrentClock(); if (clock instanceof DefaultClockController) { listener.onClockChanged(null); Loading Loading @@ -287,20 +331,13 @@ public final class ClockManager { @Override public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { addClockPlugin(plugin); reload(); if (plugin == mCurrentClock) { ClockManager.this.reload(); } reloadIfNeeded(plugin); } @Override public void onPluginDisconnected(ClockPlugin plugin) { boolean isCurrentClock = plugin == mCurrentClock; removeClockPlugin(plugin); reload(); if (isCurrentClock) { ClockManager.this.reload(); } reloadIfNeeded(plugin); } /** Loading @@ -313,10 +350,12 @@ public final class ClockManager { } /** * Get information about available clock faces. * Get information about clock faces which are available and not in blacklist. */ List<ClockInfo> getInfo() { return mClockInfo; return mClockInfo.stream() .filter(info -> !mBlacklistedClockPlugins.contains(info.getId())) .collect(Collectors.toList()); } /** Loading Loading @@ -347,10 +386,19 @@ public final class ClockManager { } } private void reloadIfNeeded(ClockPlugin plugin) { final boolean wasCurrentClock = plugin == mCurrentClock; reloadCurrentClock(); final boolean isCurrentClock = plugin == mCurrentClock; if (wasCurrentClock || isCurrentClock) { ClockManager.this.reload(); } } /** * Update the current clock. */ void reload() { void reloadCurrentClock() { mCurrentClock = getClockPlugin(); } Loading @@ -359,7 +407,7 @@ public final class ClockManager { if (ClockManager.this.isDocked()) { final String name = mSettingsWrapper.getDockedClockFace( mCurrentUserObservable.getCurrentUser().getValue()); if (name != null) { if (name != null && !mBlacklistedClockPlugins.contains(name)) { plugin = mClocks.get(name); if (plugin != null) { return plugin; Loading @@ -368,7 +416,7 @@ public final class ClockManager { } final String name = mSettingsWrapper.getLockScreenCustomClockFace( mCurrentUserObservable.getCurrentUser().getValue()); if (name != null) { if (name != null && !mBlacklistedClockPlugins.contains(name)) { plugin = mClocks.get(name); } return plugin; Loading
packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java +32 −1 Original line number Diff line number Diff line Loading @@ -20,12 +20,14 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.database.ContentObserver; import android.net.Uri; import android.provider.DeviceConfig; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; Loading @@ -50,6 +52,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.List; @SmallTest @RunWith(AndroidTestingRunner.class) // Need to run tests on main looper because LiveData operations such as setData, observe, Loading @@ -63,7 +67,7 @@ public final class ClockManagerTest extends SysuiTestCase { private static final int SECONDARY_USER_ID = 11; private static final Uri SETTINGS_URI = null; private ClockManager mClockManager; ClockManager mClockManager; private ContentObserver mContentObserver; private DockManagerFake mFakeDockManager; private MutableLiveData<Integer> mCurrentUser; Loading Loading @@ -139,6 +143,33 @@ public final class ClockManagerTest extends SysuiTestCase { assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS); } @Test public void getCurrentClock_inBlackList() { mClockManager = spy(mClockManager); // GIVEN that settings is set to the bubble clock face when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(BUBBLE_CLOCK); // WHEN settings change event is fired mContentObserver.onChange(false, SETTINGS_URI, MAIN_USER_ID); // GIVEN that bubble clock is in blacklist when(mClockManager.getBlackListFromConfig()).thenReturn(BUBBLE_CLOCK); // WHEN device config change of systemui is fired mClockManager.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI); // THEN the result is null, indicated the current clock should be reset to the default one. assertThat(mClockManager.getCurrentClock()).isNull(); } @Test public void getClockInfo_inBlackList() { mClockManager = spy(mClockManager); // GIVEN that bubble clock is in blacklist when(mClockManager.getBlackListFromConfig()).thenReturn(BUBBLE_CLOCK); // WHEN device config change of systemui is fired mClockManager.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI); // THEN the ClockInfo should not contain bubble clock List<ClockInfo> clocks = mClockManager.getClockInfos(); assertThat(clocks.stream().anyMatch(info -> BUBBLE_CLOCK.equals(info.getId()))).isFalse(); } @Test public void onClockChanged_customClock() { // GIVEN that settings is set to the bubble clock face Loading