Merge "Remove user icon avatar from memory when unlocked" into tm-dev

This commit is contained in:
Peter Kalauskas
2022-04-11 17:05:14 +00:00
committed by Android (Google) Code Review
4 changed files with 112 additions and 36 deletions

View File

@@ -176,6 +176,10 @@ public class UserIconDrawable extends Drawable implements Drawable.Callback {
return this;
}
public boolean isEmpty() {
return getUserIcon() == null && getUserDrawable() == null;
}
public UserIconDrawable setBadge(Drawable badge) {
mBadge = badge;
if (mBadge != null) {

View File

@@ -137,4 +137,8 @@ public class UserAvatarView extends View {
mDrawable.setIconDrawable(d);
mDrawable.setBadgeIfManagedUser(getContext(), userId);
}
public boolean isEmpty() {
return mDrawable.isEmpty();
}
}

View File

@@ -29,6 +29,7 @@ import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardVisibilityHelper;
@@ -36,7 +37,6 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.user.UserSwitchDialogController;
@@ -68,7 +68,6 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
private final Context mContext;
private Resources mResources;
private final UserSwitcherController mUserSwitcherController;
private final ScreenLifecycle mScreenLifecycle;
private UserSwitcherController.BaseUserAdapter mAdapter;
private final KeyguardStateController mKeyguardStateController;
private final FalsingManager mFalsingManager;
@@ -77,8 +76,10 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
private final UserSwitchDialogController mUserSwitchDialogController;
private final UiEventLogger mUiEventLogger;
private UserAvatarView mUserAvatarView;
@VisibleForTesting
UserAvatarView mUserAvatarView;
UserSwitcherController.UserRecord mCurrentUser;
private boolean mIsKeyguardShowing;
// State info for the user switch and keyguard
private int mBarState;
@@ -87,8 +88,6 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
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;
@@ -102,12 +101,34 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
}
};
private ConfigurationController.ConfigurationListener
mConfigurationListener = new ConfigurationController.ConfigurationListener() {
private ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@Override
public void onUiModeChanged() {
updateView(true);
// Force update when dark theme toggled. Otherwise, icon will not update
// until it is clicked
if (mIsKeyguardShowing) {
updateView();
}
}
};
private final KeyguardStateController.Callback mKeyguardStateCallback =
new KeyguardStateController.Callback() {
@Override
public void onUnlockedChanged() {
updateKeyguardShowing(false /* forceViewUpdate */);
}
@Override
public void onKeyguardShowingChanged() {
updateKeyguardShowing(false /* forceViewUpdate */);
}
@Override
public void onKeyguardFadingAwayChanged() {
updateKeyguardShowing(false /* forceViewUpdate */);
}
};
@@ -116,7 +137,6 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
FrameLayout view,
Context context,
@Main Resources resources,
ScreenLifecycle screenLifecycle,
UserSwitcherController userSwitcherController,
KeyguardStateController keyguardStateController,
FalsingManager falsingManager,
@@ -130,7 +150,6 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
if (DEBUG) Log.d(TAG, "New KeyguardQsUserSwitchController");
mContext = context;
mResources = resources;
mScreenLifecycle = screenLifecycle;
mUserSwitcherController = userSwitcherController;
mKeyguardStateController = keyguardStateController;
mFalsingManager = falsingManager;
@@ -188,7 +207,10 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
mDataSetObserver.onChanged();
mStatusBarStateController.addCallback(mStatusBarStateListener);
mConfigurationController.addCallback(mConfigurationListener);
updateView(true /* forceUpdate */);
mKeyguardStateController.addCallback(mKeyguardStateCallback);
// Force update when view attached in case configuration changed while the view was detached
updateCurrentUser();
updateKeyguardShowing(true /* forceViewUpdate */);
}
@Override
@@ -198,15 +220,48 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
mAdapter.unregisterDataSetObserver(mDataSetObserver);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mConfigurationController.removeCallback(mConfigurationListener);
mKeyguardStateController.removeCallback(mKeyguardStateCallback);
}
public final DataSetObserver mDataSetObserver = new DataSetObserver() {
@Override
public void onChanged() {
updateView(false /* forceUpdate */);
boolean userChanged = updateCurrentUser();
if (userChanged || (mIsKeyguardShowing && mUserAvatarView.isEmpty())) {
updateView();
}
}
};
private void clearAvatar() {
if (DEBUG) Log.d(TAG, "clearAvatar");
mUserAvatarView.setAvatar(null);
}
/**
* @param forceViewUpdate whether view should be updated regardless of whether
* keyguard-showing state changed
*/
@VisibleForTesting
void updateKeyguardShowing(boolean forceViewUpdate) {
boolean wasKeyguardShowing = mIsKeyguardShowing;
mIsKeyguardShowing = mKeyguardStateController.isShowing()
|| mKeyguardStateController.isKeyguardGoingAway();
if (wasKeyguardShowing == mIsKeyguardShowing && !forceViewUpdate) {
return;
}
if (DEBUG) {
Log.d(TAG, "updateKeyguardShowing:"
+ " mIsKeyguardShowing=" + mIsKeyguardShowing
+ " forceViewUpdate=" + forceViewUpdate);
}
if (mIsKeyguardShowing) {
updateView();
} else {
clearAvatar();
}
}
/**
* @return true if the current user has changed
*/
@@ -223,31 +278,22 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
return mCurrentUser == null && previousUser != null;
}
/**
* @param forceUpdate whether to update view even if current user did not change
*/
private void updateView(boolean forceUpdate) {
if (!updateCurrentUser() && !forceUpdate) {
return;
}
String contentDescription = null;
if (mCurrentUser != null && mCurrentUser.info != null && !TextUtils.isEmpty(
mCurrentUser.info.name)) {
private String getContentDescription() {
if (mCurrentUser != null && mCurrentUser.info != null
&& !TextUtils.isEmpty(mCurrentUser.info.name)) {
// If we know the current user's name, have TalkBack to announce "Signed in as [user
// name]" when the icon is selected
contentDescription = mContext.getString(R.string.accessibility_quick_settings_user,
mCurrentUser.info.name);
return mContext.getString(
R.string.accessibility_quick_settings_user, mCurrentUser.info.name);
} else {
// As a fallback, have TalkBack announce "Switch user"
contentDescription = mContext.getString(
R.string.accessibility_multi_user_switch_switcher);
}
if (!TextUtils.equals(mUserAvatarView.getContentDescription(), contentDescription)) {
mUserAvatarView.setContentDescription(contentDescription);
return mContext.getString(R.string.accessibility_multi_user_switch_switcher);
}
}
private void updateView() {
if (DEBUG) Log.d(TAG, "updateView");
mUserAvatarView.setContentDescription(getContentDescription());
int userId = mCurrentUser != null ? mCurrentUser.resolveId() : UserHandle.USER_NULL;
mUserAvatarView.setDrawableWithBadge(getCurrentUserIcon().mutate(), userId);
}

View File

@@ -26,13 +26,13 @@ import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.user.UserSwitchDialogController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.LockscreenGestureLogger
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -47,9 +47,6 @@ import org.mockito.MockitoAnnotations
@TestableLooper.RunWithLooper
@RunWith(AndroidTestingRunner::class)
class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
@Mock
private lateinit var screenLifecycle: ScreenLifecycle
@Mock
private lateinit var userSwitcherController: UserSwitcherController
@@ -93,7 +90,6 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
view,
context,
context.resources,
screenLifecycle,
userSwitcherController,
keyguardStateController,
falsingManager,
@@ -108,6 +104,8 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
testableLooper.processAllMessages()
`when`(userSwitcherController.keyguardStateController).thenReturn(keyguardStateController)
`when`(userSwitcherController.keyguardStateController.isShowing).thenReturn(true)
`when`(keyguardStateController.isShowing).thenReturn(true)
`when`(keyguardStateController.isKeyguardGoingAway).thenReturn(false)
keyguardQsUserSwitchController.init()
}
@@ -122,4 +120,28 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
verify(uiEventLogger, times(1))
.log(LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_SWITCH_USER_TAP)
}
@Test
fun testAvatarExistsWhenKeyguardGoingAway() {
`when`(keyguardStateController.isShowing).thenReturn(false)
`when`(keyguardStateController.isKeyguardGoingAway).thenReturn(true)
keyguardQsUserSwitchController.updateKeyguardShowing(true /* forceViewUpdate */)
assertThat(keyguardQsUserSwitchController.mUserAvatarView.isEmpty).isFalse()
}
@Test
fun testAvatarExistsWhenKeyguardShown() {
`when`(keyguardStateController.isShowing).thenReturn(true)
`when`(keyguardStateController.isKeyguardGoingAway).thenReturn(false)
keyguardQsUserSwitchController.updateKeyguardShowing(true /* forceViewUpdate */)
assertThat(keyguardQsUserSwitchController.mUserAvatarView.isEmpty).isFalse()
}
@Test
fun testAvatarGoneWhenKeyguardGone() {
`when`(keyguardStateController.isShowing).thenReturn(false)
`when`(keyguardStateController.isKeyguardGoingAway).thenReturn(false)
keyguardQsUserSwitchController.updateKeyguardShowing(true /* forceViewUpdate */)
assertThat(keyguardQsUserSwitchController.mUserAvatarView.isEmpty).isTrue()
}
}