Loading packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +10 −106 Original line number Diff line number Diff line package com.android.keyguard; import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; import android.animation.Animator; import android.animation.ValueAnimator; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Paint; import android.graphics.Paint.Style; Loading @@ -24,16 +21,10 @@ import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.TextClock; import androidx.annotation.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener; import com.android.keyguard.clock.ClockManager; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.util.wakelock.KeepAwakeAnimationListener; Loading @@ -42,37 +33,18 @@ import java.io.PrintWriter; import java.util.Arrays; import java.util.TimeZone; import javax.inject.Inject; import javax.inject.Named; /** * Switch to show plugin clock when plugin is connected, otherwise it will show default clock. */ public class KeyguardClockSwitch extends RelativeLayout { private static final String TAG = "KeyguardClockSwitch"; private static final boolean CUSTOM_CLOCKS_ENABLED = true; /** * Animation fraction when text is transitioned to/from bold. */ private static final float TO_BOLD_TRANSITION_FRACTION = 0.7f; /** * Controller used to track StatusBar state to know when to show the big_clock_container. */ private final StatusBarStateController mStatusBarStateController; /** * Color extractor used to apply colors from wallpaper to custom clock faces. */ private final SysuiColorExtractor mSysuiColorExtractor; /** * Manager used to know when to show a custom clock face. */ private final ClockManager mClockManager; /** * Layout transition that scales the default clock face. */ Loading Loading @@ -130,42 +102,8 @@ public class KeyguardClockSwitch extends RelativeLayout { private boolean mSupportsDarkText; private int[] mColorPalette; /** * Track the state of the status bar to know when to hide the big_clock_container. */ private int mStatusBarState; private final StatusBarStateController.StateListener mStateListener = new StatusBarStateController.StateListener() { @Override public void onStateChanged(int newState) { mStatusBarState = newState; updateBigClockVisibility(); } }; private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin; /** * Listener for changes to the color palette. * * The color palette changes when the wallpaper is changed. */ private final OnColorsChangedListener mColorsListener = (extractor, which) -> { if ((which & WallpaperManager.FLAG_LOCK) != 0) { updateColors(); } }; @Inject public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor, ClockManager clockManager) { public KeyguardClockSwitch(Context context, AttributeSet attrs) { super(context, attrs); mStatusBarStateController = statusBarStateController; mStatusBarState = mStatusBarStateController.getState(); mSysuiColorExtractor = colorExtractor; mClockManager = clockManager; mClockTransition = new ClockVisibilityTransition().setCutoff( 1 - TO_BOLD_TRANSITION_FRACTION); Loading Loading @@ -197,29 +135,7 @@ public class KeyguardClockSwitch extends RelativeLayout { mKeyguardStatusArea = findViewById(R.id.keyguard_status_area); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (CUSTOM_CLOCKS_ENABLED) { mClockManager.addOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.addCallback(mStateListener); mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener); updateColors(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (CUSTOM_CLOCKS_ENABLED) { mClockManager.removeOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.removeCallback(mStateListener); mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener); setClockPlugin(null); } private void setClockPlugin(ClockPlugin plugin) { void setClockPlugin(ClockPlugin plugin, int statusBarState) { // Disconnect from existing plugin. if (mClockPlugin != null) { View smallClockView = mClockPlugin.getView(); Loading @@ -228,7 +144,7 @@ public class KeyguardClockSwitch extends RelativeLayout { } if (mBigClockContainer != null) { mBigClockContainer.removeAllViews(); updateBigClockVisibility(); updateBigClockVisibility(statusBarState); } mClockPlugin.onDestroyView(); mClockPlugin = null; Loading Loading @@ -256,7 +172,7 @@ public class KeyguardClockSwitch extends RelativeLayout { View bigClockView = plugin.getBigClockView(); if (bigClockView != null && mBigClockContainer != null) { mBigClockContainer.addView(bigClockView); updateBigClockVisibility(); updateBigClockVisibility(statusBarState); } // Hide default clock. if (!plugin.shouldShowStatusArea()) { Loading @@ -275,7 +191,7 @@ public class KeyguardClockSwitch extends RelativeLayout { /** * Set container for big clock face appearing behind NSSL and KeyguardStatusView. */ public void setBigClockContainer(ViewGroup container) { public void setBigClockContainer(ViewGroup container, int statusBarState) { if (mClockPlugin != null && container != null) { View bigClockView = mClockPlugin.getBigClockView(); if (bigClockView != null) { Loading @@ -283,7 +199,7 @@ public class KeyguardClockSwitch extends RelativeLayout { } } mBigClockContainer = container; updateBigClockVisibility(); updateBigClockVisibility(statusBarState); } /** Loading Loading @@ -407,9 +323,7 @@ public class KeyguardClockSwitch extends RelativeLayout { } } private void updateColors() { ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors( WallpaperManager.FLAG_LOCK); void updateColors(ColorExtractor.GradientColors colors) { mSupportsDarkText = colors.supportsDarkText(); mColorPalette = colors.getColorPalette(); if (mClockPlugin != null) { Loading @@ -417,12 +331,12 @@ public class KeyguardClockSwitch extends RelativeLayout { } } private void updateBigClockVisibility() { void updateBigClockVisibility(int statusBarState) { if (mBigClockContainer == null) { return; } final boolean inDisplayState = mStatusBarState == StatusBarState.KEYGUARD || mStatusBarState == StatusBarState.SHADE_LOCKED; final boolean inDisplayState = statusBarState == StatusBarState.KEYGUARD || statusBarState == StatusBarState.SHADE_LOCKED; final int visibility = !mShowingHeader && inDisplayState && mBigClockContainer.getChildCount() != 0 ? View.VISIBLE : View.GONE; if (mBigClockContainer.getVisibility() != visibility) { Loading Loading @@ -506,16 +420,6 @@ public class KeyguardClockSwitch extends RelativeLayout { } } @VisibleForTesting(otherwise = VisibleForTesting.NONE) ClockManager.ClockChangedListener getClockChangedListener() { return mClockChangedListener; } @VisibleForTesting(otherwise = VisibleForTesting.NONE) StatusBarStateController.StateListener getStateListener() { return mStateListener; } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("KeyguardClockSwitch:"); pw.println(" mClockPlugin: " + mClockPlugin); Loading packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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; import android.app.WallpaperManager; import android.view.View; import android.view.ViewGroup; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import javax.inject.Inject; /** * Injectable controller for {@link KeyguardClockSwitch}. */ public class KeyguardClockSwitchController { private static final boolean CUSTOM_CLOCKS_ENABLED = true; private final StatusBarStateController mStatusBarStateController; private final SysuiColorExtractor mColorExtractor; private final ClockManager mClockManager; private KeyguardClockSwitch mView; private final StatusBarStateController.StateListener mStateListener = new StatusBarStateController.StateListener() { @Override public void onStateChanged(int newState) { mView.updateBigClockVisibility(newState); } }; /** * Listener for changes to the color palette. * * The color palette changes when the wallpaper is changed. */ private final ColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> { if ((which & WallpaperManager.FLAG_LOCK) != 0) { mView.updateColors(getGradientColors()); } }; private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin; private final View.OnAttachStateChangeListener mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { if (CUSTOM_CLOCKS_ENABLED) { mClockManager.addOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.addCallback(mStateListener); mColorExtractor.addOnColorsChangedListener(mColorsListener); mView.updateColors(getGradientColors()); } @Override public void onViewDetachedFromWindow(View v) { if (CUSTOM_CLOCKS_ENABLED) { mClockManager.removeOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.removeCallback(mStateListener); mColorExtractor.removeOnColorsChangedListener(mColorsListener); mView.setClockPlugin(null, mStatusBarStateController.getState()); } }; @Inject public KeyguardClockSwitchController(StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor, ClockManager clockManager) { mStatusBarStateController = statusBarStateController; mColorExtractor = colorExtractor; mClockManager = clockManager; } /** * Attach the controller to the view it relates to. */ public void attach(KeyguardClockSwitch view) { mView = view; if (mView.isAttachedToWindow()) { mOnAttachStateChangeListener.onViewAttachedToWindow(mView); } mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener); } /** * Set container for big clock face appearing behind NSSL and KeyguardStatusView. */ public void setBigClockContainer(ViewGroup bigClockContainer) { mView.setBigClockContainer(bigClockContainer, mStatusBarStateController.getState()); } private void setClockPlugin(ClockPlugin plugin) { mView.setClockPlugin(plugin, mStatusBarStateController.getState()); } private ColorExtractor.GradientColors getGradientColors() { return mColorExtractor.getColors(WallpaperManager.FLAG_LOCK); } } packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +14 −6 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardClockSwitchController; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; Loading Loading @@ -124,6 +124,7 @@ import java.util.function.Consumer; import java.util.function.Function; import javax.inject.Inject; import javax.inject.Provider; @StatusBarComponent.StatusBarScope public class NotificationPanelViewController extends PanelViewController { Loading Loading @@ -252,6 +253,7 @@ public class NotificationPanelViewController extends PanelViewController { private final ConversationNotificationManager mConversationNotificationManager; private final MediaHierarchyManager mMediaHierarchyManager; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final Provider<KeyguardClockSwitchController> mKeyguardClockSwitchControllerProvider; private KeyguardAffordanceHelper mAffordanceHelper; private KeyguardUserSwitcher mKeyguardUserSwitcher; Loading Loading @@ -495,7 +497,8 @@ public class NotificationPanelViewController extends PanelViewController { ConversationNotificationManager conversationNotificationManager, MediaHierarchyManager mediaHierarchyManager, BiometricUnlockController biometricUnlockController, StatusBarKeyguardViewManager statusBarKeyguardViewManager) { StatusBarKeyguardViewManager statusBarKeyguardViewManager, Provider<KeyguardClockSwitchController> keyguardClockSwitchControllerProvider) { super(view, falsingManager, dozeLog, keyguardStateController, (SysuiStatusBarStateController) statusBarStateController, vibratorHelper, latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager); Loading @@ -507,6 +510,7 @@ public class NotificationPanelViewController extends PanelViewController { mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder; mMediaHierarchyManager = mediaHierarchyManager; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardClockSwitchControllerProvider = keyguardClockSwitchControllerProvider; mView.setWillNotDraw(!DEBUG); mInjectionInflationController = injectionInflationController; mFalsingManager = falsingManager; Loading Loading @@ -579,9 +583,11 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header); mKeyguardStatusView = mView.findViewById(R.id.keyguard_status_view); KeyguardClockSwitch keyguardClockSwitch = mView.findViewById(R.id.keyguard_clock_container); KeyguardClockSwitchController keyguardClockSwitchController = mKeyguardClockSwitchControllerProvider.get(); keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container)); mBigClockContainer = mView.findViewById(R.id.big_clock_container); keyguardClockSwitch.setBigClockContainer(mBigClockContainer); keyguardClockSwitchController.setBigClockContainer(mBigClockContainer); mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent); mNotificationStackScroller = mView.findViewById(R.id.notification_stack_scroller); Loading Loading @@ -703,8 +709,10 @@ public class NotificationPanelViewController extends PanelViewController { // Re-associate the clock container with the keyguard clock switch. mBigClockContainer.removeAllViews(); KeyguardClockSwitch keyguardClockSwitch = mView.findViewById(R.id.keyguard_clock_container); keyguardClockSwitch.setBigClockContainer(mBigClockContainer); KeyguardClockSwitchController keyguardClockSwitchController = mKeyguardClockSwitchControllerProvider.get(); keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container)); keyguardClockSwitchController.setBigClockContainer(mBigClockContainer); // Update keyguard bottom area index = mView.indexOfChild(mKeyguardBottomArea); Loading packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +0 −6 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.view.InflateException; import android.view.LayoutInflater; import android.view.View; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardMessageArea; import com.android.keyguard.KeyguardSliceView; import com.android.systemui.dagger.SystemUIRootComponent; Loading Loading @@ -131,11 +130,6 @@ public class InjectionInflationController { */ NotificationShelf creatNotificationShelf(); /** * Creates the KeyguardClockSwitch. */ KeyguardClockSwitch createKeyguardClockSwitch(); /** * Creates the KeyguardSliceView. */ Loading packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java 0 → 100644 +162 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; @SmallTest @RunWith(AndroidTestingRunner.class) public class KeyguardClockSwitchControllerTest extends SysuiTestCase { @Mock private StatusBarStateController mStatusBarStateController; @Mock private SysuiColorExtractor mColorExtractor; @Mock private ClockManager mClockManager; @Mock private KeyguardClockSwitch mView; @Mock private ClockPlugin mClockPlugin; @Mock ColorExtractor.GradientColors mGradientColors; private KeyguardClockSwitchController mController; @Before public void setup() { MockitoAnnotations.initMocks(this); mController = new KeyguardClockSwitchController( mStatusBarStateController, mColorExtractor, mClockManager); when(mView.isAttachedToWindow()).thenReturn(true); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors); } @Test public void testAttach_viewAlreadyAttached() { mController.attach(mView); verifyAttachment(times(1)); } @Test public void testAttach_viewNotYetAttached() { ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); when(mView.isAttachedToWindow()).thenReturn(false); mController.attach(mView); verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture()); verifyAttachment(never()); listenerArgumentCaptor.getValue().onViewAttachedToWindow(mView); verifyAttachment(times(1)); } @Test public void testAttach_viewDetached() { ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); mController.attach(mView); verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture()); verifyAttachment(times(1)); listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView); verify(mStatusBarStateController).removeCallback( any(StatusBarStateController.StateListener.class)); verify(mColorExtractor).removeOnColorsChangedListener( any(ColorExtractor.OnColorsChangedListener.class)); } @Test public void testBigClockPassesStatusBarState() { ViewGroup testView = new FrameLayout(mContext); mController.attach(mView); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); mController.setBigClockContainer(testView); verify(mView).setBigClockContainer(testView, StatusBarState.SHADE); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); mController.setBigClockContainer(testView); verify(mView).setBigClockContainer(testView, StatusBarState.KEYGUARD); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED); mController.setBigClockContainer(testView); verify(mView).setBigClockContainer(testView, StatusBarState.SHADE_LOCKED); } @Test public void testPluginPassesStatusBarState() { ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor = ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class); mController.attach(mView); verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture()); listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin); verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE); } private void verifyAttachment(VerificationMode times) { verify(mClockManager, times).addOnClockChangedListener( any(ClockManager.ClockChangedListener.class)); verify(mStatusBarStateController, times).addCallback( any(StatusBarStateController.StateListener.class)); verify(mColorExtractor, times).addOnColorsChangedListener( any(ColorExtractor.OnColorsChangedListener.class)); verify(mView, times).updateColors(mGradientColors); } } Loading
packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +10 −106 Original line number Diff line number Diff line package com.android.keyguard; import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; import android.animation.Animator; import android.animation.ValueAnimator; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Paint; import android.graphics.Paint.Style; Loading @@ -24,16 +21,10 @@ import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.TextClock; import androidx.annotation.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener; import com.android.keyguard.clock.ClockManager; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.util.wakelock.KeepAwakeAnimationListener; Loading @@ -42,37 +33,18 @@ import java.io.PrintWriter; import java.util.Arrays; import java.util.TimeZone; import javax.inject.Inject; import javax.inject.Named; /** * Switch to show plugin clock when plugin is connected, otherwise it will show default clock. */ public class KeyguardClockSwitch extends RelativeLayout { private static final String TAG = "KeyguardClockSwitch"; private static final boolean CUSTOM_CLOCKS_ENABLED = true; /** * Animation fraction when text is transitioned to/from bold. */ private static final float TO_BOLD_TRANSITION_FRACTION = 0.7f; /** * Controller used to track StatusBar state to know when to show the big_clock_container. */ private final StatusBarStateController mStatusBarStateController; /** * Color extractor used to apply colors from wallpaper to custom clock faces. */ private final SysuiColorExtractor mSysuiColorExtractor; /** * Manager used to know when to show a custom clock face. */ private final ClockManager mClockManager; /** * Layout transition that scales the default clock face. */ Loading Loading @@ -130,42 +102,8 @@ public class KeyguardClockSwitch extends RelativeLayout { private boolean mSupportsDarkText; private int[] mColorPalette; /** * Track the state of the status bar to know when to hide the big_clock_container. */ private int mStatusBarState; private final StatusBarStateController.StateListener mStateListener = new StatusBarStateController.StateListener() { @Override public void onStateChanged(int newState) { mStatusBarState = newState; updateBigClockVisibility(); } }; private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin; /** * Listener for changes to the color palette. * * The color palette changes when the wallpaper is changed. */ private final OnColorsChangedListener mColorsListener = (extractor, which) -> { if ((which & WallpaperManager.FLAG_LOCK) != 0) { updateColors(); } }; @Inject public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor, ClockManager clockManager) { public KeyguardClockSwitch(Context context, AttributeSet attrs) { super(context, attrs); mStatusBarStateController = statusBarStateController; mStatusBarState = mStatusBarStateController.getState(); mSysuiColorExtractor = colorExtractor; mClockManager = clockManager; mClockTransition = new ClockVisibilityTransition().setCutoff( 1 - TO_BOLD_TRANSITION_FRACTION); Loading Loading @@ -197,29 +135,7 @@ public class KeyguardClockSwitch extends RelativeLayout { mKeyguardStatusArea = findViewById(R.id.keyguard_status_area); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (CUSTOM_CLOCKS_ENABLED) { mClockManager.addOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.addCallback(mStateListener); mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener); updateColors(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (CUSTOM_CLOCKS_ENABLED) { mClockManager.removeOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.removeCallback(mStateListener); mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener); setClockPlugin(null); } private void setClockPlugin(ClockPlugin plugin) { void setClockPlugin(ClockPlugin plugin, int statusBarState) { // Disconnect from existing plugin. if (mClockPlugin != null) { View smallClockView = mClockPlugin.getView(); Loading @@ -228,7 +144,7 @@ public class KeyguardClockSwitch extends RelativeLayout { } if (mBigClockContainer != null) { mBigClockContainer.removeAllViews(); updateBigClockVisibility(); updateBigClockVisibility(statusBarState); } mClockPlugin.onDestroyView(); mClockPlugin = null; Loading Loading @@ -256,7 +172,7 @@ public class KeyguardClockSwitch extends RelativeLayout { View bigClockView = plugin.getBigClockView(); if (bigClockView != null && mBigClockContainer != null) { mBigClockContainer.addView(bigClockView); updateBigClockVisibility(); updateBigClockVisibility(statusBarState); } // Hide default clock. if (!plugin.shouldShowStatusArea()) { Loading @@ -275,7 +191,7 @@ public class KeyguardClockSwitch extends RelativeLayout { /** * Set container for big clock face appearing behind NSSL and KeyguardStatusView. */ public void setBigClockContainer(ViewGroup container) { public void setBigClockContainer(ViewGroup container, int statusBarState) { if (mClockPlugin != null && container != null) { View bigClockView = mClockPlugin.getBigClockView(); if (bigClockView != null) { Loading @@ -283,7 +199,7 @@ public class KeyguardClockSwitch extends RelativeLayout { } } mBigClockContainer = container; updateBigClockVisibility(); updateBigClockVisibility(statusBarState); } /** Loading Loading @@ -407,9 +323,7 @@ public class KeyguardClockSwitch extends RelativeLayout { } } private void updateColors() { ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors( WallpaperManager.FLAG_LOCK); void updateColors(ColorExtractor.GradientColors colors) { mSupportsDarkText = colors.supportsDarkText(); mColorPalette = colors.getColorPalette(); if (mClockPlugin != null) { Loading @@ -417,12 +331,12 @@ public class KeyguardClockSwitch extends RelativeLayout { } } private void updateBigClockVisibility() { void updateBigClockVisibility(int statusBarState) { if (mBigClockContainer == null) { return; } final boolean inDisplayState = mStatusBarState == StatusBarState.KEYGUARD || mStatusBarState == StatusBarState.SHADE_LOCKED; final boolean inDisplayState = statusBarState == StatusBarState.KEYGUARD || statusBarState == StatusBarState.SHADE_LOCKED; final int visibility = !mShowingHeader && inDisplayState && mBigClockContainer.getChildCount() != 0 ? View.VISIBLE : View.GONE; if (mBigClockContainer.getVisibility() != visibility) { Loading Loading @@ -506,16 +420,6 @@ public class KeyguardClockSwitch extends RelativeLayout { } } @VisibleForTesting(otherwise = VisibleForTesting.NONE) ClockManager.ClockChangedListener getClockChangedListener() { return mClockChangedListener; } @VisibleForTesting(otherwise = VisibleForTesting.NONE) StatusBarStateController.StateListener getStateListener() { return mStateListener; } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("KeyguardClockSwitch:"); pw.println(" mClockPlugin: " + mClockPlugin); Loading
packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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; import android.app.WallpaperManager; import android.view.View; import android.view.ViewGroup; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import javax.inject.Inject; /** * Injectable controller for {@link KeyguardClockSwitch}. */ public class KeyguardClockSwitchController { private static final boolean CUSTOM_CLOCKS_ENABLED = true; private final StatusBarStateController mStatusBarStateController; private final SysuiColorExtractor mColorExtractor; private final ClockManager mClockManager; private KeyguardClockSwitch mView; private final StatusBarStateController.StateListener mStateListener = new StatusBarStateController.StateListener() { @Override public void onStateChanged(int newState) { mView.updateBigClockVisibility(newState); } }; /** * Listener for changes to the color palette. * * The color palette changes when the wallpaper is changed. */ private final ColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> { if ((which & WallpaperManager.FLAG_LOCK) != 0) { mView.updateColors(getGradientColors()); } }; private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin; private final View.OnAttachStateChangeListener mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { if (CUSTOM_CLOCKS_ENABLED) { mClockManager.addOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.addCallback(mStateListener); mColorExtractor.addOnColorsChangedListener(mColorsListener); mView.updateColors(getGradientColors()); } @Override public void onViewDetachedFromWindow(View v) { if (CUSTOM_CLOCKS_ENABLED) { mClockManager.removeOnClockChangedListener(mClockChangedListener); } mStatusBarStateController.removeCallback(mStateListener); mColorExtractor.removeOnColorsChangedListener(mColorsListener); mView.setClockPlugin(null, mStatusBarStateController.getState()); } }; @Inject public KeyguardClockSwitchController(StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor, ClockManager clockManager) { mStatusBarStateController = statusBarStateController; mColorExtractor = colorExtractor; mClockManager = clockManager; } /** * Attach the controller to the view it relates to. */ public void attach(KeyguardClockSwitch view) { mView = view; if (mView.isAttachedToWindow()) { mOnAttachStateChangeListener.onViewAttachedToWindow(mView); } mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener); } /** * Set container for big clock face appearing behind NSSL and KeyguardStatusView. */ public void setBigClockContainer(ViewGroup bigClockContainer) { mView.setBigClockContainer(bigClockContainer, mStatusBarStateController.getState()); } private void setClockPlugin(ClockPlugin plugin) { mView.setClockPlugin(plugin, mStatusBarStateController.getState()); } private ColorExtractor.GradientColors getGradientColors() { return mColorExtractor.getColors(WallpaperManager.FLAG_LOCK); } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +14 −6 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardClockSwitchController; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; Loading Loading @@ -124,6 +124,7 @@ import java.util.function.Consumer; import java.util.function.Function; import javax.inject.Inject; import javax.inject.Provider; @StatusBarComponent.StatusBarScope public class NotificationPanelViewController extends PanelViewController { Loading Loading @@ -252,6 +253,7 @@ public class NotificationPanelViewController extends PanelViewController { private final ConversationNotificationManager mConversationNotificationManager; private final MediaHierarchyManager mMediaHierarchyManager; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final Provider<KeyguardClockSwitchController> mKeyguardClockSwitchControllerProvider; private KeyguardAffordanceHelper mAffordanceHelper; private KeyguardUserSwitcher mKeyguardUserSwitcher; Loading Loading @@ -495,7 +497,8 @@ public class NotificationPanelViewController extends PanelViewController { ConversationNotificationManager conversationNotificationManager, MediaHierarchyManager mediaHierarchyManager, BiometricUnlockController biometricUnlockController, StatusBarKeyguardViewManager statusBarKeyguardViewManager) { StatusBarKeyguardViewManager statusBarKeyguardViewManager, Provider<KeyguardClockSwitchController> keyguardClockSwitchControllerProvider) { super(view, falsingManager, dozeLog, keyguardStateController, (SysuiStatusBarStateController) statusBarStateController, vibratorHelper, latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager); Loading @@ -507,6 +510,7 @@ public class NotificationPanelViewController extends PanelViewController { mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder; mMediaHierarchyManager = mediaHierarchyManager; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardClockSwitchControllerProvider = keyguardClockSwitchControllerProvider; mView.setWillNotDraw(!DEBUG); mInjectionInflationController = injectionInflationController; mFalsingManager = falsingManager; Loading Loading @@ -579,9 +583,11 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header); mKeyguardStatusView = mView.findViewById(R.id.keyguard_status_view); KeyguardClockSwitch keyguardClockSwitch = mView.findViewById(R.id.keyguard_clock_container); KeyguardClockSwitchController keyguardClockSwitchController = mKeyguardClockSwitchControllerProvider.get(); keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container)); mBigClockContainer = mView.findViewById(R.id.big_clock_container); keyguardClockSwitch.setBigClockContainer(mBigClockContainer); keyguardClockSwitchController.setBigClockContainer(mBigClockContainer); mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent); mNotificationStackScroller = mView.findViewById(R.id.notification_stack_scroller); Loading Loading @@ -703,8 +709,10 @@ public class NotificationPanelViewController extends PanelViewController { // Re-associate the clock container with the keyguard clock switch. mBigClockContainer.removeAllViews(); KeyguardClockSwitch keyguardClockSwitch = mView.findViewById(R.id.keyguard_clock_container); keyguardClockSwitch.setBigClockContainer(mBigClockContainer); KeyguardClockSwitchController keyguardClockSwitchController = mKeyguardClockSwitchControllerProvider.get(); keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container)); keyguardClockSwitchController.setBigClockContainer(mBigClockContainer); // Update keyguard bottom area index = mView.indexOfChild(mKeyguardBottomArea); Loading
packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +0 −6 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.view.InflateException; import android.view.LayoutInflater; import android.view.View; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardMessageArea; import com.android.keyguard.KeyguardSliceView; import com.android.systemui.dagger.SystemUIRootComponent; Loading Loading @@ -131,11 +130,6 @@ public class InjectionInflationController { */ NotificationShelf creatNotificationShelf(); /** * Creates the KeyguardClockSwitch. */ KeyguardClockSwitch createKeyguardClockSwitch(); /** * Creates the KeyguardSliceView. */ Loading
packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java 0 → 100644 +162 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; @SmallTest @RunWith(AndroidTestingRunner.class) public class KeyguardClockSwitchControllerTest extends SysuiTestCase { @Mock private StatusBarStateController mStatusBarStateController; @Mock private SysuiColorExtractor mColorExtractor; @Mock private ClockManager mClockManager; @Mock private KeyguardClockSwitch mView; @Mock private ClockPlugin mClockPlugin; @Mock ColorExtractor.GradientColors mGradientColors; private KeyguardClockSwitchController mController; @Before public void setup() { MockitoAnnotations.initMocks(this); mController = new KeyguardClockSwitchController( mStatusBarStateController, mColorExtractor, mClockManager); when(mView.isAttachedToWindow()).thenReturn(true); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors); } @Test public void testAttach_viewAlreadyAttached() { mController.attach(mView); verifyAttachment(times(1)); } @Test public void testAttach_viewNotYetAttached() { ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); when(mView.isAttachedToWindow()).thenReturn(false); mController.attach(mView); verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture()); verifyAttachment(never()); listenerArgumentCaptor.getValue().onViewAttachedToWindow(mView); verifyAttachment(times(1)); } @Test public void testAttach_viewDetached() { ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); mController.attach(mView); verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture()); verifyAttachment(times(1)); listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView); verify(mStatusBarStateController).removeCallback( any(StatusBarStateController.StateListener.class)); verify(mColorExtractor).removeOnColorsChangedListener( any(ColorExtractor.OnColorsChangedListener.class)); } @Test public void testBigClockPassesStatusBarState() { ViewGroup testView = new FrameLayout(mContext); mController.attach(mView); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); mController.setBigClockContainer(testView); verify(mView).setBigClockContainer(testView, StatusBarState.SHADE); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); mController.setBigClockContainer(testView); verify(mView).setBigClockContainer(testView, StatusBarState.KEYGUARD); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED); mController.setBigClockContainer(testView); verify(mView).setBigClockContainer(testView, StatusBarState.SHADE_LOCKED); } @Test public void testPluginPassesStatusBarState() { ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor = ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class); mController.attach(mView); verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture()); listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin); verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE); } private void verifyAttachment(VerificationMode times) { verify(mClockManager, times).addOnClockChangedListener( any(ClockManager.ClockChangedListener.class)); verify(mStatusBarStateController, times).addCallback( any(StatusBarStateController.StateListener.class)); verify(mColorExtractor, times).addOnColorsChangedListener( any(ColorExtractor.OnColorsChangedListener.class)); verify(mView, times).updateColors(mGradientColors); } }