Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +10 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { private val listeners: MutableList<ConfigurationController.ConfigurationListener> = ArrayList() private val lastConfig = Configuration() private var density: Int = 0 private var smallestScreenWidth: Int = 0 private var fontScale: Float = 0.toFloat() private val inCarMode: Boolean private var uiMode: Int = 0 Loading @@ -38,6 +39,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { this.context = context fontScale = currentConfig.fontScale density = currentConfig.densityDpi smallestScreenWidth = currentConfig.smallestScreenWidthDp inCarMode = currentConfig.uiMode and Configuration.UI_MODE_TYPE_MASK == Configuration.UI_MODE_TYPE_CAR uiMode = currentConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK Loading Loading @@ -72,6 +74,14 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { this.fontScale = fontScale } val smallestScreenWidth = newConfig.smallestScreenWidthDp if (smallestScreenWidth != this.smallestScreenWidth) { this.smallestScreenWidth = smallestScreenWidth listeners.filterForEach({ this.listeners.contains(it) }) { it.onSmallestScreenWidthChanged() } } val localeList = newConfig.locales if (localeList != this.localeList) { this.localeList = localeList Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +64 −5 Original line number Diff line number Diff line Loading @@ -36,9 +36,11 @@ import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.Fragment; import android.app.StatusBarManager; import android.content.ContentResolver; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; Loading @@ -50,10 +52,12 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.os.Bundle; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserManager; import android.os.VibrationEffect; import android.provider.Settings; import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; Loading Loading @@ -210,6 +214,8 @@ public class NotificationPanelViewController extends PanelViewController { new MyOnHeadsUpChangedListener(); private final HeightListener mHeightListener = new HeightListener(); private final ConfigurationListener mConfigurationListener = new ConfigurationListener(); private final SettingsChangeObserver mSettingsChangeObserver; @VisibleForTesting final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener(); private final BiometricUnlockController mBiometricUnlockController; Loading Loading @@ -594,6 +600,8 @@ public class NotificationPanelViewController extends PanelViewController { private int mScreenCornerRadius; private boolean mQSAnimatingHiddenFromCollapsed; private final ContentResolver mContentResolver; private final Executor mUiExecutor; private final SecureSettings mSecureSettings; Loading Loading @@ -635,6 +643,7 @@ public class NotificationPanelViewController extends PanelViewController { @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, @Main Handler handler, LayoutInflater layoutInflater, NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler, DynamicPrivacyController dynamicPrivacyController, Loading Loading @@ -678,6 +687,7 @@ public class NotificationPanelViewController extends PanelViewController { TapAgainViewController tapAgainViewController, NavigationModeController navigationModeController, FragmentService fragmentService, ContentResolver contentResolver, QuickAccessWalletController quickAccessWalletController, @Main Executor uiExecutor, SecureSettings secureSettings, Loading @@ -704,15 +714,12 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory; mDepthController = notificationShadeDepthController; mFeatureFlags = featureFlags; mContentResolver = contentResolver; mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory; mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory; mQSDetailDisplayer = qsDetailDisplayer; mFragmentService = fragmentService; mKeyguardUserSwitcherEnabled = mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher); mKeyguardQsUserSwitchEnabled = mKeyguardUserSwitcherEnabled && mResources.getBoolean( R.bool.config_keyguard_user_switch_opens_qs_details); mSettingsChangeObserver = new SettingsChangeObserver(handler); mShouldUseSplitNotificationShade = Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources); mView.setWillNotDraw(!DEBUG); Loading Loading @@ -795,6 +802,7 @@ public class NotificationPanelViewController extends PanelViewController { } mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count); updateUserSwitcherFlags(); onFinishInflate(); } Loading Loading @@ -1034,6 +1042,10 @@ public class NotificationPanelViewController extends PanelViewController { view = mLayoutInflater.inflate(layoutId, mView, false); mView.addView(view, index); } else { // Add the stub back so we can re-inflate it again if necessary ViewStub stub = new ViewStub(mView.getContext(), layoutId); stub.setId(stubId); mView.addView(stub, index); view = null; } } else if (enabled) { Loading Loading @@ -1061,6 +1073,7 @@ public class NotificationPanelViewController extends PanelViewController { updateResources(); // Re-inflate the keyguard user switcher group. updateUserSwitcherFlags(); boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled(); boolean showQsUserSwitch = mKeyguardQsUserSwitchEnabled && isUserSwitcherEnabled; boolean showKeyguardUserSwitcher = Loading Loading @@ -3873,6 +3886,26 @@ public class NotificationPanelViewController extends PanelViewController { return false; } private void updateUserSwitcherFlags() { mKeyguardUserSwitcherEnabled = mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher); mKeyguardQsUserSwitchEnabled = mKeyguardUserSwitcherEnabled && mResources.getBoolean( R.bool.config_keyguard_user_switch_opens_qs_details); } private void registerSettingsChangeListener() { mContentResolver.registerContentObserver( Settings.Global.getUriFor(Settings.Global.USER_SWITCHER_ENABLED), /* notifyForDescendants */ false, mSettingsChangeObserver ); } private void unregisterSettingsChangeListener() { mContentResolver.unregisterContentObserver(mSettingsChangeObserver); } private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener { @Override public void onHeightChanged(ExpandableView view, boolean needsAnimation) { Loading Loading @@ -4193,6 +4226,15 @@ public class NotificationPanelViewController extends PanelViewController { reInflateViews(); } @Override public void onSmallestScreenWidthChanged() { if (DEBUG) Log.d(TAG, "onSmallestScreenWidthChanged"); // Can affect multi-user switcher visibility as it depends on screen size by default: // it is enabled only for devices with large screens (see config_keyguardUserSwitcher) reInflateViews(); } @Override public void onOverlayChanged() { if (DEBUG) Log.d(TAG, "onOverlayChanged"); Loading @@ -4206,6 +4248,21 @@ public class NotificationPanelViewController extends PanelViewController { } } private class SettingsChangeObserver extends ContentObserver { SettingsChangeObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { if (DEBUG) Log.d(TAG, "onSettingsChanged"); // Can affect multi-user switcher visibility reInflateViews(); } } private class StatusBarStateListener implements StateListener { @Override public void onStateChanged(int statusBarState) { Loading Loading @@ -4321,10 +4378,12 @@ public class NotificationPanelViewController extends PanelViewController { mConfigurationListener.onThemeChanged(); mFalsingManager.addTapListener(mFalsingTapListener); mKeyguardIndicationController.init(); registerSettingsChangeListener(); } @Override public void onViewDetachedFromWindow(View v) { unregisterSettingsChangeListener(); mFragmentService.getFragmentHostManager(mView) .removeTagListener(QS.TAG, mFragmentListener); mStatusBarStateController.removeCallback(mStatusBarStateListener); Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ public interface ConfigurationController extends CallbackController<Configuratio interface ConfigurationListener { default void onConfigChanged(Configuration newConfig) {} default void onDensityOrFontScaleChanged() {} default void onSmallestScreenWidthChanged() {} default void onOverlayChanged() {} default void onUiModeChanged() {} default void onThemeChanged() {} Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +84 −2 Original line number Diff line number Diff line Loading @@ -26,9 +26,12 @@ import static com.android.systemui.statusbar.notification.ViewGroupFadeHelper.re import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -37,9 +40,13 @@ import static org.mockito.Mockito.when; import android.annotation.IdRes; import android.app.ActivityManager; import android.content.ContentResolver; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; import android.os.Looper; import android.os.PowerManager; import android.os.UserManager; import android.testing.AndroidTestingRunner; Loading @@ -50,6 +57,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; Loading @@ -60,6 +68,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.internal.util.CollectionUtils; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardClockSwitchController; Loading Loading @@ -140,6 +149,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { private KeyguardBottomAreaView mKeyguardBottomArea; @Mock private KeyguardBottomAreaView mQsFrame; private KeyguardStatusView mKeyguardStatusView; @Mock private ViewGroup mBigClockContainer; @Mock Loading @@ -153,6 +163,10 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardStatusBarView mKeyguardStatusBar; @Mock private View mUserSwitcherView; @Mock private ViewStub mUserSwitcherStubView; @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback; @Mock private PanelBar mPanelBar; Loading Loading @@ -204,7 +218,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardClockSwitch mKeyguardClockSwitch; private PanelViewController.TouchHandler mTouchHandler; @Mock private ConfigurationController mConfigurationController; @Mock private MediaHierarchyManager mMediaHiearchyManager; Loading Loading @@ -265,6 +278,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock private ContentResolver mContentResolver; @Mock private TapAgainViewController mTapAgainViewController; @Mock private KeyguardIndicationController mKeyguardIndicationController; Loading @@ -287,6 +302,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger); mKeyguardStatusView = new KeyguardStatusView(mContext); mKeyguardStatusView.setId(R.id.keyguard_status_view); when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false); when(mHeadsUpCallback.getContext()).thenReturn(mContext); when(mView.getResources()).thenReturn(mResources); Loading @@ -301,6 +319,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { when(mResources.getDimensionPixelSize(R.dimen.notification_panel_width)).thenReturn(400); when(mView.getContext()).thenReturn(getContext()); when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar); when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView); when(mView.findViewById(R.id.keyguard_user_switcher_stub)).thenReturn( mUserSwitcherStubView); when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch); when(mView.findViewById(R.id.notification_stack_scroller)) .thenReturn(mNotificationStackScrollLayout); Loading @@ -320,7 +341,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null); mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame)); mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller)); mNotificationContainerParent.addView(newViewWithId(R.id.keyguard_status_view)); mNotificationContainerParent.addView(mKeyguardStatusView); when(mView.findViewById(R.id.notification_container_parent)) .thenReturn(mNotificationContainerParent); when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager); Loading Loading @@ -348,6 +369,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mFalsingManager, mLockscreenShadeTransitionController, new FalsingCollectorFake()); mConfigurationController = new ConfigurationControllerImpl(mContext); when(mKeyguardStatusViewComponentFactory.build(any())) .thenReturn(mKeyguardStatusViewComponent); when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController()) Loading @@ -358,10 +380,16 @@ public class NotificationPanelViewTest extends SysuiTestCase { .thenReturn(mKeyguardStatusBarViewComponent); when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController()) .thenReturn(mKeyguardStatusBarViewController); when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean())) .thenReturn(mKeyguardStatusView); when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean())) .thenReturn(mKeyguardBottomArea); reset(mView); mNotificationPanelViewController = new NotificationPanelViewController(mView, mResources, new Handler(Looper.getMainLooper()), mLayoutInflater, coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, mFalsingManager, new FalsingCollectorFake(), Loading Loading @@ -395,6 +423,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mTapAgainViewController, mNavigationModeController, mFragmentService, mContentResolver, mQuickAccessWalletController, new FakeExecutor(new FakeSystemClock()), mSecureSettings, Loading Loading @@ -548,6 +577,38 @@ public class NotificationPanelViewTest extends SysuiTestCase { .isEqualTo(R.id.qs_edge_guideline); } @Test public void testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() { givenViewAttached(); when(mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); updateMultiUserSetting(true); clearInvocations(mView); updateMultiUserSetting(false); ArgumentCaptor<View> captor = ArgumentCaptor.forClass(View.class); verify(mView, atLeastOnce()).addView(captor.capture(), anyInt()); final View userSwitcherStub = CollectionUtils.find(captor.getAllValues(), view -> view.getId() == R.id.keyguard_user_switcher_stub); assertThat(userSwitcherStub).isNotNull(); assertThat(userSwitcherStub).isInstanceOf(ViewStub.class); } @Test public void testChangeSmallestScreenWidthAndUserSwitchEnabled_inflatesUserSwitchView() { givenViewAttached(); when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(null); updateSmallestScreenWidth(300); when(mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); when(mUserManager.isUserSwitcherEnabled()).thenReturn(true); updateSmallestScreenWidth(800); verify(mUserSwitcherStubView).inflate(); } @Test public void testSplitShadeLayout_isAlignedToGuideline() { enableSplitShade(); Loading Loading @@ -682,6 +743,12 @@ public class NotificationPanelViewTest extends SysuiTestCase { return mFalsingManager.getTapListeners().get(0); } private void givenViewAttached() { for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) { listener.onViewAttachedToWindow(mView); } } private View newViewWithId(int id) { View view = new View(mContext); view.setId(id); Loading @@ -704,6 +771,21 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationPanelViewController.updateResources(); } private void updateMultiUserSetting(boolean enabled) { when(mUserManager.isUserSwitcherEnabled()).thenReturn(enabled); final ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); verify(mContentResolver) .registerContentObserver(any(), anyBoolean(), observerCaptor.capture()); observerCaptor.getValue().onChange(/* selfChange */ false); } private void updateSmallestScreenWidth(int smallestScreenWidthDp) { Configuration configuration = new Configuration(); configuration.smallestScreenWidthDp = smallestScreenWidthDp; mConfigurationController.onConfigurationChanged(configuration); } private void onTouchEvent(MotionEvent ev) { mTouchHandler.onTouch(mView, ev); } Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +10 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { private val listeners: MutableList<ConfigurationController.ConfigurationListener> = ArrayList() private val lastConfig = Configuration() private var density: Int = 0 private var smallestScreenWidth: Int = 0 private var fontScale: Float = 0.toFloat() private val inCarMode: Boolean private var uiMode: Int = 0 Loading @@ -38,6 +39,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { this.context = context fontScale = currentConfig.fontScale density = currentConfig.densityDpi smallestScreenWidth = currentConfig.smallestScreenWidthDp inCarMode = currentConfig.uiMode and Configuration.UI_MODE_TYPE_MASK == Configuration.UI_MODE_TYPE_CAR uiMode = currentConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK Loading Loading @@ -72,6 +74,14 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { this.fontScale = fontScale } val smallestScreenWidth = newConfig.smallestScreenWidthDp if (smallestScreenWidth != this.smallestScreenWidth) { this.smallestScreenWidth = smallestScreenWidth listeners.filterForEach({ this.listeners.contains(it) }) { it.onSmallestScreenWidthChanged() } } val localeList = newConfig.locales if (localeList != this.localeList) { this.localeList = localeList Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +64 −5 Original line number Diff line number Diff line Loading @@ -36,9 +36,11 @@ import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.Fragment; import android.app.StatusBarManager; import android.content.ContentResolver; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; Loading @@ -50,10 +52,12 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.os.Bundle; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserManager; import android.os.VibrationEffect; import android.provider.Settings; import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; Loading Loading @@ -210,6 +214,8 @@ public class NotificationPanelViewController extends PanelViewController { new MyOnHeadsUpChangedListener(); private final HeightListener mHeightListener = new HeightListener(); private final ConfigurationListener mConfigurationListener = new ConfigurationListener(); private final SettingsChangeObserver mSettingsChangeObserver; @VisibleForTesting final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener(); private final BiometricUnlockController mBiometricUnlockController; Loading Loading @@ -594,6 +600,8 @@ public class NotificationPanelViewController extends PanelViewController { private int mScreenCornerRadius; private boolean mQSAnimatingHiddenFromCollapsed; private final ContentResolver mContentResolver; private final Executor mUiExecutor; private final SecureSettings mSecureSettings; Loading Loading @@ -635,6 +643,7 @@ public class NotificationPanelViewController extends PanelViewController { @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, @Main Handler handler, LayoutInflater layoutInflater, NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler, DynamicPrivacyController dynamicPrivacyController, Loading Loading @@ -678,6 +687,7 @@ public class NotificationPanelViewController extends PanelViewController { TapAgainViewController tapAgainViewController, NavigationModeController navigationModeController, FragmentService fragmentService, ContentResolver contentResolver, QuickAccessWalletController quickAccessWalletController, @Main Executor uiExecutor, SecureSettings secureSettings, Loading @@ -704,15 +714,12 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory; mDepthController = notificationShadeDepthController; mFeatureFlags = featureFlags; mContentResolver = contentResolver; mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory; mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory; mQSDetailDisplayer = qsDetailDisplayer; mFragmentService = fragmentService; mKeyguardUserSwitcherEnabled = mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher); mKeyguardQsUserSwitchEnabled = mKeyguardUserSwitcherEnabled && mResources.getBoolean( R.bool.config_keyguard_user_switch_opens_qs_details); mSettingsChangeObserver = new SettingsChangeObserver(handler); mShouldUseSplitNotificationShade = Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources); mView.setWillNotDraw(!DEBUG); Loading Loading @@ -795,6 +802,7 @@ public class NotificationPanelViewController extends PanelViewController { } mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count); updateUserSwitcherFlags(); onFinishInflate(); } Loading Loading @@ -1034,6 +1042,10 @@ public class NotificationPanelViewController extends PanelViewController { view = mLayoutInflater.inflate(layoutId, mView, false); mView.addView(view, index); } else { // Add the stub back so we can re-inflate it again if necessary ViewStub stub = new ViewStub(mView.getContext(), layoutId); stub.setId(stubId); mView.addView(stub, index); view = null; } } else if (enabled) { Loading Loading @@ -1061,6 +1073,7 @@ public class NotificationPanelViewController extends PanelViewController { updateResources(); // Re-inflate the keyguard user switcher group. updateUserSwitcherFlags(); boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled(); boolean showQsUserSwitch = mKeyguardQsUserSwitchEnabled && isUserSwitcherEnabled; boolean showKeyguardUserSwitcher = Loading Loading @@ -3873,6 +3886,26 @@ public class NotificationPanelViewController extends PanelViewController { return false; } private void updateUserSwitcherFlags() { mKeyguardUserSwitcherEnabled = mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher); mKeyguardQsUserSwitchEnabled = mKeyguardUserSwitcherEnabled && mResources.getBoolean( R.bool.config_keyguard_user_switch_opens_qs_details); } private void registerSettingsChangeListener() { mContentResolver.registerContentObserver( Settings.Global.getUriFor(Settings.Global.USER_SWITCHER_ENABLED), /* notifyForDescendants */ false, mSettingsChangeObserver ); } private void unregisterSettingsChangeListener() { mContentResolver.unregisterContentObserver(mSettingsChangeObserver); } private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener { @Override public void onHeightChanged(ExpandableView view, boolean needsAnimation) { Loading Loading @@ -4193,6 +4226,15 @@ public class NotificationPanelViewController extends PanelViewController { reInflateViews(); } @Override public void onSmallestScreenWidthChanged() { if (DEBUG) Log.d(TAG, "onSmallestScreenWidthChanged"); // Can affect multi-user switcher visibility as it depends on screen size by default: // it is enabled only for devices with large screens (see config_keyguardUserSwitcher) reInflateViews(); } @Override public void onOverlayChanged() { if (DEBUG) Log.d(TAG, "onOverlayChanged"); Loading @@ -4206,6 +4248,21 @@ public class NotificationPanelViewController extends PanelViewController { } } private class SettingsChangeObserver extends ContentObserver { SettingsChangeObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { if (DEBUG) Log.d(TAG, "onSettingsChanged"); // Can affect multi-user switcher visibility reInflateViews(); } } private class StatusBarStateListener implements StateListener { @Override public void onStateChanged(int statusBarState) { Loading Loading @@ -4321,10 +4378,12 @@ public class NotificationPanelViewController extends PanelViewController { mConfigurationListener.onThemeChanged(); mFalsingManager.addTapListener(mFalsingTapListener); mKeyguardIndicationController.init(); registerSettingsChangeListener(); } @Override public void onViewDetachedFromWindow(View v) { unregisterSettingsChangeListener(); mFragmentService.getFragmentHostManager(mView) .removeTagListener(QS.TAG, mFragmentListener); mStatusBarStateController.removeCallback(mStatusBarStateListener); Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ public interface ConfigurationController extends CallbackController<Configuratio interface ConfigurationListener { default void onConfigChanged(Configuration newConfig) {} default void onDensityOrFontScaleChanged() {} default void onSmallestScreenWidthChanged() {} default void onOverlayChanged() {} default void onUiModeChanged() {} default void onThemeChanged() {} Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +84 −2 Original line number Diff line number Diff line Loading @@ -26,9 +26,12 @@ import static com.android.systemui.statusbar.notification.ViewGroupFadeHelper.re import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -37,9 +40,13 @@ import static org.mockito.Mockito.when; import android.annotation.IdRes; import android.app.ActivityManager; import android.content.ContentResolver; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; import android.os.Looper; import android.os.PowerManager; import android.os.UserManager; import android.testing.AndroidTestingRunner; Loading @@ -50,6 +57,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; Loading @@ -60,6 +68,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.internal.util.CollectionUtils; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardClockSwitchController; Loading Loading @@ -140,6 +149,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { private KeyguardBottomAreaView mKeyguardBottomArea; @Mock private KeyguardBottomAreaView mQsFrame; private KeyguardStatusView mKeyguardStatusView; @Mock private ViewGroup mBigClockContainer; @Mock Loading @@ -153,6 +163,10 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardStatusBarView mKeyguardStatusBar; @Mock private View mUserSwitcherView; @Mock private ViewStub mUserSwitcherStubView; @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback; @Mock private PanelBar mPanelBar; Loading Loading @@ -204,7 +218,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardClockSwitch mKeyguardClockSwitch; private PanelViewController.TouchHandler mTouchHandler; @Mock private ConfigurationController mConfigurationController; @Mock private MediaHierarchyManager mMediaHiearchyManager; Loading Loading @@ -265,6 +278,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock private ContentResolver mContentResolver; @Mock private TapAgainViewController mTapAgainViewController; @Mock private KeyguardIndicationController mKeyguardIndicationController; Loading @@ -287,6 +302,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger); mKeyguardStatusView = new KeyguardStatusView(mContext); mKeyguardStatusView.setId(R.id.keyguard_status_view); when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false); when(mHeadsUpCallback.getContext()).thenReturn(mContext); when(mView.getResources()).thenReturn(mResources); Loading @@ -301,6 +319,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { when(mResources.getDimensionPixelSize(R.dimen.notification_panel_width)).thenReturn(400); when(mView.getContext()).thenReturn(getContext()); when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar); when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView); when(mView.findViewById(R.id.keyguard_user_switcher_stub)).thenReturn( mUserSwitcherStubView); when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch); when(mView.findViewById(R.id.notification_stack_scroller)) .thenReturn(mNotificationStackScrollLayout); Loading @@ -320,7 +341,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null); mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame)); mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller)); mNotificationContainerParent.addView(newViewWithId(R.id.keyguard_status_view)); mNotificationContainerParent.addView(mKeyguardStatusView); when(mView.findViewById(R.id.notification_container_parent)) .thenReturn(mNotificationContainerParent); when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager); Loading Loading @@ -348,6 +369,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mFalsingManager, mLockscreenShadeTransitionController, new FalsingCollectorFake()); mConfigurationController = new ConfigurationControllerImpl(mContext); when(mKeyguardStatusViewComponentFactory.build(any())) .thenReturn(mKeyguardStatusViewComponent); when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController()) Loading @@ -358,10 +380,16 @@ public class NotificationPanelViewTest extends SysuiTestCase { .thenReturn(mKeyguardStatusBarViewComponent); when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController()) .thenReturn(mKeyguardStatusBarViewController); when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean())) .thenReturn(mKeyguardStatusView); when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean())) .thenReturn(mKeyguardBottomArea); reset(mView); mNotificationPanelViewController = new NotificationPanelViewController(mView, mResources, new Handler(Looper.getMainLooper()), mLayoutInflater, coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, mFalsingManager, new FalsingCollectorFake(), Loading Loading @@ -395,6 +423,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mTapAgainViewController, mNavigationModeController, mFragmentService, mContentResolver, mQuickAccessWalletController, new FakeExecutor(new FakeSystemClock()), mSecureSettings, Loading Loading @@ -548,6 +577,38 @@ public class NotificationPanelViewTest extends SysuiTestCase { .isEqualTo(R.id.qs_edge_guideline); } @Test public void testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() { givenViewAttached(); when(mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); updateMultiUserSetting(true); clearInvocations(mView); updateMultiUserSetting(false); ArgumentCaptor<View> captor = ArgumentCaptor.forClass(View.class); verify(mView, atLeastOnce()).addView(captor.capture(), anyInt()); final View userSwitcherStub = CollectionUtils.find(captor.getAllValues(), view -> view.getId() == R.id.keyguard_user_switcher_stub); assertThat(userSwitcherStub).isNotNull(); assertThat(userSwitcherStub).isInstanceOf(ViewStub.class); } @Test public void testChangeSmallestScreenWidthAndUserSwitchEnabled_inflatesUserSwitchView() { givenViewAttached(); when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(null); updateSmallestScreenWidth(300); when(mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); when(mUserManager.isUserSwitcherEnabled()).thenReturn(true); updateSmallestScreenWidth(800); verify(mUserSwitcherStubView).inflate(); } @Test public void testSplitShadeLayout_isAlignedToGuideline() { enableSplitShade(); Loading Loading @@ -682,6 +743,12 @@ public class NotificationPanelViewTest extends SysuiTestCase { return mFalsingManager.getTapListeners().get(0); } private void givenViewAttached() { for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) { listener.onViewAttachedToWindow(mView); } } private View newViewWithId(int id) { View view = new View(mContext); view.setId(id); Loading @@ -704,6 +771,21 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationPanelViewController.updateResources(); } private void updateMultiUserSetting(boolean enabled) { when(mUserManager.isUserSwitcherEnabled()).thenReturn(enabled); final ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); verify(mContentResolver) .registerContentObserver(any(), anyBoolean(), observerCaptor.capture()); observerCaptor.getValue().onChange(/* selfChange */ false); } private void updateSmallestScreenWidth(int smallestScreenWidthDp) { Configuration configuration = new Configuration(); configuration.smallestScreenWidthDp = smallestScreenWidthDp; mConfigurationController.onConfigurationChanged(configuration); } private void onTouchEvent(MotionEvent ev) { mTouchHandler.onTouch(mView, ev); } Loading