Merge "Add keyguard shortcut for opening QS user panel" into sc-dev

This commit is contained in:
Rajeev Kumar
2021-02-16 16:10:27 +00:00
committed by Android (Google) Code Review
18 changed files with 673 additions and 76 deletions

View File

@@ -46,6 +46,21 @@ public interface DetailAdapter {
return true;
}
/**
* @return if detail panel should animate when shown or closed
*/
default boolean shouldAnimate() {
return true;
}
/**
* @return true if the callback handled the event and wants to keep the detail panel open, false
* otherwise. Returning false will close the panel.
*/
default boolean onDoneButtonClicked() {
return false;
}
default UiEventLogger.UiEventEnum openDetailEvent() {
return INVALID;
}

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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
-->
<!-- This is a view that shows a user switcher in Keyguard. -->
<com.android.systemui.statusbar.phone.UserAvatarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/keyguard_qs_user_switch_view"
android:layout_width="@dimen/kg_framed_avatar_size"
android:layout_height="@dimen/kg_framed_avatar_size"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal|bottom"
systemui:avatarPadding="0dp"
systemui:badgeDiameter="18dp"
systemui:badgeMargin="1dp"
systemui:frameColor="@color/kg_user_avatar_frame"
systemui:framePadding="0dp"
systemui:frameWidth="0dp">
</com.android.systemui.statusbar.phone.UserAvatarView>

View File

@@ -31,6 +31,12 @@
android:layout_height="match_parent"
android:visibility="gone" />
<ViewStub
android:id="@+id/keyguard_qs_user_switch_stub"
android:layout="@layout/keyguard_qs_user_switch"
android:layout_height="match_parent"
android:layout_width="match_parent" />
<ViewStub
android:id="@+id/keyguard_user_switcher_stub"
android:layout="@layout/keyguard_user_switcher"

View File

@@ -279,6 +279,11 @@
<!-- Whether to show the full screen user switcher. -->
<bool name="config_enableFullscreenUserSwitcher">false</bool>
<!-- Whether the multi-user switch on the keyguard opens QS user panel. If false, clicking the
user switch on the keyguard will replace the notifications and status area with the user
switcher. The multi-user switch is only shown if config_keyguardUserSwitcher=false. -->
<bool name="config_keyguard_user_switch_opens_qs_details">false</bool>
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>

View File

@@ -802,7 +802,7 @@
<!-- Size of user icon + frame in the qs user picker (incl. frame) -->
<dimen name="qs_framed_avatar_size">54dp</dimen>
<!-- Size of user icon + frame in the keyguard user picker (incl. frame) -->
<dimen name="kg_framed_avatar_size">32dp</dimen>
<dimen name="kg_framed_avatar_size">48dp</dimen>
<!-- Margin on the left side of the carrier text on Keyguard -->
<dimen name="keyguard_carrier_text_margin">16dp</dimen>

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 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.dagger;
import com.android.systemui.statusbar.phone.UserAvatarView;
import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
import dagger.BindsInstance;
import dagger.Subcomponent;
/**
* Subcomponent for helping work with KeyguardQsUserSwitch and its children.
*/
@Subcomponent(modules = {KeyguardUserSwitcherModule.class})
@KeyguardUserSwitcherScope
public interface KeyguardQsUserSwitchComponent {
/** Simple factory for {@link KeyguardUserSwitcherComponent}. */
@Subcomponent.Factory
interface Factory {
KeyguardQsUserSwitchComponent build(
@BindsInstance UserAvatarView userAvatarView);
}
/** Builds a {@link KeyguardQsUserSwitchController}. */
KeyguardQsUserSwitchController getKeyguardQsUserSwitchController();
}

View File

@@ -29,6 +29,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -62,7 +63,8 @@ import dagger.Provides;
/**
* Dagger Module providing {@link StatusBar}.
*/
@Module(subcomponents = {KeyguardStatusViewComponent.class, KeyguardUserSwitcherComponent.class},
@Module(subcomponents = {KeyguardStatusViewComponent.class,
KeyguardQsUserSwitchComponent.class, KeyguardUserSwitcherComponent.class},
includes = {FalsingModule.class})
public class KeyguardModule {
/**

View File

@@ -72,6 +72,7 @@ public class QSDetail extends LinearLayout {
private boolean mFullyExpanded;
private QuickStatusBarHeader mHeader;
private boolean mTriggeredExpand;
private boolean mShouldAnimate;
private int mOpenX;
private int mOpenY;
private boolean mAnimatingOpen;
@@ -108,16 +109,6 @@ public class QSDetail extends LinearLayout {
updateDetailText();
mClipper = new QSDetailClipper(this);
final OnClickListener doneListener = new OnClickListener() {
@Override
public void onClick(View v) {
announceForAccessibility(
mContext.getString(R.string.accessibility_desc_quick_settings));
mQsPanelController.closeDetail();
}
};
mDetailDoneButton.setOnClickListener(doneListener);
}
/** */
@@ -169,6 +160,7 @@ public class QSDetail extends LinearLayout {
public void handleShowingDetail(final DetailAdapter adapter, int x, int y,
boolean toggleQs) {
final boolean showingDetail = adapter != null;
final boolean wasShowingDetail = mDetailAdapter != null;
setClickable(showingDetail);
if (showingDetail) {
setupDetailHeader(adapter);
@@ -178,6 +170,7 @@ public class QSDetail extends LinearLayout {
} else {
mTriggeredExpand = false;
}
mShouldAnimate = adapter.shouldAnimate();
mOpenX = x;
mOpenY = y;
} else {
@@ -190,10 +183,10 @@ public class QSDetail extends LinearLayout {
}
}
boolean visibleDiff = (mDetailAdapter != null) != (adapter != null);
if (!visibleDiff && mDetailAdapter == adapter) return; // already in right state
AnimatorListener listener = null;
if (adapter != null) {
boolean visibleDiff = wasShowingDetail != showingDetail;
if (!visibleDiff && !wasShowingDetail) return; // already in right state
AnimatorListener listener;
if (showingDetail) {
int viewCacheIndex = adapter.getMetricsCategory();
View detailView = adapter.createDetailView(mContext, mDetailViews.get(viewCacheIndex),
mDetailContent);
@@ -213,7 +206,7 @@ public class QSDetail extends LinearLayout {
listener = mHideGridContentWhenDone;
setVisibility(View.VISIBLE);
} else {
if (mDetailAdapter != null) {
if (wasShowingDetail) {
Dependency.get(MetricsLogger.class).hidden(mDetailAdapter.getMetricsCategory());
mUiEventLogger.log(mDetailAdapter.closeDetailEvent());
}
@@ -227,7 +220,15 @@ public class QSDetail extends LinearLayout {
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
animateDetailVisibleDiff(x, y, visibleDiff, listener);
if (mShouldAnimate) {
animateDetailVisibleDiff(x, y, visibleDiff, listener);
} else {
if (showingDetail) {
showImmediately();
} else {
hideImmediately();
}
}
}
protected void animateDetailVisibleDiff(int x, int y, boolean visibleDiff, AnimatorListener listener) {
@@ -245,6 +246,17 @@ public class QSDetail extends LinearLayout {
}
}
void showImmediately() {
setVisibility(VISIBLE);
mClipper.cancelAnimator();
mClipper.showBackground();
}
public void hideImmediately() {
mClipper.cancelAnimator();
setVisibility(View.GONE);
}
protected void setupDetailFooter(DetailAdapter adapter) {
final Intent settingsIntent = adapter.getSettingsIntent();
mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
@@ -255,6 +267,13 @@ public class QSDetail extends LinearLayout {
Dependency.get(ActivityStarter.class)
.postStartActivityDismissingKeyguard(settingsIntent, 0);
});
mDetailDoneButton.setOnClickListener(v -> {
announceForAccessibility(
mContext.getString(R.string.accessibility_desc_quick_settings));
if (!adapter.onDoneButtonClicked()) {
mQsPanelController.closeDetail();
}
});
}
protected void setupDetailHeader(final DetailAdapter adapter) {

View File

@@ -39,7 +39,7 @@ public class QSDetailDisplayer {
/** Show the supplied DetailAdapter in the Quick Settings. */
public void showDetailAdapter(DetailAdapter detailAdapter, int x, int y) {
if (mQsPanelController != null) {
mQsPanelController.showDetailDapater(detailAdapter, x, y);
mQsPanelController.showDetailAdapter(detailAdapter, x, y);
}
}
}

View File

@@ -311,7 +311,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
}
/** */
public void showDetailDapater(DetailAdapter detailAdapter, int x, int y) {
public void showDetailAdapter(DetailAdapter detailAdapter, int x, int y) {
mView.showDetailAdapter(true, detailAdapter, new int[]{x, y});
}

View File

@@ -82,7 +82,7 @@ public class UserTile extends QSTileImpl<State> implements UserInfoController.On
@Override
public DetailAdapter getDetailAdapter() {
return mUserSwitcherController.userDetailAdapter;
return mUserSwitcherController.mUserDetailAdapter;
}
@Override

View File

@@ -56,16 +56,23 @@ public class KeyguardClockPositionAlgorithm {
private int mKeyguardStatusHeight;
/**
* Height of {@link KeyguardUserSwitcherListView} when it
* is closed and only the current user's icon is visible.
* Height of user avatar used by the multi-user switcher. This could either be the
* {@link KeyguardUserSwitcherListView} when it is closed and only the current user's icon is
* visible, or it could be height of the avatar used by the
* {@link com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController}.
*/
private int mKeyguardUserSwitcherHeight;
private int mUserSwitchHeight;
/**
* Preferred Y position of clock.
*/
private int mClockPreferredY;
/**
* Preferred Y position of user avatar used by the multi-user switcher.
*/
private int mUserSwitchPreferredY;
/**
* Whether or not there is a custom clock face on keyguard.
*/
@@ -181,20 +188,21 @@ public class KeyguardClockPositionAlgorithm {
*/
public void setup(int statusBarMinHeight, int maxShadeBottom, int notificationStackHeight,
float panelExpansion, int parentHeight, int keyguardStatusHeight,
int keyguardUserSwitcherHeight, int clockPreferredY, boolean hasCustomClock,
boolean hasVisibleNotifs, float dark, float emptyDragAmount, boolean bypassEnabled,
int unlockedStackScrollerPadding, boolean showLockIcon, float qsExpansion,
int cutoutTopInset) {
int userSwitchHeight, int clockPreferredY, int userSwitchPreferredY,
boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
boolean bypassEnabled, int unlockedStackScrollerPadding, boolean showLockIcon,
float qsExpansion, int cutoutTopInset) {
mMinTopMargin = statusBarMinHeight + (showLockIcon
? mContainerTopPaddingWithLockIcon : mContainerTopPaddingWithoutLockIcon)
+ keyguardUserSwitcherHeight;
+ userSwitchHeight;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
mPanelExpansion = panelExpansion;
mHeight = parentHeight;
mKeyguardStatusHeight = keyguardStatusHeight;
mKeyguardUserSwitcherHeight = keyguardUserSwitcherHeight;
mUserSwitchHeight = userSwitchHeight;
mClockPreferredY = clockPreferredY;
mUserSwitchPreferredY = userSwitchPreferredY;
mHasCustomClock = hasCustomClock;
mHasVisibleNotifs = hasVisibleNotifs;
mDarkAmount = dark;
@@ -208,6 +216,7 @@ public class KeyguardClockPositionAlgorithm {
public void run(Result result) {
final int y = getClockY(mPanelExpansion, mDarkAmount);
result.clockY = y;
result.userSwitchY = getUserSwitcherY(mPanelExpansion);
result.clockYFullyDozing = getClockY(
1.0f /* panelExpansion */, 1.0f /* darkAmount */);
result.clockAlpha = getClockAlpha(y);
@@ -241,7 +250,7 @@ public class KeyguardClockPositionAlgorithm {
private int getExpandedPreferredClockY() {
if (mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
return mMinTopMargin;
return mMinTopMargin + mUserSwitchHeight;
}
return (mHasCustomClock && (!mHasVisibleNotifs || mBypassEnabled)) ? getPreferredClockY()
: getExpandedClockPosition();
@@ -257,7 +266,7 @@ public class KeyguardClockPositionAlgorithm {
final int containerCenter = mMinTopMargin + availableHeight / 2;
float y = containerCenter
- (mKeyguardStatusHeight + mKeyguardUserSwitcherHeight) * CLOCK_HEIGHT_WEIGHT
- (mKeyguardStatusHeight + mUserSwitchHeight) * CLOCK_HEIGHT_WEIGHT
- mClockNotificationsMargin - mNotificationStackHeight / 2;
if (y < mMinTopMargin) {
y = mMinTopMargin;
@@ -299,6 +308,17 @@ public class KeyguardClockPositionAlgorithm {
return (int) (MathUtils.lerp(clockY, clockYDark, darkAmount) + mEmptyDragAmount);
}
private int getUserSwitcherY(float panelExpansion) {
float userSwitchYRegular = mUserSwitchPreferredY;
float userSwitchYBouncer = -mKeyguardStatusHeight - mUserSwitchHeight;
// Move user-switch up while collapsing the shade
float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(panelExpansion);
float userSwitchY = MathUtils.lerp(userSwitchYBouncer, userSwitchYRegular, shadeExpansion);
return (int) (userSwitchY + mEmptyDragAmount);
}
/**
* We might want to fade out the clock when the user is swiping up.
* One exception is when the bouncer will become visible, in this cause the clock
@@ -340,6 +360,11 @@ public class KeyguardClockPositionAlgorithm {
*/
public int clockY;
/**
* The y translation of the multi-user switch.
*/
public int userSwitchY;
/**
* The y translation of the clock when we're fully dozing.
*/

View File

@@ -168,6 +168,6 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
}
protected DetailAdapter getUserDetailAdapter() {
return mUserSwitcherController.userDetailAdapter;
return mUserSwitcherController.mUserDetailAdapter;
}
}

View File

@@ -77,6 +77,7 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.DejankUtils;
@@ -95,9 +96,11 @@ import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.GestureRecorder;
@@ -133,6 +136,7 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
@@ -292,14 +296,13 @@ public class NotificationPanelViewController extends PanelViewController {
new KeyguardUserSwitcherController.KeyguardUserSwitcherListener() {
@Override
public void onKeyguardUserSwitcherChanged(boolean open) {
if (mKeyguardUserSwitcherController != null
&& mKeyguardUserSwitcherController.isSimpleUserSwitcher()) {
return;
if (mKeyguardUserSwitcherController == null) {
updateUserSwitcherVisibility(false);
} else if (!mKeyguardUserSwitcherController.isSimpleUserSwitcher()) {
updateUserSwitcherVisibility(open
&& mKeyguardStateController.isShowing()
&& !mKeyguardStateController.isKeyguardFadingAway());
}
updateUserSwitcherVisibility(open
&& mKeyguardStateController.isShowing()
&& !mKeyguardStateController.isKeyguardFadingAway());
}
};
@@ -315,7 +318,9 @@ public class NotificationPanelViewController extends PanelViewController {
private final MediaHierarchyManager mMediaHierarchyManager;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
private final QSDetailDisplayer mQSDetailDisplayer;
private final FeatureFlags mFeatureFlags;
private final ScrimController mScrimController;
private final ControlsComponent mControlsComponent;
@@ -327,6 +332,8 @@ public class NotificationPanelViewController extends PanelViewController {
private int mMaxAllowedKeyguardNotifications;
private KeyguardAffordanceHelper mAffordanceHelper;
private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
private boolean mKeyguardUserSwitcherIsShowing;
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
private KeyguardStatusBarView mKeyguardStatusBar;
private ViewGroup mBigClockContainer;
@@ -352,6 +359,7 @@ public class NotificationPanelViewController extends PanelViewController {
private boolean mQsExpandedWhenExpandingStarted;
private boolean mQsFullyExpanded;
private boolean mKeyguardShowing;
private boolean mKeyguardQsUserSwitchEnabled;
private boolean mKeyguardUserSwitcherEnabled;
private boolean mDozing;
private boolean mDozingOnDown;
@@ -578,7 +586,9 @@ public class NotificationPanelViewController extends PanelViewController {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
QSDetailDisplayer qsDetailDisplayer,
NotificationGroupManagerLegacy groupManager,
NotificationIconAreaController notificationIconAreaController,
AuthController authController,
@@ -605,9 +615,14 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationIconAreaController = notificationIconAreaController;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mFeatureFlags = featureFlags;
mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
mQSDetailDisplayer = qsDetailDisplayer;
mKeyguardUserSwitcherEnabled = mResources.getBoolean(
com.android.internal.R.bool.config_keyguardUserSwitcher);
mKeyguardQsUserSwitchEnabled =
mKeyguardUserSwitcherEnabled && mResources.getBoolean(
R.bool.config_keyguard_user_switch_opens_qs_details);
mView.setWillNotDraw(!DEBUG);
mLayoutInflater = layoutInflater;
mFalsingManager = falsingManager;
@@ -688,15 +703,21 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
mBigClockContainer = mView.findViewById(R.id.big_clock_container);
UserAvatarView userAvatarView = null;
KeyguardUserSwitcherView keyguardUserSwitcherView = null;
if (mKeyguardUserSwitcherEnabled && mUserManager.isUserSwitcherEnabled()) {
ViewStub userSwitcherStub = mView.findViewById(R.id.keyguard_user_switcher_stub);
keyguardUserSwitcherView = (KeyguardUserSwitcherView) userSwitcherStub.inflate();
if (mKeyguardQsUserSwitchEnabled) {
ViewStub stub = mView.findViewById(R.id.keyguard_qs_user_switch_stub);
userAvatarView = (UserAvatarView) stub.inflate();
} else {
ViewStub stub = mView.findViewById(R.id.keyguard_user_switcher_stub);
keyguardUserSwitcherView = (KeyguardUserSwitcherView) stub.inflate();
}
}
updateViewControllers(mView.findViewById(R.id.keyguard_status_view),
keyguardUserSwitcherView);
userAvatarView, keyguardUserSwitcherView);
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
R.id.notification_stack_scroller);
@@ -770,7 +791,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
KeyguardUserSwitcherView keyguardUserSwitcherView) {
UserAvatarView userAvatarView, KeyguardUserSwitcherView keyguardUserSwitcherView) {
// Re-associate the KeyguardStatusViewController
KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
@@ -789,18 +810,27 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardUserSwitcherController.removeCallback();
}
mKeyguardQsUserSwitchController = null;
mKeyguardUserSwitcherController = null;
// Re-associate the KeyguardUserSwitcherController
if (keyguardUserSwitcherView != null) {
if (userAvatarView != null) {
KeyguardQsUserSwitchComponent userSwitcherComponent =
mKeyguardQsUserSwitchComponentFactory.build(userAvatarView);
mKeyguardQsUserSwitchController =
userSwitcherComponent.getKeyguardQsUserSwitchController();
mKeyguardQsUserSwitchController.setNotificationPanelViewController(this);
mKeyguardQsUserSwitchController.init();
mKeyguardStatusBar.setKeyguardUserSwitcherEnabled(true);
} else if (keyguardUserSwitcherView != null) {
KeyguardUserSwitcherComponent userSwitcherComponent =
mKeyguardUserSwitcherComponentFactory.build(keyguardUserSwitcherView);
mKeyguardUserSwitcherController =
userSwitcherComponent.getKeyguardUserSwitcherController();
mKeyguardUserSwitcherController.setCallback(mKeyguardUserSwitcherListener);
mKeyguardUserSwitcherController.init();
mKeyguardStatusBar.setKeyguardUserSwitcherEnabled(true);
} else {
mKeyguardUserSwitcherController = null;
mKeyguardStatusBar.setKeyguardUserSwitcherEnabled(false);
}
}
@@ -856,6 +886,25 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
private View reInflateStub(int viewId, int stubId, int layoutId, boolean enabled) {
View view = mView.findViewById(viewId);
if (view != null) {
int index = mView.indexOfChild(view);
mView.removeView(view);
if (enabled) {
view = mLayoutInflater.inflate(layoutId, mView, false);
mView.addView(view, index);
} else {
view = null;
}
} else if (enabled) {
// It's possible the stub was never inflated if the configuration changed
ViewStub stub = mView.findViewById(stubId);
view = stub.inflate();
}
return view;
}
private void reInflateViews() {
if (DEBUG) Log.d(TAG, "reInflateViews");
// Re-inflate the status view group.
@@ -867,26 +916,26 @@ public class NotificationPanelViewController extends PanelViewController {
mView.addView(keyguardStatusView, index);
// Re-inflate the keyguard user switcher group.
boolean showUserSwitcher =
mKeyguardUserSwitcherEnabled && mUserManager.isUserSwitcherEnabled();
KeyguardUserSwitcherView keyguardUserSwitcherView = mView.findViewById(
R.id.keyguard_user_switcher_view);
if (keyguardUserSwitcherView != null) {
index = mView.indexOfChild(keyguardUserSwitcherView);
mView.removeView(keyguardUserSwitcherView);
if (showUserSwitcher) {
keyguardUserSwitcherView = (KeyguardUserSwitcherView) mLayoutInflater.inflate(
R.layout.keyguard_user_switcher, mView, false);
mView.addView(keyguardUserSwitcherView, index);
}
} else if (showUserSwitcher) {
// It's possible the user switcher was never inflated if the configuration changed
ViewStub userSwitcherStub = mView.findViewById(R.id.keyguard_user_switcher_stub);
keyguardUserSwitcherView = (KeyguardUserSwitcherView) userSwitcherStub.inflate();
}
boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled();
boolean showQsUserSwitch = mKeyguardQsUserSwitchEnabled && isUserSwitcherEnabled;
boolean showKeyguardUserSwitcher =
!mKeyguardQsUserSwitchEnabled
&& mKeyguardUserSwitcherEnabled
&& isUserSwitcherEnabled;
UserAvatarView userAvatarView = (UserAvatarView) reInflateStub(
R.id.keyguard_qs_user_switch_view /* viewId */,
R.id.keyguard_qs_user_switch_stub /* stubId */,
R.layout.keyguard_qs_user_switch /* layoutId */,
showQsUserSwitch /* enabled */);
KeyguardUserSwitcherView keyguardUserSwitcherView =
(KeyguardUserSwitcherView) reInflateStub(
R.id.keyguard_user_switcher_view /* viewId */,
R.id.keyguard_user_switcher_stub /* stubId */,
R.layout.keyguard_user_switcher /* layoutId */,
showKeyguardUserSwitcher /* enabled */);
mBigClockContainer.removeAllViews();
updateViewControllers(keyguardStatusView, keyguardUserSwitcherView);
updateViewControllers(keyguardStatusView, userAvatarView, keyguardUserSwitcherView);
// Update keyguard bottom area
index = mView.indexOfChild(mKeyguardBottomArea);
@@ -910,6 +959,13 @@ public class NotificationPanelViewController extends PanelViewController {
false,
false,
mBarState);
if (mKeyguardQsUserSwitchController != null) {
mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility(
mBarState,
false,
false,
mBarState);
}
if (mKeyguardUserSwitcherController != null) {
mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
mBarState,
@@ -1009,10 +1065,15 @@ public class NotificationPanelViewController extends PanelViewController {
int totalHeight = mView.getHeight();
int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
int clockPreferredY = mKeyguardStatusViewController.getClockPreferredY(totalHeight);
int userSwitcherPreferredY = mStatusBarMinHeight;
boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
final boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
.getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
mKeyguardStatusViewController.setHasVisibleNotifications(hasVisibleNotifications);
int userIconHeight = mKeyguardQsUserSwitchController != null
? mKeyguardQsUserSwitchController.getUserIconHeight()
: (mKeyguardUserSwitcherController != null
? mKeyguardUserSwitcherController.getUserIconHeight() : 0);
mClockPositionAlgorithm.setup(mStatusBarMinHeight, totalHeight - bottomPadding,
mNotificationStackScrollLayoutController.getIntrinsicContentHeight(),
getExpandedFraction(),
@@ -1021,9 +1082,8 @@ public class NotificationPanelViewController extends PanelViewController {
? mKeyguardStatusViewController.getHeight()
: (int) (mKeyguardStatusViewController.getHeight()
- mShelfHeight / 2.0f - mDarkIconSize / 2.0f),
mKeyguardUserSwitcherController == null
? 0 : mKeyguardUserSwitcherController.getUserIconHeight(),
clockPreferredY, hasCustomClock(),
userIconHeight,
clockPreferredY, userSwitcherPreferredY, hasCustomClock(),
hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
bypassEnabled, getUnlockedStackScrollerPadding(),
mUpdateMonitor.canShowLockIcon(),
@@ -1033,11 +1093,16 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardStatusViewController.updatePosition(
mClockPositionResult.clockX, mClockPositionResult.clockY,
mClockPositionResult.clockScale, animateClock);
if (mKeyguardQsUserSwitchController != null) {
mKeyguardQsUserSwitchController.updatePosition(
mClockPositionResult.clockX,
mClockPositionResult.userSwitchY,
animateClock);
}
if (mKeyguardUserSwitcherController != null) {
mKeyguardUserSwitcherController.updatePosition(
mClockPositionResult.clockX,
mClockPositionResult.clockY
- mKeyguardUserSwitcherController.getUserIconHeight(),
mClockPositionResult.userSwitchY,
animateClock);
}
updateNotificationTranslucency();
@@ -1180,6 +1245,9 @@ public class NotificationPanelViewController extends PanelViewController {
private void updateClock() {
mKeyguardStatusViewController.setAlpha(mClockPositionResult.clockAlpha);
if (mKeyguardQsUserSwitchController != null) {
mKeyguardQsUserSwitchController.setAlpha(mClockPositionResult.clockAlpha);
}
if (mKeyguardUserSwitcherController != null) {
mKeyguardUserSwitcherController.setAlpha(mClockPositionResult.clockAlpha);
}
@@ -1271,6 +1339,12 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
public void expandWithQsDetail(DetailAdapter qsDetailAdapter) {
traceQsJank(true /* startTracing */, false /* wasCancelled */);
flingSettings(0 /* velocity */, FLING_EXPAND);
mQSDetailDisplayer.showDetailAdapter(qsDetailAdapter, 0, 0);
}
public void expandWithoutQs() {
if (isQsExpanded()) {
flingSettings(0 /* velocity */, FLING_COLLAPSE);
@@ -3166,6 +3240,13 @@ public class NotificationPanelViewController extends PanelViewController {
true /* keyguardFadingAway */,
false /* goingToFullShade */,
mBarState);
if (mKeyguardQsUserSwitchController != null) {
mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility(
mBarState,
true /* keyguardFadingAway */,
false /* goingToFullShade */,
mBarState);
}
if (mKeyguardUserSwitcherController != null) {
mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
mBarState,
@@ -3432,6 +3513,12 @@ public class NotificationPanelViewController extends PanelViewController {
}
private void updateUserSwitcherVisibility(boolean open) {
// Do not update if previously called with the same state.
if (mKeyguardUserSwitcherIsShowing == open) {
return;
}
mKeyguardUserSwitcherIsShowing = open;
if (open) {
animateKeyguardStatusBarOut();
mKeyguardStatusViewController.setKeyguardStatusViewVisibility(

View File

@@ -0,0 +1,345 @@
/*
* Copyright (C) 2021 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.systemui.statusbar.policy;
import android.content.Context;
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardVisibilityHelper;
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.UserAvatarView;
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
/**
* Manages the user switch on the Keyguard that is used for opening the QS user panel.
*/
@KeyguardUserSwitcherScope
public class KeyguardQsUserSwitchController extends ViewController<UserAvatarView> {
private static final String TAG = "KeyguardQsUserSwitchController";
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final AnimationProperties ANIMATION_PROPERTIES =
new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
private final Context mContext;
private Resources mResources;
private final UserSwitcherController mUserSwitcherController;
private final ScreenLifecycle mScreenLifecycle;
private UserSwitcherController.BaseUserAdapter mAdapter;
private final KeyguardStateController mKeyguardStateController;
protected final SysuiStatusBarStateController mStatusBarStateController;
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
private final KeyguardUserDetailAdapter mUserDetailAdapter;
private NotificationPanelViewController mNotificationPanelViewController;
private UserManager mUserManager;
UserSwitcherController.UserRecord mCurrentUser;
// State info for the user switch and keyguard
private int mBarState;
private float mDarkAmount;
private final StatusBarStateController.StateListener mStatusBarStateListener =
new StatusBarStateController.StateListener() {
@Override
public void onStateChanged(int newState) {
if (DEBUG) Log.d(TAG, String.format("onStateChanged: newState=%d", newState));
boolean goingToFullShade = mStatusBarStateController.goingToFullShade();
boolean keyguardFadingAway = mKeyguardStateController.isKeyguardFadingAway();
int oldState = mBarState;
mBarState = newState;
setKeyguardQsUserSwitchVisibility(
newState,
keyguardFadingAway,
goingToFullShade,
oldState);
}
@Override
public void onDozeAmountChanged(float linearAmount, float amount) {
if (DEBUG) {
Log.d(TAG, String.format("onDozeAmountChanged: linearAmount=%f amount=%f",
linearAmount, amount));
}
setDarkAmount(amount);
}
};
@Inject
public KeyguardQsUserSwitchController(
UserAvatarView view,
Context context,
@Main Resources resources,
UserManager userManager,
ScreenLifecycle screenLifecycle,
UserSwitcherController userSwitcherController,
KeyguardStateController keyguardStateController,
SysuiStatusBarStateController statusBarStateController,
DozeParameters dozeParameters,
UiEventLogger uiEventLogger) {
super(view);
if (DEBUG) Log.d(TAG, "New KeyguardQsUserSwitchController");
mContext = context;
mResources = resources;
mUserManager = userManager;
mScreenLifecycle = screenLifecycle;
mUserSwitcherController = userSwitcherController;
mKeyguardStateController = keyguardStateController;
mStatusBarStateController = statusBarStateController;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
keyguardStateController, dozeParameters);
mUserDetailAdapter = new KeyguardUserDetailAdapter(mUserSwitcherController, mContext,
uiEventLogger);
}
@Override
protected void onInit() {
super.onInit();
if (DEBUG) Log.d(TAG, "onInit");
mAdapter = new UserSwitcherController.BaseUserAdapter(mUserSwitcherController) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
};
mView.setOnClickListener(v -> {
if (isListAnimating()) {
return;
}
// Tapping anywhere in the view will open QS user panel
openQsUserPanel();
});
updateView(true /* forceUpdate */);
}
@Override
protected void onViewAttached() {
if (DEBUG) Log.d(TAG, "onViewAttached");
mAdapter.registerDataSetObserver(mDataSetObserver);
mDataSetObserver.onChanged();
mStatusBarStateController.addCallback(mStatusBarStateListener);
}
@Override
protected void onViewDetached() {
if (DEBUG) Log.d(TAG, "onViewDetached");
mAdapter.unregisterDataSetObserver(mDataSetObserver);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
}
public final DataSetObserver mDataSetObserver = new DataSetObserver() {
@Override
public void onChanged() {
updateView(false /* forceUpdate */);
}
};
/**
* @return true if the current user has changed
*/
private boolean updateCurrentUser() {
UserSwitcherController.UserRecord previousUser = mCurrentUser;
mCurrentUser = null;
for (int i = 0; i < mAdapter.getCount(); i++) {
UserSwitcherController.UserRecord r = mAdapter.getItem(i);
if (r.isCurrent) {
mCurrentUser = r;
return !mCurrentUser.equals(previousUser);
}
}
return mCurrentUser == null && previousUser != null;
}
/**
* @param forceUpdate whether to update view even if current user did not change
*/
private void updateView(boolean forceUpdate) {
if (!updateCurrentUser() && !forceUpdate) {
return;
}
if (mCurrentUser == null) {
mView.setVisibility(View.GONE);
return;
}
mView.setVisibility(View.VISIBLE);
String currentUserName = mCurrentUser.info.name;
String contentDescription = null;
if (!TextUtils.isEmpty(currentUserName)) {
contentDescription = mContext.getString(
R.string.accessibility_quick_settings_user,
currentUserName);
}
if (!TextUtils.equals(mView.getContentDescription(), contentDescription)) {
mView.setContentDescription(contentDescription);
}
if (mCurrentUser.picture == null) {
mView.setDrawableWithBadge(getDrawable(mCurrentUser).mutate(),
mCurrentUser.resolveId());
} else {
int avatarSize =
(int) mResources.getDimension(R.dimen.kg_framed_avatar_size);
Drawable drawable = new CircleFramedDrawable(mCurrentUser.picture, avatarSize);
drawable.setColorFilter(
mCurrentUser.isSwitchToEnabled ? null
: mAdapter.getDisabledUserAvatarColorFilter());
mView.setDrawableWithBadge(drawable, mCurrentUser.info.id);
}
}
Drawable getDrawable(UserSwitcherController.UserRecord item) {
Drawable drawable;
if (item.isCurrent && item.isGuest) {
drawable = mContext.getDrawable(R.drawable.ic_avatar_guest_user);
} else {
drawable = mAdapter.getIconDrawable(mContext, item);
}
int iconColorRes;
if (item.isSwitchToEnabled) {
iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
} else {
iconColorRes = R.color.kg_user_switcher_restricted_avatar_icon_color;
}
drawable.setTint(mResources.getColor(iconColorRes, mContext.getTheme()));
Drawable bg = mContext.getDrawable(R.drawable.kg_bg_avatar);
drawable = new LayerDrawable(new Drawable[]{bg, drawable});
return drawable;
}
/**
* Get the height of the keyguard user switcher view when closed.
*/
public int getUserIconHeight() {
return mView.getHeight();
}
/**
* Set the visibility of the user avatar view based on some new state.
*/
public void setKeyguardQsUserSwitchVisibility(
int statusBarState,
boolean keyguardFadingAway,
boolean goingToFullShade,
int oldStatusBarState) {
mKeyguardVisibilityHelper.setViewVisibility(
statusBarState, keyguardFadingAway, goingToFullShade, oldStatusBarState);
}
/**
* Update position of the view with an optional animation
*/
public void updatePosition(int x, int y, boolean animate) {
PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, ANIMATION_PROPERTIES, animate);
PropertyAnimator.setProperty(mView, AnimatableProperty.TRANSLATION_X, -Math.abs(x),
ANIMATION_PROPERTIES, animate);
}
/**
* Set keyguard user avatar view alpha.
*/
public void setAlpha(float alpha) {
if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
mView.setAlpha(alpha);
}
}
/**
* Set the amount (ratio) that the device has transitioned to doze.
*
* @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake.
*/
private void setDarkAmount(float darkAmount) {
boolean isAwake = darkAmount != 0;
if (darkAmount == mDarkAmount) {
return;
}
mDarkAmount = darkAmount;
mView.setVisibility(isAwake ? View.VISIBLE : View.GONE);
}
private boolean isListAnimating() {
return mKeyguardVisibilityHelper.isVisibilityAnimating();
}
private void openQsUserPanel() {
mNotificationPanelViewController.expandWithQsDetail(mUserDetailAdapter);
}
public void setNotificationPanelViewController(
NotificationPanelViewController notificationPanelViewController) {
mNotificationPanelViewController = notificationPanelViewController;
}
class KeyguardUserDetailAdapter extends UserSwitcherController.UserDetailAdapter {
KeyguardUserDetailAdapter(UserSwitcherController userSwitcherController, Context context,
UiEventLogger uiEventLogger) {
super(userSwitcherController, context, uiEventLogger);
}
@Override
public boolean shouldAnimate() {
return false;
}
@Override
public boolean onDoneButtonClicked() {
if (mNotificationPanelViewController != null) {
mNotificationPanelViewController.animateCloseQs(true /* animateAway */);
return true;
} else {
return false;
}
}
}
}

View File

@@ -121,6 +121,7 @@ public class UserSwitcherController implements Dumpable {
private Intent mSecondaryUserServiceIntent;
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
private final UiEventLogger mUiEventLogger;
public final DetailAdapter mUserDetailAdapter;
@Inject
public UserSwitcherController(Context context, KeyguardStateController keyguardStateController,
@@ -131,6 +132,7 @@ public class UserSwitcherController implements Dumpable {
mBroadcastDispatcher = broadcastDispatcher;
mActivityTaskManager = activityTaskManager;
mUiEventLogger = uiEventLogger;
mUserDetailAdapter = new UserDetailAdapter(this, mContext, mUiEventLogger);
if (!UserManager.isGuestUserEphemeral()) {
mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
}
@@ -781,9 +783,20 @@ public class UserSwitcherController implements Dumpable {
}
}
public final DetailAdapter userDetailAdapter = new DetailAdapter() {
public static class UserDetailAdapter implements DetailAdapter {
private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS);
private final UserSwitcherController mUserSwitcherController;
private final Context mContext;
private final UiEventLogger mUiEventLogger;
UserDetailAdapter(UserSwitcherController userSwitcherController, Context context,
UiEventLogger uiEventLogger) {
mUserSwitcherController = userSwitcherController;
mContext = context;
mUiEventLogger = uiEventLogger;
}
@Override
public CharSequence getTitle() {
return mContext.getString(R.string.quick_settings_user_title);
@@ -794,7 +807,7 @@ public class UserSwitcherController implements Dumpable {
UserDetailView v;
if (!(convertView instanceof UserDetailView)) {
v = UserDetailView.inflate(context, parent, false);
v.createAndSetAdapter(UserSwitcherController.this, mUiEventLogger);
v.createAndSetAdapter(mUserSwitcherController, mUiEventLogger);
} else {
v = (UserDetailView) convertView;
}

View File

@@ -394,8 +394,8 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
private void positionClock() {
mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight,
0 /* keyguardUserSwitcherHeight */, mPreferredClockY, mHasCustomClock,
mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
0 /* userSwitchHeight */, mPreferredClockY, 0 /* userSwitchPreferredY */,
mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
0 /* unlockedStackScrollerPadding */, false /* udfpsEnrolled */, mQsExpansion,
mCutoutTopInset);
mClockPositionAlgorithm.run(mClockPosition);

View File

@@ -58,6 +58,7 @@ import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.R;
@@ -70,6 +71,7 @@ import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -194,7 +196,11 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
@Mock
private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponent;
private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
@Mock
private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
@Mock
private QSDetailDisplayer mQSDetailDisplayer;
@Mock
private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
@Mock
@@ -305,7 +311,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mBiometricUnlockController, mStatusBarKeyguardViewManager,
mNotificationStackScrollLayoutController,
mKeyguardStatusViewComponentFactory,
mKeyguardUserSwitcherComponent,
mKeyguardQsUserSwitchComponentFactory,
mKeyguardUserSwitcherComponentFactory,
mQSDetailDisplayer,
mGroupManager,
mNotificationAreaController,
mAuthController,