diff options
| author | 2016-08-31 13:27:51 +0100 | |
|---|---|---|
| committer | 2016-09-08 13:41:48 +0100 | |
| commit | 92b83c6495abb3c091474b3a2f16dcbd949d6da7 (patch) | |
| tree | b306d30d6a6121d2e71e747d3c9c434bf42c48d7 | |
| parent | a6f04afbc9b944ac5e4e5d4b846d173bba0c27c1 (diff) | |
Redact work notifications separately from personal
This will strictly decrease the set of cases where work notifications
can be shown.
They will continue to honour the parent profile's settings, but will
also get redacted/hidden if the work profile has stricter settings
than the parent or when the parent is unlocked but the profile is still
locked.
Bug: 31001762
Change-Id: I2152631dbb8beb7a9899d6406b05f4447d757010
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); |