summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peter Kalauskas <peskal@google.com> 2021-02-11 16:32:54 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-02-11 16:32:54 +0000
commit3dba81dfea20f1880ee1378f8821e1ba5c90ab3e (patch)
tree4bb8d89a1edea5f8d092d310eee9bed631711bae
parent7f89361004ada3fbdcb8f2a8680255d7c04666e0 (diff)
parent1970915c2c88c05ca8d5f669a72ff22c2f4beef2 (diff)
Merge changes from topic "new-keyguard-user-switcher" into sc-dev
* changes: New keyguard user switcher Remove MultiUserSwitch from KeyguardStatusBarView
-rw-r--r--packages/SystemUI/res/color/kg_user_avatar_frame.xml (renamed from packages/SystemUI/res/layout/keyguard_user_switcher_inner.xml)18
-rw-r--r--packages/SystemUI/res/drawable/end_guest_button_background.xml25
-rw-r--r--packages/SystemUI/res/drawable/kg_bg_avatar.xml28
-rw-r--r--packages/SystemUI/res/layout/keyguard_status_bar.xml17
-rw-r--r--packages/SystemUI/res/layout/keyguard_user_switcher.xml54
-rw-r--r--packages/SystemUI/res/layout/keyguard_user_switcher_item.xml41
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml12
-rw-r--r--packages/SystemUI/res/values-night/colors.xml2
-rw-r--r--packages/SystemUI/res/values-sw600dp/styles.xml7
-rw-r--r--packages/SystemUI/res/values/colors.xml10
-rw-r--r--packages/SystemUI/res/values/dimens.xml13
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/res/values/styles.xml4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java94
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java137
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherComponent.java40
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherModule.java24
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherScope.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java113
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java176
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java414
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java639
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java168
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherView.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt19
36 files changed, 1597 insertions, 756 deletions
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher_inner.xml b/packages/SystemUI/res/color/kg_user_avatar_frame.xml
index 4c1042e70c1a..174981e2a660 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher_inner.xml
+++ b/packages/SystemUI/res/color/kg_user_avatar_frame.xml
@@ -14,14 +14,10 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<com.android.keyguard.AlphaOptimizedLinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_user_switcher_inner"
- android:orientation="vertical"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_marginTop="@dimen/status_bar_header_height_keyguard"
- android:layout_gravity="end"
- android:gravity="end"
- android:paddingTop="4dp">
-</com.android.keyguard.AlphaOptimizedLinearLayout>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_activated="true"
+ android:color="@color/kg_user_switcher_avatar_background" />
+ <item android:color="@color/kg_user_switcher_avatar_background" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/end_guest_button_background.xml b/packages/SystemUI/res/drawable/end_guest_button_background.xml
new file mode 100644
index 000000000000..5644b657a609
--- /dev/null
+++ b/packages/SystemUI/res/drawable/end_guest_button_background.xml
@@ -0,0 +1,25 @@
+<?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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <stroke
+ android:width="@dimen/end_guest_button_border_size"
+ android:color="?android:attr/colorControlHighlight" />
+ <corners android:radius="@dimen/end_guest_button_corner_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/kg_bg_avatar.xml b/packages/SystemUI/res/drawable/kg_bg_avatar.xml
new file mode 100644
index 000000000000..addb3f7508f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/kg_bg_avatar.xml
@@ -0,0 +1,28 @@
+<?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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="100"
+ android:viewportHeight="100">
+
+ <path
+ android:fillColor="@color/kg_user_switcher_avatar_background"
+ android:pathData="M50,50m-50,0a50,50 0,1 1,100 0a50,50 0,1 1,-100 0"/>
+
+</vector>
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index 416ee8147e33..2789ed125b09 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -43,17 +43,12 @@
<include layout="@layout/system_icons" />
</FrameLayout>
- <com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch"
- android:layout_width="@dimen/multi_user_switch_width_keyguard"
- android:layout_height="match_parent"
- android:background="@drawable/ripple_drawable"
- android:layout_marginEnd="@dimen/multi_user_switch_keyguard_margin">
- <ImageView android:id="@+id/multi_user_avatar"
- android:layout_width="@dimen/multi_user_avatar_keyguard_size"
- android:layout_height="@dimen/multi_user_avatar_keyguard_size"
- android:layout_gravity="center"
- android:scaleType="centerInside"/>
- </com.android.systemui.statusbar.phone.MultiUserSwitch>
+
+ <ImageView android:id="@+id/multi_user_avatar"
+ android:layout_width="@dimen/multi_user_avatar_keyguard_size"
+ android:layout_height="@dimen/multi_user_avatar_keyguard_size"
+ android:layout_gravity="center"
+ android:scaleType="centerInside"/>
</LinearLayout>
<Space
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher.xml b/packages/SystemUI/res/layout/keyguard_user_switcher.xml
index 983ba6d5e240..253c03e9effb 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher.xml
@@ -14,10 +14,50 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<view xmlns:android="http://schemas.android.com/apk/res/android"
- class="com.android.systemui.statusbar.policy.KeyguardUserSwitcher$Container"
- android:visibility="gone"
- android:layout_height="match_parent"
- android:layout_width="match_parent">
- <!-- KeyguardUserSwitcher loads keyguard_user_switcher_inner.xml here -->
-</view> \ No newline at end of file
+<!-- This is a view that shows a user switcher in Keyguard. -->
+<com.android.systemui.statusbar.policy.KeyguardUserSwitcherView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/keyguard_user_switcher_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="end">
+
+ <com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView
+ android:id="@+id/keyguard_user_switcher_list"
+ android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="top|end"
+ android:gravity="end" />
+
+ <LinearLayout
+ android:id="@+id/end_guest_button"
+ android:layout_height="@dimen/end_guest_button_layout_height"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_centerHorizontal="true"
+ android:layout_marginBottom="@dimen/end_guest_button_margin_bottom"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:paddingLeft="@dimen/end_guest_button_padding_horizontal"
+ android:paddingRight="@dimen/end_guest_button_padding_horizontal"
+ android:background="@drawable/end_guest_button_background"
+ android:visibility="gone">
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:src="@drawable/ic_exit_to_app"
+ android:background="@android:color/transparent"
+ android:color="?attr/wallpaperTextColor" />
+ <TextView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:gravity="center"
+ android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="13sp"
+ android:text="@string/guest_exit_button" />
+ </LinearLayout>
+
+</com.android.systemui.statusbar.policy.KeyguardUserSwitcherView>
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
index 1cd1a04ab462..aaa372a5be6e 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
@@ -19,29 +19,30 @@
<!-- LinearLayout -->
<com.android.systemui.statusbar.policy.KeyguardUserDetailItemView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:sysui="http://schemas.android.com/apk/res-auto"
+ xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_marginEnd="8dp"
- android:gravity="center_vertical"
+ android:gravity="end|center_vertical"
android:clickable="true"
- android:background="@drawable/ripple_drawable"
- sysui:regularTextAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher"
- sysui:activatedTextAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher.Activated">
- <TextView android:id="@+id/user_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="13dp"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher"
- />
- <com.android.systemui.statusbar.phone.UserAvatarView android:id="@+id/user_picture"
- android:layout_width="@dimen/kg_framed_avatar_size"
- android:layout_height="@dimen/kg_framed_avatar_size"
- android:contentDescription="@null"
- sysui:frameWidth="@dimen/keyguard_user_switcher_border_thickness"
- sysui:framePadding="2.5dp"
- sysui:badgeDiameter="18dp"
- sysui:badgeMargin="1dp"
- sysui:frameColor="@color/kg_user_switcher_rounded_background_color" />
+ android:background="@drawable/kg_user_switcher_rounded_bg"
+ systemui:activatedTextAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher"
+ systemui:regularTextAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher">
+ <TextView
+ android:id="@+id/user_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="16dp" />
+ <com.android.systemui.statusbar.phone.UserAvatarView
+ android:id="@+id/user_picture"
+ android:layout_width="@dimen/kg_framed_avatar_size"
+ android:layout_height="@dimen/kg_framed_avatar_size"
+ systemui:avatarPadding="0dp"
+ systemui:badgeDiameter="18dp"
+ systemui:badgeMargin="1dp"
+ systemui:frameWidth="0dp"
+ systemui:framePadding="0dp"
+ systemui:frameColor="@color/kg_user_avatar_frame" />
</com.android.systemui.statusbar.policy.KeyguardUserDetailItemView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index d6385ffbcc0c..859d9048cee3 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -31,6 +31,12 @@
android:layout_height="match_parent"
android:visibility="gone" />
+ <ViewStub
+ android:id="@+id/keyguard_user_switcher_stub"
+ android:layout="@layout/keyguard_user_switcher"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent" />
+
<include
layout="@layout/keyguard_status_view"
android:visibility="gone" />
@@ -72,12 +78,6 @@
<include layout="@layout/photo_preview_overlay" />
- <ViewStub
- android:id="@+id/keyguard_user_switcher"
- android:layout="@layout/keyguard_user_switcher"
- android:layout_height="match_parent"
- android:layout_width="match_parent" />
-
<include
layout="@layout/keyguard_status_bar"
android:visibility="invisible" />
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 3153d0d0123d..37ec576be4be 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -89,6 +89,8 @@
<color name="kg_user_switcher_avatar_icon_color">@android:color/background_light</color>
<!-- Icon color for selected user avatars in keyguard user switcher -->
<color name="kg_user_switcher_selected_avatar_icon_color">#202124</color>
+ <!-- Color of background circle of user avatars in keyguard user switcher -->
+ <color name="kg_user_switcher_avatar_background">#3C4043</color>
<!-- Icon color for user avatars in quick settings user switcher -->
<color name="qs_user_switcher_avatar_icon_color">@android:color/background_light</color>
<!-- Icon color for selected user avatars in quick settings user switcher -->
diff --git a/packages/SystemUI/res/values-sw600dp/styles.xml b/packages/SystemUI/res/values-sw600dp/styles.xml
index 02bd60210e81..ee2b82dca811 100644
--- a/packages/SystemUI/res/values-sw600dp/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp/styles.xml
@@ -23,13 +23,6 @@
<item name="numColumns">4</item>
</style>
- <style name="TextAppearance.StatusBar.Expanded.UserSwitcher">
- <item name="android:textSize">@dimen/kg_user_switcher_text_size</item>
- <item name="android:textStyle">normal</item>
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textColor">?attr/wallpaperTextColor</item>
- </style>
-
<style name="TextAppearance.QS.UserSwitcher">
<item name="android:textSize">@dimen/kg_user_switcher_text_size</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 5fb6de7bb588..8bd9de919bee 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -66,9 +66,13 @@
<!-- Color for rounded background for activated user in keyguard user switcher -->
<color name="kg_user_switcher_activated_background_color">#26000000</color>
<!-- Icon color for user avatars in keyguard user switcher -->
- <color name="kg_user_switcher_avatar_icon_color">@android:color/background_light</color>
- <!-- Icon color for selected user avatars in keyguard user switcher -->
- <color name="kg_user_switcher_selected_avatar_icon_color">@android:color/background_light</color>
+ <color name="kg_user_switcher_avatar_icon_color">@color/GM2_grey_800</color>
+ <!-- Icon color for user avatars in keyguard user switcher that restricted
+ (e.g. cannot be switched to) -->
+ <color name="kg_user_switcher_restricted_avatar_icon_color">@color/GM2_grey_600</color>
+ <!-- Color of background circle of user avatars in keyguard user switcher -->
+ <color name="kg_user_switcher_avatar_background">@color/GM2_grey_300</color>
+
<!-- Icon color for user avatars in user switcher quick settings -->
<color name="qs_user_switcher_avatar_icon_color">#3C4043</color>
<!-- Icon color for selected user avatars in user switcher quick settings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 08cd6553e252..594fbdf55d3c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -743,9 +743,6 @@
<!-- end margin for system icons if multi user switch is hidden -->
<dimen name="system_icons_switcher_hidden_expanded_margin">16dp</dimen>
- <!-- The thickness of the colored border around the current user. -->
- <dimen name="keyguard_user_switcher_border_thickness">2dp</dimen>
-
<dimen name="data_usage_graph_marker_width">4dp</dimen>
<!-- The padding bottom of the clock group when QS is expanded. -->
@@ -805,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">54dp</dimen>
+ <dimen name="kg_framed_avatar_size">32dp</dimen>
<!-- Margin on the left side of the carrier text on Keyguard -->
<dimen name="keyguard_carrier_text_margin">16dp</dimen>
@@ -1324,8 +1321,16 @@
<dimen name="screenrecord_status_icon_height">17.5dp</dimen>
<dimen name="screenrecord_status_icon_bg_radius">8dp</dimen>
+ <!-- Keyguard user switcher -->
<dimen name="kg_user_switcher_text_size">16sp</dimen>
+ <!-- End guest session button -->
+ <dimen name="end_guest_button_layout_height">32dp</dimen>
+ <dimen name="end_guest_button_padding_horizontal">16dp</dimen>
+ <dimen name="end_guest_button_margin_bottom">96dp</dimen>
+ <dimen name="end_guest_button_border_size">1dp</dimen>
+ <dimen name="end_guest_button_corner_radius">16dp</dimen>
+
<!-- Opacity at which the background for the shutdown UI will be drawn. -->
<item name="shutdown_scrim_behind_alpha" format="float" type="dimen">0.95</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index abcf4e802ab9..7c1c24bf280e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1112,6 +1112,9 @@
<!-- Name for a freshly added user [CHAR LIMIT=30] -->
<string name="user_new_user_name">New user</string>
+ <!-- Label for button that exits guest session and clears the guest user data [CHAR LIMIT=50]-->
+ <string name="guest_exit_button">End guest session</string>
+
<!-- Title of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
<string name="guest_exit_guest_dialog_title">End guest session?</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index afdf23b14a7a..85c470f8e706 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -114,12 +114,12 @@
<style name="TextAppearance.StatusBar.Expanded.UserSwitcher">
<item name="android:textSize">@dimen/kg_user_switcher_text_size</item>
<item name="android:textStyle">normal</item>
- <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ <item name="android:textColor">?attr/wallpaperTextColor</item>
</style>
<style name="TextAppearance.StatusBar.Expanded.UserSwitcher.Activated">
<item name="android:fontWeight">700</item>
- <item name="android:textStyle">bold</item>
</style>
<style name="TextAppearance" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index a5f364d30d7d..6fb6760be653 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -16,13 +16,9 @@
package com.android.keyguard;
-import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
-
import android.util.Slog;
import android.view.View;
-import com.android.systemui.Interpolators;
-import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
@@ -50,13 +46,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private final KeyguardSliceViewController mKeyguardSliceViewController;
private final KeyguardClockSwitchController mKeyguardClockSwitchController;
- private final KeyguardStateController mKeyguardStateController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ConfigurationController mConfigurationController;
private final NotificationIconAreaController mNotificationIconAreaController;
private final DozeParameters mDozeParameters;
+ private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
- private boolean mKeyguardStatusViewVisibilityAnimating;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
@Inject
@@ -72,11 +67,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController;
mKeyguardClockSwitchController = keyguardClockSwitchController;
- mKeyguardStateController = keyguardStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mConfigurationController = configurationController;
mNotificationIconAreaController = notificationIconAreaController;
mDozeParameters = dozeParameters;
+ mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
+ dozeParameters);
}
@Override
@@ -144,7 +140,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
* Set keyguard status view alpha.
*/
public void setAlpha(float alpha) {
- if (!mKeyguardStatusViewVisibilityAnimating) {
+ if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
mView.setAlpha(alpha);
}
}
@@ -200,7 +196,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
public void updatePosition(int x, int y, float scale, boolean animate) {
// We animate the status view visible/invisible using Y translation, so don't change it
// while the animation is running.
- if (!mKeyguardStatusViewVisibilityAnimating) {
+ if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, CLOCK_ANIMATION_PROPERTIES,
animate);
}
@@ -230,69 +226,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
boolean keyguardFadingAway,
boolean goingToFullShade,
int oldStatusBarState) {
- mView.animate().cancel();
- mKeyguardStatusViewVisibilityAnimating = false;
- if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD
- && statusBarState != KEYGUARD) || goingToFullShade) {
- mKeyguardStatusViewVisibilityAnimating = true;
- mView.animate()
- .alpha(0f)
- .setStartDelay(0)
- .setDuration(160)
- .setInterpolator(Interpolators.ALPHA_OUT)
- .withEndAction(
- mAnimateKeyguardStatusViewGoneEndRunnable);
- if (keyguardFadingAway) {
- mView.animate()
- .setStartDelay(mKeyguardStateController.getKeyguardFadingAwayDelay())
- .setDuration(mKeyguardStateController.getShortenedFadingAwayDuration())
- .start();
- }
- } else if (oldStatusBarState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) {
- mView.setVisibility(View.VISIBLE);
- mKeyguardStatusViewVisibilityAnimating = true;
- mView.setAlpha(0f);
- mView.animate()
- .alpha(1f)
- .setStartDelay(0)
- .setDuration(320)
- .setInterpolator(Interpolators.ALPHA_IN)
- .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
- } else if (statusBarState == KEYGUARD) {
- if (keyguardFadingAway) {
- mKeyguardStatusViewVisibilityAnimating = true;
- mView.animate()
- .alpha(0)
- .translationYBy(-getHeight() * 0.05f)
- .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
- .setDuration(125)
- .setStartDelay(0)
- .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable)
- .start();
- } else if (mDozeParameters.shouldControlUnlockedScreenOff()) {
- mKeyguardStatusViewVisibilityAnimating = true;
-
- mView.setVisibility(View.VISIBLE);
- mView.setAlpha(0f);
-
- float curTranslationY = mView.getTranslationY();
- mView.setTranslationY(curTranslationY - getHeight() * 0.1f);
- mView.animate()
- .setStartDelay((int) (StackStateAnimator.ANIMATION_DURATION_WAKEUP * .6f))
- .setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .alpha(1f)
- .translationY(curTranslationY)
- .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
- .start();
- } else {
- mView.setVisibility(View.VISIBLE);
- mView.setAlpha(1f);
- }
- } else {
- mView.setVisibility(View.GONE);
- mView.setAlpha(1f);
- }
+ mKeyguardVisibilityHelper.setViewVisibility(
+ statusBarState, keyguardFadingAway, goingToFullShade, oldStatusBarState);
}
private void refreshTime() {
@@ -393,19 +328,4 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mView.updateLogoutView();
}
};
-
- private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = () -> {
- mKeyguardStatusViewVisibilityAnimating = false;
- mView.setVisibility(View.INVISIBLE);
- };
-
-
- private final Runnable mAnimateKeyguardStatusViewGoneEndRunnable = () -> {
- mKeyguardStatusViewVisibilityAnimating = false;
- mView.setVisibility(View.GONE);
- };
-
- private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> {
- mKeyguardStatusViewVisibilityAnimating = false;
- };
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
new file mode 100644
index 000000000000..724e1f660fb9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -0,0 +1,137 @@
+/*
+ * 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;
+
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+
+import android.view.View;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+/**
+ * Helper class for updating visibility of keyguard views based on keyguard and status bar state.
+ * This logic is shared by both the keyguard status view and the keyguard user switcher.
+ */
+public class KeyguardVisibilityHelper {
+
+ private View mView;
+ private final KeyguardStateController mKeyguardStateController;
+ private final DozeParameters mDozeParameters;
+ private boolean mKeyguardViewVisibilityAnimating;
+
+ public KeyguardVisibilityHelper(View view, KeyguardStateController keyguardStateController,
+ DozeParameters dozeParameters) {
+ mView = view;
+ mKeyguardStateController = keyguardStateController;
+ mDozeParameters = dozeParameters;
+ }
+
+ public boolean isVisibilityAnimating() {
+ return mKeyguardViewVisibilityAnimating;
+ }
+
+ /**
+ * Set the visibility of a keyguard view based on some new state.
+ */
+ public void setViewVisibility(
+ int statusBarState,
+ boolean keyguardFadingAway,
+ boolean goingToFullShade,
+ int oldStatusBarState) {
+ mView.animate().cancel();
+ mKeyguardViewVisibilityAnimating = false;
+ if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD
+ && statusBarState != KEYGUARD) || goingToFullShade) {
+ mKeyguardViewVisibilityAnimating = true;
+ mView.animate()
+ .alpha(0f)
+ .setStartDelay(0)
+ .setDuration(160)
+ .setInterpolator(Interpolators.ALPHA_OUT)
+ .withEndAction(
+ mAnimateKeyguardStatusViewGoneEndRunnable);
+ if (keyguardFadingAway) {
+ mView.animate()
+ .setStartDelay(mKeyguardStateController.getKeyguardFadingAwayDelay())
+ .setDuration(mKeyguardStateController.getShortenedFadingAwayDuration())
+ .start();
+ }
+ } else if (oldStatusBarState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) {
+ mView.setVisibility(View.VISIBLE);
+ mKeyguardViewVisibilityAnimating = true;
+ mView.setAlpha(0f);
+ mView.animate()
+ .alpha(1f)
+ .setStartDelay(0)
+ .setDuration(320)
+ .setInterpolator(Interpolators.ALPHA_IN)
+ .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
+ } else if (statusBarState == KEYGUARD) {
+ if (keyguardFadingAway) {
+ mKeyguardViewVisibilityAnimating = true;
+ mView.animate()
+ .alpha(0)
+ .translationYBy(-mView.getHeight() * 0.05f)
+ .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
+ .setDuration(125)
+ .setStartDelay(0)
+ .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable)
+ .start();
+ } else if (mDozeParameters.shouldControlUnlockedScreenOff()) {
+ mKeyguardViewVisibilityAnimating = true;
+
+ mView.setVisibility(View.VISIBLE);
+ mView.setAlpha(0f);
+
+ float curTranslationY = mView.getTranslationY();
+ mView.setTranslationY(curTranslationY - mView.getHeight() * 0.1f);
+ mView.animate()
+ .setStartDelay((int) (StackStateAnimator.ANIMATION_DURATION_WAKEUP * .6f))
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .alpha(1f)
+ .translationY(curTranslationY)
+ .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
+ .start();
+ } else {
+ mView.setVisibility(View.VISIBLE);
+ mView.setAlpha(1f);
+ }
+ } else {
+ mView.setVisibility(View.GONE);
+ mView.setAlpha(1f);
+ }
+ }
+
+ private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = () -> {
+ mKeyguardViewVisibilityAnimating = false;
+ mView.setVisibility(View.INVISIBLE);
+ };
+
+ private final Runnable mAnimateKeyguardStatusViewGoneEndRunnable = () -> {
+ mKeyguardViewVisibilityAnimating = false;
+ mView.setVisibility(View.GONE);
+ };
+
+ private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> {
+ mKeyguardViewVisibilityAnimating = false;
+ };
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherComponent.java
new file mode 100644
index 000000000000..730c14dc9600
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherComponent.java
@@ -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.policy.KeyguardUserSwitcherController;
+import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+
+/**
+ * Subcomponent for helping work with KeyguardUserSwitcher and its children.
+ */
+@Subcomponent(modules = {KeyguardUserSwitcherModule.class})
+@KeyguardUserSwitcherScope
+public interface KeyguardUserSwitcherComponent {
+ /** Simple factory for {@link KeyguardUserSwitcherComponent}. */
+ @Subcomponent.Factory
+ interface Factory {
+ KeyguardUserSwitcherComponent build(
+ @BindsInstance KeyguardUserSwitcherView keyguardUserSwitcherView);
+ }
+
+ /** Builds a {@link com.android.systemui.statusbar.policy.KeyguardUserSwitcherController}. */
+ KeyguardUserSwitcherController getKeyguardUserSwitcherController();
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherModule.java
new file mode 100644
index 000000000000..b9184f405bf9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherModule.java
@@ -0,0 +1,24 @@
+/*
+ * 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 dagger.Module;
+
+/** Dagger module for {@link KeyguardUserSwitcherComponent}. */
+@Module
+public abstract class KeyguardUserSwitcherModule {
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherScope.java
new file mode 100644
index 000000000000..864472e53ce7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardUserSwitcherScope.java
@@ -0,0 +1,32 @@
+/*
+ * 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 static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the KeyguardUserSwitcherComponent.
+ */
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface KeyguardUserSwitcherScope {}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c55fdf4783e3..91cf7108c728 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -415,6 +415,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
@Override
public void onUserSwitching(int userId) {
+ if (DEBUG) Log.d(TAG, String.format("onUserSwitching %d", userId));
// Note that the mLockPatternUtils user has already been updated from setCurrentUser.
// We need to force a reset of the views, since lockNow (called by
// ActivityManagerService) will not reconstruct the keyguard if it is already showing.
@@ -432,6 +433,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
@Override
public void onUserSwitchComplete(int userId) {
+ if (DEBUG) Log.d(TAG, String.format("onUserSwitchComplete %d", userId));
if (userId != UserHandle.USER_SYSTEM) {
UserInfo info = UserManager.get(mContext).getUserInfo(userId);
// Don't try to dismiss if the user has Pin/Patter/Password set
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 76281d8c0f00..9e5b225fbefc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -30,6 +30,7 @@ import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
+import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.classifier.FalsingModule;
@@ -61,7 +62,7 @@ import dagger.Provides;
/**
* Dagger Module providing {@link StatusBar}.
*/
-@Module(subcomponents = {KeyguardStatusViewComponent.class},
+@Module(subcomponents = {KeyguardStatusViewComponent.class, KeyguardUserSwitcherComponent.class},
includes = {FalsingModule.class})
public class KeyguardModule {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index 6a8c61491709..6ca550c9ddb2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -41,7 +41,7 @@ public class UserDetailItemView extends LinearLayout {
protected static int layoutResId = R.layout.qs_user_detail_item;
private UserAvatarView mAvatar;
- private TextView mName;
+ protected TextView mName;
private int mActivatedStyle;
private int mRegularStyle;
private View mRestrictedPadlock;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 57a64e440bf6..e0df4f8bfea9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -27,6 +27,7 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView;
/**
* Utility class to calculate the clock position and top padding of notifications on Keyguard.
@@ -55,6 +56,12 @@ public class KeyguardClockPositionAlgorithm {
private int mKeyguardStatusHeight;
/**
+ * Height of {@link KeyguardUserSwitcherListView} when it
+ * is closed and only the current user's icon is visible.
+ */
+ private int mKeyguardUserSwitcherHeight;
+
+ /**
* Preferred Y position of clock.
*/
private int mClockPreferredY;
@@ -173,17 +180,20 @@ public class KeyguardClockPositionAlgorithm {
* Sets up algorithm values.
*/
public void setup(int statusBarMinHeight, int maxShadeBottom, int notificationStackHeight,
- float panelExpansion, int parentHeight, int keyguardStatusHeight, int clockPreferredY,
- boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
- boolean bypassEnabled, int unlockedStackScrollerPadding, boolean showLockIcon,
- float qsExpansion, int cutoutTopInset) {
+ 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) {
mMinTopMargin = statusBarMinHeight + (showLockIcon
- ? mContainerTopPaddingWithLockIcon : mContainerTopPaddingWithoutLockIcon);
+ ? mContainerTopPaddingWithLockIcon : mContainerTopPaddingWithoutLockIcon)
+ + keyguardUserSwitcherHeight;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
mPanelExpansion = panelExpansion;
mHeight = parentHeight;
mKeyguardStatusHeight = keyguardStatusHeight;
+ mKeyguardUserSwitcherHeight = keyguardUserSwitcherHeight;
mClockPreferredY = clockPreferredY;
mHasCustomClock = hasCustomClock;
mHasVisibleNotifs = hasVisibleNotifs;
@@ -246,7 +256,8 @@ public class KeyguardClockPositionAlgorithm {
final int availableHeight = mMaxShadeBottom - mMinTopMargin;
final int containerCenter = mMinTopMargin + availableHeight / 2;
- float y = containerCenter - mKeyguardStatusHeight * CLOCK_HEIGHT_WEIGHT
+ float y = containerCenter
+ - (mKeyguardStatusHeight + mKeyguardUserSwitcherHeight) * CLOCK_HEIGHT_WEIGHT
- mClockNotificationsMargin - mNotificationStackHeight / 2;
if (y < mMinTopMargin) {
y = mMinTopMargin;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 5f547b5df671..33798d680d05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
import android.annotation.ColorInt;
@@ -25,6 +26,7 @@ import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.TypedValue;
@@ -45,18 +47,15 @@ import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -75,18 +74,16 @@ public class KeyguardStatusBarView extends RelativeLayout
private boolean mShowPercentAvailable;
private boolean mBatteryCharging;
- private boolean mKeyguardUserSwitcherShowing;
private boolean mBatteryListening;
private TextView mCarrierLabel;
- private MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
private BatteryMeterView mBatteryView;
private StatusIconContainer mStatusIconContainer;
private BatteryController mBatteryController;
- private KeyguardUserSwitcher mKeyguardUserSwitcher;
- private UserSwitcherController mUserSwitcherController;
+ private boolean mKeyguardUserSwitcherEnabled;
+ private final UserManager mUserManager;
private int mSystemIconsSwitcherHiddenExpandedMargin;
private int mSystemIconsBaseMargin;
@@ -109,13 +106,13 @@ public class KeyguardStatusBarView extends RelativeLayout
public KeyguardStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mUserManager = UserManager.get(getContext());
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mSystemIconsContainer = findViewById(R.id.system_icons_container);
- mMultiUserSwitch = findViewById(R.id.multi_user_switch);
mMultiUserAvatar = findViewById(R.id.multi_user_avatar);
mCarrierLabel = findViewById(R.id.keyguard_carrier_text);
mBatteryView = mSystemIconsContainer.findViewById(R.id.battery);
@@ -124,7 +121,6 @@ public class KeyguardStatusBarView extends RelativeLayout
mStatusIconContainer = findViewById(R.id.statusIcons);
loadDimens();
- updateUserSwitcher();
mBatteryController = Dependency.get(BatteryController.class);
}
@@ -137,14 +133,6 @@ public class KeyguardStatusBarView extends RelativeLayout
R.dimen.multi_user_avatar_keyguard_size);
mMultiUserAvatar.setLayoutParams(lp);
- // Multi-user switch
- lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams();
- lp.width = getResources().getDimensionPixelSize(
- R.dimen.multi_user_switch_width_keyguard);
- lp.setMarginEnd(getResources().getDimensionPixelSize(
- R.dimen.multi_user_switch_keyguard_margin));
- mMultiUserSwitch.setLayoutParams(lp);
-
// System icons
lp = (MarginLayoutParams) mSystemIconsContainer.getLayoutParams();
lp.setMarginStart(getResources().getDimensionPixelSize(
@@ -194,22 +182,28 @@ public class KeyguardStatusBarView extends RelativeLayout
}
private void updateVisibilities() {
- if (mMultiUserSwitch.getParent() != mStatusIconArea && !mKeyguardUserSwitcherShowing) {
- if (mMultiUserSwitch.getParent() != null) {
- getOverlay().remove(mMultiUserSwitch);
+ if (mMultiUserAvatar.getParent() != mStatusIconArea
+ && !mKeyguardUserSwitcherEnabled) {
+ if (mMultiUserAvatar.getParent() != null) {
+ getOverlay().remove(mMultiUserAvatar);
}
- mStatusIconArea.addView(mMultiUserSwitch, 0);
- } else if (mMultiUserSwitch.getParent() == mStatusIconArea && mKeyguardUserSwitcherShowing) {
- mStatusIconArea.removeView(mMultiUserSwitch);
+ mStatusIconArea.addView(mMultiUserAvatar, 0);
+ } else if (mMultiUserAvatar.getParent() == mStatusIconArea
+ && mKeyguardUserSwitcherEnabled) {
+ mStatusIconArea.removeView(mMultiUserAvatar);
}
- if (mKeyguardUserSwitcher == null) {
+ if (!mKeyguardUserSwitcherEnabled) {
// If we have no keyguard switcher, the screen width is under 600dp. In this case,
// we only show the multi-user switch if it's enabled through UserManager as well as
// by the user.
- if (mMultiUserSwitch.isMultiUserEnabled()) {
- mMultiUserSwitch.setVisibility(View.VISIBLE);
+ // TODO(b/138661450) Move IPC calls to background
+ boolean isMultiUserEnabled = whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
+ mContext.getResources().getBoolean(
+ R.bool.qs_show_user_switcher_for_single_user)));
+ if (isMultiUserEnabled) {
+ mMultiUserAvatar.setVisibility(View.VISIBLE);
} else {
- mMultiUserSwitch.setVisibility(View.GONE);
+ mMultiUserAvatar.setVisibility(View.GONE);
}
}
mBatteryView.setForceShowPercent(mBatteryCharging && mShowPercentAvailable);
@@ -220,11 +214,12 @@ public class KeyguardStatusBarView extends RelativeLayout
(LinearLayout.LayoutParams) mSystemIconsContainer.getLayoutParams();
// If the avatar icon is gone, we need to have some end margin to display the system icons
// correctly.
- int baseMarginEnd = mMultiUserSwitch.getVisibility() == View.GONE
+ int baseMarginEnd = mMultiUserAvatar.getVisibility() == View.GONE
? mSystemIconsBaseMargin
: 0;
- int marginEnd = mKeyguardUserSwitcherShowing ? mSystemIconsSwitcherHiddenExpandedMargin :
- baseMarginEnd;
+ int marginEnd =
+ mKeyguardUserSwitcherEnabled ? mSystemIconsSwitcherHiddenExpandedMargin
+ : baseMarginEnd;
marginEnd = calculateMargin(marginEnd, mPadding.second);
if (marginEnd != lp.getMarginEnd()) {
lp.setMarginEnd(marginEnd);
@@ -334,20 +329,11 @@ public class KeyguardStatusBarView extends RelativeLayout
}
}
- private void updateUserSwitcher() {
- boolean keyguardSwitcherAvailable = mKeyguardUserSwitcher != null;
- mMultiUserSwitch.setClickable(keyguardSwitcherAvailable);
- mMultiUserSwitch.setFocusable(keyguardSwitcherAvailable);
- mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable);
- }
-
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
UserInfoController userInfoController = Dependency.get(UserInfoController.class);
userInfoController.addCallback(this);
- mUserSwitcherController = Dependency.get(UserSwitcherController.class);
- mMultiUserSwitch.setUserSwitcherController(mUserSwitcherController);
userInfoController.reloadUserInfo();
Dependency.get(ConfigurationController.class).addCallback(this);
mIconManager = new TintedIconManager(findViewById(R.id.statusIcons),
@@ -369,11 +355,6 @@ public class KeyguardStatusBarView extends RelativeLayout
mMultiUserAvatar.setImageDrawable(picture);
}
- /** */
- public void setQSDetailDisplayer(QSDetailDisplayer detailDisplayer) {
- mMultiUserSwitch.setQSDetailDisplayer(detailDisplayer);
- }
-
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
if (mBatteryCharging != charging) {
@@ -387,54 +368,42 @@ public class KeyguardStatusBarView extends RelativeLayout
// could not care less
}
- public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
- mKeyguardUserSwitcher = keyguardUserSwitcher;
- mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher);
- updateUserSwitcher();
- }
-
- public void setKeyguardUserSwitcherShowing(boolean showing, boolean animate) {
- mKeyguardUserSwitcherShowing = showing;
- if (animate) {
- animateNextLayoutChange();
- }
- updateVisibilities();
- updateLayoutConsideringCutout();
- updateSystemIconsLayoutParams();
+ public void setKeyguardUserSwitcherEnabled(boolean enabled) {
+ mKeyguardUserSwitcherEnabled = enabled;
}
private void animateNextLayoutChange() {
final int systemIconsCurrentX = mSystemIconsContainer.getLeft();
- final boolean userSwitcherVisible = mMultiUserSwitch.getParent() == mStatusIconArea;
+ final boolean userAvatarVisible = mMultiUserAvatar.getParent() == mStatusIconArea;
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
- boolean userSwitcherHiding = userSwitcherVisible
- && mMultiUserSwitch.getParent() != mStatusIconArea;
+ boolean userAvatarHiding = userAvatarVisible
+ && mMultiUserAvatar.getParent() != mStatusIconArea;
mSystemIconsContainer.setX(systemIconsCurrentX);
mSystemIconsContainer.animate()
.translationX(0)
.setDuration(400)
- .setStartDelay(userSwitcherHiding ? 300 : 0)
+ .setStartDelay(userAvatarHiding ? 300 : 0)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.start();
- if (userSwitcherHiding) {
- getOverlay().add(mMultiUserSwitch);
- mMultiUserSwitch.animate()
+ if (userAvatarHiding) {
+ getOverlay().add(mMultiUserAvatar);
+ mMultiUserAvatar.animate()
.alpha(0f)
.setDuration(300)
.setStartDelay(0)
.setInterpolator(Interpolators.ALPHA_OUT)
.withEndAction(() -> {
- mMultiUserSwitch.setAlpha(1f);
- getOverlay().remove(mMultiUserSwitch);
+ mMultiUserAvatar.setAlpha(1f);
+ getOverlay().remove(mMultiUserAvatar);
})
.start();
} else {
- mMultiUserSwitch.setAlpha(0f);
- mMultiUserSwitch.animate()
+ mMultiUserAvatar.setAlpha(0f);
+ mMultiUserAvatar.animate()
.alpha(1f)
.setDuration(300)
.setStartDelay(200)
@@ -452,8 +421,8 @@ public class KeyguardStatusBarView extends RelativeLayout
if (visibility != View.VISIBLE) {
mSystemIconsContainer.animate().cancel();
mSystemIconsContainer.setTranslationX(0);
- mMultiUserSwitch.animate().cancel();
- mMultiUserSwitch.setAlpha(1f);
+ mMultiUserAvatar.animate().cancel();
+ mMultiUserAvatar.setAlpha(1f);
} else {
updateVisibilities();
updateSystemIconsLayoutParams();
@@ -523,9 +492,9 @@ public class KeyguardStatusBarView extends RelativeLayout
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardStatusBarView:");
pw.println(" mBatteryCharging: " + mBatteryCharging);
- pw.println(" mKeyguardUserSwitcherShowing: " + mKeyguardUserSwitcherShowing);
pw.println(" mBatteryListening: " + mBatteryListening);
pw.println(" mLayoutState: " + mLayoutState);
+ pw.println(" mKeyguardUserSwitcherEnabled: " + mKeyguardUserSwitcherEnabled);
if (mBatteryView != null) {
mBatteryView.dump(fd, pw, args);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 480d3f42ae77..d9cb9ce21330 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -35,7 +35,6 @@ import com.android.systemui.Prefs.Key;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSDetailDisplayer;
-import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.UserSwitcherController;
/**
@@ -44,8 +43,6 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
public class MultiUserSwitch extends FrameLayout implements View.OnClickListener {
protected QSDetailDisplayer mQSDetailDisplayer;
- private KeyguardUserSwitcher mKeyguardUserSwitcher;
- private boolean mKeyguardMode;
private UserSwitcherController.BaseUserAdapter mUserListener;
final UserManager mUserManager;
@@ -85,15 +82,6 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
refreshContentDescription();
}
- public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
- mKeyguardUserSwitcher = keyguardUserSwitcher;
- }
-
- public void setKeyguardMode(boolean keyguardShowing) {
- mKeyguardMode = keyguardShowing;
- registerListener();
- }
-
public boolean isMultiUserEnabled() {
// TODO(b/138661450) Move IPC calls to background
return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
@@ -123,11 +111,7 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
@Override
public void onClick(View v) {
- if (mKeyguardMode) {
- if (mKeyguardUserSwitcher != null) {
- mKeyguardUserSwitcher.show(true /* animate */);
- }
- } else if (mQSDetailDisplayer != null && mUserSwitcherController != null) {
+ if (mQSDetailDisplayer != null && mUserSwitcherController != null) {
View center = getChildCount() > 0 ? getChildAt(0) : this;
int[] tmpInt = new int[2];
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 0e40cc0de914..3b09eda4003e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -48,6 +48,7 @@ import android.hardware.biometrics.BiometricSourceType;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.os.UserManager;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
@@ -57,6 +58,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
+import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityManager;
@@ -76,6 +78,7 @@ import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
+import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.DejankUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -95,7 +98,6 @@ import com.android.systemui.plugins.FalsingManager;
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;
@@ -132,7 +134,8 @@ import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUi
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
+import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
+import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.util.Utils;
import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -284,6 +287,22 @@ public class NotificationPanelViewController extends PanelViewController {
}
};
+ final KeyguardUserSwitcherController.KeyguardUserSwitcherListener
+ mKeyguardUserSwitcherListener =
+ new KeyguardUserSwitcherController.KeyguardUserSwitcherListener() {
+ @Override
+ public void onKeyguardUserSwitcherChanged(boolean open) {
+ if (mKeyguardUserSwitcherController != null
+ && mKeyguardUserSwitcherController.isSimpleUserSwitcher()) {
+ return;
+ }
+
+ updateUserSwitcherVisibility(open
+ && mKeyguardStateController.isShowing()
+ && !mKeyguardStateController.isKeyguardFadingAway());
+ }
+ };
+
private final LayoutInflater mLayoutInflater;
private final PowerManager mPowerManager;
private final AccessibilityManager mAccessibilityManager;
@@ -296,7 +315,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final MediaHierarchyManager mMediaHierarchyManager;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
- private final QSDetailDisplayer mQSDetailDisplayer;
+ private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
private final FeatureFlags mFeatureFlags;
private final ScrimController mScrimController;
private final ControlsComponent mControlsComponent;
@@ -308,7 +327,7 @@ public class NotificationPanelViewController extends PanelViewController {
private int mMaxAllowedKeyguardNotifications;
private KeyguardAffordanceHelper mAffordanceHelper;
- private KeyguardUserSwitcher mKeyguardUserSwitcher;
+ private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
private KeyguardStatusBarView mKeyguardStatusBar;
private ViewGroup mBigClockContainer;
private QS mQs;
@@ -333,6 +352,7 @@ public class NotificationPanelViewController extends PanelViewController {
private boolean mQsExpandedWhenExpandingStarted;
private boolean mQsFullyExpanded;
private boolean mKeyguardShowing;
+ private boolean mKeyguardUserSwitcherEnabled;
private boolean mDozing;
private boolean mDozingOnDown;
private int mBarState;
@@ -465,6 +485,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final CommandQueue mCommandQueue;
private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final UserManager mUserManager;
private final ShadeController mShadeController;
private final MediaDataManager mMediaDataManager;
private int mDisplayId;
@@ -557,11 +578,12 @@ public class NotificationPanelViewController extends PanelViewController {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
+ KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
NotificationGroupManagerLegacy groupManager,
NotificationIconAreaController notificationIconAreaController,
AuthController authController,
- QSDetailDisplayer qsDetailDisplayer,
ScrimController scrimController,
+ UserManager userManager,
MediaDataManager mediaDataManager,
AmbientState ambientState,
FeatureFlags featureFlags,
@@ -582,8 +604,10 @@ public class NotificationPanelViewController extends PanelViewController {
mGroupManager = groupManager;
mNotificationIconAreaController = notificationIconAreaController;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
- mQSDetailDisplayer = qsDetailDisplayer;
mFeatureFlags = featureFlags;
+ mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
+ mKeyguardUserSwitcherEnabled = mResources.getBoolean(
+ com.android.internal.R.bool.config_keyguardUserSwitcher);
mView.setWillNotDraw(!DEBUG);
mLayoutInflater = layoutInflater;
mFalsingManager = falsingManager;
@@ -599,6 +623,7 @@ public class NotificationPanelViewController extends PanelViewController {
mDozeParameters = dozeParameters;
mBiometricUnlockController = biometricUnlockController;
mScrimController = scrimController;
+ mUserManager = userManager;
mMediaDataManager = mediaDataManager;
mControlsComponent = controlsComponent;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
@@ -661,9 +686,17 @@ public class NotificationPanelViewController extends PanelViewController {
private void onFinishInflate() {
loadDimens();
mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
- mKeyguardStatusBar.setQSDetailDisplayer(mQSDetailDisplayer);
mBigClockContainer = mView.findViewById(R.id.big_clock_container);
- updateViewControllers(mView.findViewById(R.id.keyguard_status_view));
+
+ KeyguardUserSwitcherView keyguardUserSwitcherView = null;
+
+ if (mKeyguardUserSwitcherEnabled && mUserManager.isUserSwitcherEnabled()) {
+ ViewStub userSwitcherStub = mView.findViewById(R.id.keyguard_user_switcher_stub);
+ keyguardUserSwitcherView = (KeyguardUserSwitcherView) userSwitcherStub.inflate();
+ }
+
+ updateViewControllers(mView.findViewById(R.id.keyguard_status_view),
+ keyguardUserSwitcherView);
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
R.id.notification_stack_scroller);
@@ -736,7 +769,8 @@ public class NotificationPanelViewController extends PanelViewController {
R.dimen.heads_up_status_bar_padding);
}
- private void updateViewControllers(KeyguardStatusView keyguardStatusView) {
+ private void updateViewControllers(KeyguardStatusView keyguardStatusView,
+ KeyguardUserSwitcherView keyguardUserSwitcherView) {
// Re-associate the KeyguardStatusViewController
KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
@@ -747,6 +781,28 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardClockSwitchController keyguardClockSwitchController =
statusViewComponent.getKeyguardClockSwitchController();
keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
+
+ if (mKeyguardUserSwitcherController != null) {
+ // Try to close the switcher so that callbacks are triggered if necessary.
+ // Otherwise, NPV can get into a state where some of the views are still hidden
+ mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(false);
+ mKeyguardUserSwitcherController.removeCallback();
+ }
+
+ // Re-associate the KeyguardUserSwitcherController
+ 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);
+ }
}
/**
@@ -801,6 +857,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
private void reInflateViews() {
+ if (DEBUG) Log.d(TAG, "reInflateViews");
// Re-inflate the status view group.
KeyguardStatusView keyguardStatusView = mView.findViewById(R.id.keyguard_status_view);
int index = mView.indexOfChild(keyguardStatusView);
@@ -809,8 +866,27 @@ public class NotificationPanelViewController extends PanelViewController {
R.layout.keyguard_status_view, mView, false);
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();
+ }
+
mBigClockContainer.removeAllViews();
- updateViewControllers(keyguardStatusView);
+ updateViewControllers(keyguardStatusView, keyguardUserSwitcherView);
// Update keyguard bottom area
index = mView.indexOfChild(mKeyguardBottomArea);
@@ -834,6 +910,13 @@ public class NotificationPanelViewController extends PanelViewController {
false,
false,
mBarState);
+ if (mKeyguardUserSwitcherController != null) {
+ mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
+ mBarState,
+ false,
+ false,
+ mBarState);
+ }
setKeyguardBottomAreaVisibility(mBarState, false);
}
@@ -938,6 +1021,8 @@ public class NotificationPanelViewController extends PanelViewController {
? mKeyguardStatusViewController.getHeight()
: (int) (mKeyguardStatusViewController.getHeight()
- mShelfHeight / 2.0f - mDarkIconSize / 2.0f),
+ mKeyguardUserSwitcherController == null
+ ? 0 : mKeyguardUserSwitcherController.getUserIconHeight(),
clockPreferredY, hasCustomClock(),
hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
bypassEnabled, getUnlockedStackScrollerPadding(),
@@ -948,6 +1033,13 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardStatusViewController.updatePosition(
mClockPositionResult.clockX, mClockPositionResult.clockY,
mClockPositionResult.clockScale, animateClock);
+ if (mKeyguardUserSwitcherController != null) {
+ mKeyguardUserSwitcherController.updatePosition(
+ mClockPositionResult.clockX,
+ mClockPositionResult.clockY
+ - mKeyguardUserSwitcherController.getUserIconHeight(),
+ animateClock);
+ }
updateNotificationTranslucency();
updateClock();
stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;
@@ -1088,6 +1180,9 @@ public class NotificationPanelViewController extends PanelViewController {
private void updateClock() {
mKeyguardStatusViewController.setAlpha(mClockPositionResult.clockAlpha);
+ if (mKeyguardUserSwitcherController != null) {
+ mKeyguardUserSwitcherController.setAlpha(mClockPositionResult.clockAlpha);
+ }
}
public void animateToFullShade(long delay) {
@@ -1769,8 +1864,9 @@ public class NotificationPanelViewController extends PanelViewController {
mBarState != KEYGUARD && (!mQsExpanded
|| mQsExpansionFromOverscroll));
- if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
- mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
+ if (mKeyguardUserSwitcherController != null && mQsExpanded
+ && !mStackScrollerOverscrolling) {
+ mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(true);
}
if (mQs == null) return;
mQs.setExpanded(mQsExpanded);
@@ -2604,10 +2700,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
- public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
- mKeyguardUserSwitcher = keyguardUserSwitcher;
- }
-
public void onScreenTurningOn() {
mKeyguardStatusViewController.dozeTimeTick();
}
@@ -3074,6 +3166,13 @@ public class NotificationPanelViewController extends PanelViewController {
true /* keyguardFadingAway */,
false /* goingToFullShade */,
mBarState);
+ if (mKeyguardUserSwitcherController != null) {
+ mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
+ mBarState,
+ true /* keyguardFadingAway */,
+ false /* goingToFullShade */,
+ mBarState);
+ }
}
/**
@@ -3316,6 +3415,44 @@ public class NotificationPanelViewController extends PanelViewController {
return mNotificationStackScrollLayoutController;
}
+ /**
+ * Close the keyguard user switcher if it is open and capable of closing.
+ *
+ * Has no effect if user switcher isn't supported, if the user switcher is already closed, or
+ * if the user switcher uses "simple" mode. The simple user switcher cannot be closed.
+ *
+ * @return true if the keyguard user switcher was open, and is now closed
+ */
+ public boolean closeUserSwitcherIfOpen() {
+ if (mKeyguardUserSwitcherController != null) {
+ return mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(
+ true /* animate */);
+ }
+ return false;
+ }
+
+ private void updateUserSwitcherVisibility(boolean open) {
+ if (open) {
+ animateKeyguardStatusBarOut();
+ mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
+ mBarState,
+ true /* keyguardFadingAway */,
+ true /* goingToFullShade */,
+ mBarState);
+ setKeyguardBottomAreaVisibility(mBarState, true);
+ mNotificationContainerParent.setVisibility(View.GONE);
+ } else {
+ animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
+ StatusBarState.KEYGUARD,
+ false,
+ false,
+ StatusBarState.SHADE_LOCKED);
+ setKeyguardBottomAreaVisibility(mBarState, false);
+ mNotificationContainerParent.setVisibility(View.VISIBLE);
+ }
+ }
+
private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener {
@Override
public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
@@ -3616,6 +3753,7 @@ public class NotificationPanelViewController extends PanelViewController {
private class ConfigurationListener implements ConfigurationController.ConfigurationListener {
@Override
public void onThemeChanged() {
+ if (DEBUG) Log.d(TAG, "onThemeChanged");
final int themeResId = mView.getContext().getThemeResId();
if (mThemeResId == themeResId) {
return;
@@ -3627,11 +3765,15 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
public void onOverlayChanged() {
+ if (DEBUG) Log.d(TAG, "onOverlayChanged");
reInflateViews();
}
@Override
- public void onUiModeChanged() {}
+ public void onDensityOrFontScaleChanged() {
+ if (DEBUG) Log.d(TAG, "onDensityOrFontScaleChanged");
+ reInflateViews();
+ }
}
private class StatusBarStateListener implements StateListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index b36740620d08..e394ebc65a6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -22,8 +22,6 @@ import android.content.res.Configuration;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
-import android.view.ViewStub;
-import android.view.ViewStub.OnInflateListener;
import android.view.WindowInsets;
import android.widget.FrameLayout;
@@ -44,14 +42,11 @@ import java.util.Comparator;
* The container with notification stack scroller and quick settings inside.
*/
public class NotificationsQuickSettingsContainer extends ConstraintLayout
- implements OnInflateListener, FragmentListener,
- AboveShelfObserver.HasViewAboveShelfChangedListener {
+ implements FragmentListener, AboveShelfObserver.HasViewAboveShelfChangedListener {
private FrameLayout mQsFrame;
- private View mUserSwitcher;
private NotificationStackScrollLayout mStackScroller;
private View mKeyguardStatusBar;
- private boolean mInflated;
private boolean mQsExpanded;
private boolean mCustomizerAnimating;
@@ -73,9 +68,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
mStackScroller = findViewById(R.id.notification_stack_scroller);
mStackScrollerMargin = ((LayoutParams) mStackScroller.getLayoutParams()).bottomMargin;
mKeyguardStatusBar = findViewById(R.id.keyguard_header);
- ViewStub userSwitcher = findViewById(R.id.keyguard_user_switcher);
- userSwitcher.setOnInflateListener(this);
- mUserSwitcher = userSwitcher;
}
@Override
@@ -119,10 +111,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
// touches first but the panel gets drawn above.
mDrawingOrderedChildren.clear();
mLayoutDrawingOrder.clear();
- if (mInflated && mUserSwitcher.getVisibility() == View.VISIBLE) {
- mDrawingOrderedChildren.add(mUserSwitcher);
- mLayoutDrawingOrder.add(mUserSwitcher);
- }
if (mKeyguardStatusBar.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mKeyguardStatusBar);
mLayoutDrawingOrder.add(mKeyguardStatusBar);
@@ -158,14 +146,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
}
@Override
- public void onInflate(ViewStub stub, View inflated) {
- if (stub == mUserSwitcher) {
- mUserSwitcher = inflated;
- mInflated = true;
- }
- }
-
- @Override
public void onFragmentViewCreated(String tag, Fragment fragment) {
QS container = (QS) fragment;
container.setContainer(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 1e19beeff730..041a97e1d404 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -89,7 +89,6 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
-import android.os.UserManager;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
@@ -226,7 +225,6 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
@@ -623,7 +621,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- private KeyguardUserSwitcher mKeyguardUserSwitcher;
private final UserSwitcherController mUserSwitcherController;
private final NetworkController mNetworkController;
private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
@@ -1212,9 +1209,6 @@ public class StatusBar extends SystemUI implements DemoMode,
});
mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
- if (UserManager.get(mContext).isUserSwitcherEnabled()) {
- createUserSwitcher();
- }
// Set up the quick settings tile panel
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
@@ -1441,9 +1435,6 @@ public class StatusBar extends SystemUI implements DemoMode,
// TODO: Bring these out of StatusBar.
mUserInfoControllerImpl.onDensityOrFontScaleChanged();
mUserSwitcherController.onDensityOrFontScaleChanged();
- if (mKeyguardUserSwitcher != null) {
- mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
- }
mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
mHeadsUpManager.onDensityOrFontScaleChanged();
}
@@ -1477,13 +1468,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- protected void createUserSwitcher() {
- mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
- mNotificationShadeWindowView.findViewById(R.id.keyguard_user_switcher),
- mNotificationShadeWindowView.findViewById(R.id.keyguard_header),
- mNotificationPanelViewController);
- }
-
private void inflateStatusBarWindow() {
mNotificationShadeWindowView = mSuperStatusBarViewFactory.getNotificationShadeWindowView();
StatusBarComponent statusBarComponent = mStatusBarComponentBuilder.get()
@@ -3266,7 +3250,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
mStatusBarStateController.setState(StatusBarState.FULLSCREEN_USER_SWITCHER);
- } else if (!mPulseExpansionHandler.isWakingToShadeLocked()){
+ } else if (!mPulseExpansionHandler.isWakingToShadeLocked()) {
mStatusBarStateController.setState(StatusBarState.KEYGUARD);
}
updatePanelExpansionForKeyguard();
@@ -3565,15 +3549,15 @@ public class StatusBar extends SystemUI implements DemoMode,
}
return true;
}
+ if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
+ return true;
+ }
if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
if (mNotificationPanelViewController.canPanelBeCollapsed()) {
mShadeController.animateCollapsePanels();
}
return true;
}
- if (mKeyguardUserSwitcher != null && mKeyguardUserSwitcher.hideIfNotSimple(true)) {
- return true;
- }
return false;
}
@@ -3622,20 +3606,8 @@ public class StatusBar extends SystemUI implements DemoMode,
updateTheme();
mNavigationBarController.touchAutoDim(mDisplayId);
Trace.beginSection("StatusBar#updateKeyguardState");
- if (mState == StatusBarState.KEYGUARD) {
- if (mKeyguardUserSwitcher != null) {
- mKeyguardUserSwitcher.setKeyguard(true,
- mStatusBarStateController.fromShadeLocked());
- }
- if (mStatusBarView != null) mStatusBarView.removePendingHideExpandedRunnables();
- } else {
- if (mKeyguardUserSwitcher != null) {
- mKeyguardUserSwitcher.setKeyguard(false,
- mStatusBarStateController.goingToFullShade() ||
- mState == StatusBarState.SHADE_LOCKED ||
- mStatusBarStateController.fromShadeLocked());
- }
-
+ if (mState == StatusBarState.KEYGUARD && mStatusBarView != null) {
+ mStatusBarView.removePendingHideExpandedRunnables();
}
updateDozingState();
checkBarModes();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
index 07433e13104c..0649478a42aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
@@ -17,8 +17,15 @@
package com.android.systemui.statusbar.policy;
import android.content.Context;
+import android.graphics.Color;
import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import androidx.core.graphics.ColorUtils;
+
+import com.android.keyguard.KeyguardConstants;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.qs.tiles.UserDetailItemView;
@@ -27,6 +34,14 @@ import com.android.systemui.qs.tiles.UserDetailItemView;
*/
public class KeyguardUserDetailItemView extends UserDetailItemView {
+ private static final String TAG = "KeyguardUserDetailItemView";
+ private static final boolean DEBUG = KeyguardConstants.DEBUG;
+
+ private static final int ANIMATION_DURATION_FADE_NAME = 240;
+
+ private float mDarkAmount;
+ private int mTextColor;
+
public KeyguardUserDetailItemView(Context context) {
this(context, null);
}
@@ -48,4 +63,89 @@ public class KeyguardUserDetailItemView extends UserDetailItemView {
protected int getFontSizeDimen() {
return R.dimen.kg_user_switcher_text_size;
}
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mTextColor = mName.getCurrentTextColor();
+ updateDark();
+ }
+
+ /**
+ * Update visibility of this view.
+ *
+ * @param showItem If true, this item is visible on the screen to the user. Generally this
+ * means that the item would be clickable. If false, item visibility will be
+ * set to GONE and hidden entirely.
+ * @param showTextName Whether or not the name should be shown next to the icon. If false,
+ * only the icon is shown.
+ * @param animate Whether the transition should be animated. Note, this only applies to
+ * animating the text name. The item itself will not animate (i.e. fade in/out).
+ * Instead, we delegate that to the parent view.
+ */
+ void updateVisibilities(boolean showItem, boolean showTextName, boolean animate) {
+ if (DEBUG) {
+ Log.d(TAG, String.format("updateVisibilities itemIsShown=%b nameIsShown=%b animate=%b",
+ showItem, showTextName, animate));
+ }
+
+ getBackground().setAlpha((showItem && showTextName) ? 255 : 0);
+
+ if (showItem) {
+ if (showTextName) {
+ mName.setVisibility(View.VISIBLE);
+ if (animate) {
+ mName.setAlpha(0f);
+ mName.animate()
+ .alpha(1f)
+ .setDuration(ANIMATION_DURATION_FADE_NAME)
+ .setInterpolator(Interpolators.ALPHA_IN);
+ } else {
+ mName.setAlpha(1f);
+ }
+ } else {
+ if (animate) {
+ mName.setVisibility(View.VISIBLE);
+ mName.setAlpha(1f);
+ mName.animate()
+ .alpha(0f)
+ .setDuration(ANIMATION_DURATION_FADE_NAME)
+ .setInterpolator(Interpolators.ALPHA_OUT)
+ .withEndAction(() -> {
+ mName.setVisibility(View.GONE);
+ mName.setAlpha(1f);
+ });
+ } else {
+ mName.setVisibility(View.GONE);
+ mName.setAlpha(1f);
+ }
+ }
+ setVisibility(View.VISIBLE);
+ setAlpha(1f);
+ } else {
+ // If item isn't shown, don't animate. The parent class will animate the view instead
+ setVisibility(View.GONE);
+ setAlpha(1f);
+ mName.setVisibility(showTextName ? View.VISIBLE : View.GONE);
+ mName.setAlpha(1f);
+ }
+ }
+
+ /**
+ * 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.
+ */
+ public void setDarkAmount(float darkAmount) {
+ if (mDarkAmount == darkAmount) {
+ return;
+ }
+ mDarkAmount = darkAmount;
+ updateDark();
+ }
+
+ private void updateDark() {
+ final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
+ mName.setTextColor(blendedTextColor);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
deleted file mode 100644
index 90f557753132..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright (C) 2014 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 static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA;
-import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.widget.FrameLayout;
-
-import com.android.settingslib.animation.AppearAnimationUtils;
-import com.android.settingslib.drawable.CircleFramedDrawable;
-import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.qs.tiles.UserDetailItemView;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-
-import java.util.ArrayList;
-
-/**
- * Manages the user switcher on the Keyguard.
- */
-public class KeyguardUserSwitcher {
-
- private static final String TAG = "KeyguardUserSwitcher";
- private static final boolean ALWAYS_ON = false;
-
- private final Container mUserSwitcherContainer;
- private final KeyguardStatusBarView mStatusBarView;
- private final KeyguardUserAdapter mAdapter;
- private final AppearAnimationUtils mAppearAnimationUtils;
- private final KeyguardUserSwitcherScrim mBackground;
-
- private ViewGroup mUserSwitcher;
- private ObjectAnimator mBgAnimator;
- private UserSwitcherController mUserSwitcherController;
- private boolean mAnimating;
-
- public KeyguardUserSwitcher(Context context, ViewStub userSwitcher,
- KeyguardStatusBarView statusBarView,
- NotificationPanelViewController panelViewController) {
- boolean keyguardUserSwitcherEnabled =
- context.getResources().getBoolean(
- com.android.internal.R.bool.config_keyguardUserSwitcher) || ALWAYS_ON;
- UserSwitcherController userSwitcherController = Dependency.get(UserSwitcherController.class);
- if (userSwitcherController != null && keyguardUserSwitcherEnabled) {
- mUserSwitcherContainer = (Container) userSwitcher.inflate();
- mBackground = new KeyguardUserSwitcherScrim(context);
- reinflateViews();
- mStatusBarView = statusBarView;
- mStatusBarView.setKeyguardUserSwitcher(this);
- panelViewController.setKeyguardUserSwitcher(this);
- mAdapter = new KeyguardUserAdapter(context, userSwitcherController, this);
- mAdapter.registerDataSetObserver(mDataSetObserver);
- mUserSwitcherController = userSwitcherController;
- mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f,
- Interpolators.FAST_OUT_SLOW_IN);
- mUserSwitcherContainer.setKeyguardUserSwitcher(this);
- } else {
- mUserSwitcherContainer = null;
- mStatusBarView = null;
- mAdapter = null;
- mAppearAnimationUtils = null;
- mBackground = null;
- }
- }
-
- private void reinflateViews() {
- if (mUserSwitcher != null) {
- mUserSwitcher.setBackground(null);
- mUserSwitcher.removeOnLayoutChangeListener(mBackground);
- }
- mUserSwitcherContainer.removeAllViews();
-
- LayoutInflater.from(mUserSwitcherContainer.getContext())
- .inflate(R.layout.keyguard_user_switcher_inner, mUserSwitcherContainer);
-
- mUserSwitcher = (ViewGroup) mUserSwitcherContainer.findViewById(
- R.id.keyguard_user_switcher_inner);
- mUserSwitcher.addOnLayoutChangeListener(mBackground);
- mUserSwitcher.setBackground(mBackground);
- }
-
- public void setKeyguard(boolean keyguard, boolean animate) {
- if (mUserSwitcher != null) {
- if (keyguard && shouldExpandByDefault()) {
- show(animate);
- } else {
- hide(animate);
- }
- }
- }
-
- /**
- * @return true if the user switcher should be expanded by default on the lock screen.
- * @see android.os.UserManager#isUserSwitcherEnabled()
- */
- private boolean shouldExpandByDefault() {
- return (mUserSwitcherController != null) && mUserSwitcherController.isSimpleUserSwitcher();
- }
-
- public void show(boolean animate) {
- if (mUserSwitcher != null && mUserSwitcherContainer.getVisibility() != View.VISIBLE) {
- cancelAnimations();
- mAdapter.refresh();
- mUserSwitcherContainer.setVisibility(View.VISIBLE);
- mStatusBarView.setKeyguardUserSwitcherShowing(true, animate);
- if (animate) {
- startAppearAnimation();
- }
- }
- }
-
- private boolean hide(boolean animate) {
- if (mUserSwitcher != null && mUserSwitcherContainer.getVisibility() == View.VISIBLE) {
- cancelAnimations();
- if (animate) {
- startDisappearAnimation();
- } else {
- mUserSwitcherContainer.setVisibility(View.GONE);
- }
- mStatusBarView.setKeyguardUserSwitcherShowing(false, animate);
- return true;
- }
- return false;
- }
-
- private void cancelAnimations() {
- int count = mUserSwitcher.getChildCount();
- for (int i = 0; i < count; i++) {
- mUserSwitcher.getChildAt(i).animate().cancel();
- }
- if (mBgAnimator != null) {
- mBgAnimator.cancel();
- }
- mUserSwitcher.animate().cancel();
- mAnimating = false;
- }
-
- private void startAppearAnimation() {
- int count = mUserSwitcher.getChildCount();
- View[] objects = new View[count];
- for (int i = 0; i < count; i++) {
- objects[i] = mUserSwitcher.getChildAt(i);
- }
- mUserSwitcher.setClipChildren(false);
- mUserSwitcher.setClipToPadding(false);
- mAppearAnimationUtils.startAnimation(objects, new Runnable() {
- @Override
- public void run() {
- mUserSwitcher.setClipChildren(true);
- mUserSwitcher.setClipToPadding(true);
- }
- });
- mAnimating = true;
- mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
- mBgAnimator.setDuration(400);
- mBgAnimator.setInterpolator(Interpolators.ALPHA_IN);
- mBgAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mBgAnimator = null;
- mAnimating = false;
- }
- });
- mBgAnimator.start();
- }
-
- private void startDisappearAnimation() {
- mAnimating = true;
- mUserSwitcher.animate()
- .alpha(0f)
- .setDuration(300)
- .setInterpolator(Interpolators.ALPHA_OUT)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mUserSwitcherContainer.setVisibility(View.GONE);
- mUserSwitcher.setAlpha(1f);
- mAnimating = false;
- }
- });
- }
-
- private void refresh() {
- final int childCount = mUserSwitcher.getChildCount();
- final int adapterCount = mAdapter.getCount();
- final int N = Math.max(childCount, adapterCount);
- for (int i = 0; i < N; i++) {
- if (i < adapterCount) {
- View oldView = null;
- if (i < childCount) {
- oldView = mUserSwitcher.getChildAt(i);
- }
- View newView = mAdapter.getView(i, oldView, mUserSwitcher);
- if (oldView == null) {
- // We ran out of existing views. Add it at the end.
- mUserSwitcher.addView(newView);
- } else if (oldView != newView) {
- // We couldn't rebind the view. Replace it.
- mUserSwitcher.removeViewAt(i);
- mUserSwitcher.addView(newView, i);
- }
- } else {
- int lastIndex = mUserSwitcher.getChildCount() - 1;
- mUserSwitcher.removeViewAt(lastIndex);
- }
- }
- }
-
- public boolean hideIfNotSimple(boolean animate) {
- if (mUserSwitcherContainer != null && !mUserSwitcherController.isSimpleUserSwitcher()) {
- return hide(animate);
- }
- return false;
- }
-
- boolean isAnimating() {
- return mAnimating;
- }
-
- public final DataSetObserver mDataSetObserver = new DataSetObserver() {
- @Override
- public void onChanged() {
- refresh();
- }
- };
-
- public void onDensityOrFontScaleChanged() {
- if (mUserSwitcherContainer != null) {
- reinflateViews();
- refresh();
- }
- }
-
- static class KeyguardUserAdapter extends
- UserSwitcherController.BaseUserAdapter implements View.OnClickListener {
-
- private Context mContext;
- private KeyguardUserSwitcher mKeyguardUserSwitcher;
- private View mCurrentUserView;
- // List of users where the first entry is always the current user
- private ArrayList<UserSwitcherController.UserRecord> mUsersOrdered = new ArrayList<>();
-
- KeyguardUserAdapter(Context context, UserSwitcherController controller,
- KeyguardUserSwitcher kgu) {
- super(controller);
- mContext = context;
- mKeyguardUserSwitcher = kgu;
- }
-
- @Override
- public void notifyDataSetChanged() {
- refreshUserOrder();
- super.notifyDataSetChanged();
- }
-
- void refreshUserOrder() {
- ArrayList<UserSwitcherController.UserRecord> users = super.getUsers();
- mUsersOrdered = new ArrayList<>(users.size());
- for (int i = 0; i < users.size(); i++) {
- UserSwitcherController.UserRecord record = users.get(i);
- if (record.isCurrent) {
- mUsersOrdered.add(0, record);
- } else {
- mUsersOrdered.add(record);
- }
- }
- }
-
- @Override
- protected ArrayList<UserSwitcherController.UserRecord> getUsers() {
- return mUsersOrdered;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- UserSwitcherController.UserRecord item = getItem(position);
- return createUserDetailItemView(convertView, parent, item);
- }
-
- KeyguardUserDetailItemView convertOrInflate(View convertView, ViewGroup parent) {
- if (!(convertView instanceof KeyguardUserDetailItemView)
- || !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) {
- convertView = LayoutInflater.from(mContext).inflate(
- R.layout.keyguard_user_switcher_item, parent, false);
- }
- return (KeyguardUserDetailItemView) convertView;
- }
-
- UserDetailItemView createUserDetailItemView(View convertView, ViewGroup parent,
- UserSwitcherController.UserRecord item) {
- KeyguardUserDetailItemView v = convertOrInflate(convertView, parent);
- if (!item.isCurrent || item.isGuest) {
- v.setOnClickListener(this);
- } else {
- v.setOnClickListener(null);
- v.setClickable(false);
- }
-
- String name = getName(mContext, item);
- if (item.picture == null) {
- v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
- } else {
- int avatarSize =
- (int) mContext.getResources().getDimension(R.dimen.kg_framed_avatar_size);
- Drawable drawable = new CircleFramedDrawable(item.picture, avatarSize);
- drawable.setColorFilter(
- item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
- v.bind(name, drawable, item.info.id);
- }
- v.setActivated(item.isCurrent);
- v.setDisabledByAdmin(item.isDisabledByAdmin);
- v.setEnabled(item.isSwitchToEnabled);
- v.setAlpha(v.isEnabled() ? USER_SWITCH_ENABLED_ALPHA : USER_SWITCH_DISABLED_ALPHA);
-
- if (item.isCurrent) {
- mCurrentUserView = v;
- }
- v.setTag(item);
- return v;
- }
-
- private static Drawable getDrawable(Context context,
- UserSwitcherController.UserRecord item) {
- Drawable drawable = getIconDrawable(context, item);
- int iconColorRes;
- if (item.isCurrent) {
- iconColorRes = R.color.kg_user_switcher_selected_avatar_icon_color;
- } else if (!item.isSwitchToEnabled) {
- iconColorRes = R.color.GM2_grey_600;
- } else {
- iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
- }
- drawable.setTint(context.getResources().getColor(iconColorRes, context.getTheme()));
-
- if (item.isCurrent) {
- Drawable bg = context.getDrawable(R.drawable.bg_avatar_selected);
- drawable = new LayerDrawable(new Drawable[]{bg, drawable});
- }
-
- return drawable;
- }
-
- @Override
- public void onClick(View v) {
- UserSwitcherController.UserRecord user = (UserSwitcherController.UserRecord) v.getTag();
- if (user.isCurrent && !user.isGuest) {
- // Close the switcher if tapping the current user. Guest is excluded because
- // tapping the guest user while it's current clears the session.
- mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
- } else if (user.isSwitchToEnabled) {
- if (!user.isAddUser && !user.isRestricted && !user.isDisabledByAdmin) {
- if (mCurrentUserView != null) {
- mCurrentUserView.setActivated(false);
- }
- v.setActivated(true);
- }
- onUserListItemClicked(user);
- }
- }
- }
-
- public static class Container extends FrameLayout {
-
- private KeyguardUserSwitcher mKeyguardUserSwitcher;
-
- public Container(Context context, AttributeSet attrs) {
- super(context, attrs);
- setClipChildren(false);
- }
-
- public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
- mKeyguardUserSwitcher = keyguardUserSwitcher;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- // Hide switcher if it didn't handle the touch event (and let the event go through).
- if (mKeyguardUserSwitcher != null && !mKeyguardUserSwitcher.isAnimating()) {
- mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
- }
- return false;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
new file mode 100644
index 000000000000..b76e451cb681
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -0,0 +1,639 @@
+/*
+ * 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 static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA;
+import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA;
+
+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.UserHandle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.keyguard.KeyguardConstants;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.keyguard.KeyguardVisibilityHelper;
+import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
+import com.android.settingslib.drawable.CircleFramedDrawable;
+import com.android.systemui.Interpolators;
+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.util.ViewController;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+import javax.inject.Inject;
+
+/**
+ * Manages the user switcher on the Keyguard.
+ */
+@KeyguardUserSwitcherScope
+public class KeyguardUserSwitcherController extends ViewController<KeyguardUserSwitcherView> {
+
+ private static final String TAG = "KeyguardUserSwitcherController";
+ 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 final UserSwitcherController mUserSwitcherController;
+ private final ScreenLifecycle mScreenLifecycle;
+ private final KeyguardUserAdapter mAdapter;
+ private final KeyguardStateController mKeyguardStateController;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private WeakReference<KeyguardUserSwitcherListener> mKeyguardUserSwitcherCallback;
+ protected final SysuiStatusBarStateController mStatusBarStateController;
+ private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
+
+ // Child views of KeyguardUserSwitcherView
+ private KeyguardUserSwitcherListView mListView;
+ private LinearLayout mEndGuestButton;
+
+ // State info for the user switcher
+ private boolean mUserSwitcherOpen;
+ private int mCurrentUserId = UserHandle.USER_NULL;
+ private boolean mCurrentUserIsGuest;
+ private int mBarState;
+ private float mDarkAmount;
+
+ private final KeyguardUpdateMonitorCallback mInfoCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ if (DEBUG) Log.d(TAG, String.format("onKeyguardVisibilityChanged %b", showing));
+ // Any time the keyguard is hidden, try to close the user switcher menu to
+ // restore keyguard to the default state
+ if (!showing) {
+ closeSwitcherIfOpenAndNotSimple(false);
+ }
+ }
+
+ @Override
+ public void onUserSwitching(int userId) {
+ closeSwitcherIfOpenAndNotSimple(false);
+ }
+ };
+
+ private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+ @Override
+ public void onScreenTurnedOff() {
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOff");
+ closeSwitcherIfOpenAndNotSimple(false);
+ }
+ };
+
+ 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;
+
+ if (mStatusBarStateController.goingToFullShade()
+ || mKeyguardStateController.isKeyguardFadingAway()) {
+ closeSwitcherIfOpenAndNotSimple(true);
+ }
+
+ setKeyguardUserSwitcherVisibility(
+ 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 KeyguardUserSwitcherController(
+ KeyguardUserSwitcherView keyguardUserSwitcherView,
+ Context context,
+ @Main Resources resources,
+ LayoutInflater layoutInflater,
+ ScreenLifecycle screenLifecycle,
+ UserSwitcherController userSwitcherController,
+ KeyguardStateController keyguardStateController,
+ SysuiStatusBarStateController statusBarStateController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ DozeParameters dozeParameters) {
+ super(keyguardUserSwitcherView);
+ if (DEBUG) Log.d(TAG, "New KeyguardUserSwitcherController");
+ mContext = context;
+ mScreenLifecycle = screenLifecycle;
+ mUserSwitcherController = userSwitcherController;
+ mKeyguardStateController = keyguardStateController;
+ mStatusBarStateController = statusBarStateController;
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mAdapter = new KeyguardUserAdapter(mContext, resources, layoutInflater,
+ mUserSwitcherController, this);
+ mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
+ keyguardStateController, dozeParameters);
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ if (DEBUG) Log.d(TAG, "onInit");
+
+ mListView = mView.findViewById(R.id.keyguard_user_switcher_list);
+ mEndGuestButton = mView.findViewById(R.id.end_guest_button);
+
+ mEndGuestButton.setOnClickListener(v -> {
+ mUserSwitcherController.showExitGuestDialog(mCurrentUserId);
+ });
+
+ mView.setOnTouchListener((v, event) -> {
+ if (!isListAnimating()) {
+ // Hide switcher if it didn't handle the touch event (and block the event from
+ // going through).
+ return closeSwitcherIfOpenAndNotSimple(true);
+ }
+ return false;
+ });
+ }
+
+ @Override
+ protected void onViewAttached() {
+ if (DEBUG) Log.d(TAG, "onViewAttached");
+ mAdapter.registerDataSetObserver(mDataSetObserver);
+ mDataSetObserver.onChanged();
+ mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
+ mStatusBarStateController.addCallback(mStatusBarStateListener);
+ mScreenLifecycle.addObserver(mScreenObserver);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ if (DEBUG) Log.d(TAG, "onViewDetached");
+
+ // Detaching the view will always close the switcher
+ closeSwitcherIfOpenAndNotSimple(false);
+
+ mAdapter.unregisterDataSetObserver(mDataSetObserver);
+ mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
+ mStatusBarStateController.removeCallback(mStatusBarStateListener);
+ mScreenLifecycle.removeObserver(mScreenObserver);
+ }
+
+ /**
+ * See:
+ *
+ * <ul>
+ * <li>{@link com.android.internal.R.bool.config_expandLockScreenUserSwitcher}</li>
+ * <li>{@link UserSwitcherController.SIMPLE_USER_SWITCHER_GLOBAL_SETTING}</li>
+ * </ul>
+ *
+ * @return true if the user switcher should be open by default on the lock screen.
+ * @see android.os.UserManager#isUserSwitcherEnabled()
+ */
+ public boolean isSimpleUserSwitcher() {
+ return mUserSwitcherController.isSimpleUserSwitcher();
+ }
+
+ /**
+ * @param animate if the transition should be animated
+ * @return true if the switcher state changed
+ */
+ public boolean closeSwitcherIfOpenAndNotSimple(boolean animate) {
+ if (isUserSwitcherOpen() && !isSimpleUserSwitcher()) {
+ setUserSwitcherOpened(false /* open */, animate);
+ return true;
+ }
+ return false;
+ }
+
+ public final DataSetObserver mDataSetObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ refreshUserList();
+ }
+ };
+
+ void refreshUserList() {
+ final int childCount = mListView.getChildCount();
+ final int adapterCount = mAdapter.getCount();
+ final int count = Math.max(childCount, adapterCount);
+
+ if (DEBUG) {
+ Log.d(TAG, String.format("refreshUserList childCount=%d adapterCount=%d", childCount,
+ adapterCount));
+ }
+
+ boolean foundCurrentUser = false;
+ for (int i = 0; i < count; i++) {
+ if (i < adapterCount) {
+ View oldView = null;
+ if (i < childCount) {
+ oldView = mListView.getChildAt(i);
+ }
+ KeyguardUserDetailItemView newView = (KeyguardUserDetailItemView)
+ mAdapter.getView(i, oldView, mListView);
+ UserSwitcherController.UserRecord userTag =
+ (UserSwitcherController.UserRecord) newView.getTag();
+ if (userTag.isCurrent) {
+ if (i != 0) {
+ Log.w(TAG, "Current user is not the first view in the list");
+ }
+ foundCurrentUser = true;
+ mCurrentUserId = userTag.info.id;
+ mCurrentUserIsGuest = userTag.isGuest;
+ // Current user is always visible
+ newView.updateVisibilities(true /* showItem */,
+ mUserSwitcherOpen /* showTextName */, false /* animate */);
+ } else {
+ // Views for non-current users are always expanded (e.g. they should the name
+ // next to the user icon). However, they could be hidden entirely if the list
+ // is closed.
+ newView.updateVisibilities(mUserSwitcherOpen /* showItem */,
+ true /* showTextName */, false /* animate */);
+ }
+ newView.setDarkAmount(mDarkAmount);
+ if (oldView == null) {
+ // We ran out of existing views. Add it at the end.
+ mListView.addView(newView);
+ } else if (oldView != newView) {
+ // We couldn't rebind the view. Replace it.
+ mListView.replaceView(newView, i);
+ }
+ } else {
+ mListView.removeLastView();
+ }
+ }
+ if (!foundCurrentUser) {
+ Log.w(TAG, "Current user is not listed");
+ mCurrentUserId = UserHandle.USER_NULL;
+ mCurrentUserIsGuest = false;
+ }
+ }
+
+ /**
+ * Get the height of the keyguard user switcher view when closed.
+ */
+ public int getUserIconHeight() {
+ View firstChild = mListView.getChildAt(0);
+ return firstChild == null ? 0 : firstChild.getHeight();
+ }
+
+ /**
+ * Set the visibility of the keyguard user switcher view based on some new state.
+ */
+ public void setKeyguardUserSwitcherVisibility(
+ 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(mListView, AnimatableProperty.Y, y, ANIMATION_PROPERTIES,
+ animate);
+ PropertyAnimator.setProperty(mListView, AnimatableProperty.TRANSLATION_X, -Math.abs(x),
+ ANIMATION_PROPERTIES, animate);
+ }
+
+ /**
+ * Set keyguard user switcher 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;
+ mListView.setDarkAmount(darkAmount);
+ mView.setVisibility(isAwake ? View.VISIBLE : View.GONE);
+ if (!isAwake) {
+ closeSwitcherIfOpenAndNotSimple(false);
+ }
+ }
+
+ private boolean isListAnimating() {
+ return mKeyguardVisibilityHelper.isVisibilityAnimating() || mListView.isAnimating();
+ }
+
+ /**
+ * Remove the callback if it exists.
+ */
+ public void removeCallback() {
+ if (DEBUG) Log.d(TAG, "removeCallback");
+ mKeyguardUserSwitcherCallback = null;
+ }
+
+ /**
+ * Register to receive notifications about keyguard user switcher state
+ * (see {@link KeyguardUserSwitcherListener}.
+ *
+ * Only one callback can be used at a time.
+ *
+ * @param callback The callback to register
+ */
+ public void setCallback(KeyguardUserSwitcherListener callback) {
+ if (DEBUG) Log.d(TAG, "setCallback");
+ mKeyguardUserSwitcherCallback = new WeakReference<>(callback);
+ }
+
+ /**
+ * If user switcher state changes, notifies all {@link KeyguardUserSwitcherListener}.
+ * Switcher state is updatd before animations finish.
+ *
+ * @param animate true to animate transition. The user switcher state (i.e.
+ * {@link #isUserSwitcherOpen()}) is updated before animation is finished.
+ */
+ private void setUserSwitcherOpened(boolean open, boolean animate) {
+ boolean wasOpen = mUserSwitcherOpen;
+ if (DEBUG) {
+ Log.d(TAG, String.format("setUserSwitcherOpened: %b -> %b (animate=%b)", wasOpen,
+ open, animate));
+ }
+ mUserSwitcherOpen = open;
+ if (mUserSwitcherOpen != wasOpen) {
+ notifyUserSwitcherStateChanged();
+ }
+ updateVisibilities(animate);
+ }
+
+ private void updateVisibilities(boolean animate) {
+ if (DEBUG) Log.d(TAG, String.format("updateVisibilities: animate=%b", animate));
+ mEndGuestButton.animate().cancel();
+ if (mUserSwitcherOpen && mCurrentUserIsGuest) {
+ // Show the "End guest session" button
+ mEndGuestButton.setVisibility(View.VISIBLE);
+ if (animate) {
+ mEndGuestButton.setAlpha(0f);
+ mEndGuestButton.animate()
+ .alpha(1f)
+ .setDuration(360)
+ .setInterpolator(Interpolators.ALPHA_IN)
+ .withEndAction(() -> {
+ mEndGuestButton.setClickable(true);
+ });
+ } else {
+ mEndGuestButton.setClickable(true);
+ mEndGuestButton.setAlpha(1f);
+ }
+ } else {
+ // Hide the "End guest session" button. If it's already GONE, don't try to
+ // animate it or it will appear again for an instant.
+ mEndGuestButton.setClickable(false);
+ if (animate && mEndGuestButton.getVisibility() != View.GONE) {
+ mEndGuestButton.setVisibility(View.VISIBLE);
+ mEndGuestButton.setAlpha(1f);
+ mEndGuestButton.animate()
+ .alpha(0f)
+ .setDuration(360)
+ .setInterpolator(Interpolators.ALPHA_OUT)
+ .withEndAction(() -> {
+ mEndGuestButton.setVisibility(View.GONE);
+ mEndGuestButton.setAlpha(1f);
+ });
+ } else {
+ mEndGuestButton.setVisibility(View.GONE);
+ mEndGuestButton.setAlpha(1f);
+ }
+ }
+
+ mListView.updateVisibilities(mUserSwitcherOpen, animate);
+ }
+
+ private boolean isUserSwitcherOpen() {
+ return mUserSwitcherOpen;
+ }
+
+ private void notifyUserSwitcherStateChanged() {
+ if (DEBUG) {
+ Log.d(TAG, String.format("notifyUserSwitcherStateChanged: mUserSwitcherOpen=%b",
+ mUserSwitcherOpen));
+ }
+ if (mKeyguardUserSwitcherCallback != null) {
+ KeyguardUserSwitcherListener cb = mKeyguardUserSwitcherCallback.get();
+ if (cb != null) {
+ cb.onKeyguardUserSwitcherChanged(mUserSwitcherOpen);
+ }
+ }
+ }
+
+ /**
+ * Callback for keyguard user switcher state information
+ */
+ public interface KeyguardUserSwitcherListener {
+
+ /**
+ * Called when the keyguard enters or leaves user switcher mode. This will be called
+ * before the animations are finished.
+ *
+ * @param open if true, keyguard is showing the user switcher or transitioning from/to user
+ * switcher mode.
+ */
+ void onKeyguardUserSwitcherChanged(boolean open);
+ }
+
+ static class KeyguardUserAdapter extends
+ UserSwitcherController.BaseUserAdapter implements View.OnClickListener {
+
+ private final Context mContext;
+ private final Resources mResources;
+ private final LayoutInflater mLayoutInflater;
+ private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
+ private View mCurrentUserView;
+ // List of users where the first entry is always the current user
+ private ArrayList<UserSwitcherController.UserRecord> mUsersOrdered = new ArrayList<>();
+
+ KeyguardUserAdapter(Context context, Resources resources, LayoutInflater layoutInflater,
+ UserSwitcherController controller,
+ KeyguardUserSwitcherController keyguardUserSwitcherController) {
+ super(controller);
+ mContext = context;
+ mResources = resources;
+ mLayoutInflater = layoutInflater;
+ mKeyguardUserSwitcherController = keyguardUserSwitcherController;
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ // At this point, value of isSimpleUserSwitcher() may have changed in addition to the
+ // data set
+ refreshUserOrder();
+ super.notifyDataSetChanged();
+ }
+
+ void refreshUserOrder() {
+ ArrayList<UserSwitcherController.UserRecord> users = super.getUsers();
+ mUsersOrdered = new ArrayList<>(users.size());
+ for (int i = 0; i < users.size(); i++) {
+ UserSwitcherController.UserRecord record = users.get(i);
+ if (record.isCurrent) {
+ mUsersOrdered.add(0, record);
+ } else {
+ mUsersOrdered.add(record);
+ }
+ }
+ }
+
+ @Override
+ protected ArrayList<UserSwitcherController.UserRecord> getUsers() {
+ return mUsersOrdered;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ UserSwitcherController.UserRecord item = getItem(position);
+ return createUserDetailItemView(convertView, parent, item);
+ }
+
+ @Override
+ public String getName(Context context, UserSwitcherController.UserRecord item) {
+ if (item.isGuest) {
+ return context.getString(com.android.settingslib.R.string.guest_nickname);
+ } else {
+ return super.getName(context, item);
+ }
+ }
+
+ KeyguardUserDetailItemView convertOrInflate(View convertView, ViewGroup parent) {
+ if (!(convertView instanceof KeyguardUserDetailItemView)
+ || !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) {
+ convertView = mLayoutInflater.inflate(
+ R.layout.keyguard_user_switcher_item, parent, false);
+ }
+ return (KeyguardUserDetailItemView) convertView;
+ }
+
+ KeyguardUserDetailItemView createUserDetailItemView(View convertView, ViewGroup parent,
+ UserSwitcherController.UserRecord item) {
+ KeyguardUserDetailItemView v = convertOrInflate(convertView, parent);
+ v.setOnClickListener(this);
+
+ String name = getName(mContext, item);
+ if (item.picture == null) {
+ v.bind(name, getDrawable(item).mutate(), item.resolveId());
+ } else {
+ int avatarSize =
+ (int) mResources.getDimension(R.dimen.kg_framed_avatar_size);
+ Drawable drawable = new CircleFramedDrawable(item.picture, avatarSize);
+ drawable.setColorFilter(
+ item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
+ v.bind(name, drawable, item.info.id);
+ }
+ v.setActivated(item.isCurrent);
+ v.setDisabledByAdmin(item.isDisabledByAdmin);
+ v.setEnabled(item.isSwitchToEnabled);
+ v.setAlpha(v.isEnabled() ? USER_SWITCH_ENABLED_ALPHA : USER_SWITCH_DISABLED_ALPHA);
+
+ if (item.isCurrent) {
+ mCurrentUserView = v;
+ }
+ v.setTag(item);
+ return v;
+ }
+
+ private Drawable getDrawable(UserSwitcherController.UserRecord item) {
+ Drawable drawable;
+ if (item.isCurrent && item.isGuest) {
+ drawable = mContext.getDrawable(R.drawable.ic_avatar_guest_user);
+ } else {
+ drawable = 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;
+ }
+
+ @Override
+ public void onClick(View v) {
+ UserSwitcherController.UserRecord user = (UserSwitcherController.UserRecord) v.getTag();
+
+ if (mKeyguardUserSwitcherController.isListAnimating()) {
+ return;
+ }
+
+ if (mKeyguardUserSwitcherController.isUserSwitcherOpen()) {
+ if (user.isCurrent) {
+ // Close the switcher if tapping the current user
+ mKeyguardUserSwitcherController.setUserSwitcherOpened(
+ false /* open */, true /* animate */);
+ } else if (user.isSwitchToEnabled) {
+ if (!user.isAddUser && !user.isRestricted && !user.isDisabledByAdmin) {
+ if (mCurrentUserView != null) {
+ mCurrentUserView.setActivated(false);
+ }
+ v.setActivated(true);
+ }
+ onUserListItemClicked(user);
+ }
+ } else {
+ // If switcher is closed, tapping anywhere in the view will open it
+ mKeyguardUserSwitcherController.setUserSwitcherOpened(
+ true /* open */, true /* animate */);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java
new file mode 100644
index 000000000000..7c82c116eb3d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java
@@ -0,0 +1,168 @@
+/*
+ * 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.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+import com.android.keyguard.AlphaOptimizedLinearLayout;
+import com.android.keyguard.KeyguardConstants;
+import com.android.settingslib.animation.AppearAnimationUtils;
+import com.android.settingslib.animation.DisappearAnimationUtils;
+import com.android.systemui.Interpolators;
+
+/**
+ * The container for the user switcher on Keyguard.
+ */
+public class KeyguardUserSwitcherListView extends AlphaOptimizedLinearLayout {
+
+ private static final String TAG = "KeyguardUserSwitcherListView";
+ private static final boolean DEBUG = KeyguardConstants.DEBUG;
+
+ private static final int ANIMATION_DURATION_OPENING = 360;
+ private static final int ANIMATION_DURATION_CLOSING = 240;
+
+ private boolean mAnimating;
+ private final AppearAnimationUtils mAppearAnimationUtils;
+ private final DisappearAnimationUtils mDisappearAnimationUtils;
+
+ public KeyguardUserSwitcherListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setClipChildren(false);
+ mAppearAnimationUtils = new AppearAnimationUtils(context, ANIMATION_DURATION_OPENING,
+ -0.5f, 0.5f, Interpolators.FAST_OUT_SLOW_IN);
+ mDisappearAnimationUtils = new DisappearAnimationUtils(context, ANIMATION_DURATION_CLOSING,
+ 0.5f, 0.5f, Interpolators.FAST_OUT_LINEAR_IN);
+ }
+
+ /**
+ * 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.
+ */
+ void setDarkAmount(float darkAmount) {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View v = getChildAt(i);
+ if (v instanceof KeyguardUserDetailItemView) {
+ ((KeyguardUserDetailItemView) v).setDarkAmount(darkAmount);
+ }
+ }
+ }
+
+ boolean isAnimating() {
+ return mAnimating;
+ }
+
+ /**
+ * Update visibilities of this view and child views for when the user list is open or closed.
+ * If closed, this hides everything but the first item (which is always the current user).
+ */
+ void updateVisibilities(boolean open, boolean animate) {
+ if (DEBUG) {
+ Log.d(TAG, String.format("updateVisibilities: open=%b animate=%b childCount=%d",
+ open, animate, getChildCount()));
+ }
+
+ mAnimating = false;
+
+ int userListCount = getChildCount();
+ if (userListCount > 0) {
+ // The first child is always the current user.
+ KeyguardUserDetailItemView currentUserView = ((KeyguardUserDetailItemView) getChildAt(
+ 0));
+ currentUserView.updateVisibilities(true /* showItem */, open /* showTextName */,
+ animate);
+ currentUserView.setClickable(true);
+ currentUserView.clearAnimation();
+ }
+
+ if (userListCount <= 1) {
+ return;
+ }
+
+ if (animate) {
+ // Create an array of all the remaining users (that aren't the current user).
+ KeyguardUserDetailItemView[] otherUserViews =
+ new KeyguardUserDetailItemView[userListCount - 1];
+ for (int i = 1, n = 0; i < userListCount; i++, n++) {
+ otherUserViews[n] = (KeyguardUserDetailItemView) getChildAt(i);
+
+ // Update clickable state immediately so that the menu feels more responsive
+ otherUserViews[n].setClickable(open);
+
+ // Before running the animation, ensure visibility is set correctly
+ otherUserViews[n].updateVisibilities(
+ true /* showItem */, true /* showTextName */, false /* animate */);
+ otherUserViews[n].clearAnimation();
+ }
+
+ setClipChildren(false);
+ setClipToPadding(false);
+
+ mAnimating = true;
+
+ final int nonCurrentUserCount = otherUserViews.length;
+ if (open) {
+ mAppearAnimationUtils.startAnimation(otherUserViews, () -> {
+ setClipChildren(true);
+ setClipToPadding(true);
+ mAnimating = false;
+ });
+ } else {
+ mDisappearAnimationUtils.startAnimation(otherUserViews, () -> {
+ setClipChildren(true);
+ setClipToPadding(true);
+ for (int i = 0; i < nonCurrentUserCount; i++) {
+ otherUserViews[i].updateVisibilities(
+ false /* showItem */, true /* showTextName */, false /* animate */);
+ }
+ mAnimating = false;
+ });
+ }
+ } else {
+ for (int i = 1; i < userListCount; i++) {
+ KeyguardUserDetailItemView nonCurrentUserView =
+ ((KeyguardUserDetailItemView) getChildAt(i));
+ nonCurrentUserView.clearAnimation();
+ nonCurrentUserView.updateVisibilities(
+ open /* showItem */, true /* showTextName */, false /* animate */);
+ nonCurrentUserView.setClickable(open);
+ }
+ }
+ }
+
+ /**
+ * Replaces the view at the specified position in the group.
+ *
+ * @param index the position in the group of the view to remove
+ */
+ void replaceView(KeyguardUserDetailItemView newView, int index) {
+ removeViewAt(index);
+ addView(newView, index);
+ }
+
+ /**
+ * Removes the last view in the group.
+ */
+ void removeLastView() {
+ int lastIndex = getChildCount() - 1;
+ removeViewAt(lastIndex);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherView.java
new file mode 100644
index 000000000000..3f0e23f7c72e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherView.java
@@ -0,0 +1,31 @@
+/*
+ * 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.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * The container for the user switcher on Keyguard.
+ */
+public class KeyguardUserSwitcherView extends FrameLayout {
+
+ public KeyguardUserSwitcherView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 68d74ef760b4..1838391ce2ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -423,7 +423,7 @@ public class UserSwitcherController implements Dumpable {
}
}
- private void showExitGuestDialog(int id) {
+ protected void showExitGuestDialog(int id) {
int newId = UserHandle.USER_SYSTEM;
if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index ee1d758e7ae2..4162884680a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -393,10 +393,11 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
private void positionClock() {
mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
- mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mPreferredClockY,
- mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
- 0 /* unlockedStackScrollerPadding */, false /* udfpsEnrolled */,
- mQsExpansion, mCutoutTopInset);
+ mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight,
+ 0 /* keyguardUserSwitcherHeight */, mPreferredClockY, mHasCustomClock,
+ mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
+ 0 /* unlockedStackScrollerPadding */, false /* udfpsEnrolled */, mQsExpansion,
+ mCutoutTopInset);
mClockPositionAlgorithm.run(mClockPosition);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index c07ba723ab43..d0e70310810e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -37,6 +37,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricSourceType;
import android.os.PowerManager;
+import android.os.UserManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.DisplayMetrics;
@@ -58,6 +59,7 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
+import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
@@ -68,7 +70,6 @@ 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;
@@ -193,6 +194,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
@Mock
+ private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponent;
+ @Mock
private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
@Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
@@ -216,6 +219,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private NotificationsQuickSettingsContainer mNotificationContainerParent;
@Mock
private AmbientState mAmbientState;
+ @Mock
+ private UserManager mUserManager;
+
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
@@ -299,11 +305,12 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mBiometricUnlockController, mStatusBarKeyguardViewManager,
mNotificationStackScrollLayoutController,
mKeyguardStatusViewComponentFactory,
+ mKeyguardUserSwitcherComponent,
mGroupManager,
mNotificationAreaController,
mAuthController,
- new QSDetailDisplayer(),
mScrimController,
+ mUserManager,
mMediaDataManager,
mAmbientState,
mFeatureFlags,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
index fc1a79105db1..e479882ac50a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
@@ -60,9 +60,9 @@ class KeyguardUserSwitcherAdapterTest : SysuiTestCase() {
@Mock
private lateinit var layoutInflater: LayoutInflater
@Mock
- private lateinit var keyguardUserSwitcher: KeyguardUserSwitcher
+ private lateinit var keyguardUserSwitcherController: KeyguardUserSwitcherController
- private lateinit var adapter: KeyguardUserSwitcher.KeyguardUserAdapter
+ private lateinit var adapter: KeyguardUserSwitcherController.KeyguardUserAdapter
private lateinit var picture: Bitmap
@Before
@@ -72,8 +72,11 @@ class KeyguardUserSwitcherAdapterTest : SysuiTestCase() {
mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE, layoutInflater)
`when`(layoutInflater.inflate(anyInt(), any(ViewGroup::class.java), anyBoolean()))
.thenReturn(inflatedUserDetailItemView)
- adapter = KeyguardUserSwitcher.KeyguardUserAdapter(mContext, userSwitcherController,
- keyguardUserSwitcher)
+ adapter = KeyguardUserSwitcherController.KeyguardUserAdapter(
+ mContext,
+ mContext.resources,
+ LayoutInflater.from(mContext),
+ userSwitcherController, keyguardUserSwitcherController)
picture = UserIcons.convertToBitmap(mContext.getDrawable(R.drawable.ic_avatar_user))
}
@@ -118,11 +121,11 @@ class KeyguardUserSwitcherAdapterTest : SysuiTestCase() {
}
@Test
- fun shouldRemoveOnClickListener_currentUser_notGuestUser_oldViewIsSameType() {
+ fun shouldSetOnOnClickListener_currentUser_notGuestUser_oldViewIsSameType() {
val v: UserDetailItemView? = createViewFromSameType(
isCurrentUser = true, isGuestUser = false)
assertNotNull(v)
- verify(v)!!.setOnClickListener(null)
+ verify(v)!!.setOnClickListener(adapter)
}
@Test
@@ -150,11 +153,11 @@ class KeyguardUserSwitcherAdapterTest : SysuiTestCase() {
}
@Test
- fun shouldRemoveOnClickListener_currentUser_notGuestUser_oldViewIsDifferentType() {
+ fun shouldSetOnOnClickListener_currentUser_notGuestUser_oldViewIsDifferentType() {
val v: UserDetailItemView? = createViewFromDifferentType(
isCurrentUser = true, isGuestUser = false)
assertNotNull(v)
- verify(v)!!.setOnClickListener(null)
+ verify(v)!!.setOnClickListener(adapter)
}
@Test