Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0aba10e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Update lock screen user switcher on settings update and re-create view...

Merge "Update lock screen user switcher on settings update and re-create view stub after disabling multi-user" into sc-dev am: cdd6adb5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14974991

Change-Id: I1ee4de39034705b71afe8092eb8fa5a60ac454e2
parents a5a38b2e cdd6adb5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
+64 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;

@@ -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,
@@ -678,6 +687,7 @@ public class NotificationPanelViewController extends PanelViewController {
            TapAgainViewController tapAgainViewController,
            NavigationModeController navigationModeController,
            FragmentService fragmentService,
            ContentResolver contentResolver,
            QuickAccessWalletController quickAccessWalletController,
            @Main Executor uiExecutor,
            SecureSettings secureSettings,
@@ -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);
@@ -795,6 +802,7 @@ public class NotificationPanelViewController extends PanelViewController {
        }

        mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count);
        updateUserSwitcherFlags();
        onFinishInflate();
    }

@@ -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) {
@@ -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 =
@@ -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) {
@@ -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");
@@ -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) {
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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() {}
+84 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;

@@ -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;
@@ -140,6 +149,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
    private KeyguardBottomAreaView mKeyguardBottomArea;
    @Mock
    private KeyguardBottomAreaView mQsFrame;
    private KeyguardStatusView mKeyguardStatusView;
    @Mock
    private ViewGroup mBigClockContainer;
    @Mock
@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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);
@@ -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);
@@ -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())
@@ -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(),
@@ -395,6 +423,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
                mTapAgainViewController,
                mNavigationModeController,
                mFragmentService,
                mContentResolver,
                mQuickAccessWalletController,
                new FakeExecutor(new FakeSystemClock()),
                mSecureSettings,
@@ -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();
@@ -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);
@@ -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);
    }