diff options
8 files changed, 71 insertions, 416 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7f59d35586c1..2b638f6e283f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6103,7 +6103,7 @@ public final class Settings { * Indicates which clock face to show on lock screen and AOD while docked. * @hide */ - public static final String DOCKED_CLOCK_FACE = "docked_clock_face"; + private static final String DOCKED_CLOCK_FACE = "docked_clock_face"; /** * Set by the system to track if the user needs to see the call to action for diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index c57b609023ca..4d2f005998c3 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -621,7 +621,6 @@ public class SettingsBackupTest { Settings.Secure.DISABLED_PRINT_SERVICES, Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, Settings.Secure.DISPLAY_DENSITY_FORCED, - Settings.Secure.DOCKED_CLOCK_FACE, Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION, Settings.Secure.ENABLED_INPUT_METHODS, // Intentionally removed in P diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java index 078108d658ee..95981427b642 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java @@ -15,7 +15,6 @@ */ package com.android.keyguard.clock; -import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; @@ -26,18 +25,16 @@ import android.os.Looper; import android.provider.Settings; import android.view.LayoutInflater; -import androidx.annotation.VisibleForTesting; - import com.android.keyguard.R; -import com.android.systemui.dock.DockManager; -import com.android.systemui.dock.DockManager.DockEventListener; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.statusbar.policy.ExtensionController; import com.android.systemui.statusbar.policy.ExtensionController.Extension; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; +import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Singleton; @@ -48,6 +45,7 @@ import javax.inject.Singleton; @Singleton public final class ClockManager { + private final LayoutInflater mLayoutInflater; private final ContentResolver mContentResolver; private final List<ClockInfo> mClockInfos = new ArrayList<>(); @@ -64,6 +62,7 @@ public final class ClockManager { } } }; + private final ExtensionController mExtensionController; /** * Used to select between plugin or default implementations of ClockPlugin interface. @@ -73,35 +72,13 @@ public final class ClockManager { * Consumer that accepts the a new ClockPlugin implementation when the Extension reloads. */ private final Consumer<ClockPlugin> mClockPluginConsumer = this::setClockPlugin; - /** - * Supplier of default ClockPlugin implementation. - */ - private final DefaultClockSupplier mDefaultClockSupplier; - /** - * Observe changes to dock state to know when to switch the clock face. - */ - private final DockEventListener mDockEventListener = - new DockEventListener() { - @Override - public void onEvent(int event) { - final boolean isDocked = (event == DockManager.STATE_DOCKED - || event == DockManager.STATE_DOCKED_HIDE); - mDefaultClockSupplier.setDocked(isDocked); - if (mClockExtension != null) { - mClockExtension.reload(); - } - } - }; - @Nullable - private final DockManager mDockManager; private final List<ClockChangedListener> mListeners = new ArrayList<>(); @Inject - public ClockManager(Context context, ExtensionController extensionController, - @Nullable DockManager dockManager) { + public ClockManager(Context context, ExtensionController extensionController) { mExtensionController = extensionController; - mDockManager = dockManager; + mLayoutInflater = LayoutInflater.from(context); mContentResolver = context.getContentResolver(); Resources res = context.getResources(); @@ -133,9 +110,6 @@ public final class ClockManager { .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.type_thumbnail)) .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.type_preview)) .build()); - - mDefaultClockSupplier = new DefaultClockSupplier(new SettingsWrapper(mContentResolver), - LayoutInflater.from(context)); } /** @@ -180,32 +154,41 @@ public final class ClockManager { mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE), false, mContentObserver); - mContentResolver.registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.DOCKED_CLOCK_FACE), - false, mContentObserver); - if (mDockManager != null) { - mDockManager.addListener(mDockEventListener); - } mClockExtension = mExtensionController.newExtension(ClockPlugin.class) .withPlugin(ClockPlugin.class) .withCallback(mClockPluginConsumer) - .withDefault(mDefaultClockSupplier) + // Using withDefault even though this isn't the default as a workaround. + // ExtensionBuilder doesn't provide the ability to supply a ClockPlugin + // instance based off of the value of a setting. Since multiple "default" + // can be provided, using a supplier that changes the settings value. + // A null return will cause Extension#reload to look at the next "default" + // supplier. + .withDefault( + new SettingsGattedSupplier( + mContentResolver, + Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, + BubbleClockController.class.getName(), + () -> BubbleClockController.build(mLayoutInflater))) + .withDefault( + new SettingsGattedSupplier( + mContentResolver, + Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, + StretchAnalogClockController.class.getName(), + () -> StretchAnalogClockController.build(mLayoutInflater))) + .withDefault( + new SettingsGattedSupplier( + mContentResolver, + Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, + TypeClockController.class.getName(), + () -> TypeClockController.build(mLayoutInflater))) .build(); } private void unregister() { mContentResolver.unregisterContentObserver(mContentObserver); - if (mDockManager != null) { - mDockManager.removeListener(mDockEventListener); - } mClockExtension.destroy(); } - @VisibleForTesting - boolean isDocked() { - return mDefaultClockSupplier.isDocked(); - } - /** * Listener for events that should cause the custom clock face to change. */ @@ -217,4 +200,44 @@ public final class ClockManager { */ void onClockChanged(ClockPlugin clock); } + + /** + * Supplier that only gets an instance when a settings value matches expected value. + */ + private static class SettingsGattedSupplier implements Supplier<ClockPlugin> { + + private final ContentResolver mContentResolver; + private final String mKey; + private final String mValue; + private final Supplier<ClockPlugin> mSupplier; + + /** + * Constructs a supplier that changes secure setting key against value. + * + * @param contentResolver Used to look up settings value. + * @param key Settings key. + * @param value If the setting matches this values that get supplies a ClockPlugin + * instance. + * @param supplier Supplier of ClockPlugin instance, only used if the setting + * matches value. + */ + SettingsGattedSupplier(ContentResolver contentResolver, String key, String value, + Supplier<ClockPlugin> supplier) { + mContentResolver = contentResolver; + mKey = key; + mValue = value; + mSupplier = supplier; + } + + /** + * Returns null if the settings value doesn't match the expected value. + * + * A null return causes Extension#reload to skip this supplier and move to the next. + */ + @Override + public ClockPlugin get() { + final String currentValue = Settings.Secure.getString(mContentResolver, mKey); + return Objects.equals(currentValue, mValue) ? mSupplier.get() : null; + } + } } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockSupplier.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockSupplier.java deleted file mode 100644 index 7fdd2357bc8e..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockSupplier.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.keyguard.clock; - -import android.util.ArrayMap; -import android.view.LayoutInflater; - -import com.android.systemui.plugins.ClockPlugin; - -import java.util.Map; -import java.util.function.Supplier; - -/** - * Supplier that only gets an instance when a settings value matches expected value. - */ -public class DefaultClockSupplier implements Supplier<ClockPlugin> { - - private final SettingsWrapper mSettingsWrapper; - /** - * Map from expected value stored in settings to supplier of custom clock face. - */ - private final Map<String, Supplier<ClockPlugin>> mClocks = new ArrayMap<>(); - /** - * When docked, the DOCKED_CLOCK_FACE setting will be checked for the custom clock face - * to show. - */ - private boolean mIsDocked; - - /** - * Constructs a supplier that changes secure setting key against value. - * - * @param settingsWrapper Wrapper around settings used to look up the custom clock face. - * @param layoutInflater Provided to clocks as dependency to inflate clock views. - */ - public DefaultClockSupplier(SettingsWrapper settingsWrapper, LayoutInflater layoutInflater) { - mSettingsWrapper = settingsWrapper; - - mClocks.put(BubbleClockController.class.getName(), - () -> BubbleClockController.build(layoutInflater)); - mClocks.put(StretchAnalogClockController.class.getName(), - () -> StretchAnalogClockController.build(layoutInflater)); - mClocks.put(TypeClockController.class.getName(), - () -> TypeClockController.build(layoutInflater)); - } - - /** - * Sets the dock state. - * - * @param isDocked True when docked, false otherwise. - */ - public void setDocked(boolean isDocked) { - mIsDocked = isDocked; - } - - boolean isDocked() { - return mIsDocked; - } - - /** - * Get the custom clock face based on values in settings. - * - * @return Custom clock face, null if the settings value doesn't match a custom clock. - */ - @Override - public ClockPlugin get() { - ClockPlugin plugin = null; - if (mIsDocked) { - final String name = mSettingsWrapper.getDockedClockFace(); - if (name != null) { - Supplier<ClockPlugin> supplier = mClocks.get(name); - if (supplier != null) { - plugin = supplier.get(); - if (plugin != null) { - return plugin; - } - } - } - } - final String name = mSettingsWrapper.getLockScreenCustomClockFace(); - if (name != null) { - Supplier<ClockPlugin> supplier = mClocks.get(name); - if (supplier != null) { - plugin = supplier.get(); - } - } - return plugin; - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java b/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java deleted file mode 100644 index 58e11553af9d..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.keyguard.clock; - -import android.content.ContentResolver; -import android.provider.Settings; - -/** - * Wrapper around Settings used for testing. - */ -public class SettingsWrapper { - - private static final String CUSTOM_CLOCK_FACE = Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE; - private static final String DOCKED_CLOCK_FACE = Settings.Secure.DOCKED_CLOCK_FACE; - - private ContentResolver mContentResolver; - - public SettingsWrapper(ContentResolver contentResolver) { - mContentResolver = contentResolver; - } - - /** - * Gets the value stored in settings for the custom clock face. - */ - public String getLockScreenCustomClockFace() { - return Settings.Secure.getString(mContentResolver, CUSTOM_CLOCK_FACE); - } - - /** - * Gets the value stored in settings for the clock face to use when docked. - */ - public String getDockedClockFace() { - return Settings.Secure.getString(mContentResolver, DOCKED_CLOCK_FACE); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index d27a90332ac5..755d6fcffb43 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -31,7 +31,6 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.assist.AssistManager; import com.android.systemui.classifier.FalsingManager; -import com.android.systemui.dock.DockManager; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -229,16 +228,6 @@ public class SystemUIFactory { return SysUiServiceProvider.getComponent(context, StatusBar.class); } - /** - * Provides DockManager. - */ - @Singleton - @Provides - @Nullable - public DockManager providesDockManager(Context context) { - return SysUiServiceProvider.getComponent(context, DockManager.class); - } - @Module protected static class ContextHolder { private Context mContext; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java deleted file mode 100644 index f813ac693d42..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.keyguard.clock; - -import static com.google.common.truth.Truth.assertThat; - -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -import android.testing.LeakCheck; -import android.testing.TestableLooper.RunWithLooper; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.dock.DockManager; -import com.android.systemui.dock.DockManagerFake; -import com.android.systemui.utils.leaks.FakeExtensionController; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@RunWithLooper -public final class ClockManagerTest extends SysuiTestCase { - - private ClockManager mClockManager; - private LeakCheck mLeakCheck; - private FakeExtensionController mFakeExtensionController; - private DockManagerFake mFakeDockManager; - @Mock ClockManager.ClockChangedListener mMockListener; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mLeakCheck = new LeakCheck(); - mFakeExtensionController = new FakeExtensionController(mLeakCheck); - mFakeDockManager = new DockManagerFake(); - mClockManager = new ClockManager(getContext(), mFakeExtensionController, - mFakeDockManager); - mClockManager.addOnClockChangedListener(mMockListener); - } - - @After - public void tearDown() { - mClockManager.removeOnClockChangedListener(mMockListener); - } - - @Test - public void dockEvent() { - mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED); - assertThat(mClockManager.isDocked()).isTrue(); - } - - @Test - public void undockEvent() { - mFakeDockManager.setDockEvent(DockManager.STATE_NONE); - assertThat(mClockManager.isDocked()).isFalse(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/DefaultClockSupplierTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/DefaultClockSupplierTest.java deleted file mode 100644 index 1a3b198ac0d6..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/DefaultClockSupplierTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.keyguard.clock; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.when; - -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper.RunWithLooper; -import android.view.LayoutInflater; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.ClockPlugin; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@RunWithLooper -public final class DefaultClockSupplierTest extends SysuiTestCase { - - private static final String BUBBLE_CLOCK = BubbleClockController.class.getName(); - private static final Class<?> BUBBLE_CLOCK_CLASS = BubbleClockController.class; - - private DefaultClockSupplier mDefaultClockSupplier; - @Mock SettingsWrapper mMockSettingsWrapper; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mDefaultClockSupplier = new DefaultClockSupplier(mMockSettingsWrapper, - LayoutInflater.from(getContext())); - } - - @Test - public void get_default() { - // GIVEN that settings doesn't contain any values - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(null); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn(null); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null, indicated the default clock face should be used. - assertThat(plugin).isNull(); - } - - @Test - public void get_customClock() { - // GIVEN that settings is set to the bubble clock face - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the plugin is the bubble clock face. - assertThat(plugin).isInstanceOf(BUBBLE_CLOCK_CLASS); - } - - @Test - public void get_badSettingsValue() { - // GIVEN that settings contains a value that doesn't correspond to a - // custom clock face. - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn("bad value"); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null. - assertThat(plugin).isNull(); - } - - @Test - public void get_dockedDefault() { - // GIVEN docked - mDefaultClockSupplier.setDocked(true); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null, indicating the default clock face. - assertThat(plugin).isNull(); - } - - @Test - public void get_dockedCustomClock() { - // GIVEN docked and settings is set to the bubble clock face - mDefaultClockSupplier.setDocked(true); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn(BUBBLE_CLOCK); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the plugin is the bubble clock face. - assertThat(plugin).isInstanceOf(BUBBLE_CLOCK_CLASS); - } - - @Test - public void get_badDockedSettingsValue() { - // GIVEN docked and settings contains a value that doesn't correspond to - // an available clock face. - mDefaultClockSupplier.setDocked(true); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn("bad value"); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null. - assertThat(plugin).isNull(); - } - - @Test - public void get_badDockedSettingsFallback() { - // GIVEN docked and settings contains a value that doesn't correspond to - // an available clock face, but locked screen settings is set to bubble - // clock. - mDefaultClockSupplier.setDocked(true); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn("bad value"); - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the plugin is the bubble clock face. - assertThat(plugin).isInstanceOf(BUBBLE_CLOCK_CLASS); - } -} |