Merge "Revert "Don't show "Clear All" w/ redacted notifs"" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
95d2e13cc1
@@ -29,6 +29,7 @@ import com.android.keyguard.AlphaOptimizedLinearLayout;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.plugins.DarkIconDispatcher;
|
import com.android.systemui.plugins.DarkIconDispatcher;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -48,7 +49,6 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
|
|||||||
private TextView mTextView;
|
private TextView mTextView;
|
||||||
private NotificationEntry mShowingEntry;
|
private NotificationEntry mShowingEntry;
|
||||||
private Runnable mOnDrawingRectChangedListener;
|
private Runnable mOnDrawingRectChangedListener;
|
||||||
private boolean mRedactSensitiveContent;
|
|
||||||
|
|
||||||
public HeadsUpStatusBarView(Context context) {
|
public HeadsUpStatusBarView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -111,28 +111,29 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setEntry(NotificationEntry entry) {
|
public void setEntry(NotificationEntry entry) {
|
||||||
|
if (mShowingEntry != null) {
|
||||||
|
mShowingEntry.removeOnSensitivityChangedListener(mOnSensitivityChangedListener);
|
||||||
|
}
|
||||||
mShowingEntry = entry;
|
mShowingEntry = entry;
|
||||||
|
|
||||||
if (mShowingEntry != null) {
|
if (mShowingEntry != null) {
|
||||||
CharSequence text = entry.headsUpStatusBarText;
|
CharSequence text = entry.headsUpStatusBarText;
|
||||||
if (mRedactSensitiveContent && entry.hasSensitiveContents()) {
|
if (entry.isSensitive()) {
|
||||||
text = entry.headsUpStatusBarTextPublic;
|
text = entry.headsUpStatusBarTextPublic;
|
||||||
}
|
}
|
||||||
mTextView.setText(text);
|
mTextView.setText(text);
|
||||||
|
mShowingEntry.addOnSensitivityChangedListener(mOnSensitivityChangedListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRedactSensitiveContent(boolean redactSensitiveContent) {
|
private final OnSensitivityChangedListener mOnSensitivityChangedListener = entry -> {
|
||||||
if (mRedactSensitiveContent == redactSensitiveContent) {
|
if (entry != mShowingEntry) {
|
||||||
return;
|
throw new IllegalStateException("Got a sensitivity change for " + entry
|
||||||
|
+ " but mShowingEntry is " + mShowingEntry);
|
||||||
}
|
}
|
||||||
mRedactSensitiveContent = redactSensitiveContent;
|
// Update the text
|
||||||
if (mShowingEntry != null && mShowingEntry.hasSensitiveContents()) {
|
setEntry(entry);
|
||||||
mTextView.setText(
|
};
|
||||||
mRedactSensitiveContent
|
|
||||||
? mShowingEntry.headsUpStatusBarTextPublic
|
|
||||||
: mShowingEntry.headsUpStatusBarText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
}
|
}
|
||||||
if (view is ExpandableNotificationRow) {
|
if (view is ExpandableNotificationRow) {
|
||||||
// Only drag down on sensitive views, otherwise the ExpandHelper will take this
|
// Only drag down on sensitive views, otherwise the ExpandHelper will take this
|
||||||
return lockScreenUserManager.notifNeedsRedactionInPublic(view.entry)
|
return view.entry.isSensitive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -552,8 +552,7 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
logger.logShadeDisabledOnGoToLockedShade()
|
logger.logShadeDisabledOnGoToLockedShade()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val currentUser = lockScreenUserManager.currentUserId
|
var userId: Int = lockScreenUserManager.getCurrentUserId()
|
||||||
var userId: Int = currentUser
|
|
||||||
var entry: NotificationEntry? = null
|
var entry: NotificationEntry? = null
|
||||||
if (expandView is ExpandableNotificationRow) {
|
if (expandView is ExpandableNotificationRow) {
|
||||||
entry = expandView.entry
|
entry = expandView.entry
|
||||||
@@ -563,18 +562,12 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
entry.setGroupExpansionChanging(true)
|
entry.setGroupExpansionChanging(true)
|
||||||
userId = entry.sbn.userId
|
userId = entry.sbn.userId
|
||||||
}
|
}
|
||||||
val fullShadeNeedsBouncer = when {
|
var fullShadeNeedsBouncer = (!lockScreenUserManager.userAllowsPrivateNotificationsInPublic(
|
||||||
// No bouncer necessary if we're bypassing
|
lockScreenUserManager.getCurrentUserId()) ||
|
||||||
keyguardBypassController.bypassEnabled -> false
|
!lockScreenUserManager.shouldShowLockscreenNotifications() ||
|
||||||
// Redacted notificationss are present, bouncer should be shown before un-redacting in
|
falsingCollector.shouldEnforceBouncer())
|
||||||
// the full shade
|
if (keyguardBypassController.bypassEnabled) {
|
||||||
lockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(currentUser) -> true
|
fullShadeNeedsBouncer = false
|
||||||
// Notifications are hidden in public, bouncer should be shown before showing them in
|
|
||||||
// the full shade
|
|
||||||
!lockScreenUserManager.shouldShowLockscreenNotifications() -> true
|
|
||||||
// Bouncer is being enforced, so we need to show it
|
|
||||||
falsingCollector.shouldEnforceBouncer() -> true
|
|
||||||
else -> false
|
|
||||||
}
|
}
|
||||||
if (lockScreenUserManager.isLockscreenPublicMode(userId) && fullShadeNeedsBouncer) {
|
if (lockScreenUserManager.isLockscreenPublicMode(userId) && fullShadeNeedsBouncer) {
|
||||||
statusBarStateController.setLeaveOpenOnKeyguardHide(true)
|
statusBarStateController.setLeaveOpenOnKeyguardHide(true)
|
||||||
@@ -918,4 +911,4 @@ class DragDownHelper(
|
|||||||
host.getLocationOnScreen(temp2)
|
host.getLocationOnScreen(temp2)
|
||||||
return expandCallback.getChildAtRawPosition(x + temp2[0], y + temp2[1])
|
return expandCallback.getChildAtRawPosition(x + temp2[0], y + temp2[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,22 +71,17 @@ public interface NotificationLockscreenUserManager {
|
|||||||
boolean shouldHideNotifications(String key);
|
boolean shouldHideNotifications(String key);
|
||||||
boolean shouldShowOnKeyguard(NotificationEntry entry);
|
boolean shouldShowOnKeyguard(NotificationEntry entry);
|
||||||
|
|
||||||
void addOnNeedsRedactionInPublicChangedListener(Runnable listener);
|
|
||||||
|
|
||||||
void removeOnNeedsRedactionInPublicChangedListener(Runnable listener);
|
|
||||||
|
|
||||||
boolean isAnyProfilePublicMode();
|
boolean isAnyProfilePublicMode();
|
||||||
|
|
||||||
void updatePublicMode();
|
void updatePublicMode();
|
||||||
|
|
||||||
/** Does this notification require redaction if it is displayed when the device is public? */
|
boolean needsRedaction(NotificationEntry entry);
|
||||||
boolean notifNeedsRedactionInPublic(NotificationEntry entry);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do all sensitive notifications belonging to the given user require redaction when they are
|
* Has the given user chosen to allow their private (full) notifications to be shown even
|
||||||
* displayed in public?
|
* when the lockscreen is in "public" (secure & locked) mode?
|
||||||
*/
|
*/
|
||||||
boolean sensitiveNotifsNeedRedactionInPublic(int userId);
|
boolean userAllowsPrivateNotificationsInPublic(int currentUserId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
|
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static com.android.systemui.statusbar.notification.stack.NotificationPrio
|
|||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -44,6 +45,7 @@ import android.util.SparseBooleanArray;
|
|||||||
import com.android.internal.statusbar.NotificationVisibility;
|
import com.android.internal.statusbar.NotificationVisibility;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||||
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
@@ -58,7 +60,6 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co
|
|||||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.util.ListenerSet;
|
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -84,12 +85,13 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
private final KeyguardStateController mKeyguardStateController;
|
||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
private final Lazy<OverviewProxyService> mOverviewProxyService;
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
|
// Lazy
|
||||||
|
private NotificationEntryManager mEntryManager;
|
||||||
|
|
||||||
private final Lazy<NotificationVisibilityProvider> mVisibilityProviderLazy;
|
private final Lazy<NotificationVisibilityProvider> mVisibilityProviderLazy;
|
||||||
private final Lazy<CommonNotifCollection> mCommonNotifCollectionLazy;
|
private final Lazy<CommonNotifCollection> mCommonNotifCollectionLazy;
|
||||||
private final Lazy<NotificationEntryManager> mEntryManagerLazy;
|
|
||||||
private final DevicePolicyManager mDevicePolicyManager;
|
private final DevicePolicyManager mDevicePolicyManager;
|
||||||
private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
|
private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
|
||||||
private final SparseBooleanArray mUsersWithSeparateWorkChallenge = new SparseBooleanArray();
|
private final SparseBooleanArray mUsersWithSeparateWorkChallenge = new SparseBooleanArray();
|
||||||
@@ -101,14 +103,13 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
private final List<UserChangedListener> mListeners = new ArrayList<>();
|
private final List<UserChangedListener> mListeners = new ArrayList<>();
|
||||||
private final BroadcastDispatcher mBroadcastDispatcher;
|
private final BroadcastDispatcher mBroadcastDispatcher;
|
||||||
private final NotificationClickNotifier mClickNotifier;
|
private final NotificationClickNotifier mClickNotifier;
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
|
||||||
private final List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>();
|
private boolean mShowLockscreenNotifications;
|
||||||
protected final Context mContext;
|
private boolean mAllowLockscreenRemoteInput;
|
||||||
private final Handler mMainHandler;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
|
protected KeyguardManager mKeyguardManager;
|
||||||
protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>();
|
private int mState = StatusBarState.SHADE;
|
||||||
private final ListenerSet<Runnable> mOnSensitiveContentRedactionChangeListeners =
|
private List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>();
|
||||||
new ListenerSet<>();
|
|
||||||
|
|
||||||
protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
|
protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
@@ -119,11 +120,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
isCurrentProfile(getSendingUserId())) {
|
isCurrentProfile(getSendingUserId())) {
|
||||||
mUsersAllowingPrivateNotifications.clear();
|
mUsersAllowingPrivateNotifications.clear();
|
||||||
updateLockscreenNotificationSetting();
|
updateLockscreenNotificationSetting();
|
||||||
for (Runnable listener : mOnSensitiveContentRedactionChangeListeners) {
|
getEntryManager().updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED");
|
||||||
listener.run();
|
|
||||||
}
|
|
||||||
mEntryManagerLazy.get()
|
|
||||||
.updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -145,7 +142,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
// The filtering needs to happen before the update call below in order to
|
// The filtering needs to happen before the update call below in order to
|
||||||
// make sure
|
// make sure
|
||||||
// the presenter has the updated notifications from the new user
|
// the presenter has the updated notifications from the new user
|
||||||
mEntryManagerLazy.get().reapplyFilterAndSort("user switched");
|
getEntryManager().reapplyFilterAndSort("user switched");
|
||||||
mPresenter.onUserSwitched(mCurrentUserId);
|
mPresenter.onUserSwitched(mCurrentUserId);
|
||||||
|
|
||||||
for (UserChangedListener listener : mListeners) {
|
for (UserChangedListener listener : mListeners) {
|
||||||
@@ -168,7 +165,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
break;
|
break;
|
||||||
case Intent.ACTION_USER_UNLOCKED:
|
case Intent.ACTION_USER_UNLOCKED:
|
||||||
// Start the overview connection to the launcher service
|
// Start the overview connection to the launcher service
|
||||||
mOverviewProxyService.get().startConnectionToCurrentUser();
|
Dependency.get(OverviewProxyService.class).startConnectionToCurrentUser();
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION:
|
case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION:
|
||||||
final IntentSender intentSender = intent.getParcelableExtra(
|
final IntentSender intentSender = intent.getParcelableExtra(
|
||||||
@@ -191,26 +188,28 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Late-init
|
protected final Context mContext;
|
||||||
|
private final Handler mMainHandler;
|
||||||
|
protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
|
||||||
|
protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>();
|
||||||
|
|
||||||
|
protected int mCurrentUserId = 0;
|
||||||
protected NotificationPresenter mPresenter;
|
protected NotificationPresenter mPresenter;
|
||||||
protected ContentObserver mLockscreenSettingsObserver;
|
protected ContentObserver mLockscreenSettingsObserver;
|
||||||
protected ContentObserver mSettingsObserver;
|
protected ContentObserver mSettingsObserver;
|
||||||
protected KeyguardManager mKeyguardManager;
|
|
||||||
|
|
||||||
protected int mCurrentUserId = 0;
|
|
||||||
private int mState = StatusBarState.SHADE;
|
|
||||||
private boolean mHideSilentNotificationsOnLockscreen;
|
private boolean mHideSilentNotificationsOnLockscreen;
|
||||||
private boolean mShowLockscreenNotifications;
|
|
||||||
private boolean mAllowLockscreenRemoteInput;
|
private NotificationEntryManager getEntryManager() {
|
||||||
|
if (mEntryManager == null) {
|
||||||
|
mEntryManager = Dependency.get(NotificationEntryManager.class);
|
||||||
|
}
|
||||||
|
return mEntryManager;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NotificationLockscreenUserManagerImpl(
|
public NotificationLockscreenUserManagerImpl(Context context,
|
||||||
Context context,
|
|
||||||
BroadcastDispatcher broadcastDispatcher,
|
BroadcastDispatcher broadcastDispatcher,
|
||||||
DevicePolicyManager devicePolicyManager,
|
DevicePolicyManager devicePolicyManager,
|
||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
|
||||||
Lazy<NotificationEntryManager> notificationEntryManagerLazy,
|
|
||||||
Lazy<OverviewProxyService> overviewProxyServiceLazy,
|
|
||||||
UserManager userManager,
|
UserManager userManager,
|
||||||
Lazy<NotificationVisibilityProvider> visibilityProviderLazy,
|
Lazy<NotificationVisibilityProvider> visibilityProviderLazy,
|
||||||
Lazy<CommonNotifCollection> commonNotifCollectionLazy,
|
Lazy<CommonNotifCollection> commonNotifCollectionLazy,
|
||||||
@@ -226,11 +225,9 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mMainHandler = mainHandler;
|
mMainHandler = mainHandler;
|
||||||
mDevicePolicyManager = devicePolicyManager;
|
mDevicePolicyManager = devicePolicyManager;
|
||||||
mUserManager = userManager;
|
mUserManager = userManager;
|
||||||
mOverviewProxyService = overviewProxyServiceLazy;
|
|
||||||
mCurrentUserId = ActivityManager.getCurrentUser();
|
mCurrentUserId = ActivityManager.getCurrentUser();
|
||||||
mVisibilityProviderLazy = visibilityProviderLazy;
|
mVisibilityProviderLazy = visibilityProviderLazy;
|
||||||
mCommonNotifCollectionLazy = commonNotifCollectionLazy;
|
mCommonNotifCollectionLazy = commonNotifCollectionLazy;
|
||||||
mEntryManagerLazy = notificationEntryManagerLazy;
|
|
||||||
mClickNotifier = clickNotifier;
|
mClickNotifier = clickNotifier;
|
||||||
statusBarStateController.addCallback(this);
|
statusBarStateController.addCallback(this);
|
||||||
mLockPatternUtils = new LockPatternUtils(context);
|
mLockPatternUtils = new LockPatternUtils(context);
|
||||||
@@ -239,12 +236,10 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mDeviceProvisionedController = deviceProvisionedController;
|
mDeviceProvisionedController = deviceProvisionedController;
|
||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
mKeyguardStateController = keyguardStateController;
|
mKeyguardStateController = keyguardStateController;
|
||||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
|
||||||
|
|
||||||
dumpManager.registerDumpable(this);
|
dumpManager.registerDumpable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUpWithPresenter(NotificationPresenter presenter) {
|
public void setUpWithPresenter(NotificationPresenter presenter) {
|
||||||
mPresenter = presenter;
|
mPresenter = presenter;
|
||||||
|
|
||||||
@@ -257,10 +252,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mUsersAllowingNotifications.clear();
|
mUsersAllowingNotifications.clear();
|
||||||
// ... and refresh all the notifications
|
// ... and refresh all the notifications
|
||||||
updateLockscreenNotificationSetting();
|
updateLockscreenNotificationSetting();
|
||||||
for (Runnable listener : mOnSensitiveContentRedactionChangeListeners) {
|
getEntryManager().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS,"
|
||||||
listener.run();
|
|
||||||
}
|
|
||||||
mEntryManagerLazy.get().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS,"
|
|
||||||
+ " or LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS change");
|
+ " or LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS change");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -270,7 +262,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
updateLockscreenNotificationSetting();
|
updateLockscreenNotificationSetting();
|
||||||
if (mDeviceProvisionedController.isDeviceProvisioned()) {
|
if (mDeviceProvisionedController.isDeviceProvisioned()) {
|
||||||
mEntryManagerLazy.get().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT"
|
getEntryManager().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT"
|
||||||
+ " or ZEN_MODE change");
|
+ " or ZEN_MODE change");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,17 +322,14 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mSettingsObserver.onChange(false); // set up
|
mSettingsObserver.onChange(false); // set up
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldShowLockscreenNotifications() {
|
public boolean shouldShowLockscreenNotifications() {
|
||||||
return mShowLockscreenNotifications;
|
return mShowLockscreenNotifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldAllowLockscreenRemoteInput() {
|
public boolean shouldAllowLockscreenRemoteInput() {
|
||||||
return mAllowLockscreenRemoteInput;
|
return mAllowLockscreenRemoteInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCurrentProfile(int userId) {
|
public boolean isCurrentProfile(int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
|
return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
|
||||||
@@ -355,7 +344,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
if (userId == UserHandle.USER_ALL) {
|
if (userId == UserHandle.USER_ALL) {
|
||||||
userId = mCurrentUserId;
|
userId = mCurrentUserId;
|
||||||
}
|
}
|
||||||
boolean inLockdown = mKeyguardUpdateMonitor.isUserInLockdown(userId);
|
boolean inLockdown = Dependency.get(KeyguardUpdateMonitor.class).isUserInLockdown(userId);
|
||||||
mUsersInLockdownLatestResult.put(userId, inLockdown);
|
mUsersInLockdownLatestResult.put(userId, inLockdown);
|
||||||
return inLockdown;
|
return inLockdown;
|
||||||
}
|
}
|
||||||
@@ -364,7 +353,6 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
* Returns true if we're on a secure lockscreen and the user wants to hide notification data.
|
* Returns true if we're on a secure lockscreen and the user wants to hide notification data.
|
||||||
* If so, notifications should be hidden.
|
* If so, notifications should be hidden.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean shouldHideNotifications(int userId) {
|
public boolean shouldHideNotifications(int userId) {
|
||||||
boolean hide = isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId)
|
boolean hide = isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId)
|
||||||
|| (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId))
|
|| (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId))
|
||||||
@@ -377,7 +365,6 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
* Returns true if we're on a secure lockscreen and the user wants to hide notifications via
|
* Returns true if we're on a secure lockscreen and the user wants to hide notifications via
|
||||||
* package-specific override.
|
* package-specific override.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean shouldHideNotifications(String key) {
|
public boolean shouldHideNotifications(String key) {
|
||||||
if (mCommonNotifCollectionLazy.get() == null) {
|
if (mCommonNotifCollectionLazy.get() == null) {
|
||||||
Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable());
|
Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable());
|
||||||
@@ -388,7 +375,6 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
&& visibleEntry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET;
|
&& visibleEntry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldShowOnKeyguard(NotificationEntry entry) {
|
public boolean shouldShowOnKeyguard(NotificationEntry entry) {
|
||||||
if (mCommonNotifCollectionLazy.get() == null) {
|
if (mCommonNotifCollectionLazy.get() == null) {
|
||||||
Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable());
|
Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable());
|
||||||
@@ -411,6 +397,14 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
return mShowLockscreenNotifications && exceedsPriorityThreshold;
|
return mShowLockscreenNotifications && exceedsPriorityThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setShowLockscreenNotifications(boolean show) {
|
||||||
|
mShowLockscreenNotifications = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
|
||||||
|
mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
|
||||||
|
}
|
||||||
|
|
||||||
protected void updateLockscreenNotificationSetting() {
|
protected void updateLockscreenNotificationSetting() {
|
||||||
final boolean show = mSecureSettings.getIntForUser(
|
final boolean show = mSecureSettings.getIntForUser(
|
||||||
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
|
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
|
||||||
@@ -424,7 +418,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mHideSilentNotificationsOnLockscreen = mSecureSettings.getIntForUser(
|
mHideSilentNotificationsOnLockscreen = mSecureSettings.getIntForUser(
|
||||||
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1, mCurrentUserId) == 0;
|
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1, mCurrentUserId) == 0;
|
||||||
|
|
||||||
mShowLockscreenNotifications = show && allowedByDpm;
|
setShowLockscreenNotifications(show && allowedByDpm);
|
||||||
|
|
||||||
if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
|
if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
|
||||||
final boolean remoteInput = mSecureSettings.getIntForUser(
|
final boolean remoteInput = mSecureSettings.getIntForUser(
|
||||||
@@ -434,9 +428,9 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
final boolean remoteInputDpm =
|
final boolean remoteInputDpm =
|
||||||
(dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
|
(dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
|
||||||
|
|
||||||
mAllowLockscreenRemoteInput = remoteInput && remoteInputDpm;
|
setLockscreenAllowRemoteInput(remoteInput && remoteInputDpm);
|
||||||
} else {
|
} else {
|
||||||
mAllowLockscreenRemoteInput = false;
|
setLockscreenAllowRemoteInput(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +438,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
* Has the given user chosen to allow their private (full) notifications to be shown even
|
* Has the given user chosen to allow their private (full) notifications to be shown even
|
||||||
* when the lockscreen is in "public" (secure & locked) mode?
|
* when the lockscreen is in "public" (secure & locked) mode?
|
||||||
*/
|
*/
|
||||||
protected boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
|
public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
|
||||||
if (userHandle == UserHandle.USER_ALL) {
|
if (userHandle == UserHandle.USER_ALL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -489,12 +483,10 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
/**
|
/**
|
||||||
* Save the current "public" (locked and secure) state of the lockscreen.
|
* Save the current "public" (locked and secure) state of the lockscreen.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void setLockscreenPublicMode(boolean publicMode, int userId) {
|
public void setLockscreenPublicMode(boolean publicMode, int userId) {
|
||||||
mLockscreenPublicMode.put(userId, publicMode);
|
mLockscreenPublicMode.put(userId, publicMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLockscreenPublicMode(int userId) {
|
public boolean isLockscreenPublicMode(int userId) {
|
||||||
if (userId == UserHandle.USER_ALL) {
|
if (userId == UserHandle.USER_ALL) {
|
||||||
return mLockscreenPublicMode.get(mCurrentUserId, false);
|
return mLockscreenPublicMode.get(mCurrentUserId, false);
|
||||||
@@ -511,7 +503,6 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
|
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
|
||||||
* "public" (secure & locked) mode?
|
* "public" (secure & locked) mode?
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean userAllowsNotificationsInPublic(int userHandle) {
|
public boolean userAllowsNotificationsInPublic(int userHandle) {
|
||||||
if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) {
|
if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) {
|
||||||
return true;
|
return true;
|
||||||
@@ -532,37 +523,36 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if the entry needs redaction when on the lockscreen. */
|
/** @return true if the entry needs redaction when on the lockscreen. */
|
||||||
@Override
|
public boolean needsRedaction(NotificationEntry ent) {
|
||||||
public boolean notifNeedsRedactionInPublic(NotificationEntry ent) {
|
|
||||||
int userId = ent.getSbn().getUserId();
|
int userId = ent.getSbn().getUserId();
|
||||||
return ent.hasSensitiveContents() && sensitiveNotifsNeedRedactionInPublic(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sensitiveNotifsNeedRedactionInPublic(int userId) {
|
|
||||||
boolean isCurrentUserRedactingNotifs =
|
boolean isCurrentUserRedactingNotifs =
|
||||||
!userAllowsPrivateNotificationsInPublic(mCurrentUserId);
|
!userAllowsPrivateNotificationsInPublic(mCurrentUserId);
|
||||||
if (userId == mCurrentUserId) {
|
|
||||||
return isCurrentUserRedactingNotifs;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId);
|
boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId);
|
||||||
boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId);
|
boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId);
|
||||||
|
|
||||||
// redact notifications if the current user is redacting notifications; however if the
|
// redact notifications if the current user is redacting notifications; however if the
|
||||||
// notification is associated with a managed profile, we rely on the managed profile
|
// notification is associated with a managed profile, we rely on the managed profile
|
||||||
// setting to determine whether to redact it
|
// setting to determine whether to redact it
|
||||||
return (!isNotifForManagedProfile && isCurrentUserRedactingNotifs) || isNotifUserRedacted;
|
boolean isNotifRedacted = (!isNotifForManagedProfile && isCurrentUserRedactingNotifs)
|
||||||
|
|| isNotifUserRedacted;
|
||||||
|
|
||||||
|
boolean notificationRequestsRedaction =
|
||||||
|
ent.getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE;
|
||||||
|
boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey());
|
||||||
|
|
||||||
|
return userForcesRedaction || notificationRequestsRedaction && isNotifRedacted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean packageHasVisibilityOverride(String key) {
|
||||||
public void addOnNeedsRedactionInPublicChangedListener(Runnable listener) {
|
if (mCommonNotifCollectionLazy.get() == null) {
|
||||||
mOnSensitiveContentRedactionChangeListeners.addIfAbsent(listener);
|
Log.wtf(TAG, "mEntryManager was null!", new Throwable());
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
@Override
|
NotificationEntry entry = mCommonNotifCollectionLazy.get().getEntry(key);
|
||||||
public void removeOnNeedsRedactionInPublicChangedListener(Runnable listener) {
|
return entry != null
|
||||||
mOnSensitiveContentRedactionChangeListeners.remove(listener);
|
&& entry.getRanking().getLockscreenVisibilityOverride()
|
||||||
|
== Notification.VISIBILITY_PRIVATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCurrentProfilesCache() {
|
private void updateCurrentProfilesCache() {
|
||||||
@@ -582,16 +572,12 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
for (UserChangedListener listener : mListeners) {
|
for (UserChangedListener listener : mListeners) {
|
||||||
listener.onCurrentProfilesChanged(mCurrentProfiles);
|
listener.onCurrentProfilesChanged(mCurrentProfiles);
|
||||||
}
|
}
|
||||||
for (Runnable listener : mOnSensitiveContentRedactionChangeListeners) {
|
|
||||||
listener.run();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If any of the profiles are in public mode.
|
* If any of the profiles are in public mode.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean isAnyProfilePublicMode() {
|
public boolean isAnyProfilePublicMode() {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
|
for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
|
||||||
@@ -620,12 +606,10 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
/**
|
/**
|
||||||
* Returns the current user id. This can change if the user is switched.
|
* Returns the current user id. This can change if the user is switched.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public int getCurrentUserId() {
|
public int getCurrentUserId() {
|
||||||
return mCurrentUserId;
|
return mCurrentUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SparseArray<UserInfo> getCurrentProfiles() {
|
public SparseArray<UserInfo> getCurrentProfiles() {
|
||||||
return mCurrentProfiles;
|
return mCurrentProfiles;
|
||||||
}
|
}
|
||||||
@@ -666,8 +650,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
setLockscreenPublicMode(isProfilePublic, userId);
|
setLockscreenPublicMode(isProfilePublic, userId);
|
||||||
mUsersWithSeparateWorkChallenge.put(userId, needsSeparateChallenge);
|
mUsersWithSeparateWorkChallenge.put(userId, needsSeparateChallenge);
|
||||||
}
|
}
|
||||||
mEntryManagerLazy.get()
|
getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
|
||||||
.updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import com.android.wm.shell.bubbles.Bubbles;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
@@ -208,9 +207,12 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
|| !mLockscreenUserManager.needsSeparateWorkChallenge(userId))) {
|
|| !mLockscreenUserManager.needsSeparateWorkChallenge(userId))) {
|
||||||
userPublic = false;
|
userPublic = false;
|
||||||
}
|
}
|
||||||
boolean needsRedaction = mLockscreenUserManager.notifNeedsRedactionInPublic(ent);
|
boolean needsRedaction = mLockscreenUserManager.needsRedaction(ent);
|
||||||
boolean sensitive = userPublic && needsRedaction;
|
boolean sensitive = userPublic && needsRedaction;
|
||||||
ent.getRow().setSensitive(sensitive);
|
boolean deviceSensitive = devicePublic
|
||||||
|
&& !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
|
||||||
|
currentUserId);
|
||||||
|
ent.setSensitive(sensitive, deviceSensitive);
|
||||||
ent.getRow().setNeedsRedaction(needsRedaction);
|
ent.getRow().setNeedsRedaction(needsRedaction);
|
||||||
mLowPriorityInflationHelper.recheckLowPriorityViewAndInflate(ent, ent.getRow());
|
mLowPriorityInflationHelper.recheckLowPriorityViewAndInflate(ent, ent.getRow());
|
||||||
boolean isChildInGroup = mGroupManager.isChildInGroup(ent);
|
boolean isChildInGroup = mGroupManager.isChildInGroup(ent);
|
||||||
@@ -363,8 +365,6 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
boolean hasClearableAlertingNotifs = false;
|
boolean hasClearableAlertingNotifs = false;
|
||||||
boolean hasNonClearableSilentNotifs = false;
|
boolean hasNonClearableSilentNotifs = false;
|
||||||
boolean hasClearableSilentNotifs = false;
|
boolean hasClearableSilentNotifs = false;
|
||||||
HashSet<Integer> clearableAlertingSensitiveNotifUsers = new HashSet<>();
|
|
||||||
HashSet<Integer> clearableSilentSensitiveNotifUsers = new HashSet<>();
|
|
||||||
final int childCount = mListContainer.getContainerChildCount();
|
final int childCount = mListContainer.getContainerChildCount();
|
||||||
int visibleTopLevelEntries = 0;
|
int visibleTopLevelEntries = 0;
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
@@ -376,11 +376,10 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
final ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
||||||
NotificationEntry entry = row.getEntry();
|
boolean isSilent = row.getEntry().getBucket() == BUCKET_SILENT;
|
||||||
boolean isSilent = entry.getBucket() == BUCKET_SILENT;
|
|
||||||
// NOTE: NotificationEntry.isClearable() will internally check group children to ensure
|
// NOTE: NotificationEntry.isClearable() will internally check group children to ensure
|
||||||
// the group itself definitively clearable.
|
// the group itself definitively clearable.
|
||||||
boolean isClearable = entry.isClearable();
|
boolean isClearable = row.getEntry().isClearable();
|
||||||
visibleTopLevelEntries++;
|
visibleTopLevelEntries++;
|
||||||
if (isSilent) {
|
if (isSilent) {
|
||||||
if (isClearable) {
|
if (isClearable) {
|
||||||
@@ -395,24 +394,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
hasNonClearableAlertingNotifs = true;
|
hasNonClearableAlertingNotifs = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isClearable && entry.hasSensitiveContents()) {
|
|
||||||
int userId = entry.getSbn().getUserId();
|
|
||||||
if (isSilent) {
|
|
||||||
clearableSilentSensitiveNotifUsers.add(userId);
|
|
||||||
} else {
|
|
||||||
clearableAlertingSensitiveNotifUsers.add(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mStackController.setNotifStats(new NotifStats(
|
mStackController.setNotifStats(new NotifStats(
|
||||||
visibleTopLevelEntries /* numActiveNotifs */,
|
visibleTopLevelEntries /* numActiveNotifs */,
|
||||||
hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */,
|
hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */,
|
||||||
hasClearableAlertingNotifs /* hasClearableAlertingNotifs */,
|
hasClearableAlertingNotifs /* hasClearableAlertingNotifs */,
|
||||||
hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */,
|
hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */,
|
||||||
hasClearableSilentNotifs /* hasClearableSilentNotifs */,
|
hasClearableSilentNotifs /* hasClearableSilentNotifs */
|
||||||
clearableAlertingSensitiveNotifUsers /* clearableAlertingSensitiveNotifUsers */,
|
|
||||||
clearableSilentSensitiveNotifUsers /* clearableSilentSensitiveNotifUsers */
|
|
||||||
|
|
||||||
));
|
));
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean isDynamicPrivacyEnabled() {
|
boolean isDynamicPrivacyEnabled() {
|
||||||
return mLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(
|
return !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
|
||||||
mLockscreenUserManager.getCurrentUserId());
|
mLockscreenUserManager.getCurrentUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,10 +95,6 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac
|
|||||||
mListeners.add(listener);
|
mListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener(Listener listener) {
|
|
||||||
mListeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the notification shade currently in a locked down mode where it's fully showing but the
|
* Is the notification shade currently in a locked down mode where it's fully showing but the
|
||||||
* contents aren't revealed yet?
|
* contents aren't revealed yet?
|
||||||
|
|||||||
@@ -169,6 +169,9 @@ public final class NotificationEntry extends ListEntry {
|
|||||||
*/
|
*/
|
||||||
private boolean hasSentReply;
|
private boolean hasSentReply;
|
||||||
|
|
||||||
|
private boolean mSensitive = true;
|
||||||
|
private List<OnSensitivityChangedListener> mOnSensitivityChangedListeners = new ArrayList<>();
|
||||||
|
|
||||||
private boolean mAutoHeadsUp;
|
private boolean mAutoHeadsUp;
|
||||||
private boolean mPulseSupressed;
|
private boolean mPulseSupressed;
|
||||||
private int mBucket = BUCKET_ALERTING;
|
private int mBucket = BUCKET_ALERTING;
|
||||||
@@ -864,29 +867,33 @@ public final class NotificationEntry extends ListEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the visibility of this notification on the lockscreen, taking into account both the
|
* Set this notification to be sensitive.
|
||||||
* notification's defined visibility, as well as the visibility override as determined by the
|
*
|
||||||
* device policy.
|
* @param sensitive true if the content of this notification is sensitive right now
|
||||||
|
* @param deviceSensitive true if the device in general is sensitive right now
|
||||||
*/
|
*/
|
||||||
public int getLockscreenVisibility() {
|
public void setSensitive(boolean sensitive, boolean deviceSensitive) {
|
||||||
int setting = mRanking.getLockscreenVisibilityOverride();
|
getRow().setSensitive(sensitive, deviceSensitive);
|
||||||
if (setting == Ranking.VISIBILITY_NO_OVERRIDE) {
|
if (sensitive != mSensitive) {
|
||||||
setting = mSbn.getNotification().visibility;
|
mSensitive = sensitive;
|
||||||
|
for (int i = 0; i < mOnSensitivityChangedListeners.size(); i++) {
|
||||||
|
mOnSensitivityChangedListeners.get(i).onSensitivityChanged(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return setting;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean isSensitive() {
|
||||||
* Does this notification contain sensitive content? If the user's settings specify, then this
|
return mSensitive;
|
||||||
* content would need to be redacted when the device this public.
|
}
|
||||||
*
|
|
||||||
* NOTE: If the notification's visibility setting is VISIBILITY_SECRET, then this will return
|
/** Add a listener to be notified when the entry's sensitivity changes. */
|
||||||
* false; SECRET notifications are omitted entirely when the device is public, so effectively
|
public void addOnSensitivityChangedListener(OnSensitivityChangedListener listener) {
|
||||||
* the contents of the notification are not sensitive whenever the notification is actually
|
mOnSensitivityChangedListeners.add(listener);
|
||||||
* visible.
|
}
|
||||||
*/
|
|
||||||
public boolean hasSensitiveContents() {
|
/** Remove a listener that was registered above. */
|
||||||
return getLockscreenVisibility() == Notification.VISIBILITY_PRIVATE;
|
public void removeOnSensitivityChangedListener(OnSensitivityChangedListener listener) {
|
||||||
|
mOnSensitivityChangedListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPulseSuppressed() {
|
public boolean isPulseSuppressed() {
|
||||||
@@ -947,6 +954,12 @@ public final class NotificationEntry extends ListEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Listener interface for {@link #addOnSensitivityChangedListener} */
|
||||||
|
public interface OnSensitivityChangedListener {
|
||||||
|
/** Called when the sensitivity changes */
|
||||||
|
void onSensitivityChanged(@NonNull NotificationEntry entry);
|
||||||
|
}
|
||||||
|
|
||||||
/** @see #getDismissState() */
|
/** @see #getDismissState() */
|
||||||
public enum DismissState {
|
public enum DismissState {
|
||||||
/** User has not dismissed this notif or its parent */
|
/** User has not dismissed this notif or its parent */
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class NotifCoordinatorsImpl @Inject constructor(
|
|||||||
smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
|
smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
|
||||||
viewConfigCoordinator: ViewConfigCoordinator,
|
viewConfigCoordinator: ViewConfigCoordinator,
|
||||||
visualStabilityCoordinator: VisualStabilityCoordinator,
|
visualStabilityCoordinator: VisualStabilityCoordinator,
|
||||||
|
sensitiveContentCoordinator: SensitiveContentCoordinator,
|
||||||
) : NotifCoordinators {
|
) : NotifCoordinators {
|
||||||
|
|
||||||
private val mCoordinators: MutableList<Coordinator> = ArrayList()
|
private val mCoordinators: MutableList<Coordinator> = ArrayList()
|
||||||
@@ -92,6 +93,7 @@ class NotifCoordinatorsImpl @Inject constructor(
|
|||||||
mCoordinators.add(shadeEventCoordinator)
|
mCoordinators.add(shadeEventCoordinator)
|
||||||
mCoordinators.add(viewConfigCoordinator)
|
mCoordinators.add(viewConfigCoordinator)
|
||||||
mCoordinators.add(visualStabilityCoordinator)
|
mCoordinators.add(visualStabilityCoordinator)
|
||||||
|
mCoordinators.add(sensitiveContentCoordinator)
|
||||||
if (notifPipelineFlags.isSmartspaceDedupingEnabled()) {
|
if (notifPipelineFlags.isSmartspaceDedupingEnabled()) {
|
||||||
mCoordinators.add(smartspaceDedupingCoordinator)
|
mCoordinators.add(smartspaceDedupingCoordinator)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.notification.collection.coordinator;
|
package com.android.systemui.statusbar.notification.collection.coordinator;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
@@ -28,11 +29,13 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NodeController;
|
import com.android.systemui.statusbar.notification.collection.render.NodeController;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
|
||||||
import com.android.systemui.statusbar.notification.dagger.AlertingHeader;
|
import com.android.systemui.statusbar.notification.dagger.AlertingHeader;
|
||||||
import com.android.systemui.statusbar.notification.dagger.SilentHeader;
|
import com.android.systemui.statusbar.notification.dagger.SilentHeader;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
|
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -50,10 +53,10 @@ public class RankingCoordinator implements Coordinator {
|
|||||||
private final HighPriorityProvider mHighPriorityProvider;
|
private final HighPriorityProvider mHighPriorityProvider;
|
||||||
private final SectionClassifier mSectionClassifier;
|
private final SectionClassifier mSectionClassifier;
|
||||||
private final NodeController mSilentNodeController;
|
private final NodeController mSilentNodeController;
|
||||||
|
private final SectionHeaderController mSilentHeaderController;
|
||||||
private final NodeController mAlertingHeaderController;
|
private final NodeController mAlertingHeaderController;
|
||||||
private final AlertingNotifSectioner mAlertingNotifSectioner = new AlertingNotifSectioner();
|
private boolean mHasSilentEntries;
|
||||||
private final SilentNotifSectioner mSilentNotifSectioner = new SilentNotifSectioner();
|
private boolean mHasMinimizedEntries;
|
||||||
private final MinimizedNotifSectioner mMinimizedNotifSectioner = new MinimizedNotifSectioner();
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RankingCoordinator(
|
public RankingCoordinator(
|
||||||
@@ -61,12 +64,14 @@ public class RankingCoordinator implements Coordinator {
|
|||||||
HighPriorityProvider highPriorityProvider,
|
HighPriorityProvider highPriorityProvider,
|
||||||
SectionClassifier sectionClassifier,
|
SectionClassifier sectionClassifier,
|
||||||
@AlertingHeader NodeController alertingHeaderController,
|
@AlertingHeader NodeController alertingHeaderController,
|
||||||
|
@SilentHeader SectionHeaderController silentHeaderController,
|
||||||
@SilentHeader NodeController silentNodeController) {
|
@SilentHeader NodeController silentNodeController) {
|
||||||
mStatusBarStateController = statusBarStateController;
|
mStatusBarStateController = statusBarStateController;
|
||||||
mHighPriorityProvider = highPriorityProvider;
|
mHighPriorityProvider = highPriorityProvider;
|
||||||
mSectionClassifier = sectionClassifier;
|
mSectionClassifier = sectionClassifier;
|
||||||
mAlertingHeaderController = alertingHeaderController;
|
mAlertingHeaderController = alertingHeaderController;
|
||||||
mSilentNodeController = silentNodeController;
|
mSilentNodeController = silentNodeController;
|
||||||
|
mSilentHeaderController = silentHeaderController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -90,6 +95,82 @@ public class RankingCoordinator implements Coordinator {
|
|||||||
return mMinimizedNotifSectioner;
|
return mMinimizedNotifSectioner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final NotifSectioner mAlertingNotifSectioner = new NotifSectioner("Alerting",
|
||||||
|
NotificationPriorityBucketKt.BUCKET_ALERTING) {
|
||||||
|
@Override
|
||||||
|
public boolean isInSection(ListEntry entry) {
|
||||||
|
return mHighPriorityProvider.isHighPriority(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public NodeController getHeaderNodeController() {
|
||||||
|
// TODO: remove SHOW_ALL_SECTIONS, this redundant method, and mAlertingHeaderController
|
||||||
|
if (SHOW_ALL_SECTIONS) {
|
||||||
|
return mAlertingHeaderController;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final NotifSectioner mSilentNotifSectioner = new NotifSectioner("Silent",
|
||||||
|
NotificationPriorityBucketKt.BUCKET_SILENT) {
|
||||||
|
@Override
|
||||||
|
public boolean isInSection(ListEntry entry) {
|
||||||
|
return !mHighPriorityProvider.isHighPriority(entry)
|
||||||
|
&& !entry.getRepresentativeEntry().isAmbient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public NodeController getHeaderNodeController() {
|
||||||
|
return mSilentNodeController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public void onEntriesUpdated(@NonNull List<ListEntry> entries) {
|
||||||
|
mHasSilentEntries = false;
|
||||||
|
for (int i = 0; i < entries.size(); i++) {
|
||||||
|
if (entries.get(i).getRepresentativeEntry().getSbn().isClearable()) {
|
||||||
|
mHasSilentEntries = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSilentHeaderController.setClearSectionEnabled(
|
||||||
|
mHasSilentEntries | mHasMinimizedEntries);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final NotifSectioner mMinimizedNotifSectioner = new NotifSectioner("Minimized",
|
||||||
|
NotificationPriorityBucketKt.BUCKET_SILENT) {
|
||||||
|
@Override
|
||||||
|
public boolean isInSection(ListEntry entry) {
|
||||||
|
return !mHighPriorityProvider.isHighPriority(entry)
|
||||||
|
&& entry.getRepresentativeEntry().isAmbient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public NodeController getHeaderNodeController() {
|
||||||
|
return mSilentNodeController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public void onEntriesUpdated(@NonNull List<ListEntry> entries) {
|
||||||
|
mHasMinimizedEntries = false;
|
||||||
|
for (int i = 0; i < entries.size(); i++) {
|
||||||
|
if (entries.get(i).getRepresentativeEntry().getSbn().isClearable()) {
|
||||||
|
mHasMinimizedEntries = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSilentHeaderController.setClearSectionEnabled(
|
||||||
|
mHasSilentEntries | mHasMinimizedEntries);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether to filter out the given notification based the notification's Ranking object.
|
* Checks whether to filter out the given notification based the notification's Ranking object.
|
||||||
* NotifListBuilder invalidates the notification list each time the ranking is updated,
|
* NotifListBuilder invalidates the notification list each time the ranking is updated,
|
||||||
@@ -121,64 +202,4 @@ public class RankingCoordinator implements Coordinator {
|
|||||||
mDndVisualEffectsFilter.invalidateList();
|
mDndVisualEffectsFilter.invalidateList();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private class AlertingNotifSectioner extends NotifSectioner {
|
|
||||||
|
|
||||||
AlertingNotifSectioner() {
|
|
||||||
super("Alerting", NotificationPriorityBucketKt.BUCKET_ALERTING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInSection(ListEntry entry) {
|
|
||||||
return mHighPriorityProvider.isHighPriority(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public NodeController getHeaderNodeController() {
|
|
||||||
// TODO: remove SHOW_ALL_SECTIONS, this redundant method, and mAlertingHeaderController
|
|
||||||
if (SHOW_ALL_SECTIONS) {
|
|
||||||
return mAlertingHeaderController;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SilentNotifSectioner extends NotifSectioner {
|
|
||||||
|
|
||||||
SilentNotifSectioner() {
|
|
||||||
super("Silent", NotificationPriorityBucketKt.BUCKET_SILENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInSection(ListEntry entry) {
|
|
||||||
return !mHighPriorityProvider.isHighPriority(entry)
|
|
||||||
&& !entry.getRepresentativeEntry().isAmbient();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public NodeController getHeaderNodeController() {
|
|
||||||
return mSilentNodeController;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MinimizedNotifSectioner extends NotifSectioner {
|
|
||||||
|
|
||||||
MinimizedNotifSectioner() {
|
|
||||||
super("Minimized", NotificationPriorityBucketKt.BUCKET_SILENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInSection(ListEntry entry) {
|
|
||||||
return !mHighPriorityProvider.isHighPriority(entry)
|
|
||||||
&& entry.getRepresentativeEntry().isAmbient();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public NodeController getHeaderNodeController() {
|
|
||||||
return mSilentNodeController;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.statusbar.notification.collection.coordinator
|
||||||
|
|
||||||
|
import android.os.UserHandle
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
|
import com.android.systemui.statusbar.StatusBarState
|
||||||
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController
|
||||||
|
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
|
||||||
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Module(includes = [PrivateSensitiveContentCoordinatorModule::class])
|
||||||
|
interface SensitiveContentCoordinatorModule
|
||||||
|
|
||||||
|
@Module
|
||||||
|
private interface PrivateSensitiveContentCoordinatorModule {
|
||||||
|
@Binds
|
||||||
|
fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Coordinates re-inflation and post-processing of sensitive notification content. */
|
||||||
|
interface SensitiveContentCoordinator : Coordinator
|
||||||
|
|
||||||
|
@CoordinatorScope
|
||||||
|
private class SensitiveContentCoordinatorImpl @Inject constructor(
|
||||||
|
private val dynamicPrivacyController: DynamicPrivacyController,
|
||||||
|
private val lockscreenUserManager: NotificationLockscreenUserManager,
|
||||||
|
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
|
private val statusBarStateController: StatusBarStateController,
|
||||||
|
private val keyguardStateController: KeyguardStateController
|
||||||
|
) : Invalidator("SensitiveContentInvalidator"),
|
||||||
|
SensitiveContentCoordinator,
|
||||||
|
DynamicPrivacyController.Listener,
|
||||||
|
OnBeforeRenderListListener {
|
||||||
|
|
||||||
|
override fun attach(pipeline: NotifPipeline) {
|
||||||
|
dynamicPrivacyController.addListener(this)
|
||||||
|
pipeline.addOnBeforeRenderListListener(this)
|
||||||
|
pipeline.addPreRenderInvalidator(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDynamicPrivacyChanged(): Unit = invalidateList()
|
||||||
|
|
||||||
|
override fun onBeforeRenderList(entries: List<ListEntry>) {
|
||||||
|
if (keyguardStateController.isKeyguardGoingAway() ||
|
||||||
|
statusBarStateController.getState() == StatusBarState.KEYGUARD &&
|
||||||
|
keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(
|
||||||
|
KeyguardUpdateMonitor.getCurrentUser())) {
|
||||||
|
// don't update yet if:
|
||||||
|
// - the keyguard is currently going away
|
||||||
|
// - LS is about to be dismissed by a biometric that bypasses LS (avoid notif flash)
|
||||||
|
|
||||||
|
// TODO(b/206118999): merge this class with KeyguardCoordinator which ensures the
|
||||||
|
// dependent state changes invalidate the pipeline
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val currentUserId = lockscreenUserManager.currentUserId
|
||||||
|
val devicePublic = lockscreenUserManager.isLockscreenPublicMode(currentUserId)
|
||||||
|
val deviceSensitive = devicePublic &&
|
||||||
|
!lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId)
|
||||||
|
val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked
|
||||||
|
for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) {
|
||||||
|
val notifUserId = entry.sbn.user.identifier
|
||||||
|
val userLockscreen = devicePublic ||
|
||||||
|
lockscreenUserManager.isLockscreenPublicMode(notifUserId)
|
||||||
|
val userPublic = when {
|
||||||
|
// if we're not on the lockscreen, we're definitely private
|
||||||
|
!userLockscreen -> false
|
||||||
|
// we are on the lockscreen, so unless we're dynamically unlocked, we're
|
||||||
|
// definitely public
|
||||||
|
!dynamicallyUnlocked -> true
|
||||||
|
// we're dynamically unlocked, but check if the notification needs
|
||||||
|
// a separate challenge if it's from a work profile
|
||||||
|
else -> when (notifUserId) {
|
||||||
|
currentUserId -> false
|
||||||
|
UserHandle.USER_ALL -> false
|
||||||
|
else -> lockscreenUserManager.needsSeparateWorkChallenge(notifUserId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val needsRedaction = lockscreenUserManager.needsRedaction(entry)
|
||||||
|
val isSensitive = userPublic && needsRedaction
|
||||||
|
entry.setSensitive(isSensitive, deviceSensitive)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractAllRepresentativeEntries(
|
||||||
|
entries: List<ListEntry>
|
||||||
|
): Sequence<NotificationEntry> =
|
||||||
|
entries.asSequence().flatMap(::extractAllRepresentativeEntries)
|
||||||
|
|
||||||
|
private fun extractAllRepresentativeEntries(listEntry: ListEntry): Sequence<NotificationEntry> =
|
||||||
|
sequence {
|
||||||
|
listEntry.representativeEntry?.let { yield(it) }
|
||||||
|
if (listEntry is GroupEntry) {
|
||||||
|
yieldAll(extractAllRepresentativeEntries(listEntry.children))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,8 +50,6 @@ class StackCoordinator @Inject internal constructor(
|
|||||||
var hasClearableAlertingNotifs = false
|
var hasClearableAlertingNotifs = false
|
||||||
var hasNonClearableSilentNotifs = false
|
var hasNonClearableSilentNotifs = false
|
||||||
var hasClearableSilentNotifs = false
|
var hasClearableSilentNotifs = false
|
||||||
val clearableAlertingSensitiveNotifUsers = mutableSetOf<Int>()
|
|
||||||
val clearableSilentSensitiveNotifUsers = mutableSetOf<Int>()
|
|
||||||
entries.forEach {
|
entries.forEach {
|
||||||
val section = checkNotNull(it.section) { "Null section for ${it.key}" }
|
val section = checkNotNull(it.section) { "Null section for ${it.key}" }
|
||||||
val entry = checkNotNull(it.representativeEntry) { "Null notif entry for ${it.key}" }
|
val entry = checkNotNull(it.representativeEntry) { "Null notif entry for ${it.key}" }
|
||||||
@@ -65,22 +63,13 @@ class StackCoordinator @Inject internal constructor(
|
|||||||
!isSilent && isClearable -> hasClearableAlertingNotifs = true
|
!isSilent && isClearable -> hasClearableAlertingNotifs = true
|
||||||
!isSilent && !isClearable -> hasNonClearableAlertingNotifs = true
|
!isSilent && !isClearable -> hasNonClearableAlertingNotifs = true
|
||||||
}
|
}
|
||||||
if (isClearable && entry.hasSensitiveContents()) {
|
|
||||||
if (isSilent) {
|
|
||||||
clearableSilentSensitiveNotifUsers.add(entry.sbn.userId)
|
|
||||||
} else {
|
|
||||||
clearableAlertingSensitiveNotifUsers.add(entry.sbn.userId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NotifStats(
|
return NotifStats(
|
||||||
numActiveNotifs = entries.size,
|
numActiveNotifs = entries.size,
|
||||||
hasNonClearableAlertingNotifs = hasNonClearableAlertingNotifs,
|
hasNonClearableAlertingNotifs = hasNonClearableAlertingNotifs,
|
||||||
hasClearableAlertingNotifs = hasClearableAlertingNotifs,
|
hasClearableAlertingNotifs = hasClearableAlertingNotifs,
|
||||||
hasNonClearableSilentNotifs = hasNonClearableSilentNotifs,
|
hasNonClearableSilentNotifs = hasNonClearableSilentNotifs,
|
||||||
hasClearableSilentNotifs = hasClearableSilentNotifs,
|
hasClearableSilentNotifs = hasClearableSilentNotifs
|
||||||
clearableAlertingSensitiveNotifUsers = clearableAlertingSensitiveNotifUsers,
|
|
||||||
clearableSilentSensitiveNotifUsers = clearableSilentSensitiveNotifUsers
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator.dagge
|
|||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
|
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
|
||||||
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
|
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
@@ -47,6 +48,7 @@ interface CoordinatorsSubcomponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Module(includes = [
|
@Module(includes = [
|
||||||
|
SensitiveContentCoordinatorModule::class,
|
||||||
])
|
])
|
||||||
private abstract class InternalCoordinatorsModule {
|
private abstract class InternalCoordinatorsModule {
|
||||||
@Binds
|
@Binds
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.notification.collection.inflation;
|
package com.android.systemui.statusbar.notification.collection.inflation;
|
||||||
|
|
||||||
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
|
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -251,13 +249,10 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
|
|||||||
RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
|
RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
|
||||||
params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
|
params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
|
||||||
params.setUseLowPriority(isLowPriority);
|
params.setUseLowPriority(isLowPriority);
|
||||||
boolean needsRedaction =
|
|
||||||
mNotificationLockscreenUserManager.notifNeedsRedactionInPublic(entry);
|
// TODO: Replace this API with RowContentBindParams directly. Also move to a separate
|
||||||
if (needsRedaction) {
|
// redaction controller.
|
||||||
params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC);
|
row.setNeedsRedaction(mNotificationLockscreenUserManager.needsRedaction(entry));
|
||||||
} else {
|
|
||||||
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
params.rebindAllContentViews();
|
params.rebindAllContentViews();
|
||||||
mRowContentBindStage.requestRebind(entry, en -> {
|
mRowContentBindStage.requestRebind(entry, en -> {
|
||||||
|
|||||||
@@ -28,21 +28,11 @@ data class NotifStats(
|
|||||||
val hasNonClearableAlertingNotifs: Boolean,
|
val hasNonClearableAlertingNotifs: Boolean,
|
||||||
val hasClearableAlertingNotifs: Boolean,
|
val hasClearableAlertingNotifs: Boolean,
|
||||||
val hasNonClearableSilentNotifs: Boolean,
|
val hasNonClearableSilentNotifs: Boolean,
|
||||||
val hasClearableSilentNotifs: Boolean,
|
val hasClearableSilentNotifs: Boolean
|
||||||
val clearableAlertingSensitiveNotifUsers: Set<Int>,
|
|
||||||
val clearableSilentSensitiveNotifUsers: Set<Int>
|
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val empty = NotifStats(
|
val empty = NotifStats(0, false, false, false, false)
|
||||||
numActiveNotifs = 0,
|
|
||||||
hasNonClearableAlertingNotifs = false,
|
|
||||||
hasClearableAlertingNotifs = false,
|
|
||||||
hasNonClearableSilentNotifs = false,
|
|
||||||
hasClearableSilentNotifs = false,
|
|
||||||
clearableAlertingSensitiveNotifUsers = emptySet(),
|
|
||||||
clearableSilentSensitiveNotifUsers = emptySet(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,4 +182,4 @@ annotation class HeaderClickAction
|
|||||||
|
|
||||||
@Scope
|
@Scope
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class SectionHeaderScope
|
annotation class SectionHeaderScope
|
||||||
@@ -28,7 +28,6 @@ import android.widget.ImageView
|
|||||||
import com.android.internal.statusbar.StatusBarIcon
|
import com.android.internal.statusbar.StatusBarIcon
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
|
||||||
import com.android.systemui.statusbar.StatusBarIconView
|
import com.android.systemui.statusbar.StatusBarIconView
|
||||||
import com.android.systemui.statusbar.notification.InflationException
|
import com.android.systemui.statusbar.notification.InflationException
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
@@ -50,29 +49,31 @@ import javax.inject.Inject
|
|||||||
class IconManager @Inject constructor(
|
class IconManager @Inject constructor(
|
||||||
private val notifCollection: CommonNotifCollection,
|
private val notifCollection: CommonNotifCollection,
|
||||||
private val launcherApps: LauncherApps,
|
private val launcherApps: LauncherApps,
|
||||||
private val iconBuilder: IconBuilder,
|
private val iconBuilder: IconBuilder
|
||||||
private val notifLockscreenUserManager: NotificationLockscreenUserManager
|
|
||||||
) : ConversationIconManager {
|
) : ConversationIconManager {
|
||||||
private var unimportantConversationKeys: Set<String> = emptySet()
|
private var unimportantConversationKeys: Set<String> = emptySet()
|
||||||
|
|
||||||
fun attach() {
|
fun attach() {
|
||||||
notifCollection.addCollectionListener(entryListener)
|
notifCollection.addCollectionListener(entryListener)
|
||||||
notifLockscreenUserManager.addOnNeedsRedactionInPublicChangedListener(sensitivityListener)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val entryListener = object : NotifCollectionListener {
|
private val entryListener = object : NotifCollectionListener {
|
||||||
|
override fun onEntryInit(entry: NotificationEntry) {
|
||||||
|
entry.addOnSensitivityChangedListener(sensitivityListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEntryCleanUp(entry: NotificationEntry) {
|
||||||
|
entry.removeOnSensitivityChangedListener(sensitivityListener)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onRankingApplied() {
|
override fun onRankingApplied() {
|
||||||
// rankings affect whether a conversation is important, which can change the icons
|
// rankings affect whether a conversation is important, which can change the icons
|
||||||
recalculateForImportantConversationChange()
|
recalculateForImportantConversationChange()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val sensitivityListener = Runnable {
|
private val sensitivityListener = NotificationEntry.OnSensitivityChangedListener {
|
||||||
for (entry in notifCollection.allNotifs) {
|
entry -> updateIconsSafe(entry)
|
||||||
if (entry.hasSensitiveContents()) {
|
|
||||||
updateIconsSafe(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recalculateForImportantConversationChange() {
|
private fun recalculateForImportantConversationChange() {
|
||||||
@@ -181,16 +182,12 @@ class IconManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline val NotificationEntry.needsRedactionInPublic: Boolean get() =
|
|
||||||
hasSensitiveContents() &&
|
|
||||||
notifLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(sbn.userId)
|
|
||||||
|
|
||||||
@Throws(InflationException::class)
|
@Throws(InflationException::class)
|
||||||
private fun getIconDescriptors(
|
private fun getIconDescriptors(
|
||||||
entry: NotificationEntry
|
entry: NotificationEntry
|
||||||
): Pair<StatusBarIcon, StatusBarIcon> {
|
): Pair<StatusBarIcon, StatusBarIcon> {
|
||||||
val iconDescriptor = getIconDescriptor(entry, false /* redact */)
|
val iconDescriptor = getIconDescriptor(entry, false /* redact */)
|
||||||
val sensitiveDescriptor = if (entry.needsRedactionInPublic) {
|
val sensitiveDescriptor = if (entry.isSensitive) {
|
||||||
getIconDescriptor(entry, true /* redact */)
|
getIconDescriptor(entry, true /* redact */)
|
||||||
} else {
|
} else {
|
||||||
iconDescriptor
|
iconDescriptor
|
||||||
@@ -313,7 +310,7 @@ class IconManager @Inject constructor(
|
|||||||
iconView === entry.icons.shelfIcon || iconView === entry.icons.aodIcon
|
iconView === entry.icons.shelfIcon || iconView === entry.icons.aodIcon
|
||||||
val isSmallIcon = iconDescriptor.icon.equals(entry.sbn.notification.smallIcon)
|
val isSmallIcon = iconDescriptor.icon.equals(entry.sbn.notification.smallIcon)
|
||||||
return isImportantConversation(entry) && !isSmallIcon &&
|
return isImportantConversation(entry) && !isSmallIcon &&
|
||||||
(!usedInSensitiveContext || !entry.needsRedactionInPublic)
|
(!usedInSensitiveContext || !entry.isSensitive)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isImportantConversation(entry: NotificationEntry): Boolean {
|
private fun isImportantConversation(entry: NotificationEntry): Boolean {
|
||||||
@@ -341,4 +338,4 @@ interface ConversationIconManager {
|
|||||||
* of a group from which the priority notification has been removed.
|
* of a group from which the priority notification has been removed.
|
||||||
*/
|
*/
|
||||||
fun setUnimportantConversations(keys: Collection<String>)
|
fun setUnimportantConversations(keys: Collection<String>)
|
||||||
}
|
}
|
||||||
@@ -90,8 +90,8 @@ import com.android.systemui.statusbar.RemoteInputController;
|
|||||||
import com.android.systemui.statusbar.SmartReplyController;
|
import com.android.systemui.statusbar.SmartReplyController;
|
||||||
import com.android.systemui.statusbar.StatusBarIconView;
|
import com.android.systemui.statusbar.StatusBarIconView;
|
||||||
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
|
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
|
||||||
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
|
||||||
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
||||||
|
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
|
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
@@ -202,6 +202,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
/** Are we showing the "public" version */
|
/** Are we showing the "public" version */
|
||||||
private boolean mShowingPublic;
|
private boolean mShowingPublic;
|
||||||
private boolean mSensitive;
|
private boolean mSensitive;
|
||||||
|
private boolean mSensitiveHiddenInGeneral;
|
||||||
private boolean mShowingPublicInitialized;
|
private boolean mShowingPublicInitialized;
|
||||||
private boolean mHideSensitiveForIntrinsicHeight;
|
private boolean mHideSensitiveForIntrinsicHeight;
|
||||||
private float mHeaderVisibleAmount = DEFAULT_HEADER_VISIBLE_AMOUNT;
|
private float mHeaderVisibleAmount = DEFAULT_HEADER_VISIBLE_AMOUNT;
|
||||||
@@ -1504,7 +1505,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mUseIncreasedHeadsUpHeight = use;
|
mUseIncreasedHeadsUpHeight = use;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this method and mNeedsRedaction entirely once the old pipeline is gone
|
|
||||||
public void setNeedsRedaction(boolean needsRedaction) {
|
public void setNeedsRedaction(boolean needsRedaction) {
|
||||||
// TODO: Move inflation logic out of this call and remove this method
|
// TODO: Move inflation logic out of this call and remove this method
|
||||||
if (mNeedsRedaction != needsRedaction) {
|
if (mNeedsRedaction != needsRedaction) {
|
||||||
@@ -2587,8 +2587,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked());
|
getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSensitive(boolean sensitive) {
|
public void setSensitive(boolean sensitive, boolean hideSensitive) {
|
||||||
mSensitive = sensitive;
|
mSensitive = sensitive;
|
||||||
|
mSensitiveHiddenInGeneral = hideSensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2678,15 +2679,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
* see {@link NotificationEntry#isDismissable()}.
|
* see {@link NotificationEntry#isDismissable()}.
|
||||||
*/
|
*/
|
||||||
public boolean canViewBeDismissed() {
|
public boolean canViewBeDismissed() {
|
||||||
// Entry not dismissable.
|
return mEntry.isDismissable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
|
||||||
if (!mEntry.isDismissable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Entry shouldn't be showing the public layout, it can be dismissed.
|
|
||||||
if (!shouldShowPublic()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2695,7 +2688,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
* clearability see {@link NotificationEntry#isClearable()}.
|
* clearability see {@link NotificationEntry#isClearable()}.
|
||||||
*/
|
*/
|
||||||
public boolean canViewBeCleared() {
|
public boolean canViewBeCleared() {
|
||||||
return mEntry.isClearable() && !shouldShowPublic();
|
return mEntry.isClearable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldShowPublic() {
|
private boolean shouldShowPublic() {
|
||||||
@@ -3459,28 +3452,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
pw.print(", translation: " + getTranslation());
|
pw.print(", translation: " + getTranslation());
|
||||||
pw.print(", removed: " + isRemoved());
|
pw.print(", removed: " + isRemoved());
|
||||||
pw.print(", expandAnimationRunning: " + mExpandAnimationRunning);
|
pw.print(", expandAnimationRunning: " + mExpandAnimationRunning);
|
||||||
pw.print(", sensitive: " + mSensitive);
|
NotificationContentView showingLayout = getShowingLayout();
|
||||||
pw.print(", hideSensitiveForIntrinsicHeight: " + mHideSensitiveForIntrinsicHeight);
|
pw.print(", privateShowing: " + (showingLayout == mPrivateLayout));
|
||||||
pw.println(", privateShowing: " + !shouldShowPublic());
|
pw.println();
|
||||||
pw.print("privateLayout: ");
|
showingLayout.dump(pw, args);
|
||||||
if (mPrivateLayout != null) {
|
|
||||||
pw.println();
|
|
||||||
DumpUtilsKt.withIncreasedIndent(pw, () -> {
|
|
||||||
mPrivateLayout.dump(pw, args);
|
|
||||||
mPrivateLayout.dumpSmartReplies(pw);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
pw.println("null");
|
|
||||||
}
|
|
||||||
pw.print("publicLayout: ");
|
|
||||||
if (mPublicLayout != null) {
|
|
||||||
pw.println();
|
|
||||||
DumpUtilsKt.withIncreasedIndent(pw, () -> {
|
|
||||||
mPublicLayout.dump(pw, args);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
pw.println("null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getViewState() != null) {
|
if (getViewState() != null) {
|
||||||
getViewState().dump(pw, args);
|
getViewState().dump(pw, args);
|
||||||
@@ -3506,6 +3481,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
}
|
}
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.println("}");
|
pw.println("}");
|
||||||
|
} else if (mPrivateLayout != null) {
|
||||||
|
mPrivateLayout.dumpSmartReplies(pw);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import com.android.systemui.plugins.FalsingManager;
|
|||||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.shared.plugins.PluginManager;
|
import com.android.systemui.shared.plugins.PluginManager;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|
||||||
import com.android.systemui.statusbar.NotificationMediaManager;
|
import com.android.systemui.statusbar.NotificationMediaManager;
|
||||||
import com.android.systemui.statusbar.SmartReplyController;
|
import com.android.systemui.statusbar.SmartReplyController;
|
||||||
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
||||||
@@ -70,7 +69,6 @@ import javax.inject.Named;
|
|||||||
public class ExpandableNotificationRowController implements NotifViewController {
|
public class ExpandableNotificationRowController implements NotifViewController {
|
||||||
private static final String TAG = "NotifRowController";
|
private static final String TAG = "NotifRowController";
|
||||||
private final ExpandableNotificationRow mView;
|
private final ExpandableNotificationRow mView;
|
||||||
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
|
||||||
private final NotificationListContainer mListContainer;
|
private final NotificationListContainer mListContainer;
|
||||||
private final RemoteInputViewSubcomponent.Factory mRemoteInputViewSubcomponentFactory;
|
private final RemoteInputViewSubcomponent.Factory mRemoteInputViewSubcomponentFactory;
|
||||||
private final ActivatableNotificationViewController mActivatableNotificationViewController;
|
private final ActivatableNotificationViewController mActivatableNotificationViewController;
|
||||||
@@ -88,6 +86,7 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener;
|
private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener;
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
private final MetricsLogger mMetricsLogger;
|
private final MetricsLogger mMetricsLogger;
|
||||||
|
|
||||||
private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
|
private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
|
||||||
this::logNotificationExpansion;
|
this::logNotificationExpansion;
|
||||||
private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
|
private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
|
||||||
@@ -101,12 +100,12 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
private final Optional<BubblesManager> mBubblesManagerOptional;
|
private final Optional<BubblesManager> mBubblesManagerOptional;
|
||||||
private final SmartReplyConstants mSmartReplyConstants;
|
private final SmartReplyConstants mSmartReplyConstants;
|
||||||
private final SmartReplyController mSmartReplyController;
|
private final SmartReplyController mSmartReplyController;
|
||||||
|
|
||||||
private final ExpandableNotificationRowDragController mDragController;
|
private final ExpandableNotificationRowDragController mDragController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ExpandableNotificationRowController(
|
public ExpandableNotificationRowController(
|
||||||
ExpandableNotificationRow view,
|
ExpandableNotificationRow view,
|
||||||
NotificationLockscreenUserManager lockscreenUserManager,
|
|
||||||
ActivatableNotificationViewController activatableNotificationViewController,
|
ActivatableNotificationViewController activatableNotificationViewController,
|
||||||
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
|
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
|
||||||
MetricsLogger metricsLogger,
|
MetricsLogger metricsLogger,
|
||||||
@@ -136,7 +135,6 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
Optional<BubblesManager> bubblesManagerOptional,
|
Optional<BubblesManager> bubblesManagerOptional,
|
||||||
ExpandableNotificationRowDragController dragController) {
|
ExpandableNotificationRowDragController dragController) {
|
||||||
mView = view;
|
mView = view;
|
||||||
mLockscreenUserManager = lockscreenUserManager;
|
|
||||||
mListContainer = listContainer;
|
mListContainer = listContainer;
|
||||||
mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
|
mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
|
||||||
mActivatableNotificationViewController = activatableNotificationViewController;
|
mActivatableNotificationViewController = activatableNotificationViewController;
|
||||||
@@ -216,10 +214,6 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
mView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
|
mView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
mLockscreenUserManager
|
|
||||||
.addOnNeedsRedactionInPublicChangedListener(mNeedsRedactionListener);
|
|
||||||
mNeedsRedactionListener.run();
|
|
||||||
|
|
||||||
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onViewAttachedToWindow(View v) {
|
public void onViewAttachedToWindow(View v) {
|
||||||
@@ -238,14 +232,6 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Runnable mNeedsRedactionListener = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mView.setSensitive(
|
|
||||||
mLockscreenUserManager.notifNeedsRedactionInPublic(mView.getEntry()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
||||||
new StatusBarStateController.StateListener() {
|
new StatusBarStateController.StateListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -347,5 +333,4 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
public void setFeedbackIcon(@Nullable FeedbackIcon icon) {
|
public void setFeedbackIcon(@Nullable FeedbackIcon icon) {
|
||||||
mView.setFeedbackIcon(icon);
|
mView.setFeedbackIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ import com.android.systemui.statusbar.policy.SmartReplyStateInflaterKt;
|
|||||||
import com.android.systemui.statusbar.policy.SmartReplyView;
|
import com.android.systemui.statusbar.policy.SmartReplyView;
|
||||||
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
|
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
|
||||||
import com.android.systemui.util.Compile;
|
import com.android.systemui.util.Compile;
|
||||||
import com.android.systemui.util.DumpUtilsKt;
|
|
||||||
import com.android.systemui.wmshell.BubblesManager;
|
import com.android.systemui.wmshell.BubblesManager;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -1995,33 +1994,22 @@ public class NotificationContentView extends FrameLayout implements Notification
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump(PrintWriter pwOriginal, String[] args) {
|
public void dump(PrintWriter pw, String[] args) {
|
||||||
IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
|
|
||||||
pw.print("contentView visibility: " + getVisibility());
|
pw.print("contentView visibility: " + getVisibility());
|
||||||
pw.print(", alpha: " + getAlpha());
|
pw.print(", alpha: " + getAlpha());
|
||||||
pw.print(", clipBounds: " + getClipBounds());
|
pw.print(", clipBounds: " + getClipBounds());
|
||||||
pw.print(", contentHeight: " + mContentHeight);
|
pw.print(", contentHeight: " + mContentHeight);
|
||||||
pw.println(", currentVisibleType: " + mVisibleType);
|
pw.print(", visibleType: " + mVisibleType);
|
||||||
DumpUtilsKt.withIncreasedIndent(pw, () -> {
|
View view = getViewForVisibleType(mVisibleType);
|
||||||
int[] visTypes = {
|
pw.print(", visibleView ");
|
||||||
VISIBLE_TYPE_CONTRACTED,
|
if (view != null) {
|
||||||
VISIBLE_TYPE_EXPANDED,
|
pw.print(" visibility: " + view.getVisibility());
|
||||||
VISIBLE_TYPE_HEADSUP,
|
pw.print(", alpha: " + view.getAlpha());
|
||||||
VISIBLE_TYPE_SINGLELINE
|
pw.print(", clipBounds: " + view.getClipBounds());
|
||||||
};
|
} else {
|
||||||
for (int visType : visTypes) {
|
pw.print("null");
|
||||||
pw.print("visType: " + visType + " :: ");
|
}
|
||||||
View view = getViewForVisibleType(visType);
|
pw.println();
|
||||||
if (view != null) {
|
|
||||||
pw.print("visibility: " + view.getVisibility());
|
|
||||||
pw.print(", alpha: " + view.getAlpha());
|
|
||||||
pw.print(", clipBounds: " + view.getClipBounds());
|
|
||||||
} else {
|
|
||||||
pw.print("null");
|
|
||||||
}
|
|
||||||
pw.println();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add any existing SmartReplyView to the dump */
|
/** Add any existing SmartReplyView to the dump */
|
||||||
|
|||||||
@@ -102,9 +102,8 @@ public final class RowContentBindParams {
|
|||||||
* @see InflationFlag
|
* @see InflationFlag
|
||||||
*/
|
*/
|
||||||
public void markContentViewsFreeable(@InflationFlag int contentViews) {
|
public void markContentViewsFreeable(@InflationFlag int contentViews) {
|
||||||
@InflationFlag int existingContentViews = contentViews &= mContentViews;
|
|
||||||
mContentViews &= ~contentViews;
|
mContentViews &= ~contentViews;
|
||||||
mDirtyContentViews |= existingContentViews;
|
mDirtyContentViews &= ~contentViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @InflationFlag int getContentViews() {
|
public @InflationFlag int getContentViews() {
|
||||||
|
|||||||
@@ -216,9 +216,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mBarState = mStatusBarStateController.getState();
|
mBarState = mStatusBarStateController.getState();
|
||||||
mStatusBarStateController.addCallback(
|
mStatusBarStateController.addCallback(
|
||||||
mStateListener, SysuiStatusBarStateController.RANK_STACK_SCROLLER);
|
mStateListener, SysuiStatusBarStateController.RANK_STACK_SCROLLER);
|
||||||
mLockscreenUserManager.addOnNeedsRedactionInPublicChangedListener(
|
|
||||||
mOnNeedsRedactionInPublicChangedListener);
|
|
||||||
updateClearButtonVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -226,8 +223,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mConfigurationController.removeCallback(mConfigurationListener);
|
mConfigurationController.removeCallback(mConfigurationListener);
|
||||||
mZenModeController.removeCallback(mZenModeControllerCallback);
|
mZenModeController.removeCallback(mZenModeControllerCallback);
|
||||||
mStatusBarStateController.removeCallback(mStateListener);
|
mStatusBarStateController.removeCallback(mStateListener);
|
||||||
mLockscreenUserManager.removeOnNeedsRedactionInPublicChangedListener(
|
|
||||||
mOnNeedsRedactionInPublicChangedListener);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -331,7 +326,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mLockscreenUserManager.isAnyProfilePublicMode());
|
mLockscreenUserManager.isAnyProfilePublicMode());
|
||||||
mView.onStatePostChange(mStatusBarStateController.fromShadeLocked());
|
mView.onStatePostChange(mStatusBarStateController.fromShadeLocked());
|
||||||
mNotificationEntryManager.updateNotifications("CentralSurfaces state changed");
|
mNotificationEntryManager.updateNotifications("CentralSurfaces state changed");
|
||||||
updateClearButtonVisibility();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -344,17 +338,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Runnable mOnNeedsRedactionInPublicChangedListener = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Whether or not the notification needs redaction when in public has changed, but if
|
|
||||||
// we're not actually in public, then we don't need to update anything.
|
|
||||||
if (mLockscreenUserManager.isAnyProfilePublicMode()) {
|
|
||||||
updateClearButtonVisibility();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the overexpansion of the panel to be applied to the view.
|
* Set the overexpansion of the panel to be applied to the view.
|
||||||
*/
|
*/
|
||||||
@@ -1291,44 +1274,12 @@ public class NotificationStackScrollLayoutController {
|
|||||||
return hasNotifications(selection, true /* clearable */);
|
return hasNotifications(selection, true /* clearable */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasRedactedClearableSilentNotifs() {
|
|
||||||
if (!mLockscreenUserManager.isAnyProfilePublicMode()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int userId : mNotifStats.getClearableSilentSensitiveNotifUsers()) {
|
|
||||||
if (mLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(userId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasClearableSilentNotifs() {
|
|
||||||
return mNotifStats.getHasClearableSilentNotifs() && !hasRedactedClearableSilentNotifs();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasRedactedClearableAlertingNotifs() {
|
|
||||||
if (!mLockscreenUserManager.isAnyProfilePublicMode()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int userId : mNotifStats.getClearableAlertingSensitiveNotifUsers()) {
|
|
||||||
if (mLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(userId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasClearableAlertingNotifs() {
|
|
||||||
return mNotifStats.getHasClearableAlertingNotifs() && !hasRedactedClearableAlertingNotifs();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNotifications(@SelectedRows int selection, boolean isClearable) {
|
public boolean hasNotifications(@SelectedRows int selection, boolean isClearable) {
|
||||||
boolean hasAlertingMatchingClearable = isClearable
|
boolean hasAlertingMatchingClearable = isClearable
|
||||||
? hasClearableAlertingNotifs()
|
? mNotifStats.getHasClearableAlertingNotifs()
|
||||||
: mNotifStats.getHasNonClearableAlertingNotifs();
|
: mNotifStats.getHasNonClearableAlertingNotifs();
|
||||||
boolean hasSilentMatchingClearable = isClearable
|
boolean hasSilentMatchingClearable = isClearable
|
||||||
? hasClearableSilentNotifs()
|
? mNotifStats.getHasClearableSilentNotifs()
|
||||||
: mNotifStats.getHasNonClearableSilentNotifs();
|
: mNotifStats.getHasNonClearableSilentNotifs();
|
||||||
switch (selection) {
|
switch (selection) {
|
||||||
case ROWS_GENTLE:
|
case ROWS_GENTLE:
|
||||||
@@ -1628,15 +1579,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mNotificationActivityStarter = activityStarter;
|
mNotificationActivityStarter = activityStarter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateClearButtonVisibility() {
|
|
||||||
updateClearSilentButton();
|
|
||||||
updateFooter();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateClearSilentButton() {
|
|
||||||
mSilentHeaderController.setClearSectionEnabled(hasClearableSilentNotifs());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum for UiEvent logged from this class
|
* Enum for UiEvent logged from this class
|
||||||
*/
|
*/
|
||||||
@@ -1962,7 +1904,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
@Override
|
@Override
|
||||||
public void setNotifStats(@NonNull NotifStats notifStats) {
|
public void setNotifStats(@NonNull NotifStats notifStats) {
|
||||||
mNotifStats = notifStats;
|
mNotifStats = notifStats;
|
||||||
updateClearSilentButton();
|
|
||||||
updateFooter();
|
updateFooter();
|
||||||
updateShowEmptyShadeView();
|
updateShowEmptyShadeView();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||||
import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
@@ -41,8 +40,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|||||||
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
||||||
import com.android.systemui.util.ViewController;
|
import com.android.systemui.util.ViewController;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -62,17 +61,17 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
private final NotificationIconAreaController mNotificationIconAreaController;
|
private final NotificationIconAreaController mNotificationIconAreaController;
|
||||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||||
private final NotificationStackScrollLayoutController mStackScrollerController;
|
private final NotificationStackScrollLayoutController mStackScrollerController;
|
||||||
|
|
||||||
private final DarkIconDispatcher mDarkIconDispatcher;
|
private final DarkIconDispatcher mDarkIconDispatcher;
|
||||||
private final NotificationPanelViewController mNotificationPanelViewController;
|
private final NotificationPanelViewController mNotificationPanelViewController;
|
||||||
private final Consumer<ExpandableNotificationRow> mSetTrackingHeadsUp =
|
private final Consumer<ExpandableNotificationRow>
|
||||||
this::setTrackingHeadsUp;
|
mSetTrackingHeadsUp = this::setTrackingHeadsUp;
|
||||||
private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
|
private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
|
||||||
private final KeyguardBypassController mBypassController;
|
private final KeyguardBypassController mBypassController;
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
private final CommandQueue mCommandQueue;
|
private final CommandQueue mCommandQueue;
|
||||||
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
|
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
|
||||||
private final NotificationLockscreenUserManager mNotifLockscreenUserManager;
|
|
||||||
private final Runnable mRedactionChanged = this::updateRedaction;
|
|
||||||
private final View mClockView;
|
private final View mClockView;
|
||||||
private final Optional<View> mOperatorNameViewOptional;
|
private final Optional<View> mOperatorNameViewOptional;
|
||||||
|
|
||||||
@@ -91,13 +90,6 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
};
|
};
|
||||||
private boolean mAnimationsEnabled = true;
|
private boolean mAnimationsEnabled = true;
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
private final KeyguardStateController mKeyguardStateController;
|
||||||
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
|
||||||
new StatusBarStateController.StateListener() {
|
|
||||||
@Override
|
|
||||||
public void onStatePostChange() {
|
|
||||||
updateRedaction();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Inject
|
@Inject
|
||||||
@@ -106,7 +98,6 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
HeadsUpManagerPhone headsUpManager,
|
HeadsUpManagerPhone headsUpManager,
|
||||||
StatusBarStateController stateController,
|
StatusBarStateController stateController,
|
||||||
KeyguardBypassController bypassController,
|
KeyguardBypassController bypassController,
|
||||||
NotificationLockscreenUserManager notifLockscreenUserManager,
|
|
||||||
NotificationWakeUpCoordinator wakeUpCoordinator,
|
NotificationWakeUpCoordinator wakeUpCoordinator,
|
||||||
DarkIconDispatcher darkIconDispatcher,
|
DarkIconDispatcher darkIconDispatcher,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
@@ -134,7 +125,6 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
mClockView = clockView;
|
mClockView = clockView;
|
||||||
mOperatorNameViewOptional = operatorNameViewOptional;
|
mOperatorNameViewOptional = operatorNameViewOptional;
|
||||||
mDarkIconDispatcher = darkIconDispatcher;
|
mDarkIconDispatcher = darkIconDispatcher;
|
||||||
mNotifLockscreenUserManager = notifLockscreenUserManager;
|
|
||||||
|
|
||||||
mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
|
mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -166,8 +156,6 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
mNotificationPanelViewController.setHeadsUpAppearanceController(this);
|
mNotificationPanelViewController.setHeadsUpAppearanceController(this);
|
||||||
mStackScrollerController.addOnExpandedHeightChangedListener(mSetExpandedHeight);
|
mStackScrollerController.addOnExpandedHeightChangedListener(mSetExpandedHeight);
|
||||||
mDarkIconDispatcher.addDarkReceiver(this);
|
mDarkIconDispatcher.addDarkReceiver(this);
|
||||||
mNotifLockscreenUserManager.addOnNeedsRedactionInPublicChangedListener(mRedactionChanged);
|
|
||||||
mStatusBarStateController.addCallback(mStatusBarStateListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -179,9 +167,6 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
mNotificationPanelViewController.setHeadsUpAppearanceController(null);
|
mNotificationPanelViewController.setHeadsUpAppearanceController(null);
|
||||||
mStackScrollerController.removeOnExpandedHeightChangedListener(mSetExpandedHeight);
|
mStackScrollerController.removeOnExpandedHeightChangedListener(mSetExpandedHeight);
|
||||||
mDarkIconDispatcher.removeDarkReceiver(this);
|
mDarkIconDispatcher.removeDarkReceiver(this);
|
||||||
mNotifLockscreenUserManager
|
|
||||||
.removeOnNeedsRedactionInPublicChangedListener(mRedactionChanged);
|
|
||||||
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateIsolatedIconLocation(boolean requireStateUpdate) {
|
private void updateIsolatedIconLocation(boolean requireStateUpdate) {
|
||||||
@@ -195,19 +180,6 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
updateHeader(entry);
|
updateHeader(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRedaction() {
|
|
||||||
NotificationEntry showingEntry = mView.getShowingEntry();
|
|
||||||
if (showingEntry == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int notifUserId = showingEntry.getSbn().getUserId();
|
|
||||||
boolean redactSensitiveContent =
|
|
||||||
mNotifLockscreenUserManager.isLockscreenPublicMode(notifUserId)
|
|
||||||
&& mNotifLockscreenUserManager
|
|
||||||
.sensitiveNotifsNeedRedactionInPublic(notifUserId);
|
|
||||||
mView.setRedactSensitiveContent(redactSensitiveContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTopEntry() {
|
private void updateTopEntry() {
|
||||||
NotificationEntry newEntry = null;
|
NotificationEntry newEntry = null;
|
||||||
if (shouldBeVisible()) {
|
if (shouldBeVisible()) {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
|
|||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
||||||
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
||||||
import static com.android.systemui.statusbar.StatusBarState.SHADE;
|
import static com.android.systemui.statusbar.StatusBarState.SHADE;
|
||||||
|
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
|
||||||
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD;
|
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD;
|
||||||
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
|
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
|
||||||
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPEN;
|
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPEN;
|
||||||
@@ -3950,6 +3951,10 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasActiveClearableNotifications() {
|
||||||
|
return mNotificationStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
public RemoteInputController.Delegate createRemoteInputDelegate() {
|
public RemoteInputController.Delegate createRemoteInputDelegate() {
|
||||||
return mNotificationStackScrollLayoutController.createDelegate();
|
return mNotificationStackScrollLayoutController.createDelegate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -411,8 +411,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
if (nowExpanded) {
|
if (nowExpanded) {
|
||||||
if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
|
if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
|
||||||
mShadeTransitionController.goToLockedShade(clickedEntry.getRow());
|
mShadeTransitionController.goToLockedShade(clickedEntry.getRow());
|
||||||
} else if (mDynamicPrivacyController.isInLockedDownShade()
|
} else if (clickedEntry.isSensitive()
|
||||||
&& mLockscreenUserManager.notifNeedsRedactionInPublic(clickedEntry)) {
|
&& mDynamicPrivacyController.isInLockedDownShade()) {
|
||||||
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
|
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
|
||||||
mActivityStarter.dismissKeyguardThenExecute(() -> false /* dismissAction */
|
mActivityStarter.dismissKeyguardThenExecute(() -> false /* dismissAction */
|
||||||
, null /* cancelRunnable */, false /* afterKeyguardGone */);
|
, null /* cancelRunnable */, false /* afterKeyguardGone */);
|
||||||
@@ -480,7 +480,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
.isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
|
.isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
|
||||||
boolean userPublic = devicePublic
|
boolean userPublic = devicePublic
|
||||||
|| mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
|
|| mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
|
||||||
boolean needsRedaction = mLockscreenUserManager.notifNeedsRedactionInPublic(entry);
|
boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
|
||||||
if (userPublic && needsRedaction) {
|
if (userPublic && needsRedaction) {
|
||||||
// TODO(b/135046837): we can probably relax this with dynamic privacy
|
// TODO(b/135046837): we can probably relax this with dynamic privacy
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -130,8 +130,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
whenever(statusbarStateController.state).thenReturn(StatusBarState.KEYGUARD)
|
whenever(statusbarStateController.state).thenReturn(StatusBarState.KEYGUARD)
|
||||||
whenever(nsslController.isInLockedDownShade).thenReturn(false)
|
whenever(nsslController.isInLockedDownShade).thenReturn(false)
|
||||||
whenever(qS.isFullyCollapsed).thenReturn(true)
|
whenever(qS.isFullyCollapsed).thenReturn(true)
|
||||||
whenever(lockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(anyInt()))
|
whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
|
||||||
.thenReturn(false)
|
true)
|
||||||
whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true)
|
whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true)
|
||||||
whenever(lockScreenUserManager.isLockscreenPublicMode(anyInt())).thenReturn(true)
|
whenever(lockScreenUserManager.isLockscreenPublicMode(anyInt())).thenReturn(true)
|
||||||
whenever(falsingCollector.shouldEnforceBouncer()).thenReturn(false)
|
whenever(falsingCollector.shouldEnforceBouncer()).thenReturn(false)
|
||||||
@@ -207,8 +207,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testTriggeringBouncerWhenPrivateNotificationsArentAllowed() {
|
fun testTriggeringBouncerWhenPrivateNotificationsArentAllowed() {
|
||||||
whenever(lockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(anyInt()))
|
whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
|
||||||
.thenReturn(true)
|
false)
|
||||||
transitionController.goToLockedShade(null)
|
transitionController.goToLockedShade(null)
|
||||||
verify(statusbarStateController, never()).setState(anyInt())
|
verify(statusbarStateController, never()).setState(anyInt())
|
||||||
verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
|
verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
|
||||||
|
|||||||
@@ -53,13 +53,11 @@ import android.testing.TestableLooper;
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.recents.OverviewProxyService;
|
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager.KeyguardNotificationSuppressor;
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager.KeyguardNotificationSuppressor;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
@@ -108,10 +106,6 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
private BroadcastDispatcher mBroadcastDispatcher;
|
private BroadcastDispatcher mBroadcastDispatcher;
|
||||||
@Mock
|
@Mock
|
||||||
private KeyguardStateController mKeyguardStateController;
|
private KeyguardStateController mKeyguardStateController;
|
||||||
@Mock
|
|
||||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
@Mock
|
|
||||||
private OverviewProxyService mOverviewProxyService;
|
|
||||||
|
|
||||||
private UserInfo mCurrentUser;
|
private UserInfo mCurrentUser;
|
||||||
private UserInfo mSecondaryUser;
|
private UserInfo mSecondaryUser;
|
||||||
@@ -125,6 +119,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
|
||||||
|
|
||||||
int currentUserId = ActivityManager.getCurrentUser();
|
int currentUserId = ActivityManager.getCurrentUser();
|
||||||
mSettings = new FakeSettings();
|
mSettings = new FakeSettings();
|
||||||
@@ -217,7 +212,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
||||||
|
|
||||||
// THEN current user's notification is redacted
|
// THEN current user's notification is redacted
|
||||||
assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif));
|
assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -228,7 +223,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
||||||
|
|
||||||
// THEN current user's notification isn't redacted
|
// THEN current user's notification isn't redacted
|
||||||
assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif));
|
assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -239,7 +234,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
||||||
|
|
||||||
// THEN work profile notification is redacted
|
// THEN work profile notification is redacted
|
||||||
assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif));
|
assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -250,7 +245,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
||||||
|
|
||||||
// THEN work profile notification isn't redacted
|
// THEN work profile notification isn't redacted
|
||||||
assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif));
|
assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -265,11 +260,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
||||||
|
|
||||||
// THEN the work profile notification doesn't need to be redacted
|
// THEN the work profile notification doesn't need to be redacted
|
||||||
assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif));
|
assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
|
||||||
|
|
||||||
// THEN the current user and secondary user notifications do need to be redacted
|
// THEN the current user and secondary user notifications do need to be redacted
|
||||||
assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif));
|
assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
|
||||||
assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mSecondaryUserNotif));
|
assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -284,11 +279,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
|
||||||
|
|
||||||
// THEN the work profile notification needs to be redacted
|
// THEN the work profile notification needs to be redacted
|
||||||
assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif));
|
assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif));
|
||||||
|
|
||||||
// THEN the current user and secondary user notifications don't need to be redacted
|
// THEN the current user and secondary user notifications don't need to be redacted
|
||||||
assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif));
|
assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif));
|
||||||
assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mSecondaryUserNotif));
|
assertFalse(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -303,7 +298,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// THEN the secondary profile notification still needs to be redacted because the current
|
// THEN the secondary profile notification still needs to be redacted because the current
|
||||||
// user's setting takes precedence
|
// user's setting takes precedence
|
||||||
assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mSecondaryUserNotif));
|
assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -423,12 +418,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
|||||||
context,
|
context,
|
||||||
mBroadcastDispatcher,
|
mBroadcastDispatcher,
|
||||||
mDevicePolicyManager,
|
mDevicePolicyManager,
|
||||||
mKeyguardUpdateMonitor,
|
|
||||||
() -> mEntryManager,
|
|
||||||
() -> mOverviewProxyService,
|
|
||||||
mUserManager,
|
mUserManager,
|
||||||
() -> mVisibilityProvider,
|
(() -> mVisibilityProvider),
|
||||||
() -> mNotifCollection,
|
(() -> mNotifCollection),
|
||||||
mClickNotifier,
|
mClickNotifier,
|
||||||
NotificationLockscreenUserManagerTest.this.mKeyguardManager,
|
NotificationLockscreenUserManagerTest.this.mKeyguardManager,
|
||||||
mStatusBarStateController,
|
mStatusBarStateController,
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ public class DynamicPrivacyControllerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void allowPrivateNotificationsInPublic(boolean allow) {
|
private void allowPrivateNotificationsInPublic(boolean allow) {
|
||||||
when(mLockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(anyInt())).thenReturn(
|
when(mLockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
|
||||||
!allow);
|
allow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -32,6 +33,7 @@ import android.app.Notification;
|
|||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
@@ -39,6 +41,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|||||||
import com.android.systemui.statusbar.RankingBuilder;
|
import com.android.systemui.statusbar.RankingBuilder;
|
||||||
import com.android.systemui.statusbar.SbnBuilder;
|
import com.android.systemui.statusbar.SbnBuilder;
|
||||||
import com.android.systemui.statusbar.notification.SectionClassifier;
|
import com.android.systemui.statusbar.notification.SectionClassifier;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||||
@@ -46,6 +49,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NodeController;
|
import com.android.systemui.statusbar.notification.collection.render.NodeController;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -68,6 +72,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
|||||||
@Mock private NotifPipeline mNotifPipeline;
|
@Mock private NotifPipeline mNotifPipeline;
|
||||||
@Mock private NodeController mAlertingHeaderController;
|
@Mock private NodeController mAlertingHeaderController;
|
||||||
@Mock private NodeController mSilentNodeController;
|
@Mock private NodeController mSilentNodeController;
|
||||||
|
@Mock private SectionHeaderController mSilentHeaderController;
|
||||||
|
|
||||||
@Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor;
|
@Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor;
|
||||||
|
|
||||||
@@ -89,6 +94,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
|||||||
mHighPriorityProvider,
|
mHighPriorityProvider,
|
||||||
mSectionClassifier,
|
mSectionClassifier,
|
||||||
mAlertingHeaderController,
|
mAlertingHeaderController,
|
||||||
|
mSilentHeaderController,
|
||||||
mSilentNodeController);
|
mSilentNodeController);
|
||||||
mEntry = spy(new NotificationEntryBuilder().build());
|
mEntry = spy(new NotificationEntryBuilder().build());
|
||||||
mEntry.setRanking(getRankingForUnfilteredNotif().build());
|
mEntry.setRanking(getRankingForUnfilteredNotif().build());
|
||||||
@@ -105,6 +111,25 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
|||||||
mSections.addAll(Arrays.asList(mAlertingSectioner, mSilentSectioner, mMinimizedSectioner));
|
mSections.addAll(Arrays.asList(mAlertingSectioner, mSilentSectioner, mMinimizedSectioner));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSilentHeaderClearableChildrenUpdate() {
|
||||||
|
ListEntry listEntry = new ListEntry(mEntry.getKey(), 0L) {
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public NotificationEntry getRepresentativeEntry() {
|
||||||
|
return mEntry;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setRankingAmbient(false);
|
||||||
|
setSbnClearable(true);
|
||||||
|
mSilentSectioner.onEntriesUpdated(Arrays.asList(listEntry));
|
||||||
|
verify(mSilentHeaderController).setClearSectionEnabled(eq(true));
|
||||||
|
|
||||||
|
setSbnClearable(false);
|
||||||
|
mSilentSectioner.onEntriesUpdated(Arrays.asList(listEntry));
|
||||||
|
verify(mSilentHeaderController).setClearSectionEnabled(eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnfilteredState() {
|
public void testUnfilteredState() {
|
||||||
// GIVEN no suppressed visual effects + app not suspended
|
// GIVEN no suppressed visual effects + app not suspended
|
||||||
@@ -200,6 +225,46 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
|||||||
assertInSection(mEntry, mSilentSectioner);
|
assertInSection(mEntry, mSilentSectioner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClearableSilentSection() {
|
||||||
|
when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
|
||||||
|
setSbnClearable(true);
|
||||||
|
setRankingAmbient(false);
|
||||||
|
mSilentSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
verify(mSilentHeaderController).setClearSectionEnabled(eq(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClearableMinimizedSection() {
|
||||||
|
when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
|
||||||
|
setSbnClearable(true);
|
||||||
|
setRankingAmbient(true);
|
||||||
|
mMinimizedSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
verify(mSilentHeaderController).setClearSectionEnabled(eq(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotClearableSilentSection() {
|
||||||
|
setSbnClearable(false);
|
||||||
|
when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
|
||||||
|
setRankingAmbient(false);
|
||||||
|
mSilentSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
mMinimizedSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
mAlertingSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
verify(mSilentHeaderController, times(2)).setClearSectionEnabled(eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotClearableMinimizedSection() {
|
||||||
|
setSbnClearable(false);
|
||||||
|
when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
|
||||||
|
setRankingAmbient(true);
|
||||||
|
mSilentSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
mMinimizedSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
mAlertingSectioner.onEntriesUpdated(Arrays.asList(mEntry));
|
||||||
|
verify(mSilentHeaderController, times(2)).setClearSectionEnabled(eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
private void assertInSection(NotificationEntry entry, NotifSectioner section) {
|
private void assertInSection(NotificationEntry entry, NotifSectioner section) {
|
||||||
for (NotifSectioner current: mSections) {
|
for (NotifSectioner current: mSections) {
|
||||||
if (current == section) {
|
if (current == section) {
|
||||||
|
|||||||
@@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.statusbar.notification.collection.coordinator
|
||||||
|
|
||||||
|
import android.os.UserHandle
|
||||||
|
import android.service.notification.StatusBarNotification
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
|
import com.android.systemui.statusbar.StatusBarState
|
||||||
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController
|
||||||
|
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
|
||||||
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
|
import com.android.systemui.util.mockito.any
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
|
import com.android.systemui.util.mockito.withArgCaptor
|
||||||
|
import dagger.BindsInstance
|
||||||
|
import dagger.Component
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
class SensitiveContentCoordinatorTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
val dynamicPrivacyController: DynamicPrivacyController = mock()
|
||||||
|
val lockscreenUserManager: NotificationLockscreenUserManager = mock()
|
||||||
|
val pipeline: NotifPipeline = mock()
|
||||||
|
val keyguardUpdateMonitor: KeyguardUpdateMonitor = mock()
|
||||||
|
val statusBarStateController: StatusBarStateController = mock()
|
||||||
|
val keyguardStateController: KeyguardStateController = mock()
|
||||||
|
|
||||||
|
val coordinator: SensitiveContentCoordinator =
|
||||||
|
DaggerTestSensitiveContentCoordinatorComponent
|
||||||
|
.factory()
|
||||||
|
.create(
|
||||||
|
dynamicPrivacyController,
|
||||||
|
lockscreenUserManager,
|
||||||
|
keyguardUpdateMonitor,
|
||||||
|
statusBarStateController,
|
||||||
|
keyguardStateController)
|
||||||
|
.coordinator
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onDynamicPrivacyChanged_invokeInvalidationListener() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val invalidator = withArgCaptor<Invalidator> {
|
||||||
|
verify(pipeline).addPreRenderInvalidator(capture())
|
||||||
|
}
|
||||||
|
val dynamicPrivacyListener = withArgCaptor<DynamicPrivacyController.Listener> {
|
||||||
|
verify(dynamicPrivacyController).addListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
|
||||||
|
invalidator.setInvalidationListener(invalidationListener)
|
||||||
|
|
||||||
|
dynamicPrivacyListener.onDynamicPrivacyChanged()
|
||||||
|
|
||||||
|
verify(invalidationListener).onPluggableInvalidated(invalidator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, false)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, false)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, false)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
|
||||||
|
val entry = fakeNotification(1, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
|
||||||
|
|
||||||
|
val entry = fakeNotification(2, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceDynamicallyUnlocked_deviceBiometricBypassingLockScreen() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
|
||||||
|
whenever(statusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD)
|
||||||
|
whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(any()))
|
||||||
|
.thenReturn(true)
|
||||||
|
|
||||||
|
val entry = fakeNotification(2, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!, never()).setSensitive(any(), any())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry {
|
||||||
|
val mockUserHandle = mock<UserHandle>().apply {
|
||||||
|
whenever(identifier).thenReturn(notifUserId)
|
||||||
|
}
|
||||||
|
val mockSbn: StatusBarNotification = mock<StatusBarNotification>().apply {
|
||||||
|
whenever(user).thenReturn(mockUserHandle)
|
||||||
|
}
|
||||||
|
val mockEntry = mock<NotificationEntry>().apply {
|
||||||
|
whenever(sbn).thenReturn(mockSbn)
|
||||||
|
}
|
||||||
|
whenever(lockscreenUserManager.needsRedaction(mockEntry)).thenReturn(needsRedaction)
|
||||||
|
whenever(mockEntry.rowExists()).thenReturn(true)
|
||||||
|
return object : ListEntry("key", 0) {
|
||||||
|
override fun getRepresentativeEntry(): NotificationEntry = mockEntry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CoordinatorScope
|
||||||
|
@Component(modules = [SensitiveContentCoordinatorModule::class])
|
||||||
|
interface TestSensitiveContentCoordinatorComponent {
|
||||||
|
val coordinator: SensitiveContentCoordinator
|
||||||
|
|
||||||
|
@Component.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(
|
||||||
|
@BindsInstance dynamicPrivacyController: DynamicPrivacyController,
|
||||||
|
@BindsInstance lockscreenUserManager: NotificationLockscreenUserManager,
|
||||||
|
@BindsInstance keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
|
@BindsInstance statusBarStateController: StatusBarStateController,
|
||||||
|
@BindsInstance keyguardStateController: KeyguardStateController
|
||||||
|
): TestSensitiveContentCoordinatorComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.statusbar.notification.collection.coordinator
|
package com.android.systemui.statusbar.notification.collection.coordinator
|
||||||
|
|
||||||
import android.os.UserHandle
|
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
@@ -44,11 +43,6 @@ import org.mockito.Mockito.`when` as whenever
|
|||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@RunWithLooper
|
@RunWithLooper
|
||||||
class StackCoordinatorTest : SysuiTestCase() {
|
class StackCoordinatorTest : SysuiTestCase() {
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val NOTIF_USER_ID = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var coordinator: StackCoordinator
|
private lateinit var coordinator: StackCoordinator
|
||||||
private lateinit var afterRenderListListener: OnAfterRenderListListener
|
private lateinit var afterRenderListListener: OnAfterRenderListListener
|
||||||
|
|
||||||
@@ -67,10 +61,7 @@ class StackCoordinatorTest : SysuiTestCase() {
|
|||||||
afterRenderListListener = withArgCaptor {
|
afterRenderListListener = withArgCaptor {
|
||||||
verify(pipeline).addOnAfterRenderListListener(capture())
|
verify(pipeline).addOnAfterRenderListListener(capture())
|
||||||
}
|
}
|
||||||
entry = NotificationEntryBuilder()
|
entry = NotificationEntryBuilder().setSection(section).build()
|
||||||
.setSection(section)
|
|
||||||
.setUser(UserHandle.of(NOTIF_USER_ID))
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -83,31 +74,13 @@ class StackCoordinatorTest : SysuiTestCase() {
|
|||||||
fun testSetNotificationStats_clearableAlerting() {
|
fun testSetNotificationStats_clearableAlerting() {
|
||||||
whenever(section.bucket).thenReturn(BUCKET_ALERTING)
|
whenever(section.bucket).thenReturn(BUCKET_ALERTING)
|
||||||
afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
|
afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
|
||||||
verify(stackController)
|
verify(stackController).setNotifStats(NotifStats(1, false, true, false, false))
|
||||||
.setNotifStats(
|
|
||||||
NotifStats(
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
setOf(NOTIF_USER_ID),
|
|
||||||
emptySet()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSetNotificationStats_clearableSilent() {
|
fun testSetNotificationStats_clearableSilent() {
|
||||||
whenever(section.bucket).thenReturn(BUCKET_SILENT)
|
whenever(section.bucket).thenReturn(BUCKET_SILENT)
|
||||||
afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
|
afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
|
||||||
verify(stackController)
|
verify(stackController).setNotifStats(NotifStats(1, false, false, false, true))
|
||||||
.setNotifStats(
|
|
||||||
NotifStats(
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
emptySet(),
|
|
||||||
setOf(NOTIF_USER_ID)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.systemui.statusbar.notification.icon
|
package com.android.systemui.statusbar.notification.icon;
|
||||||
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager;
|
||||||
import android.app.Notification
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager.IMPORTANCE_DEFAULT
|
import android.app.NotificationManager.IMPORTANCE_DEFAULT
|
||||||
import android.app.Person
|
import android.app.Person
|
||||||
@@ -27,12 +27,11 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.graphics.drawable.Icon
|
import android.graphics.drawable.Icon
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner;
|
||||||
import androidx.test.InstrumentationRegistry
|
import androidx.test.InstrumentationRegistry
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any
|
import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
|
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
|
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
|
||||||
@@ -41,7 +40,7 @@ import org.junit.Assert.assertEquals
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import org.mockito.Mockito.anyInt
|
import org.mockito.Mockito.anyInt
|
||||||
@@ -49,14 +48,15 @@ import org.mockito.MockitoAnnotations
|
|||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
class IconManagerTest : SysuiTestCase() {
|
class IconManagerTest: SysuiTestCase() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TEST_PACKAGE_NAME = "test"
|
private const val TEST_PACKAGE_NAME = "test";
|
||||||
private const val TEST_UID = 0
|
private const val TEST_UID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private var id = 0
|
private var id = 0
|
||||||
private val context = InstrumentationRegistry.getTargetContext()
|
private val context = InstrumentationRegistry.getTargetContext();
|
||||||
@Mock private lateinit var shortcut: ShortcutInfo
|
@Mock private lateinit var shortcut: ShortcutInfo
|
||||||
@Mock private lateinit var shortcutIc: Icon
|
@Mock private lateinit var shortcutIc: Icon
|
||||||
@Mock private lateinit var messageIc: Icon
|
@Mock private lateinit var messageIc: Icon
|
||||||
@@ -65,7 +65,6 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var drawable: Drawable
|
@Mock private lateinit var drawable: Drawable
|
||||||
@Mock private lateinit var row: ExpandableNotificationRow
|
@Mock private lateinit var row: ExpandableNotificationRow
|
||||||
|
|
||||||
@Mock private lateinit var notifLockscreenUserManager: NotificationLockscreenUserManager
|
|
||||||
@Mock private lateinit var notifCollection: CommonNotifCollection
|
@Mock private lateinit var notifCollection: CommonNotifCollection
|
||||||
@Mock private lateinit var launcherApps: LauncherApps
|
@Mock private lateinit var launcherApps: LauncherApps
|
||||||
|
|
||||||
@@ -84,16 +83,13 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
`when`(shortcut.icon).thenReturn(shortcutIc)
|
`when`(shortcut.icon).thenReturn(shortcutIc)
|
||||||
`when`(launcherApps.getShortcutIcon(shortcut)).thenReturn(shortcutIc)
|
`when`(launcherApps.getShortcutIcon(shortcut)).thenReturn(shortcutIc)
|
||||||
`when`(notifLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(TEST_UID))
|
|
||||||
.thenReturn(true)
|
|
||||||
|
|
||||||
iconManager =
|
iconManager = IconManager(notifCollection, launcherApps, iconBuilder)
|
||||||
IconManager(notifCollection, launcherApps, iconBuilder, notifLockscreenUserManager)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCreateIcons_importantConversation_shortcutIcon() {
|
fun testCreateIcons_importantConversation_shortcutIcon() {
|
||||||
val entry = notificationEntry()
|
val entry = notificationEntry(true, true, true)
|
||||||
entry?.channel?.isImportantConversation = true
|
entry?.channel?.isImportantConversation = true
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
@@ -103,7 +99,7 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCreateIcons_importantConversation_messageIcon() {
|
fun testCreateIcons_importantConversation_messageIcon() {
|
||||||
val entry = notificationEntry(hasShortcut = false)
|
val entry = notificationEntry(false, true, true)
|
||||||
entry?.channel?.isImportantConversation = true
|
entry?.channel?.isImportantConversation = true
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
@@ -113,7 +109,7 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCreateIcons_importantConversation_largeIcon() {
|
fun testCreateIcons_importantConversation_largeIcon() {
|
||||||
val entry = notificationEntry(hasShortcut = false, hasMessage = false)
|
val entry = notificationEntry(false, false, true)
|
||||||
entry?.channel?.isImportantConversation = true
|
entry?.channel?.isImportantConversation = true
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
@@ -123,7 +119,7 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCreateIcons_importantConversation_smallIcon() {
|
fun testCreateIcons_importantConversation_smallIcon() {
|
||||||
val entry = notificationEntry(hasShortcut = false, hasMessage = false, hasLargeIcon = false)
|
val entry = notificationEntry(false, false, false)
|
||||||
entry?.channel?.isImportantConversation = true
|
entry?.channel?.isImportantConversation = true
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
@@ -133,7 +129,7 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCreateIcons_notImportantConversation() {
|
fun testCreateIcons_notImportantConversation() {
|
||||||
val entry = notificationEntry()
|
val entry = notificationEntry(true, true, true)
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
}
|
}
|
||||||
@@ -142,10 +138,8 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCreateIcons_sensitiveImportantConversation() {
|
fun testCreateIcons_sensitiveImportantConversation() {
|
||||||
val entry = notificationEntry(
|
val entry = notificationEntry(true, false, false)
|
||||||
hasMessage = false,
|
entry?.setSensitive(true, true);
|
||||||
hasLargeIcon = false,
|
|
||||||
hasSensitiveContent = true)
|
|
||||||
entry?.channel?.isImportantConversation = true
|
entry?.channel?.isImportantConversation = true
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
@@ -157,17 +151,14 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testUpdateIcons_sensitivityChange() {
|
fun testUpdateIcons_sensitivityChange() {
|
||||||
val entry = notificationEntry(
|
val entry = notificationEntry(true, false, false)
|
||||||
hasMessage = false,
|
|
||||||
hasLargeIcon = false,
|
|
||||||
hasSensitiveContent = true)
|
|
||||||
entry?.channel?.isImportantConversation = true
|
entry?.channel?.isImportantConversation = true
|
||||||
|
entry?.setSensitive(true, true);
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.createIcons(it)
|
iconManager.createIcons(it)
|
||||||
}
|
}
|
||||||
assertEquals(entry?.icons?.aodIcon?.sourceIcon, smallIc)
|
assertEquals(entry?.icons?.aodIcon?.sourceIcon, smallIc)
|
||||||
`when`(notifLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(TEST_UID))
|
entry?.setSensitive(false, false);
|
||||||
.thenReturn(false)
|
|
||||||
entry?.let {
|
entry?.let {
|
||||||
iconManager.updateIcons(it)
|
iconManager.updateIcons(it)
|
||||||
}
|
}
|
||||||
@@ -175,19 +166,14 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun notificationEntry(
|
private fun notificationEntry(
|
||||||
hasShortcut: Boolean = true,
|
hasShortcut: Boolean,
|
||||||
hasMessage: Boolean = true,
|
hasMessage: Boolean,
|
||||||
hasLargeIcon: Boolean = true,
|
hasLargeIcon: Boolean
|
||||||
hasSensitiveContent: Boolean = false
|
|
||||||
): NotificationEntry? {
|
): NotificationEntry? {
|
||||||
val n = Notification.Builder(mContext, "id")
|
val n = Notification.Builder(mContext, "id")
|
||||||
.setSmallIcon(smallIc)
|
.setSmallIcon(smallIc)
|
||||||
.setContentTitle("Title")
|
.setContentTitle("Title")
|
||||||
.setContentText("Text")
|
.setContentText("Text")
|
||||||
.setVisibility(
|
|
||||||
if (hasSensitiveContent)
|
|
||||||
Notification.VISIBILITY_PRIVATE
|
|
||||||
else Notification.VISIBILITY_PUBLIC)
|
|
||||||
|
|
||||||
if (hasMessage) {
|
if (hasMessage) {
|
||||||
n.style = Notification.MessagingStyle("")
|
n.style = Notification.MessagingStyle("")
|
||||||
@@ -217,6 +203,7 @@ class IconManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val entry = builder.build()
|
val entry = builder.build()
|
||||||
entry.row = row
|
entry.row = row
|
||||||
|
entry.setSensitive(false, true);
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGroupSummaryNotShowingIconWhenPublic() {
|
public void testGroupSummaryNotShowingIconWhenPublic() {
|
||||||
mGroupRow.setSensitive(true);
|
mGroupRow.setSensitive(true, true);
|
||||||
mGroupRow.setHideSensitiveForIntrinsicHeight(true);
|
mGroupRow.setHideSensitiveForIntrinsicHeight(true);
|
||||||
assertTrue(mGroupRow.isSummaryWithChildren());
|
assertTrue(mGroupRow.isSummaryWithChildren());
|
||||||
assertFalse(mGroupRow.isShowingIcon());
|
assertFalse(mGroupRow.isShowingIcon());
|
||||||
@@ -99,7 +99,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotificationHeaderVisibleWhenAnimating() {
|
public void testNotificationHeaderVisibleWhenAnimating() {
|
||||||
mGroupRow.setSensitive(true);
|
mGroupRow.setSensitive(true, true);
|
||||||
mGroupRow.setHideSensitive(true, false, 0, 0);
|
mGroupRow.setHideSensitive(true, false, 0, 0);
|
||||||
mGroupRow.setHideSensitive(false, true, 0, 0);
|
mGroupRow.setHideSensitive(false, true, 0, 0);
|
||||||
assertEquals(View.VISIBLE, mGroupRow.getChildrenContainer().getVisibleWrapper()
|
assertEquals(View.VISIBLE, mGroupRow.getChildrenContainer().getVisibleWrapper()
|
||||||
@@ -130,7 +130,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
|||||||
public void testIconColorShouldBeUpdatedWhenSensitive() throws Exception {
|
public void testIconColorShouldBeUpdatedWhenSensitive() throws Exception {
|
||||||
ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow(
|
ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow(
|
||||||
FLAG_CONTENT_VIEW_ALL));
|
FLAG_CONTENT_VIEW_ALL));
|
||||||
row.setSensitive(true);
|
row.setSensitive(true, true);
|
||||||
row.setHideSensitive(true, false, 0, 0);
|
row.setHideSensitive(true, false, 0, 0);
|
||||||
verify(row).updateShelfIconColor();
|
verify(row).updateShelfIconColor();
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testFeedback_noHeader() {
|
public void testFeedback_noHeader() {
|
||||||
// public notification is custom layout - no header
|
// public notification is custom layout - no header
|
||||||
mGroupRow.setSensitive(true);
|
mGroupRow.setSensitive(true, true);
|
||||||
mGroupRow.setOnFeedbackClickListener(null);
|
mGroupRow.setOnFeedbackClickListener(null);
|
||||||
mGroupRow.setFeedbackIcon(null);
|
mGroupRow.setFeedbackIcon(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import com.android.systemui.statusbar.notification.collection.legacy.Notificatio
|
|||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
import com.android.systemui.statusbar.notification.icon.IconBuilder;
|
import com.android.systemui.statusbar.notification.icon.IconBuilder;
|
||||||
import com.android.systemui.statusbar.notification.icon.IconManager;
|
import com.android.systemui.statusbar.notification.icon.IconManager;
|
||||||
|
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||||
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
|
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
|
||||||
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
|
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
|
||||||
@@ -131,6 +132,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
|
|||||||
@Mock private NotificationEntryListener mEntryListener;
|
@Mock private NotificationEntryListener mEntryListener;
|
||||||
@Mock private NotificationRowBinderImpl.BindRowCallback mBindCallback;
|
@Mock private NotificationRowBinderImpl.BindRowCallback mBindCallback;
|
||||||
@Mock private HeadsUpManager mHeadsUpManager;
|
@Mock private HeadsUpManager mHeadsUpManager;
|
||||||
|
@Mock private NotificationInterruptStateProvider mNotificationInterruptionStateProvider;
|
||||||
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
@Mock private NotificationGutsManager mGutsManager;
|
@Mock private NotificationGutsManager mGutsManager;
|
||||||
@Mock private NotificationRemoteInputManager mRemoteInputManager;
|
@Mock private NotificationRemoteInputManager mRemoteInputManager;
|
||||||
@@ -252,7 +254,6 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
|
|||||||
.thenAnswer((Answer<ExpandableNotificationRowController>) invocation ->
|
.thenAnswer((Answer<ExpandableNotificationRowController>) invocation ->
|
||||||
new ExpandableNotificationRowController(
|
new ExpandableNotificationRowController(
|
||||||
viewCaptor.getValue(),
|
viewCaptor.getValue(),
|
||||||
mLockscreenUserManager,
|
|
||||||
mock(ActivatableNotificationViewController.class),
|
mock(ActivatableNotificationViewController.class),
|
||||||
mock(RemoteInputViewSubcomponent.Factory.class),
|
mock(RemoteInputViewSubcomponent.Factory.class),
|
||||||
mock(MetricsLogger.class),
|
mock(MetricsLogger.class),
|
||||||
@@ -299,8 +300,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
|
|||||||
new IconManager(
|
new IconManager(
|
||||||
mEntryManager,
|
mEntryManager,
|
||||||
mock(LauncherApps.class),
|
mock(LauncherApps.class),
|
||||||
new IconBuilder(mContext),
|
new IconBuilder(mContext)),
|
||||||
mLockscreenUserManager),
|
|
||||||
mock(LowPriorityInflationHelper.class),
|
mock(LowPriorityInflationHelper.class),
|
||||||
mNotifPipelineFlags);
|
mNotifPipelineFlags);
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ import com.android.systemui.dump.DumpManager;
|
|||||||
import com.android.systemui.media.MediaFeatureFlag;
|
import com.android.systemui.media.MediaFeatureFlag;
|
||||||
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
|
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|
||||||
import com.android.systemui.statusbar.NotificationMediaManager;
|
import com.android.systemui.statusbar.NotificationMediaManager;
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
@@ -157,8 +156,7 @@ public class NotificationTestHelper {
|
|||||||
mIconManager = new IconManager(
|
mIconManager = new IconManager(
|
||||||
mock(CommonNotifCollection.class),
|
mock(CommonNotifCollection.class),
|
||||||
mock(LauncherApps.class),
|
mock(LauncherApps.class),
|
||||||
new IconBuilder(mContext),
|
new IconBuilder(mContext));
|
||||||
mock(NotificationLockscreenUserManager.class));
|
|
||||||
|
|
||||||
NotificationContentInflater contentBinder = new NotificationContentInflater(
|
NotificationContentInflater contentBinder = new NotificationContentInflater(
|
||||||
mock(NotifRemoteViewCache.class),
|
mock(NotifRemoteViewCache.class),
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import com.android.systemui.plugins.DarkIconDispatcher;
|
|||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
||||||
@@ -58,12 +57,9 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
private final NotificationStackScrollLayoutController mStackScrollerController =
|
private final NotificationStackScrollLayoutController mStackScrollerController =
|
||||||
mock(NotificationStackScrollLayoutController.class);
|
mock(NotificationStackScrollLayoutController.class);
|
||||||
private final NotificationPanelViewController mPanelViewController =
|
private final NotificationPanelViewController mPanelView =
|
||||||
mock(NotificationPanelViewController.class);
|
mock(NotificationPanelViewController.class);
|
||||||
private final DarkIconDispatcher mDarkIconDispatcher = mock(DarkIconDispatcher.class);
|
private final DarkIconDispatcher mDarkIconDispatcher = mock(DarkIconDispatcher.class);
|
||||||
private final NotificationLockscreenUserManager mLockscreenUserManager =
|
|
||||||
mock(NotificationLockscreenUserManager.class);
|
|
||||||
|
|
||||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||||
private ExpandableNotificationRow mFirst;
|
private ExpandableNotificationRow mFirst;
|
||||||
private HeadsUpStatusBarView mHeadsUpStatusBarView;
|
private HeadsUpStatusBarView mHeadsUpStatusBarView;
|
||||||
@@ -97,13 +93,12 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
mHeadsUpManager,
|
mHeadsUpManager,
|
||||||
mStatusbarStateController,
|
mStatusbarStateController,
|
||||||
mBypassController,
|
mBypassController,
|
||||||
mLockscreenUserManager,
|
|
||||||
mWakeUpCoordinator,
|
mWakeUpCoordinator,
|
||||||
mDarkIconDispatcher,
|
mDarkIconDispatcher,
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mCommandQueue,
|
mCommandQueue,
|
||||||
mStackScrollerController,
|
mStackScrollerController,
|
||||||
mPanelViewController,
|
mPanelView,
|
||||||
mHeadsUpStatusBarView,
|
mHeadsUpStatusBarView,
|
||||||
new Clock(mContext, null),
|
new Clock(mContext, null),
|
||||||
Optional.of(mOperatorNameView));
|
Optional.of(mOperatorNameView));
|
||||||
@@ -180,13 +175,12 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
mHeadsUpManager,
|
mHeadsUpManager,
|
||||||
mStatusbarStateController,
|
mStatusbarStateController,
|
||||||
mBypassController,
|
mBypassController,
|
||||||
mLockscreenUserManager,
|
|
||||||
mWakeUpCoordinator,
|
mWakeUpCoordinator,
|
||||||
mDarkIconDispatcher,
|
mDarkIconDispatcher,
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mCommandQueue,
|
mCommandQueue,
|
||||||
mStackScrollerController,
|
mStackScrollerController,
|
||||||
mPanelViewController,
|
mPanelView,
|
||||||
mHeadsUpStatusBarView,
|
mHeadsUpStatusBarView,
|
||||||
new Clock(mContext, null),
|
new Clock(mContext, null),
|
||||||
Optional.empty());
|
Optional.empty());
|
||||||
@@ -199,15 +193,15 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
public void testDestroy() {
|
public void testDestroy() {
|
||||||
reset(mHeadsUpManager);
|
reset(mHeadsUpManager);
|
||||||
reset(mDarkIconDispatcher);
|
reset(mDarkIconDispatcher);
|
||||||
reset(mPanelViewController);
|
reset(mPanelView);
|
||||||
reset(mStackScrollerController);
|
reset(mStackScrollerController);
|
||||||
|
|
||||||
mHeadsUpAppearanceController.onViewDetached();
|
mHeadsUpAppearanceController.onViewDetached();
|
||||||
|
|
||||||
verify(mHeadsUpManager).removeListener(any());
|
verify(mHeadsUpManager).removeListener(any());
|
||||||
verify(mDarkIconDispatcher).removeDarkReceiver((DarkIconDispatcher.DarkReceiver) any());
|
verify(mDarkIconDispatcher).removeDarkReceiver((DarkIconDispatcher.DarkReceiver) any());
|
||||||
verify(mPanelViewController).removeTrackingHeadsUpListener(any());
|
verify(mPanelView).removeTrackingHeadsUpListener(any());
|
||||||
verify(mPanelViewController).setHeadsUpAppearanceController(isNull());
|
verify(mPanelView).setHeadsUpAppearanceController(isNull());
|
||||||
verify(mStackScrollerController).removeOnExpandedHeightChangedListener(any());
|
verify(mStackScrollerController).removeOnExpandedHeightChangedListener(any());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user