summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Robin Lee <rgl@google.com> 2016-08-31 13:27:51 +0100
committer Robin Lee <rgl@google.com> 2016-09-08 13:41:48 +0100
commit92b83c6495abb3c091474b3a2f16dcbd949d6da7 (patch)
treeb306d30d6a6121d2e71e747d3c9c434bf42c48d7
parenta6f04afbc9b944ac5e4e5d4b846d173bba0c27c1 (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
-rw-r--r--core/java/android/content/Intent.java12
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java61
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java5
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);