Introduce AMS.getLastResumedActivityUserId to fix work profile icon issue
Problem:
Work profile status bar icon feeature is relied on two callbacks
1. onForegroundProfileSwitch (AMS.setResumedActivityLocked)
2. appTransitionStarting (WMS)
We assume callback 1 is always called before 2, but it is not the case.
These two callbacks are triggered by two handlers in two different threads,
and hence race condition happens.
Solution:
Not rely on onForegroundProfileSwitch to update mManagedProfileFocused
flag anymore. Query getLastResumedActivityUserId in appTransitionStarting.
Also, make sure mLastResumedActivity is updated before sending message
to WMS in setResumedActivityLocked.
Test: Start a work app, observe that the work icon is shown.
Test: Start a personal app, observe that work icon is gone.
Test: Dock the work app, tap on it (give it focus), observe that work
icon is shown.
Test: Start a work app, switch user, can see the icon is gone. Switch back,
icon is back.
Bug: 34159089
Change-Id: I2cee141d18e8b7d5607b26dd7a2fd5bc9cd0ebb3
This commit is contained in:
@@ -629,6 +629,11 @@ interface IActivityManager {
|
|||||||
*/
|
*/
|
||||||
void setDisablePreviewScreenshots(IBinder token, boolean disable);
|
void setDisablePreviewScreenshots(IBinder token, boolean disable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the user id of last resumed activity.
|
||||||
|
*/
|
||||||
|
int getLastResumedActivityUserId();
|
||||||
|
|
||||||
// WARNING: when these transactions are updated, check if they are any callers on the native
|
// WARNING: when these transactions are updated, check if they are any callers on the native
|
||||||
// side. If so, make sure they are using the correct transaction ids and arguments.
|
// side. If so, make sure they are using the correct transaction ids and arguments.
|
||||||
// If a transaction which will also be used on the native side is being inserted, add it
|
// If a transaction which will also be used on the native side is being inserted, add it
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
|||||||
private boolean mVolumeVisible;
|
private boolean mVolumeVisible;
|
||||||
private boolean mCurrentUserSetup;
|
private boolean mCurrentUserSetup;
|
||||||
|
|
||||||
private boolean mManagedProfileFocused = false;
|
|
||||||
private boolean mManagedProfileIconVisible = false;
|
private boolean mManagedProfileIconVisible = false;
|
||||||
private boolean mManagedProfileInQuietMode = false;
|
private boolean mManagedProfileInQuietMode = false;
|
||||||
|
|
||||||
@@ -439,30 +438,11 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void profileChanged(int userId) {
|
|
||||||
UserInfo user = null;
|
|
||||||
if (userId == UserHandle.USER_CURRENT) {
|
|
||||||
try {
|
|
||||||
user = ActivityManager.getService().getCurrentUser();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
user = mUserManager.getUserInfo(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
mManagedProfileFocused = user != null && user.isManagedProfile();
|
|
||||||
if (DEBUG) Log.v(TAG, "profileChanged: mManagedProfileFocused: " + mManagedProfileFocused);
|
|
||||||
// Actually update the icon later when transition starts.
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateManagedProfile() {
|
private void updateManagedProfile() {
|
||||||
if (DEBUG) {
|
try {
|
||||||
Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
|
|
||||||
+ mManagedProfileFocused);
|
|
||||||
}
|
|
||||||
final boolean showIcon;
|
final boolean showIcon;
|
||||||
if (mManagedProfileFocused && !mKeyguardMonitor.isShowing()) {
|
final int userId = ActivityManager.getService().getLastResumedActivityUserId();
|
||||||
|
if (mUserManager.isManagedProfile(userId) && !mKeyguardMonitor.isShowing()) {
|
||||||
showIcon = true;
|
showIcon = true;
|
||||||
mIconController.setIcon(mSlotManagedProfile,
|
mIconController.setIcon(mSlotManagedProfile,
|
||||||
R.drawable.stat_sys_managed_profile_status,
|
R.drawable.stat_sys_managed_profile_status,
|
||||||
@@ -479,6 +459,10 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
|||||||
mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
|
mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
|
||||||
mManagedProfileIconVisible = showIcon;
|
mManagedProfileIconVisible = showIcon;
|
||||||
}
|
}
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.w(TAG, "updateManagedProfile: ", ex);
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateForegroundInstantApps() {
|
private void updateForegroundInstantApps() {
|
||||||
@@ -556,35 +540,16 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
|||||||
new SynchronousUserSwitchObserver() {
|
new SynchronousUserSwitchObserver() {
|
||||||
@Override
|
@Override
|
||||||
public void onUserSwitching(int newUserId) throws RemoteException {
|
public void onUserSwitching(int newUserId) throws RemoteException {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(() -> mUserInfoController.reloadUserInfo());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mUserInfoController.reloadUserInfo();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUserSwitchComplete(int newUserId) throws RemoteException {
|
public void onUserSwitchComplete(int newUserId) throws RemoteException {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updateAlarm();
|
updateAlarm();
|
||||||
profileChanged(newUserId);
|
|
||||||
updateQuietState();
|
updateQuietState();
|
||||||
updateManagedProfile();
|
updateManagedProfile();
|
||||||
updateForegroundInstantApps();
|
updateForegroundInstantApps();
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onForegroundProfileSwitch(int newProfileId) {
|
|
||||||
mHandler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
profileChanged(newProfileId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3212,18 +3212,18 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mWindowManager.setFocusedApp(r.appToken, true);
|
|
||||||
|
|
||||||
applyUpdateLockStateLocked(r);
|
|
||||||
applyUpdateVrModeLocked(r);
|
|
||||||
if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
|
if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
|
||||||
mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
|
mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
|
||||||
mHandler.obtainMessage(
|
mHandler.obtainMessage(
|
||||||
FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
|
FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
mLastResumedActivity = r;
|
mLastResumedActivity = r;
|
||||||
|
|
||||||
|
mWindowManager.setFocusedApp(r.appToken, true);
|
||||||
|
|
||||||
|
applyUpdateLockStateLocked(r);
|
||||||
|
applyUpdateVrModeLocked(r);
|
||||||
|
|
||||||
EventLogTags.writeAmSetResumedActivity(
|
EventLogTags.writeAmSetResumedActivity(
|
||||||
r == null ? -1 : r.userId,
|
r == null ? -1 : r.userId,
|
||||||
r == null ? "NULL" : r.shortComponentName,
|
r == null ? "NULL" : r.shortComponentName,
|
||||||
@@ -23599,6 +23599,21 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the user id of the last resumed activity.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public @UserIdInt int getLastResumedActivityUserId() {
|
||||||
|
enforceCallingPermission(
|
||||||
|
permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
|
||||||
|
synchronized (this) {
|
||||||
|
if (mLastResumedActivity == null) {
|
||||||
|
return mUserController.getCurrentUserIdLocked();
|
||||||
|
}
|
||||||
|
return mLastResumedActivity.userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class SleepTokenImpl extends SleepToken {
|
private final class SleepTokenImpl extends SleepToken {
|
||||||
private final String mTag;
|
private final String mTag;
|
||||||
private final long mAcquireTime;
|
private final long mAcquireTime;
|
||||||
|
|||||||
Reference in New Issue
Block a user