Loading packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +6 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import com.android.systemui.settings.dagger.MultiUserUtilsModule import com.android.systemui.shortcut.ShortcutKeyDispatcher import com.android.systemui.statusbar.notification.InstantAppNotifier import com.android.systemui.statusbar.phone.KeyguardLiftController import com.android.systemui.statusbar.phone.LockscreenWallpaper import com.android.systemui.stylus.StylusUsiPowerStartable import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.theme.ThemeOverlayController Loading Loading @@ -301,4 +302,9 @@ abstract class SystemUICoreStartableModule { @IntoMap @ClassKey(KeyguardViewConfigurator::class) abstract fun bindKeyguardViewConfigurator(impl: KeyguardViewConfigurator): CoreStartable @Binds @IntoMap @ClassKey(LockscreenWallpaper::class) abstract fun bindLockscreenWallpaper(impl: LockscreenWallpaper): CoreStartable } packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +0 −3 Original line number Diff line number Diff line Loading @@ -2177,9 +2177,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { */ @Override public void setLockscreenUser(int newUserId) { if (mLockscreenWallpaper != null && !mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { mLockscreenWallpaper.setCurrentUser(newUserId); } if (mWallpaperSupported) { mWallpaperChangedReceiver.onReceive(mContext, null); } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +27 −2 Original line number Diff line number Diff line Loading @@ -40,12 +40,17 @@ import androidx.annotation.NonNull; import com.android.internal.util.IndentingPrintWriter; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.CoreStartable; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.user.data.model.SelectedUserModel; import com.android.systemui.user.data.model.SelectionStatus; import com.android.systemui.user.data.repository.UserRepository; import com.android.systemui.util.kotlin.JavaAdapter; import libcore.io.IoUtils; Loading @@ -59,7 +64,7 @@ import javax.inject.Inject; */ @SysUISingleton public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implements Runnable, Dumpable { Dumpable, CoreStartable { private static final String TAG = "LockscreenWallpaper"; Loading @@ -72,6 +77,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen private final WallpaperManager mWallpaperManager; private final KeyguardUpdateMonitor mUpdateMonitor; private final Handler mH; private final JavaAdapter mJavaAdapter; private final UserRepository mUserRepository; private boolean mCached; private Bitmap mCache; Loading @@ -88,6 +95,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen DumpManager dumpManager, NotificationMediaManager mediaManager, @Main Handler mainHandler, JavaAdapter javaAdapter, UserRepository userRepository, UserTracker userTracker) { dumpManager.registerDumpable(getClass().getSimpleName(), this); mWallpaperManager = wallpaperManager; Loading @@ -95,6 +104,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen mUpdateMonitor = keyguardUpdateMonitor; mMediaManager = mediaManager; mH = mainHandler; mJavaAdapter = javaAdapter; mUserRepository = userRepository; if (iWallpaperManager != null && !mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { // Service is disabled on some devices like Automotive Loading @@ -106,6 +117,14 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } } @Override public void start() { if (!isLockscreenLiveWallpaperEnabled()) { mJavaAdapter.alwaysCollectFlow( mUserRepository.getSelectedUser(), this::setSelectedUser); } } public Bitmap getBitmap() { assertLockscreenLiveWallpaperNotEnabled(); Loading Loading @@ -169,9 +188,15 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } } public void setCurrentUser(int user) { private void setSelectedUser(SelectedUserModel selectedUserModel) { assertLockscreenLiveWallpaperNotEnabled(); if (selectedUserModel.getSelectionStatus().equals(SelectionStatus.SELECTION_IN_PROGRESS)) { // Wait until the selection has finished before updating. return; } int user = selectedUserModel.getUserInfo().id; if (user != mCurrentUserId) { if (mSelectedUser == null || user != mSelectedUser.getIdentifier()) { mCached = false; Loading packages/SystemUI/src/com/android/systemui/user/data/model/SelectedUserModel.kt 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.user.data.model import android.content.pm.UserInfo /** A model for the currently selected user. */ data class SelectedUserModel( /** Information about the user. */ val userInfo: UserInfo, /** The current status of the selection. */ val selectionStatus: SelectionStatus, ) /** The current status of the selection. */ enum class SelectionStatus { /** This user has started being selected but the selection hasn't completed. */ SELECTION_IN_PROGRESS, /** The selection of this user has completed. */ SELECTION_COMPLETE, } packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt +52 −37 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.settings.UserTracker import com.android.systemui.user.data.model.SelectedUserModel import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.model.UserSwitcherSettingsModel import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.SettingsProxyExt.observerFlow Loading Loading @@ -69,6 +71,9 @@ interface UserRepository { /** List of all users on the device. */ val userInfos: Flow<List<UserInfo>> /** Information about the currently-selected user, including [UserInfo] and other details. */ val selectedUser: StateFlow<SelectedUserModel> /** [UserInfo] of the currently-selected user. */ val selectedUserInfo: Flow<UserInfo> Loading Loading @@ -146,9 +151,6 @@ constructor( private val _userInfos = MutableStateFlow<List<UserInfo>?>(null) override val userInfos: Flow<List<UserInfo>> = _userInfos.filterNotNull() private val _selectedUserInfo = MutableStateFlow<UserInfo?>(null) override val selectedUserInfo: Flow<UserInfo> = _selectedUserInfo.filterNotNull() override var mainUserId: Int = UserHandle.USER_NULL private set override var lastSelectedNonGuestUserId: Int = UserHandle.USER_NULL Loading @@ -174,12 +176,57 @@ constructor( override var isRefreshUsersPaused: Boolean = false init { observeSelectedUser() if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) { observeUserSwitching() } } override val selectedUser: StateFlow<SelectedUserModel> = run { // Some callbacks don't modify the selection status, so maintain the current value. var currentSelectionStatus = SelectionStatus.SELECTION_COMPLETE conflatedCallbackFlow { fun send(selectionStatus: SelectionStatus) { currentSelectionStatus = selectionStatus trySendWithFailureLogging( SelectedUserModel(tracker.userInfo, selectionStatus), TAG, ) } val callback = object : UserTracker.Callback { override fun onUserChanging(newUser: Int, userContext: Context) { send(SelectionStatus.SELECTION_IN_PROGRESS) } override fun onUserChanged(newUser: Int, userContext: Context) { send(SelectionStatus.SELECTION_COMPLETE) } override fun onProfilesChanged(profiles: List<UserInfo>) { send(currentSelectionStatus) } } tracker.addCallback(callback, mainDispatcher.asExecutor()) send(currentSelectionStatus) awaitClose { tracker.removeCallback(callback) } } .onEach { if (!it.userInfo.isGuest) { lastSelectedNonGuestUserId = it.userInfo.id } } .stateIn( applicationScope, SharingStarted.Eagerly, initialValue = SelectedUserModel(tracker.userInfo, currentSelectionStatus) ) } override val selectedUserInfo: Flow<UserInfo> = selectedUser.map { it.userInfo } override fun refreshUsers() { applicationScope.launch { val result = withContext(backgroundDispatcher) { manager.aliveUsers } Loading @@ -201,7 +248,7 @@ constructor( } override fun getSelectedUserInfo(): UserInfo { return checkNotNull(_selectedUserInfo.value) return selectedUser.value.userInfo } override fun isSimpleUserSwitcher(): Boolean { Loading Loading @@ -234,38 +281,6 @@ constructor( .launchIn(applicationScope) } private fun observeSelectedUser() { conflatedCallbackFlow { fun send() { trySendWithFailureLogging(tracker.userInfo, TAG) } val callback = object : UserTracker.Callback { override fun onUserChanging(newUser: Int, userContext: Context) { send() } override fun onProfilesChanged(profiles: List<UserInfo>) { send() } } tracker.addCallback(callback, mainDispatcher.asExecutor()) send() awaitClose { tracker.removeCallback(callback) } } .onEach { if (!it.isGuest) { lastSelectedNonGuestUserId = it.id } _selectedUserInfo.value = it } .launchIn(applicationScope) } private suspend fun getSettings(): UserSwitcherSettingsModel { return withContext(backgroundDispatcher) { val isSimpleUserSwitcher = Loading Loading
packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +6 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import com.android.systemui.settings.dagger.MultiUserUtilsModule import com.android.systemui.shortcut.ShortcutKeyDispatcher import com.android.systemui.statusbar.notification.InstantAppNotifier import com.android.systemui.statusbar.phone.KeyguardLiftController import com.android.systemui.statusbar.phone.LockscreenWallpaper import com.android.systemui.stylus.StylusUsiPowerStartable import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.theme.ThemeOverlayController Loading Loading @@ -301,4 +302,9 @@ abstract class SystemUICoreStartableModule { @IntoMap @ClassKey(KeyguardViewConfigurator::class) abstract fun bindKeyguardViewConfigurator(impl: KeyguardViewConfigurator): CoreStartable @Binds @IntoMap @ClassKey(LockscreenWallpaper::class) abstract fun bindLockscreenWallpaper(impl: LockscreenWallpaper): CoreStartable }
packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +0 −3 Original line number Diff line number Diff line Loading @@ -2177,9 +2177,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { */ @Override public void setLockscreenUser(int newUserId) { if (mLockscreenWallpaper != null && !mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { mLockscreenWallpaper.setCurrentUser(newUserId); } if (mWallpaperSupported) { mWallpaperChangedReceiver.onReceive(mContext, null); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +27 −2 Original line number Diff line number Diff line Loading @@ -40,12 +40,17 @@ import androidx.annotation.NonNull; import com.android.internal.util.IndentingPrintWriter; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.CoreStartable; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.user.data.model.SelectedUserModel; import com.android.systemui.user.data.model.SelectionStatus; import com.android.systemui.user.data.repository.UserRepository; import com.android.systemui.util.kotlin.JavaAdapter; import libcore.io.IoUtils; Loading @@ -59,7 +64,7 @@ import javax.inject.Inject; */ @SysUISingleton public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implements Runnable, Dumpable { Dumpable, CoreStartable { private static final String TAG = "LockscreenWallpaper"; Loading @@ -72,6 +77,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen private final WallpaperManager mWallpaperManager; private final KeyguardUpdateMonitor mUpdateMonitor; private final Handler mH; private final JavaAdapter mJavaAdapter; private final UserRepository mUserRepository; private boolean mCached; private Bitmap mCache; Loading @@ -88,6 +95,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen DumpManager dumpManager, NotificationMediaManager mediaManager, @Main Handler mainHandler, JavaAdapter javaAdapter, UserRepository userRepository, UserTracker userTracker) { dumpManager.registerDumpable(getClass().getSimpleName(), this); mWallpaperManager = wallpaperManager; Loading @@ -95,6 +104,8 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen mUpdateMonitor = keyguardUpdateMonitor; mMediaManager = mediaManager; mH = mainHandler; mJavaAdapter = javaAdapter; mUserRepository = userRepository; if (iWallpaperManager != null && !mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { // Service is disabled on some devices like Automotive Loading @@ -106,6 +117,14 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } } @Override public void start() { if (!isLockscreenLiveWallpaperEnabled()) { mJavaAdapter.alwaysCollectFlow( mUserRepository.getSelectedUser(), this::setSelectedUser); } } public Bitmap getBitmap() { assertLockscreenLiveWallpaperNotEnabled(); Loading Loading @@ -169,9 +188,15 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } } public void setCurrentUser(int user) { private void setSelectedUser(SelectedUserModel selectedUserModel) { assertLockscreenLiveWallpaperNotEnabled(); if (selectedUserModel.getSelectionStatus().equals(SelectionStatus.SELECTION_IN_PROGRESS)) { // Wait until the selection has finished before updating. return; } int user = selectedUserModel.getUserInfo().id; if (user != mCurrentUserId) { if (mSelectedUser == null || user != mSelectedUser.getIdentifier()) { mCached = false; Loading
packages/SystemUI/src/com/android/systemui/user/data/model/SelectedUserModel.kt 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.user.data.model import android.content.pm.UserInfo /** A model for the currently selected user. */ data class SelectedUserModel( /** Information about the user. */ val userInfo: UserInfo, /** The current status of the selection. */ val selectionStatus: SelectionStatus, ) /** The current status of the selection. */ enum class SelectionStatus { /** This user has started being selected but the selection hasn't completed. */ SELECTION_IN_PROGRESS, /** The selection of this user has completed. */ SELECTION_COMPLETE, }
packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt +52 −37 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.settings.UserTracker import com.android.systemui.user.data.model.SelectedUserModel import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.model.UserSwitcherSettingsModel import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.SettingsProxyExt.observerFlow Loading Loading @@ -69,6 +71,9 @@ interface UserRepository { /** List of all users on the device. */ val userInfos: Flow<List<UserInfo>> /** Information about the currently-selected user, including [UserInfo] and other details. */ val selectedUser: StateFlow<SelectedUserModel> /** [UserInfo] of the currently-selected user. */ val selectedUserInfo: Flow<UserInfo> Loading Loading @@ -146,9 +151,6 @@ constructor( private val _userInfos = MutableStateFlow<List<UserInfo>?>(null) override val userInfos: Flow<List<UserInfo>> = _userInfos.filterNotNull() private val _selectedUserInfo = MutableStateFlow<UserInfo?>(null) override val selectedUserInfo: Flow<UserInfo> = _selectedUserInfo.filterNotNull() override var mainUserId: Int = UserHandle.USER_NULL private set override var lastSelectedNonGuestUserId: Int = UserHandle.USER_NULL Loading @@ -174,12 +176,57 @@ constructor( override var isRefreshUsersPaused: Boolean = false init { observeSelectedUser() if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) { observeUserSwitching() } } override val selectedUser: StateFlow<SelectedUserModel> = run { // Some callbacks don't modify the selection status, so maintain the current value. var currentSelectionStatus = SelectionStatus.SELECTION_COMPLETE conflatedCallbackFlow { fun send(selectionStatus: SelectionStatus) { currentSelectionStatus = selectionStatus trySendWithFailureLogging( SelectedUserModel(tracker.userInfo, selectionStatus), TAG, ) } val callback = object : UserTracker.Callback { override fun onUserChanging(newUser: Int, userContext: Context) { send(SelectionStatus.SELECTION_IN_PROGRESS) } override fun onUserChanged(newUser: Int, userContext: Context) { send(SelectionStatus.SELECTION_COMPLETE) } override fun onProfilesChanged(profiles: List<UserInfo>) { send(currentSelectionStatus) } } tracker.addCallback(callback, mainDispatcher.asExecutor()) send(currentSelectionStatus) awaitClose { tracker.removeCallback(callback) } } .onEach { if (!it.userInfo.isGuest) { lastSelectedNonGuestUserId = it.userInfo.id } } .stateIn( applicationScope, SharingStarted.Eagerly, initialValue = SelectedUserModel(tracker.userInfo, currentSelectionStatus) ) } override val selectedUserInfo: Flow<UserInfo> = selectedUser.map { it.userInfo } override fun refreshUsers() { applicationScope.launch { val result = withContext(backgroundDispatcher) { manager.aliveUsers } Loading @@ -201,7 +248,7 @@ constructor( } override fun getSelectedUserInfo(): UserInfo { return checkNotNull(_selectedUserInfo.value) return selectedUser.value.userInfo } override fun isSimpleUserSwitcher(): Boolean { Loading Loading @@ -234,38 +281,6 @@ constructor( .launchIn(applicationScope) } private fun observeSelectedUser() { conflatedCallbackFlow { fun send() { trySendWithFailureLogging(tracker.userInfo, TAG) } val callback = object : UserTracker.Callback { override fun onUserChanging(newUser: Int, userContext: Context) { send() } override fun onProfilesChanged(profiles: List<UserInfo>) { send() } } tracker.addCallback(callback, mainDispatcher.asExecutor()) send() awaitClose { tracker.removeCallback(callback) } } .onEach { if (!it.isGuest) { lastSelectedNonGuestUserId = it.id } _selectedUserInfo.value = it } .launchIn(applicationScope) } private suspend fun getSettings(): UserSwitcherSettingsModel { return withContext(backgroundDispatcher) { val isSimpleUserSwitcher = Loading