diff options
6 files changed, 99 insertions, 46 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 70010b277d6e..215cb5b50efa 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3037,6 +3037,18 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.MANAGED_PROFILE_UNAVAILABLE"; /** + * Broadcast sent to the system user when the 'device locked' state changes for any user. + * Carries an extra {@link #EXTRA_USER_HANDLE} that specifies the ID of the user for which + * the device was locked or unlocked. + * + * This is only sent to registered receivers. + * + * @hide + */ + public static final String ACTION_DEVICE_LOCKED_CHANGED = + "android.intent.action.DEVICE_LOCKED_CHANGED"; + + /** * Sent when the user taps on the clock widget in the system's "quick settings" area. */ public static final String ACTION_QUICK_CLOCK = diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index effc3fc8b1bd..5d62b11ecb2e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -494,6 +494,8 @@ <protected-broadcast android:name="com.android.server.retaildemo.ACTION_RESET_DEMO" /> + <protected-broadcast android:name="android.intent.action.DEVICE_LOCKED_CHANGED" /> + <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 75b9417467f7..6c63b7dd2999 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -158,7 +158,7 @@ public abstract class BaseStatusBar extends SystemUI implements "com.android.systemui.statusbar.banner_action_cancel"; private static final String BANNER_ACTION_SETUP = "com.android.systemui.statusbar.banner_action_setup"; - private static final String WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION + private static final String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION = "com.android.systemui.statusbar.work_challenge_unlocked_notification_action"; protected CommandQueue mCommandQueue; @@ -214,14 +214,14 @@ public abstract class BaseStatusBar extends SystemUI implements protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; // public mode, private notifications, etc - private boolean mLockscreenPublicMode = false; + private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray(); private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray(); private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray(); private UserManager mUserManager; private int mDensity; - private KeyguardManager mKeyguardManager; + protected KeyguardManager mKeyguardManager; private LockPatternUtils mLockPatternUtils; // UI-specific methods @@ -460,11 +460,11 @@ public abstract class BaseStatusBar extends SystemUI implements row.setUserExpanded(true); if (!mAllowLockscreenRemoteInput) { - if (isLockscreenPublicMode()) { + final int userId = pendingIntent.getCreatorUserHandle().getIdentifier(); + if (isLockscreenPublicMode(userId)) { onLockedRemoteInput(row, view); return true; } - final int userId = pendingIntent.getCreatorUserHandle().getIdentifier(); if (mUserManager.getUserInfo(userId).isManagedProfile() && mKeyguardManager.isDeviceLocked(userId)) { onLockedWorkRemoteInput(userId, row, view); @@ -555,7 +555,7 @@ public abstract class BaseStatusBar extends SystemUI implements ); } - } else if (WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION.equals(action)) { + } else if (NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION.equals(action)) { final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT); final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX); if (intentSender != null) { @@ -572,7 +572,6 @@ public abstract class BaseStatusBar extends SystemUI implements /* ignore */ } } - onWorkChallengeUnlocked(); } } }; @@ -580,12 +579,18 @@ public abstract class BaseStatusBar extends SystemUI implements private final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); + final String action = intent.getAction(); + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); + if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) && isCurrentProfile(getSendingUserId())) { mUsersAllowingPrivateNotifications.clear(); updateLockscreenNotificationSetting(); updateNotifications(); + } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) { + if (userId != mCurrentUserId && isCurrentProfile(userId)) { + onWorkChallengeChanged(); + } } } }; @@ -810,7 +815,7 @@ public abstract class BaseStatusBar extends SystemUI implements mContext.registerReceiver(mBroadcastReceiver, filter); IntentFilter internalFilter = new IntentFilter(); - internalFilter.addAction(WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION); + internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION); internalFilter.addAction(BANNER_ACTION_CANCEL); internalFilter.addAction(BANNER_ACTION_SETUP); mContext.registerReceiver(mBroadcastReceiver, internalFilter, PERMISSION_SELF, null); @@ -818,6 +823,7 @@ public abstract class BaseStatusBar extends SystemUI implements IntentFilter allUsersFilter = new IntentFilter(); allUsersFilter.addAction( DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); + allUsersFilter.addAction(Intent.ACTION_DEVICE_LOCKED_CHANGED); mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter, null, null); updateCurrentProfilesCache(); @@ -1117,9 +1123,10 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void onClick(View v) { // If the user has security enabled, show challenge if the setting is changed. - if (guts.hasImportanceChanged() && isLockscreenPublicMode() && - (mState == StatusBarState.KEYGUARD - || mState == StatusBarState.SHADE_LOCKED)) { + if (guts.hasImportanceChanged() + && isLockscreenPublicMode(sbn.getUser().getIdentifier()) + && (mState == StatusBarState.KEYGUARD + || mState == StatusBarState.SHADE_LOCKED)) { OnDismissAction dismissAction = new OnDismissAction() { @Override public boolean onDismiss() { @@ -1421,15 +1428,15 @@ public abstract class BaseStatusBar extends SystemUI implements /** * Save the current "public" (locked and secure) state of the lockscreen. */ - public void setLockscreenPublicMode(boolean publicMode) { - mLockscreenPublicMode = publicMode; + public void setLockscreenPublicMode(boolean publicMode, int userId) { + mLockscreenPublicMode.put(userId, publicMode); } - public boolean isLockscreenPublicMode() { - return mLockscreenPublicMode; + public boolean isLockscreenPublicMode(int userId) { + return mLockscreenPublicMode.get(userId, false); } - protected void onWorkChallengeUnlocked() {} + protected void onWorkChallengeChanged() {} /** * Has the given user chosen to allow notifications to be shown even when the lockscreen is in @@ -1487,8 +1494,9 @@ public abstract class BaseStatusBar extends SystemUI implements * If so, notifications should be hidden. */ @Override // NotificationData.Environment - public boolean shouldHideNotifications(int userid) { - return isLockscreenPublicMode() && !userAllowsNotificationsInPublic(userid); + public boolean shouldHideNotifications(int userId) { + return isLockscreenPublicMode(mCurrentUserId) && !userAllowsNotificationsInPublic(userId) + || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId)); } /** @@ -1497,7 +1505,7 @@ public abstract class BaseStatusBar extends SystemUI implements */ @Override // NotificationDate.Environment public boolean shouldHideNotifications(String key) { - return isLockscreenPublicMode() + return isLockscreenPublicMode(mCurrentUserId) && mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_SECRET; } @@ -1505,8 +1513,8 @@ public abstract class BaseStatusBar extends SystemUI implements * Returns true if we're on a secure lockscreen. */ @Override // NotificationData.Environment - public boolean onSecureLockScreen() { - return isLockscreenPublicMode(); + public boolean isSecurelyLocked(int userId) { + return isLockscreenPublicMode(userId); } public void onNotificationClear(StatusBarNotification notification) { @@ -2058,8 +2066,7 @@ public abstract class BaseStatusBar extends SystemUI implements if (newIntent == null) { return false; } - final Intent callBackIntent = new Intent( - WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION); + final Intent callBackIntent = new Intent(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION); callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender); callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey); callBackIntent.setPackage(mContext.getPackageName()); @@ -2258,14 +2265,16 @@ public abstract class BaseStatusBar extends SystemUI implements entry.row.setOnKeyguard(false); entry.row.setSystemExpanded(visibleNotifications == 0 && !childNotification); } + int userId = entry.notification.getUserId(); boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup( entry.notification) && !entry.row.isRemoved(); boolean childWithVisibleSummary = childNotification && mGroupManager.getGroupSummary(entry.notification).getVisibility() == View.VISIBLE; boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification); - if (suppressedSummary || (isLockscreenPublicMode() && !mShowLockscreenNotifications) || - (onKeyguard && !childWithVisibleSummary + if (suppressedSummary + || (isLockscreenPublicMode(userId) && !mShowLockscreenNotifications) + || (onKeyguard && !childWithVisibleSummary && (visibleNotifications >= maxNotifications || !showOnKeyguard))) { entry.row.setVisibility(View.GONE); if (onKeyguard && showOnKeyguard && !childNotification && !suppressedSummary) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index b6e54af7ef08..bae16f30e338 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -380,7 +380,7 @@ public class NotificationData { return true; } - if (mEnvironment.onSecureLockScreen() && + if (mEnvironment.isSecurelyLocked(sbn.getUserId()) && (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET || mEnvironment.shouldHideNotifications(sbn.getUserId()) || mEnvironment.shouldHideNotifications(sbn.getKey()))) { @@ -463,7 +463,7 @@ public class NotificationData { * Provides access to keyguard state and user settings dependent data. */ public interface Environment { - public boolean onSecureLockScreen(); + public boolean isSecurelyLocked(int userId); public boolean shouldHideNotifications(int userid); public boolean shouldHideNotifications(String key); public boolean isDeviceProvisioned(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index fc3b02454133..023759383275 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -37,6 +37,7 @@ import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.ActivityOptions; import android.app.IActivityManager; +import android.app.KeyguardManager; import android.app.Notification; import android.app.PendingIntent; import android.app.StatusBarManager; @@ -1716,18 +1717,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, for (int i=0; i<N; i++) { Entry ent = activeNotifications.get(i); int vis = ent.notification.getNotification().visibility; + int userId = ent.notification.getUserId(); // Display public version of the notification if we need to redact. - final boolean hideSensitive = - !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId()); + boolean deviceSensitive = (isLockscreenPublicMode(mCurrentUserId) + && !userAllowsPrivateNotificationsInPublic(mCurrentUserId)); + boolean userSensitive = deviceSensitive || (isLockscreenPublicMode(userId) + && !userAllowsPrivateNotificationsInPublic(userId)); boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE; boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey()); - boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage; - boolean showingPublic = sensitive && isLockscreenPublicMode(); + boolean sensitive = (sensitiveNote && userSensitive) || sensitivePackage; + boolean showingPublic = sensitive && isLockscreenPublicMode(userId); if (showingPublic) { updatePublicContentView(ent, ent.notification); } - ent.row.setSensitive(sensitive, hideSensitive); + ent.row.setSensitive(sensitive, deviceSensitive); if (ent.autoRedacted && ent.legacy) { // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form // for legacy auto redacted notifications. @@ -4275,17 +4279,23 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void updatePublicMode() { - boolean isPublic = false; - if (mStatusBarKeyguardViewManager.isShowing()) { - for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) { - UserInfo userInfo = mCurrentProfiles.valueAt(i); - if (mStatusBarKeyguardViewManager.isSecure(userInfo.id)) { - isPublic = true; - break; + final boolean showingKeyguard = mStatusBarKeyguardViewManager.isShowing(); + final boolean devicePublic = showingKeyguard + && mStatusBarKeyguardViewManager.isSecure(mCurrentUserId); + + // Look for public mode users. Users are considered public in either case of: + // - device keyguard is shown in secure mode; + // - profile is locked with a work challenge. + for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) { + final int userId = mCurrentProfiles.valueAt(i).id; + boolean isProfilePublic = devicePublic; + if (!devicePublic && userId != mCurrentUserId) { + if (mStatusBarKeyguardViewManager.isSecure(userId)) { + isProfilePublic = mKeyguardManager.isDeviceLocked(userId); } } + setLockscreenPublicMode(isProfilePublic, userId); } - setLockscreenPublicMode(isPublic); } protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) { @@ -4342,7 +4352,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) { if (mStackScroller == null) return; boolean onKeyguard = mState == StatusBarState.KEYGUARD; - mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade); + boolean publicMode = isAnyProfilePublicMode(); + mStackScroller.setHideSensitive(publicMode, goingToFullShade); mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */); mStackScroller.setExpandingEnabled(!onKeyguard); ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild(); @@ -4591,6 +4602,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, * @param expandView The view to expand after going to the shade. */ public void goToLockedShade(View expandView) { + int userId = mCurrentUserId; ExpandableNotificationRow row = null; if (expandView instanceof ExpandableNotificationRow) { row = (ExpandableNotificationRow) expandView; @@ -4598,10 +4610,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Indicate that the group expansion is changing at this time -- this way the group // and children backgrounds / divider animations will look correct. row.setGroupExpansionChanging(true); + if (row.getStatusBarNotification() != null) { + userId = row.getStatusBarNotification().getUserId(); + } } boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId) || !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer(); - if (isLockscreenPublicMode() && fullShadeNeedsBouncer) { + if (isLockscreenPublicMode(userId) && fullShadeNeedsBouncer) { mLeaveOpenOnKeyguardHide = true; showBouncer(); mDraggedDownRow = row; @@ -4646,10 +4661,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mPendingWorkRemoteInputView = clicked; } + private boolean isAnyProfilePublicMode() { + for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) { + if (isLockscreenPublicMode(mCurrentProfiles.valueAt(i).id)) { + return true; + } + } + return false; + } + @Override - protected void onWorkChallengeUnlocked() { - if (mPendingWorkRemoteInputView != null) { - final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView; + protected void onWorkChallengeChanged() { + updatePublicMode(); + updateNotifications(); + if (mPendingWorkRemoteInputView != null && !isAnyProfilePublicMode()) { // Expand notification panel and the notification row, then click on remote input view final Runnable clickPendingViewRunnable = new Runnable() { @Override diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index d219aedf5fe7..353d6638b47b 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -872,6 +872,11 @@ public class TrustManagerService extends SystemService { } catch (RemoteException e) { } } + final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED); + lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); + mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM, + Manifest.permission.TRUST_LISTENER, /* options */ null); } } finally { Binder.restoreCallingIdentity(identity); |