Merge "Inline notif pipeline flag in NotifEntryManager" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5204191eca
@@ -81,7 +81,6 @@ 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;
|
||||||
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
|
|
||||||
import com.android.systemui.statusbar.SmartReplyController;
|
import com.android.systemui.statusbar.SmartReplyController;
|
||||||
import com.android.systemui.statusbar.VibratorHelper;
|
import com.android.systemui.statusbar.VibratorHelper;
|
||||||
import com.android.systemui.statusbar.events.PrivacyDotViewController;
|
import com.android.systemui.statusbar.events.PrivacyDotViewController;
|
||||||
@@ -323,7 +322,6 @@ public class Dependency {
|
|||||||
@Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
|
@Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
|
||||||
@Inject Lazy<NotificationListener> mNotificationListener;
|
@Inject Lazy<NotificationListener> mNotificationListener;
|
||||||
@Inject Lazy<NotificationLogger> mNotificationLogger;
|
@Inject Lazy<NotificationLogger> mNotificationLogger;
|
||||||
@Inject Lazy<NotificationViewHierarchyManager> mNotificationViewHierarchyManager;
|
|
||||||
@Inject Lazy<NotificationFilter> mNotificationFilter;
|
@Inject Lazy<NotificationFilter> mNotificationFilter;
|
||||||
@Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil;
|
@Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil;
|
||||||
@Inject Lazy<SmartReplyController> mSmartReplyController;
|
@Inject Lazy<SmartReplyController> mSmartReplyController;
|
||||||
@@ -540,8 +538,6 @@ public class Dependency {
|
|||||||
mProviders.put(SmartReplyConstants.class, mSmartReplyConstants::get);
|
mProviders.put(SmartReplyConstants.class, mSmartReplyConstants::get);
|
||||||
mProviders.put(NotificationListener.class, mNotificationListener::get);
|
mProviders.put(NotificationListener.class, mNotificationListener::get);
|
||||||
mProviders.put(NotificationLogger.class, mNotificationLogger::get);
|
mProviders.put(NotificationLogger.class, mNotificationLogger::get);
|
||||||
mProviders.put(NotificationViewHierarchyManager.class,
|
|
||||||
mNotificationViewHierarchyManager::get);
|
|
||||||
mProviders.put(NotificationFilter.class, mNotificationFilter::get);
|
mProviders.put(NotificationFilter.class, mNotificationFilter::get);
|
||||||
mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get);
|
mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get);
|
||||||
mProviders.put(SmartReplyController.class, mSmartReplyController::get);
|
mProviders.put(SmartReplyController.class, mSmartReplyController::get);
|
||||||
|
|||||||
@@ -49,16 +49,6 @@ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpan
|
|||||||
*/
|
*/
|
||||||
boolean isDeviceInVrMode();
|
boolean isDeviceInVrMode();
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the visual representation of the notifications.
|
|
||||||
*/
|
|
||||||
void updateNotificationViews(String reason);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the row states are updated by {@link NotificationViewHierarchyManager}.
|
|
||||||
*/
|
|
||||||
void onUpdateRowStates();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the shade is collapsing.
|
* @return true if the shade is collapsing.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,631 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 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;
|
|
||||||
|
|
||||||
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Trace;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|
||||||
import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
|
|
||||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
|
||||||
import com.android.systemui.statusbar.notification.DynamicChildBindController;
|
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifStats;
|
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
|
||||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|
||||||
import com.android.systemui.util.Assert;
|
|
||||||
import com.android.wm.shell.bubbles.Bubbles;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NotificationViewHierarchyManager manages updating the view hierarchy of notification views based
|
|
||||||
* on their group structure. For example, if a notification becomes bundled with another,
|
|
||||||
* NotificationViewHierarchyManager will update the view hierarchy to reflect that. It also will
|
|
||||||
* tell NotificationListContainer which notifications to display, and inform it of changes to those
|
|
||||||
* notifications that might affect their display.
|
|
||||||
*/
|
|
||||||
public class NotificationViewHierarchyManager implements DynamicPrivacyController.Listener {
|
|
||||||
private static final String TAG = "NotificationViewHierarchyManager";
|
|
||||||
|
|
||||||
private final Handler mHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-usable map of top-level notifications to their sorted children if any.
|
|
||||||
* If the top-level notification doesn't have children, its key will still exist in this map
|
|
||||||
* with its value explicitly set to null.
|
|
||||||
*/
|
|
||||||
private final HashMap<NotificationEntry, List<NotificationEntry>> mTmpChildOrderMap =
|
|
||||||
new HashMap<>();
|
|
||||||
|
|
||||||
// Dependencies:
|
|
||||||
private final DynamicChildBindController mDynamicChildBindController;
|
|
||||||
private final FeatureFlags mFeatureFlags;
|
|
||||||
protected final NotificationLockscreenUserManager mLockscreenUserManager;
|
|
||||||
protected final NotificationGroupManagerLegacy mGroupManager;
|
|
||||||
protected final VisualStabilityManager mVisualStabilityManager;
|
|
||||||
private final SysuiStatusBarStateController mStatusBarStateController;
|
|
||||||
private final NotificationEntryManager mEntryManager;
|
|
||||||
private final LowPriorityInflationHelper mLowPriorityInflationHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code true} if notifications not part of a group should by default be rendered in their
|
|
||||||
* expanded state. If {@code false}, then only the first notification will be expanded if
|
|
||||||
* possible.
|
|
||||||
*/
|
|
||||||
private final boolean mAlwaysExpandNonGroupedNotification;
|
|
||||||
private final Optional<Bubbles> mBubblesOptional;
|
|
||||||
private final DynamicPrivacyController mDynamicPrivacyController;
|
|
||||||
private final KeyguardBypassController mBypassController;
|
|
||||||
private final NotifPipelineFlags mNotifPipelineFlags;
|
|
||||||
private AssistantFeedbackController mAssistantFeedbackController;
|
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
|
||||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
private NotificationPresenter mPresenter;
|
|
||||||
private NotifStackController mStackController;
|
|
||||||
private NotificationListContainer mListContainer;
|
|
||||||
|
|
||||||
// Used to help track down re-entrant calls to our update methods, which will cause bugs.
|
|
||||||
private boolean mPerformingUpdate;
|
|
||||||
// Hack to get around re-entrant call in onDynamicPrivacyChanged() until we can track down
|
|
||||||
// the problem.
|
|
||||||
private boolean mIsHandleDynamicPrivacyChangeScheduled;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injected constructor. See {@link CentralSurfacesModule}.
|
|
||||||
*/
|
|
||||||
public NotificationViewHierarchyManager(
|
|
||||||
Context context,
|
|
||||||
@Main Handler mainHandler,
|
|
||||||
FeatureFlags featureFlags,
|
|
||||||
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
|
||||||
NotificationGroupManagerLegacy groupManager,
|
|
||||||
VisualStabilityManager visualStabilityManager,
|
|
||||||
StatusBarStateController statusBarStateController,
|
|
||||||
NotificationEntryManager notificationEntryManager,
|
|
||||||
KeyguardBypassController bypassController,
|
|
||||||
Optional<Bubbles> bubblesOptional,
|
|
||||||
DynamicPrivacyController privacyController,
|
|
||||||
DynamicChildBindController dynamicChildBindController,
|
|
||||||
LowPriorityInflationHelper lowPriorityInflationHelper,
|
|
||||||
AssistantFeedbackController assistantFeedbackController,
|
|
||||||
NotifPipelineFlags notifPipelineFlags,
|
|
||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
|
||||||
KeyguardStateController keyguardStateController) {
|
|
||||||
mContext = context;
|
|
||||||
mHandler = mainHandler;
|
|
||||||
mFeatureFlags = featureFlags;
|
|
||||||
mLockscreenUserManager = notificationLockscreenUserManager;
|
|
||||||
mBypassController = bypassController;
|
|
||||||
mGroupManager = groupManager;
|
|
||||||
mVisualStabilityManager = visualStabilityManager;
|
|
||||||
mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
|
|
||||||
mEntryManager = notificationEntryManager;
|
|
||||||
mNotifPipelineFlags = notifPipelineFlags;
|
|
||||||
Resources res = context.getResources();
|
|
||||||
mAlwaysExpandNonGroupedNotification =
|
|
||||||
res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
|
|
||||||
mBubblesOptional = bubblesOptional;
|
|
||||||
mDynamicPrivacyController = privacyController;
|
|
||||||
mDynamicChildBindController = dynamicChildBindController;
|
|
||||||
mLowPriorityInflationHelper = lowPriorityInflationHelper;
|
|
||||||
mAssistantFeedbackController = assistantFeedbackController;
|
|
||||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
|
||||||
mKeyguardStateController = keyguardStateController;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpWithPresenter(NotificationPresenter presenter,
|
|
||||||
NotifStackController stackController,
|
|
||||||
NotificationListContainer listContainer) {
|
|
||||||
mPresenter = presenter;
|
|
||||||
mStackController = stackController;
|
|
||||||
mListContainer = listContainer;
|
|
||||||
if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
|
|
||||||
mDynamicPrivacyController.addListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the visual representation of the notifications.
|
|
||||||
*/
|
|
||||||
//TODO: Rewrite this to focus on Entries, or some other data object instead of views
|
|
||||||
public void updateNotificationViews() {
|
|
||||||
Assert.isMainThread();
|
|
||||||
if (!mNotifPipelineFlags.checkLegacyPipelineEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Trace.beginSection("NotificationViewHierarchyManager.updateNotificationViews");
|
|
||||||
|
|
||||||
beginUpdate();
|
|
||||||
|
|
||||||
boolean dynamicallyUnlocked = mDynamicPrivacyController.isDynamicallyUnlocked()
|
|
||||||
&& !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
|
|
||||||
&& mKeyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(
|
|
||||||
KeyguardUpdateMonitor.getCurrentUser()))
|
|
||||||
&& !mKeyguardStateController.isKeyguardGoingAway();
|
|
||||||
List<NotificationEntry> activeNotifications = mEntryManager.getVisibleNotifications();
|
|
||||||
ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
|
|
||||||
final int N = activeNotifications.size();
|
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
NotificationEntry ent = activeNotifications.get(i);
|
|
||||||
if (shouldSuppressActiveNotification(ent)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int userId = ent.getSbn().getUserId();
|
|
||||||
|
|
||||||
// Display public version of the notification if we need to redact.
|
|
||||||
// TODO: This area uses a lot of calls into NotificationLockscreenUserManager.
|
|
||||||
// We can probably move some of this code there.
|
|
||||||
int currentUserId = mLockscreenUserManager.getCurrentUserId();
|
|
||||||
boolean devicePublic = mLockscreenUserManager.isLockscreenPublicMode(currentUserId);
|
|
||||||
boolean userPublic = devicePublic
|
|
||||||
|| mLockscreenUserManager.isLockscreenPublicMode(userId);
|
|
||||||
if (userPublic && dynamicallyUnlocked
|
|
||||||
&& (userId == currentUserId || userId == UserHandle.USER_ALL
|
|
||||||
|| !mLockscreenUserManager.needsSeparateWorkChallenge(userId))) {
|
|
||||||
userPublic = false;
|
|
||||||
}
|
|
||||||
boolean needsRedaction = mLockscreenUserManager.needsRedaction(ent);
|
|
||||||
boolean sensitive = userPublic && needsRedaction;
|
|
||||||
boolean deviceSensitive = devicePublic
|
|
||||||
&& !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
|
|
||||||
currentUserId);
|
|
||||||
ent.setSensitive(sensitive, deviceSensitive);
|
|
||||||
ent.getRow().setNeedsRedaction(needsRedaction);
|
|
||||||
mLowPriorityInflationHelper.recheckLowPriorityViewAndInflate(ent, ent.getRow());
|
|
||||||
boolean isChildInGroup = mGroupManager.isChildInGroup(ent);
|
|
||||||
|
|
||||||
boolean groupChangesAllowed =
|
|
||||||
mVisualStabilityManager.areGroupChangesAllowed() // user isn't looking at notifs
|
|
||||||
|| !ent.hasFinishedInitialization(); // notif recently added
|
|
||||||
|
|
||||||
NotificationEntry parent = mGroupManager.getGroupSummary(ent);
|
|
||||||
if (!groupChangesAllowed) {
|
|
||||||
// We don't to change groups while the user is looking at them
|
|
||||||
boolean wasChildInGroup = ent.isChildInGroup();
|
|
||||||
if (isChildInGroup && !wasChildInGroup) {
|
|
||||||
isChildInGroup = wasChildInGroup;
|
|
||||||
mVisualStabilityManager.addGroupChangesAllowedCallback(mEntryManager,
|
|
||||||
false /* persistent */);
|
|
||||||
} else if (!isChildInGroup && wasChildInGroup) {
|
|
||||||
// We allow grouping changes if the group was collapsed
|
|
||||||
if (mGroupManager.isLogicalGroupExpanded(ent.getSbn())) {
|
|
||||||
isChildInGroup = wasChildInGroup;
|
|
||||||
parent = ent.getRow().getNotificationParent().getEntry();
|
|
||||||
mVisualStabilityManager.addGroupChangesAllowedCallback(mEntryManager,
|
|
||||||
false /* persistent */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isChildInGroup) {
|
|
||||||
List<NotificationEntry> orderedChildren = mTmpChildOrderMap.get(parent);
|
|
||||||
if (orderedChildren == null) {
|
|
||||||
orderedChildren = new ArrayList<>();
|
|
||||||
mTmpChildOrderMap.put(parent, orderedChildren);
|
|
||||||
}
|
|
||||||
orderedChildren.add(ent);
|
|
||||||
} else {
|
|
||||||
// Top-level notif (either a summary or single notification)
|
|
||||||
|
|
||||||
// A child may have already added its summary to mTmpChildOrderMap with a
|
|
||||||
// list of children. This can happen since there's no guarantee summaries are
|
|
||||||
// sorted before its children.
|
|
||||||
if (!mTmpChildOrderMap.containsKey(ent)) {
|
|
||||||
// mTmpChildOrderMap's keyset is used to iterate through all entries, so it's
|
|
||||||
// necessary to add each top-level notif as a key
|
|
||||||
mTmpChildOrderMap.put(ent, null);
|
|
||||||
}
|
|
||||||
toShow.add(ent.getRow());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<ExpandableNotificationRow> viewsToRemove = new ArrayList<>();
|
|
||||||
for (int i=0; i< mListContainer.getContainerChildCount(); i++) {
|
|
||||||
View child = mListContainer.getContainerChildAt(i);
|
|
||||||
if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
|
|
||||||
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
|
||||||
|
|
||||||
// Blocking helper is effectively a detached view. Don't bother removing it from the
|
|
||||||
// layout.
|
|
||||||
if (!row.isBlockingHelperShowing()) {
|
|
||||||
viewsToRemove.add((ExpandableNotificationRow) child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ExpandableNotificationRow viewToRemove : viewsToRemove) {
|
|
||||||
NotificationEntry entry = viewToRemove.getEntry();
|
|
||||||
if (mEntryManager.getPendingOrActiveNotif(entry.getKey()) != null
|
|
||||||
&& !shouldSuppressActiveNotification(entry)) {
|
|
||||||
// we are only transferring this notification to its parent, don't generate an
|
|
||||||
// animation. If the notification is suppressed, this isn't a transfer.
|
|
||||||
mListContainer.setChildTransferInProgress(true);
|
|
||||||
}
|
|
||||||
if (viewToRemove.isSummaryWithChildren()) {
|
|
||||||
viewToRemove.removeAllChildren();
|
|
||||||
}
|
|
||||||
mListContainer.removeContainerView(viewToRemove);
|
|
||||||
mListContainer.setChildTransferInProgress(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeNotificationChildren();
|
|
||||||
|
|
||||||
for (int i = 0; i < toShow.size(); i++) {
|
|
||||||
View v = toShow.get(i);
|
|
||||||
if (v.getParent() == null) {
|
|
||||||
mVisualStabilityManager.notifyViewAddition(v);
|
|
||||||
mListContainer.addContainerView(v);
|
|
||||||
} else if (!mListContainer.containsView(v)) {
|
|
||||||
// the view is added somewhere else. Let's make sure
|
|
||||||
// the ordering works properly below, by excluding these
|
|
||||||
toShow.remove(v);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addNotificationChildrenAndSort();
|
|
||||||
|
|
||||||
// So after all this work notifications still aren't sorted correctly.
|
|
||||||
// Let's do that now by advancing through toShow and mListContainer in
|
|
||||||
// lock-step, making sure mListContainer matches what we see in toShow.
|
|
||||||
int j = 0;
|
|
||||||
for (int i = 0; i < mListContainer.getContainerChildCount(); i++) {
|
|
||||||
View child = mListContainer.getContainerChildAt(i);
|
|
||||||
if (!(child instanceof ExpandableNotificationRow)) {
|
|
||||||
// We don't care about non-notification views.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (((ExpandableNotificationRow) child).isBlockingHelperShowing()) {
|
|
||||||
// Don't count/reorder notifications that are showing the blocking helper!
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpandableNotificationRow targetChild = toShow.get(j);
|
|
||||||
if (child != targetChild) {
|
|
||||||
// Oops, wrong notification at this position. Put the right one
|
|
||||||
// here and advance both lists.
|
|
||||||
if (mVisualStabilityManager.canReorderNotification(targetChild)) {
|
|
||||||
mListContainer.changeViewPosition(targetChild, i);
|
|
||||||
} else {
|
|
||||||
mVisualStabilityManager.addReorderingAllowedCallback(mEntryManager,
|
|
||||||
false /* persistent */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mDynamicChildBindController.updateContentViews(mTmpChildOrderMap);
|
|
||||||
mVisualStabilityManager.onReorderingFinished();
|
|
||||||
// clear the map again for the next usage
|
|
||||||
mTmpChildOrderMap.clear();
|
|
||||||
|
|
||||||
updateRowStatesInternal();
|
|
||||||
updateNotifStats();
|
|
||||||
|
|
||||||
mListContainer.onNotificationViewUpdateFinished();
|
|
||||||
|
|
||||||
endUpdate();
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* In the spirit of unidirectional data flow, calculate this information when the notification
|
|
||||||
* views are updated, and set it once, speeding up lookups later.
|
|
||||||
* This is analogous to logic in the
|
|
||||||
* {@link com.android.systemui.statusbar.notification.collection.coordinator.StackCoordinator}
|
|
||||||
*/
|
|
||||||
private void updateNotifStats() {
|
|
||||||
Trace.beginSection("NotificationViewHierarchyManager.updateNotifStats");
|
|
||||||
boolean hasNonClearableAlertingNotifs = false;
|
|
||||||
boolean hasClearableAlertingNotifs = false;
|
|
||||||
boolean hasNonClearableSilentNotifs = false;
|
|
||||||
boolean hasClearableSilentNotifs = false;
|
|
||||||
final int childCount = mListContainer.getContainerChildCount();
|
|
||||||
int visibleTopLevelEntries = 0;
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
View child = mListContainer.getContainerChildAt(i);
|
|
||||||
if (child == null || child.getVisibility() == View.GONE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!(child instanceof ExpandableNotificationRow)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
|
||||||
boolean isSilent = row.getEntry().getBucket() == BUCKET_SILENT;
|
|
||||||
// NOTE: NotificationEntry.isClearable() will internally check group children to ensure
|
|
||||||
// the group itself definitively clearable.
|
|
||||||
boolean isClearable = row.getEntry().isClearable();
|
|
||||||
visibleTopLevelEntries++;
|
|
||||||
if (isSilent) {
|
|
||||||
if (isClearable) {
|
|
||||||
hasClearableSilentNotifs = true;
|
|
||||||
} else { // !isClearable
|
|
||||||
hasNonClearableSilentNotifs = true;
|
|
||||||
}
|
|
||||||
} else { // !isSilent
|
|
||||||
if (isClearable) {
|
|
||||||
hasClearableAlertingNotifs = true;
|
|
||||||
} else { // !isClearable
|
|
||||||
hasNonClearableAlertingNotifs = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mStackController.setNotifStats(new NotifStats(
|
|
||||||
visibleTopLevelEntries /* numActiveNotifs */,
|
|
||||||
hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */,
|
|
||||||
hasClearableAlertingNotifs /* hasClearableAlertingNotifs */,
|
|
||||||
hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */,
|
|
||||||
hasClearableSilentNotifs /* hasClearableSilentNotifs */
|
|
||||||
));
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should a notification entry from the active list be suppressed and not show?
|
|
||||||
*/
|
|
||||||
private boolean shouldSuppressActiveNotification(NotificationEntry ent) {
|
|
||||||
final boolean isBubbleNotificationSuppressedFromShade = mBubblesOptional.isPresent()
|
|
||||||
&& mBubblesOptional.get().isBubbleNotificationSuppressedFromShade(
|
|
||||||
ent.getKey(), ent.getSbn().getGroupKey());
|
|
||||||
if (ent.isRowDismissed() || ent.isRowRemoved()
|
|
||||||
|| isBubbleNotificationSuppressedFromShade) {
|
|
||||||
// we want to suppress removed notifications because they could
|
|
||||||
// temporarily become children if they were isolated before.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addNotificationChildrenAndSort() {
|
|
||||||
// Let's now add all notification children which are missing
|
|
||||||
boolean orderChanged = false;
|
|
||||||
ArrayList<ExpandableNotificationRow> orderedRows = new ArrayList<>();
|
|
||||||
for (int i = 0; i < mListContainer.getContainerChildCount(); i++) {
|
|
||||||
View view = mListContainer.getContainerChildAt(i);
|
|
||||||
if (!(view instanceof ExpandableNotificationRow)) {
|
|
||||||
// We don't care about non-notification views.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
|
|
||||||
List<ExpandableNotificationRow> children = parent.getAttachedChildren();
|
|
||||||
List<NotificationEntry> orderedChildren = mTmpChildOrderMap.get(parent.getEntry());
|
|
||||||
if (orderedChildren == null) {
|
|
||||||
// Not a group
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
parent.setUntruncatedChildCount(orderedChildren.size());
|
|
||||||
for (int childIndex = 0; childIndex < orderedChildren.size(); childIndex++) {
|
|
||||||
ExpandableNotificationRow childView = orderedChildren.get(childIndex).getRow();
|
|
||||||
if (children == null || !children.contains(childView)) {
|
|
||||||
if (childView.getParent() != null) {
|
|
||||||
Log.wtf(TAG, "trying to add a notification child that already has "
|
|
||||||
+ "a parent. class:" + childView.getParent().getClass()
|
|
||||||
+ "\n child: " + childView);
|
|
||||||
// This shouldn't happen. We can recover by removing it though.
|
|
||||||
((ViewGroup) childView.getParent()).removeView(childView);
|
|
||||||
}
|
|
||||||
mVisualStabilityManager.notifyViewAddition(childView);
|
|
||||||
parent.addChildNotification(childView, childIndex);
|
|
||||||
mListContainer.notifyGroupChildAdded(childView);
|
|
||||||
}
|
|
||||||
orderedRows.add(childView);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally after removing and adding has been performed we can apply the order.
|
|
||||||
orderChanged |= parent.applyChildOrder(orderedRows, mVisualStabilityManager,
|
|
||||||
mEntryManager);
|
|
||||||
orderedRows.clear();
|
|
||||||
}
|
|
||||||
if (orderChanged) {
|
|
||||||
mListContainer.generateChildOrderChangedEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeNotificationChildren() {
|
|
||||||
// First let's remove all children which don't belong in the parents
|
|
||||||
ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
|
|
||||||
for (int i = 0; i < mListContainer.getContainerChildCount(); i++) {
|
|
||||||
View view = mListContainer.getContainerChildAt(i);
|
|
||||||
if (!(view instanceof ExpandableNotificationRow)) {
|
|
||||||
// We don't care about non-notification views.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
|
|
||||||
List<ExpandableNotificationRow> children = parent.getAttachedChildren();
|
|
||||||
List<NotificationEntry> orderedChildren = mTmpChildOrderMap.get(parent.getEntry());
|
|
||||||
|
|
||||||
if (children != null) {
|
|
||||||
toRemove.clear();
|
|
||||||
for (ExpandableNotificationRow childRow : children) {
|
|
||||||
if ((orderedChildren == null
|
|
||||||
|| !orderedChildren.contains(childRow.getEntry()))
|
|
||||||
&& !childRow.keepInParent()) {
|
|
||||||
toRemove.add(childRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ExpandableNotificationRow remove : toRemove) {
|
|
||||||
parent.removeChildNotification(remove);
|
|
||||||
if (mEntryManager.getActiveNotificationUnfiltered(
|
|
||||||
remove.getEntry().getSbn().getKey()) == null) {
|
|
||||||
// We only want to add an animation if the view is completely removed
|
|
||||||
// otherwise it's just a transfer
|
|
||||||
mListContainer.notifyGroupChildRemoved(remove,
|
|
||||||
parent.getChildrenContainer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates expanded, dimmed and locked states of notification rows.
|
|
||||||
*/
|
|
||||||
public void updateRowStates() {
|
|
||||||
Assert.isMainThread();
|
|
||||||
if (!mNotifPipelineFlags.checkLegacyPipelineEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
beginUpdate();
|
|
||||||
updateRowStatesInternal();
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateRowStatesInternal() {
|
|
||||||
Trace.beginSection("NotificationViewHierarchyManager.updateRowStates");
|
|
||||||
final int N = mListContainer.getContainerChildCount();
|
|
||||||
|
|
||||||
int visibleNotifications = 0;
|
|
||||||
boolean onKeyguard =
|
|
||||||
mStatusBarStateController.getCurrentOrUpcomingState() == StatusBarState.KEYGUARD;
|
|
||||||
Stack<ExpandableNotificationRow> stack = new Stack<>();
|
|
||||||
for (int i = N - 1; i >= 0; i--) {
|
|
||||||
View child = mListContainer.getContainerChildAt(i);
|
|
||||||
if (!(child instanceof ExpandableNotificationRow)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stack.push((ExpandableNotificationRow) child);
|
|
||||||
}
|
|
||||||
while(!stack.isEmpty()) {
|
|
||||||
ExpandableNotificationRow row = stack.pop();
|
|
||||||
NotificationEntry entry = row.getEntry();
|
|
||||||
boolean isChildNotification = mGroupManager.isChildInGroup(entry);
|
|
||||||
|
|
||||||
if (!onKeyguard) {
|
|
||||||
// If mAlwaysExpandNonGroupedNotification is false, then only expand the
|
|
||||||
// very first notification and if it's not a child of grouped notifications.
|
|
||||||
row.setSystemExpanded(mAlwaysExpandNonGroupedNotification
|
|
||||||
|| (visibleNotifications == 0 && !isChildNotification
|
|
||||||
&& !row.isLowPriority()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int userId = entry.getSbn().getUserId();
|
|
||||||
boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
|
|
||||||
entry.getSbn()) && !entry.isRowRemoved();
|
|
||||||
boolean showOnKeyguard = mLockscreenUserManager.shouldShowOnKeyguard(entry);
|
|
||||||
if (!showOnKeyguard) {
|
|
||||||
// min priority notifications should show if their summary is showing
|
|
||||||
if (mGroupManager.isChildInGroup(entry)) {
|
|
||||||
NotificationEntry summary = mGroupManager.getLogicalGroupSummary(entry);
|
|
||||||
if (summary != null && mLockscreenUserManager.shouldShowOnKeyguard(summary)) {
|
|
||||||
showOnKeyguard = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (suppressedSummary
|
|
||||||
|| mLockscreenUserManager.shouldHideNotifications(userId)
|
|
||||||
|| (onKeyguard && !showOnKeyguard)) {
|
|
||||||
entry.getRow().setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
boolean wasGone = entry.getRow().getVisibility() == View.GONE;
|
|
||||||
if (wasGone) {
|
|
||||||
entry.getRow().setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
if (!isChildNotification && !entry.getRow().isRemoved()) {
|
|
||||||
if (wasGone) {
|
|
||||||
// notify the scroller of a child addition
|
|
||||||
mListContainer.generateAddAnimation(entry.getRow(),
|
|
||||||
!showOnKeyguard /* fromMoreCard */);
|
|
||||||
}
|
|
||||||
visibleNotifications++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (row.isSummaryWithChildren()) {
|
|
||||||
List<ExpandableNotificationRow> notificationChildren =
|
|
||||||
row.getAttachedChildren();
|
|
||||||
int size = notificationChildren.size();
|
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
|
||||||
stack.push(notificationChildren.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
row.setFeedbackIcon(mAssistantFeedbackController.getFeedbackIcon(entry));
|
|
||||||
row.setLastAudiblyAlertedMs(entry.getLastAudiblyAlertedMs());
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace.beginSection("NotificationPresenter#onUpdateRowStates");
|
|
||||||
mPresenter.onUpdateRowStates();
|
|
||||||
Trace.endSection();
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDynamicPrivacyChanged() {
|
|
||||||
mNotifPipelineFlags.assertLegacyPipelineEnabled();
|
|
||||||
if (mPerformingUpdate) {
|
|
||||||
Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call");
|
|
||||||
}
|
|
||||||
// This listener can be called from updateNotificationViews() via a convoluted listener
|
|
||||||
// chain, so we post here to prevent a re-entrant call. See b/136186188
|
|
||||||
// TODO: Refactor away the need for this
|
|
||||||
if (!mIsHandleDynamicPrivacyChangeScheduled) {
|
|
||||||
mIsHandleDynamicPrivacyChangeScheduled = true;
|
|
||||||
mHandler.post(this::onHandleDynamicPrivacyChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onHandleDynamicPrivacyChanged() {
|
|
||||||
mIsHandleDynamicPrivacyChangeScheduled = false;
|
|
||||||
updateNotificationViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void beginUpdate() {
|
|
||||||
if (mPerformingUpdate) {
|
|
||||||
Log.wtf(TAG, "Re-entrant code during update", new Exception());
|
|
||||||
}
|
|
||||||
mPerformingUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void endUpdate() {
|
|
||||||
if (!mPerformingUpdate) {
|
|
||||||
Log.wtf(TAG, "Manager state has become desynced", new Exception());
|
|
||||||
}
|
|
||||||
mPerformingUpdate = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,13 +23,11 @@ import android.service.dreams.IDreamManager;
|
|||||||
|
|
||||||
import com.android.internal.jank.InteractionJankMonitor;
|
import com.android.internal.jank.InteractionJankMonitor;
|
||||||
import com.android.internal.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.media.MediaDataManager;
|
import com.android.systemui.media.MediaDataManager;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
@@ -42,23 +40,16 @@ 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;
|
||||||
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
|
|
||||||
import com.android.systemui.statusbar.RemoteInputNotificationRebuilder;
|
import com.android.systemui.statusbar.RemoteInputNotificationRebuilder;
|
||||||
import com.android.systemui.statusbar.SmartReplyController;
|
import com.android.systemui.statusbar.SmartReplyController;
|
||||||
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.commandline.CommandRegistry;
|
import com.android.systemui.statusbar.commandline.CommandRegistry;
|
||||||
import com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureHandler;
|
import com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureHandler;
|
||||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
|
||||||
import com.android.systemui.statusbar.notification.DynamicChildBindController;
|
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||||
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
||||||
@@ -73,13 +64,11 @@ import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
|
|||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallFlags;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallFlags;
|
||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLogger;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLogger;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|
||||||
import com.android.systemui.statusbar.policy.RemoteInputUriController;
|
import com.android.systemui.statusbar.policy.RemoteInputUriController;
|
||||||
import com.android.systemui.statusbar.window.StatusBarWindowController;
|
import com.android.systemui.statusbar.window.StatusBarWindowController;
|
||||||
import com.android.systemui.tracing.ProtoTracer;
|
import com.android.systemui.tracing.ProtoTracer;
|
||||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||||
import com.android.systemui.util.time.SystemClock;
|
import com.android.systemui.util.time.SystemClock;
|
||||||
import com.android.wm.shell.bubbles.Bubbles;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -182,47 +171,6 @@ public interface CentralSurfacesDependenciesModule {
|
|||||||
NotificationRemoteInputManager.Callback provideNotificationRemoteInputManagerCallback(
|
NotificationRemoteInputManager.Callback provideNotificationRemoteInputManagerCallback(
|
||||||
StatusBarRemoteInputCallback callbackImpl);
|
StatusBarRemoteInputCallback callbackImpl);
|
||||||
|
|
||||||
/** */
|
|
||||||
@SysUISingleton
|
|
||||||
@Provides
|
|
||||||
static NotificationViewHierarchyManager provideNotificationViewHierarchyManager(
|
|
||||||
Context context,
|
|
||||||
@Main Handler mainHandler,
|
|
||||||
FeatureFlags featureFlags,
|
|
||||||
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
|
||||||
NotificationGroupManagerLegacy groupManager,
|
|
||||||
VisualStabilityManager visualStabilityManager,
|
|
||||||
StatusBarStateController statusBarStateController,
|
|
||||||
NotificationEntryManager notificationEntryManager,
|
|
||||||
KeyguardBypassController bypassController,
|
|
||||||
Optional<Bubbles> bubblesOptional,
|
|
||||||
DynamicPrivacyController privacyController,
|
|
||||||
DynamicChildBindController dynamicChildBindController,
|
|
||||||
LowPriorityInflationHelper lowPriorityInflationHelper,
|
|
||||||
AssistantFeedbackController assistantFeedbackController,
|
|
||||||
NotifPipelineFlags notifPipelineFlags,
|
|
||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
|
||||||
KeyguardStateController keyguardStateController) {
|
|
||||||
return new NotificationViewHierarchyManager(
|
|
||||||
context,
|
|
||||||
mainHandler,
|
|
||||||
featureFlags,
|
|
||||||
notificationLockscreenUserManager,
|
|
||||||
groupManager,
|
|
||||||
visualStabilityManager,
|
|
||||||
statusBarStateController,
|
|
||||||
notificationEntryManager,
|
|
||||||
bypassController,
|
|
||||||
bubblesOptional,
|
|
||||||
privacyController,
|
|
||||||
dynamicChildBindController,
|
|
||||||
lowPriorityInflationHelper,
|
|
||||||
assistantFeedbackController,
|
|
||||||
notifPipelineFlags,
|
|
||||||
keyguardUpdateMonitor,
|
|
||||||
keyguardStateController);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides our instance of CommandQueue which is considered optional.
|
* Provides our instance of CommandQueue which is considered optional.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ class NotifPipelineFlags @Inject constructor(
|
|||||||
val featureFlags: FeatureFlags
|
val featureFlags: FeatureFlags
|
||||||
) {
|
) {
|
||||||
fun checkLegacyPipelineEnabled(): Boolean {
|
fun checkLegacyPipelineEnabled(): Boolean {
|
||||||
if (!isNewPipelineEnabled()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Compile.IS_DEBUG) {
|
if (Compile.IS_DEBUG) {
|
||||||
Toast.makeText(context, "Old pipeline code running!", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Old pipeline code running!", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
@@ -45,11 +41,6 @@ class NotifPipelineFlags @Inject constructor(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertLegacyPipelineEnabled(): Unit =
|
|
||||||
check(!isNewPipelineEnabled()) { "Old pipeline code running w/ new pipeline enabled" }
|
|
||||||
|
|
||||||
fun isNewPipelineEnabled(): Boolean = true
|
|
||||||
|
|
||||||
fun isDevLoggingEnabled(): Boolean =
|
fun isDevLoggingEnabled(): Boolean =
|
||||||
featureFlags.isEnabled(Flags.NOTIFICATION_PIPELINE_DEVELOPER_LOGGING)
|
featureFlags.isEnabled(Flags.NOTIFICATION_PIPELINE_DEVELOPER_LOGGING)
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,9 @@ import com.android.systemui.dump.DumpManager;
|
|||||||
import com.android.systemui.statusbar.NotificationLifetimeExtender;
|
import com.android.systemui.statusbar.NotificationLifetimeExtender;
|
||||||
import com.android.systemui.statusbar.NotificationListener;
|
import com.android.systemui.statusbar.NotificationListener;
|
||||||
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
||||||
import com.android.systemui.statusbar.NotificationPresenter;
|
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
|
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
|
||||||
import com.android.systemui.statusbar.NotificationUiAdjustment;
|
import com.android.systemui.statusbar.NotificationUiAdjustment;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
|
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationRanker;
|
import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationRanker;
|
||||||
@@ -113,7 +111,6 @@ public class NotificationEntryManager implements
|
|||||||
private final Lazy<NotificationRemoteInputManager> mRemoteInputManagerLazy;
|
private final Lazy<NotificationRemoteInputManager> mRemoteInputManagerLazy;
|
||||||
private final LeakDetector mLeakDetector;
|
private final LeakDetector mLeakDetector;
|
||||||
private final IStatusBarService mStatusBarService;
|
private final IStatusBarService mStatusBarService;
|
||||||
private final NotifLiveDataStoreImpl mNotifLiveDataStore;
|
|
||||||
private final DumpManager mDumpManager;
|
private final DumpManager mDumpManager;
|
||||||
private final Executor mBgExecutor;
|
private final Executor mBgExecutor;
|
||||||
|
|
||||||
@@ -141,7 +138,6 @@ public class NotificationEntryManager implements
|
|||||||
private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
|
private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
|
||||||
|
|
||||||
private LegacyNotificationRanker mRanker = new LegacyNotificationRankerStub();
|
private LegacyNotificationRanker mRanker = new LegacyNotificationRankerStub();
|
||||||
private NotificationPresenter mPresenter;
|
|
||||||
private RankingMap mLatestRankingMap;
|
private RankingMap mLatestRankingMap;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -161,7 +157,6 @@ public class NotificationEntryManager implements
|
|||||||
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
|
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
|
||||||
LeakDetector leakDetector,
|
LeakDetector leakDetector,
|
||||||
IStatusBarService statusBarService,
|
IStatusBarService statusBarService,
|
||||||
NotifLiveDataStoreImpl notifLiveDataStore,
|
|
||||||
DumpManager dumpManager,
|
DumpManager dumpManager,
|
||||||
@Background Executor bgExecutor
|
@Background Executor bgExecutor
|
||||||
) {
|
) {
|
||||||
@@ -172,7 +167,6 @@ public class NotificationEntryManager implements
|
|||||||
mRemoteInputManagerLazy = notificationRemoteInputManagerLazy;
|
mRemoteInputManagerLazy = notificationRemoteInputManagerLazy;
|
||||||
mLeakDetector = leakDetector;
|
mLeakDetector = leakDetector;
|
||||||
mStatusBarService = statusBarService;
|
mStatusBarService = statusBarService;
|
||||||
mNotifLiveDataStore = notifLiveDataStore;
|
|
||||||
mDumpManager = dumpManager;
|
mDumpManager = dumpManager;
|
||||||
mBgExecutor = bgExecutor;
|
mBgExecutor = bgExecutor;
|
||||||
}
|
}
|
||||||
@@ -250,10 +244,6 @@ public class NotificationEntryManager implements
|
|||||||
mRemoveInterceptors.remove(interceptor);
|
mRemoveInterceptors.remove(interceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpWithPresenter(NotificationPresenter presenter) {
|
|
||||||
mPresenter = presenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds multiple {@link NotificationLifetimeExtender}s. */
|
/** Adds multiple {@link NotificationLifetimeExtender}s. */
|
||||||
public void addNotificationLifetimeExtenders(List<NotificationLifetimeExtender> extenders) {
|
public void addNotificationLifetimeExtenders(List<NotificationLifetimeExtender> extenders) {
|
||||||
for (NotificationLifetimeExtender extender : extenders) {
|
for (NotificationLifetimeExtender extender : extenders) {
|
||||||
@@ -663,11 +653,6 @@ public class NotificationEntryManager implements
|
|||||||
listener.onEntryBind(entry, notification);
|
listener.onEntryBind(entry, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the expanded view.
|
|
||||||
if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
|
|
||||||
mNotificationRowBinderLazy.get().inflateViews(entry, null, mInflationCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
mPendingNotifications.put(key, entry);
|
mPendingNotifications.put(key, entry);
|
||||||
mLogger.logNotifAdded(entry.getKey());
|
mLogger.logNotifAdded(entry.getKey());
|
||||||
for (NotificationEntryListener listener : mNotificationEntryListeners) {
|
for (NotificationEntryListener listener : mNotificationEntryListeners) {
|
||||||
@@ -724,10 +709,6 @@ public class NotificationEntryManager implements
|
|||||||
listener.onEntryUpdated(entry, fromSystem);
|
listener.onEntryUpdated(entry, fromSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
|
|
||||||
mNotificationRowBinderLazy.get().inflateViews(entry, null, mInflationCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNotifications("updateNotificationInternal");
|
updateNotifications("updateNotificationInternal");
|
||||||
|
|
||||||
for (NotificationEntryListener listener : mNotificationEntryListeners) {
|
for (NotificationEntryListener listener : mNotificationEntryListeners) {
|
||||||
@@ -752,17 +733,7 @@ public class NotificationEntryManager implements
|
|||||||
* @param reason why the notifications are updating
|
* @param reason why the notifications are updating
|
||||||
*/
|
*/
|
||||||
public void updateNotifications(String reason) {
|
public void updateNotifications(String reason) {
|
||||||
if (mNotifPipelineFlags.isNewPipelineEnabled()) {
|
mLogger.logUseWhileNewPipelineActive("updateNotifications", reason);
|
||||||
mLogger.logUseWhileNewPipelineActive("updateNotifications", reason);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Trace.beginSection("NotificationEntryManager.updateNotifications");
|
|
||||||
reapplyFilterAndSort(reason);
|
|
||||||
if (mPresenter != null) {
|
|
||||||
mPresenter.updateNotificationViews(reason);
|
|
||||||
}
|
|
||||||
mNotifLiveDataStore.setActiveNotifList(getVisibleNotifications());
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateNotificationRanking(RankingMap rankingMap) {
|
public void updateNotificationRanking(RankingMap rankingMap) {
|
||||||
@@ -939,26 +910,12 @@ public class NotificationEntryManager implements
|
|||||||
|
|
||||||
/** Resorts / filters the current notification set with the current RankingMap */
|
/** Resorts / filters the current notification set with the current RankingMap */
|
||||||
public void reapplyFilterAndSort(String reason) {
|
public void reapplyFilterAndSort(String reason) {
|
||||||
if (mNotifPipelineFlags.isNewPipelineEnabled()) {
|
mLogger.logUseWhileNewPipelineActive("reapplyFilterAndSort", reason);
|
||||||
mLogger.logUseWhileNewPipelineActive("reapplyFilterAndSort", reason);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Trace.beginSection("NotificationEntryManager.reapplyFilterAndSort");
|
|
||||||
updateRankingAndSort(mRanker.getRankingMap(), reason);
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Calls to NotificationRankingManager and updates mSortedAndFiltered */
|
/** Calls to NotificationRankingManager and updates mSortedAndFiltered */
|
||||||
private void updateRankingAndSort(RankingMap rankingMap, String reason) {
|
private void updateRankingAndSort(RankingMap rankingMap, String reason) {
|
||||||
if (mNotifPipelineFlags.isNewPipelineEnabled()) {
|
mLogger.logUseWhileNewPipelineActive("updateRankingAndSort", reason);
|
||||||
mLogger.logUseWhileNewPipelineActive("updateRankingAndSort", reason);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Trace.beginSection("NotificationEntryManager.updateRankingAndSort");
|
|
||||||
mSortedAndFiltered.clear();
|
|
||||||
mSortedAndFiltered.addAll(mRanker.updateRanking(
|
|
||||||
rankingMap, mActiveNotifications.values(), reason));
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** dump the current active notification list. Called from CentralSurfaces */
|
/** dump the current active notification list. Called from CentralSurfaces */
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ public interface NotificationsModule {
|
|||||||
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
|
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
|
||||||
LeakDetector leakDetector,
|
LeakDetector leakDetector,
|
||||||
IStatusBarService statusBarService,
|
IStatusBarService statusBarService,
|
||||||
NotifLiveDataStoreImpl notifLiveDataStore,
|
|
||||||
DumpManager dumpManager,
|
DumpManager dumpManager,
|
||||||
@Background Executor bgExecutor) {
|
@Background Executor bgExecutor) {
|
||||||
return new NotificationEntryManager(
|
return new NotificationEntryManager(
|
||||||
@@ -138,7 +137,6 @@ public interface NotificationsModule {
|
|||||||
notificationRemoteInputManagerLazy,
|
notificationRemoteInputManagerLazy,
|
||||||
leakDetector,
|
leakDetector,
|
||||||
statusBarService,
|
statusBarService,
|
||||||
notifLiveDataStore,
|
|
||||||
dumpManager,
|
dumpManager,
|
||||||
bgExecutor);
|
bgExecutor);
|
||||||
}
|
}
|
||||||
@@ -174,7 +172,6 @@ public interface NotificationsModule {
|
|||||||
accessibilityManager,
|
accessibilityManager,
|
||||||
highPriorityProvider,
|
highPriorityProvider,
|
||||||
notificationManager,
|
notificationManager,
|
||||||
notificationEntryManager,
|
|
||||||
peopleSpaceWidgetManager,
|
peopleSpaceWidgetManager,
|
||||||
launcherApps,
|
launcherApps,
|
||||||
shortcutManager,
|
shortcutManager,
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import com.android.systemui.dagger.qualifiers.Main;
|
|||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||||
@@ -60,13 +59,11 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
|
|||||||
private final List<NotificationInterruptSuppressor> mSuppressors = new ArrayList<>();
|
private final List<NotificationInterruptSuppressor> mSuppressors = new ArrayList<>();
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
private final KeyguardStateController mKeyguardStateController;
|
||||||
private final NotificationFilter mNotificationFilter;
|
|
||||||
private final ContentResolver mContentResolver;
|
private final ContentResolver mContentResolver;
|
||||||
private final PowerManager mPowerManager;
|
private final PowerManager mPowerManager;
|
||||||
private final IDreamManager mDreamManager;
|
private final IDreamManager mDreamManager;
|
||||||
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
||||||
private final BatteryController mBatteryController;
|
private final BatteryController mBatteryController;
|
||||||
private final ContentObserver mHeadsUpObserver;
|
|
||||||
private final HeadsUpManager mHeadsUpManager;
|
private final HeadsUpManager mHeadsUpManager;
|
||||||
private final NotificationInterruptLogger mLogger;
|
private final NotificationInterruptLogger mLogger;
|
||||||
private final NotifPipelineFlags mFlags;
|
private final NotifPipelineFlags mFlags;
|
||||||
@@ -81,7 +78,6 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
|
|||||||
PowerManager powerManager,
|
PowerManager powerManager,
|
||||||
IDreamManager dreamManager,
|
IDreamManager dreamManager,
|
||||||
AmbientDisplayConfiguration ambientDisplayConfiguration,
|
AmbientDisplayConfiguration ambientDisplayConfiguration,
|
||||||
NotificationFilter notificationFilter,
|
|
||||||
BatteryController batteryController,
|
BatteryController batteryController,
|
||||||
StatusBarStateController statusBarStateController,
|
StatusBarStateController statusBarStateController,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
@@ -95,14 +91,13 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
|
|||||||
mDreamManager = dreamManager;
|
mDreamManager = dreamManager;
|
||||||
mBatteryController = batteryController;
|
mBatteryController = batteryController;
|
||||||
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
|
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
|
||||||
mNotificationFilter = notificationFilter;
|
|
||||||
mStatusBarStateController = statusBarStateController;
|
mStatusBarStateController = statusBarStateController;
|
||||||
mKeyguardStateController = keyguardStateController;
|
mKeyguardStateController = keyguardStateController;
|
||||||
mHeadsUpManager = headsUpManager;
|
mHeadsUpManager = headsUpManager;
|
||||||
mLogger = logger;
|
mLogger = logger;
|
||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
|
mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
|
||||||
mHeadsUpObserver = new ContentObserver(mainHandler) {
|
ContentObserver headsUpObserver = new ContentObserver(mainHandler) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
boolean wasUsing = mUseHeadsUp;
|
boolean wasUsing = mUseHeadsUp;
|
||||||
@@ -125,12 +120,12 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
|
|||||||
mContentResolver.registerContentObserver(
|
mContentResolver.registerContentObserver(
|
||||||
Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
|
Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
|
||||||
true,
|
true,
|
||||||
mHeadsUpObserver);
|
headsUpObserver);
|
||||||
mContentResolver.registerContentObserver(
|
mContentResolver.registerContentObserver(
|
||||||
Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
|
Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
|
||||||
mHeadsUpObserver);
|
headsUpObserver);
|
||||||
}
|
}
|
||||||
mHeadsUpObserver.onChange(true); // set up
|
headsUpObserver.onChange(true); // set up
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
|
|||||||
|
|
||||||
import android.app.INotificationManager;
|
import android.app.INotificationManager;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.appwidget.AppWidgetManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.LauncherApps;
|
import android.content.pm.LauncherApps;
|
||||||
@@ -63,13 +62,11 @@ import com.android.systemui.statusbar.StatusBarState;
|
|||||||
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
||||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
||||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
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.NotifGutsViewListener;
|
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
|
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
|
||||||
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
|
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
|
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||||
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
@@ -114,7 +111,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
private NotificationPresenter mPresenter;
|
private NotificationPresenter mPresenter;
|
||||||
private NotificationActivityStarter mNotificationActivityStarter;
|
private NotificationActivityStarter mNotificationActivityStarter;
|
||||||
private NotificationListContainer mListContainer;
|
private NotificationListContainer mListContainer;
|
||||||
private CheckSaveListener mCheckSaveListener;
|
|
||||||
private OnSettingsClickListener mOnSettingsClickListener;
|
private OnSettingsClickListener mOnSettingsClickListener;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected String mKeyToRemoveOnGutsClosed;
|
protected String mKeyToRemoveOnGutsClosed;
|
||||||
@@ -131,7 +127,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
private final UserContextProvider mContextTracker;
|
private final UserContextProvider mContextTracker;
|
||||||
private final UiEventLogger mUiEventLogger;
|
private final UiEventLogger mUiEventLogger;
|
||||||
private final ShadeController mShadeController;
|
private final ShadeController mShadeController;
|
||||||
private final AppWidgetManager mAppWidgetManager;
|
|
||||||
private NotifGutsViewListener mGutsListener;
|
private NotifGutsViewListener mGutsListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +139,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
AccessibilityManager accessibilityManager,
|
AccessibilityManager accessibilityManager,
|
||||||
HighPriorityProvider highPriorityProvider,
|
HighPriorityProvider highPriorityProvider,
|
||||||
INotificationManager notificationManager,
|
INotificationManager notificationManager,
|
||||||
NotificationEntryManager notificationEntryManager,
|
|
||||||
PeopleSpaceWidgetManager peopleSpaceWidgetManager,
|
PeopleSpaceWidgetManager peopleSpaceWidgetManager,
|
||||||
LauncherApps launcherApps,
|
LauncherApps launcherApps,
|
||||||
ShortcutManager shortcutManager,
|
ShortcutManager shortcutManager,
|
||||||
@@ -173,17 +167,15 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
mUiEventLogger = uiEventLogger;
|
mUiEventLogger = uiEventLogger;
|
||||||
mOnUserInteractionCallback = onUserInteractionCallback;
|
mOnUserInteractionCallback = onUserInteractionCallback;
|
||||||
mShadeController = shadeController;
|
mShadeController = shadeController;
|
||||||
mAppWidgetManager = AppWidgetManager.getInstance(context);
|
|
||||||
|
|
||||||
dumpManager.registerDumpable(this);
|
dumpManager.registerDumpable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpWithPresenter(NotificationPresenter presenter,
|
public void setUpWithPresenter(NotificationPresenter presenter,
|
||||||
NotificationListContainer listContainer,
|
NotificationListContainer listContainer,
|
||||||
CheckSaveListener checkSave, OnSettingsClickListener onSettingsClick) {
|
OnSettingsClickListener onSettingsClick) {
|
||||||
mPresenter = presenter;
|
mPresenter = presenter;
|
||||||
mListContainer = listContainer;
|
mListContainer = listContainer;
|
||||||
mCheckSaveListener = checkSave;
|
|
||||||
mOnSettingsClickListener = onSettingsClick;
|
mOnSettingsClickListener = onSettingsClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,14 +210,11 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startAppDetailsSettingsActivity(String packageName, final int appUid,
|
private void startAppDetailsSettingsActivity(String packageName, final int appUid,
|
||||||
final NotificationChannel channel, ExpandableNotificationRow row) {
|
ExpandableNotificationRow row) {
|
||||||
final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||||
intent.setData(Uri.fromParts("package", packageName, null));
|
intent.setData(Uri.fromParts("package", packageName, null));
|
||||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
|
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
|
||||||
intent.putExtra(Settings.EXTRA_APP_UID, appUid);
|
intent.putExtra(Settings.EXTRA_APP_UID, appUid);
|
||||||
if (channel != null) {
|
|
||||||
intent.putExtra(EXTRA_FRAGMENT_ARG_KEY, channel.getId());
|
|
||||||
}
|
|
||||||
mNotificationActivityStarter.startNotificationGutsIntent(intent, appUid, row);
|
mNotificationActivityStarter.startNotificationGutsIntent(intent, appUid, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +222,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
ExpandableNotificationRow row) {
|
ExpandableNotificationRow row) {
|
||||||
if (ops.contains(OP_SYSTEM_ALERT_WINDOW)) {
|
if (ops.contains(OP_SYSTEM_ALERT_WINDOW)) {
|
||||||
if (ops.contains(OP_CAMERA) || ops.contains(OP_RECORD_AUDIO)) {
|
if (ops.contains(OP_CAMERA) || ops.contains(OP_RECORD_AUDIO)) {
|
||||||
startAppDetailsSettingsActivity(pkg, uid, null, row);
|
startAppDetailsSettingsActivity(pkg, uid, row);
|
||||||
} else {
|
} else {
|
||||||
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION);
|
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION);
|
||||||
intent.setData(Uri.fromParts("package", pkg, null));
|
intent.setData(Uri.fromParts("package", pkg, null));
|
||||||
|
|||||||
@@ -196,14 +196,12 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
|||||||
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
import com.android.systemui.statusbar.NotificationShelfController;
|
import com.android.systemui.statusbar.NotificationShelfController;
|
||||||
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
|
|
||||||
import com.android.systemui.statusbar.PowerButtonReveal;
|
import com.android.systemui.statusbar.PowerButtonReveal;
|
||||||
import com.android.systemui.statusbar.PulseExpansionHandler;
|
import com.android.systemui.statusbar.PulseExpansionHandler;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.core.StatusBarInitializer;
|
import com.android.systemui.statusbar.core.StatusBarInitializer;
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
|
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
|
||||||
@@ -515,7 +513,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
protected final NotificationEntryManager mEntryManager;
|
protected final NotificationEntryManager mEntryManager;
|
||||||
private final NotificationGutsManager mGutsManager;
|
private final NotificationGutsManager mGutsManager;
|
||||||
private final NotificationLogger mNotificationLogger;
|
private final NotificationLogger mNotificationLogger;
|
||||||
private final NotificationViewHierarchyManager mViewHierarchyManager;
|
|
||||||
private final PanelExpansionStateManager mPanelExpansionStateManager;
|
private final PanelExpansionStateManager mPanelExpansionStateManager;
|
||||||
private final KeyguardViewMediator mKeyguardViewMediator;
|
private final KeyguardViewMediator mKeyguardViewMediator;
|
||||||
protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
|
protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
|
||||||
@@ -651,7 +648,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
private final Optional<Bubbles> mBubblesOptional;
|
private final Optional<Bubbles> mBubblesOptional;
|
||||||
private final Bubbles.BubbleExpandListener mBubbleExpandListener;
|
private final Bubbles.BubbleExpandListener mBubbleExpandListener;
|
||||||
private final Optional<StartingSurface> mStartingSurfaceOptional;
|
private final Optional<StartingSurface> mStartingSurfaceOptional;
|
||||||
private final NotifPipelineFlags mNotifPipelineFlags;
|
|
||||||
|
|
||||||
private final ActivityIntentHelper mActivityIntentHelper;
|
private final ActivityIntentHelper mActivityIntentHelper;
|
||||||
private NotificationStackScrollLayoutController mStackScrollerController;
|
private NotificationStackScrollLayoutController mStackScrollerController;
|
||||||
@@ -693,7 +689,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
NotificationGutsManager notificationGutsManager,
|
NotificationGutsManager notificationGutsManager,
|
||||||
NotificationLogger notificationLogger,
|
NotificationLogger notificationLogger,
|
||||||
NotificationInterruptStateProvider notificationInterruptStateProvider,
|
NotificationInterruptStateProvider notificationInterruptStateProvider,
|
||||||
NotificationViewHierarchyManager notificationViewHierarchyManager,
|
|
||||||
PanelExpansionStateManager panelExpansionStateManager,
|
PanelExpansionStateManager panelExpansionStateManager,
|
||||||
KeyguardViewMediator keyguardViewMediator,
|
KeyguardViewMediator keyguardViewMediator,
|
||||||
DisplayMetrics displayMetrics,
|
DisplayMetrics displayMetrics,
|
||||||
@@ -756,7 +751,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
WallpaperManager wallpaperManager,
|
WallpaperManager wallpaperManager,
|
||||||
Optional<StartingSurface> startingSurfaceOptional,
|
Optional<StartingSurface> startingSurfaceOptional,
|
||||||
ActivityLaunchAnimator activityLaunchAnimator,
|
ActivityLaunchAnimator activityLaunchAnimator,
|
||||||
NotifPipelineFlags notifPipelineFlags,
|
|
||||||
InteractionJankMonitor jankMonitor,
|
InteractionJankMonitor jankMonitor,
|
||||||
DeviceStateManager deviceStateManager,
|
DeviceStateManager deviceStateManager,
|
||||||
WiredChargingRippleController wiredChargingRippleController,
|
WiredChargingRippleController wiredChargingRippleController,
|
||||||
@@ -783,7 +777,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
mGutsManager = notificationGutsManager;
|
mGutsManager = notificationGutsManager;
|
||||||
mNotificationLogger = notificationLogger;
|
mNotificationLogger = notificationLogger;
|
||||||
mNotificationInterruptStateProvider = notificationInterruptStateProvider;
|
mNotificationInterruptStateProvider = notificationInterruptStateProvider;
|
||||||
mViewHierarchyManager = notificationViewHierarchyManager;
|
|
||||||
mPanelExpansionStateManager = panelExpansionStateManager;
|
mPanelExpansionStateManager = panelExpansionStateManager;
|
||||||
mKeyguardViewMediator = keyguardViewMediator;
|
mKeyguardViewMediator = keyguardViewMediator;
|
||||||
mDisplayMetrics = displayMetrics;
|
mDisplayMetrics = displayMetrics;
|
||||||
@@ -844,7 +837,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
|
|||||||
|
|
||||||
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
|
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
|
||||||
mStartingSurfaceOptional = startingSurfaceOptional;
|
mStartingSurfaceOptional = startingSurfaceOptional;
|
||||||
mNotifPipelineFlags = notifPipelineFlags;
|
|
||||||
mDreamManager = dreamManager;
|
mDreamManager = dreamManager;
|
||||||
lockscreenShadeTransitionController.setCentralSurfaces(this);
|
lockscreenShadeTransitionController.setCentralSurfaces(this);
|
||||||
statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
|
statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import com.android.systemui.plugins.ActivityStarter;
|
|||||||
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
|
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
|
||||||
import com.android.systemui.shade.NotificationPanelViewController;
|
import com.android.systemui.shade.NotificationPanelViewController;
|
||||||
import com.android.systemui.shade.NotificationShadeWindowView;
|
import com.android.systemui.shade.NotificationShadeWindowView;
|
||||||
import com.android.systemui.shade.ShadeController;
|
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.KeyguardIndicationController;
|
import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
@@ -50,7 +49,6 @@ import com.android.systemui.statusbar.NotificationMediaManager;
|
|||||||
import com.android.systemui.statusbar.NotificationPresenter;
|
import com.android.systemui.statusbar.NotificationPresenter;
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
|
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.AboveShelfObserver;
|
import com.android.systemui.statusbar.notification.AboveShelfObserver;
|
||||||
@@ -82,7 +80,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
|
|
||||||
private final ActivityStarter mActivityStarter;
|
private final ActivityStarter mActivityStarter;
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
private final KeyguardStateController mKeyguardStateController;
|
||||||
private final NotificationViewHierarchyManager mViewHierarchyManager;
|
|
||||||
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
private final SysuiStatusBarStateController mStatusBarStateController;
|
private final SysuiStatusBarStateController mStatusBarStateController;
|
||||||
private final NotifShadeEventSource mNotifShadeEventSource;
|
private final NotifShadeEventSource mNotifShadeEventSource;
|
||||||
@@ -94,10 +91,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||||
private final AboveShelfObserver mAboveShelfObserver;
|
private final AboveShelfObserver mAboveShelfObserver;
|
||||||
private final DozeScrimController mDozeScrimController;
|
private final DozeScrimController mDozeScrimController;
|
||||||
private final ScrimController mScrimController;
|
|
||||||
private final KeyguardIndicationController mKeyguardIndicationController;
|
private final KeyguardIndicationController mKeyguardIndicationController;
|
||||||
private final CentralSurfaces mCentralSurfaces;
|
private final CentralSurfaces mCentralSurfaces;
|
||||||
private final com.android.systemui.shade.ShadeController mShadeController;
|
|
||||||
private final LockscreenShadeTransitionController mShadeTransitionController;
|
private final LockscreenShadeTransitionController mShadeTransitionController;
|
||||||
private final CommandQueue mCommandQueue;
|
private final CommandQueue mCommandQueue;
|
||||||
|
|
||||||
@@ -112,23 +107,21 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
protected boolean mVrMode;
|
protected boolean mVrMode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
StatusBarNotificationPresenter(Context context,
|
StatusBarNotificationPresenter(
|
||||||
|
Context context,
|
||||||
NotificationPanelViewController panel,
|
NotificationPanelViewController panel,
|
||||||
HeadsUpManagerPhone headsUp,
|
HeadsUpManagerPhone headsUp,
|
||||||
NotificationShadeWindowView statusBarWindow,
|
NotificationShadeWindowView statusBarWindow,
|
||||||
ActivityStarter activityStarter,
|
ActivityStarter activityStarter,
|
||||||
NotificationStackScrollLayoutController stackScrollerController,
|
NotificationStackScrollLayoutController stackScrollerController,
|
||||||
DozeScrimController dozeScrimController,
|
DozeScrimController dozeScrimController,
|
||||||
ScrimController scrimController,
|
|
||||||
NotificationShadeWindowController notificationShadeWindowController,
|
NotificationShadeWindowController notificationShadeWindowController,
|
||||||
DynamicPrivacyController dynamicPrivacyController,
|
DynamicPrivacyController dynamicPrivacyController,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
KeyguardIndicationController keyguardIndicationController,
|
KeyguardIndicationController keyguardIndicationController,
|
||||||
CentralSurfaces centralSurfaces,
|
CentralSurfaces centralSurfaces,
|
||||||
ShadeController shadeController,
|
|
||||||
LockscreenShadeTransitionController shadeTransitionController,
|
LockscreenShadeTransitionController shadeTransitionController,
|
||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
NotificationViewHierarchyManager notificationViewHierarchyManager,
|
|
||||||
NotificationLockscreenUserManager lockscreenUserManager,
|
NotificationLockscreenUserManager lockscreenUserManager,
|
||||||
SysuiStatusBarStateController sysuiStatusBarStateController,
|
SysuiStatusBarStateController sysuiStatusBarStateController,
|
||||||
NotifShadeEventSource notifShadeEventSource,
|
NotifShadeEventSource notifShadeEventSource,
|
||||||
@@ -149,10 +142,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
mKeyguardIndicationController = keyguardIndicationController;
|
mKeyguardIndicationController = keyguardIndicationController;
|
||||||
// TODO: use KeyguardStateController#isOccluded to remove this dependency
|
// TODO: use KeyguardStateController#isOccluded to remove this dependency
|
||||||
mCentralSurfaces = centralSurfaces;
|
mCentralSurfaces = centralSurfaces;
|
||||||
mShadeController = shadeController;
|
|
||||||
mShadeTransitionController = shadeTransitionController;
|
mShadeTransitionController = shadeTransitionController;
|
||||||
mCommandQueue = commandQueue;
|
mCommandQueue = commandQueue;
|
||||||
mViewHierarchyManager = notificationViewHierarchyManager;
|
|
||||||
mLockscreenUserManager = lockscreenUserManager;
|
mLockscreenUserManager = lockscreenUserManager;
|
||||||
mStatusBarStateController = sysuiStatusBarStateController;
|
mStatusBarStateController = sysuiStatusBarStateController;
|
||||||
mNotifShadeEventSource = notifShadeEventSource;
|
mNotifShadeEventSource = notifShadeEventSource;
|
||||||
@@ -166,7 +157,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
R.id.notification_container_parent));
|
R.id.notification_container_parent));
|
||||||
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
|
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
|
||||||
mDozeScrimController = dozeScrimController;
|
mDozeScrimController = dozeScrimController;
|
||||||
mScrimController = scrimController;
|
|
||||||
mKeyguardManager = context.getSystemService(KeyguardManager.class);
|
mKeyguardManager = context.getSystemService(KeyguardManager.class);
|
||||||
mBarService = IStatusBarService.Stub.asInterface(
|
mBarService = IStatusBarService.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||||
@@ -187,16 +177,13 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
|
|
||||||
initController.addPostInitTask(() -> {
|
initController.addPostInitTask(() -> {
|
||||||
mKeyguardIndicationController.init();
|
mKeyguardIndicationController.init();
|
||||||
mViewHierarchyManager.setUpWithPresenter(this,
|
|
||||||
stackScrollerController.getNotifStackController(),
|
|
||||||
mNotifListContainer);
|
|
||||||
mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied);
|
mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied);
|
||||||
mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse);
|
mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse);
|
||||||
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
|
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
|
||||||
mLockscreenUserManager.setUpWithPresenter(this);
|
mLockscreenUserManager.setUpWithPresenter(this);
|
||||||
mMediaManager.setUpWithPresenter(this);
|
mMediaManager.setUpWithPresenter(this);
|
||||||
mGutsManager.setUpWithPresenter(
|
mGutsManager.setUpWithPresenter(
|
||||||
this, mNotifListContainer, mCheckSaveListener, mOnSettingsClickListener);
|
this, mNotifListContainer, mOnSettingsClickListener);
|
||||||
// ForegroundServiceNotificationListener adds its listener in its constructor
|
// ForegroundServiceNotificationListener adds its listener in its constructor
|
||||||
// but we need to request it here in order for it to be instantiated.
|
// but we need to request it here in order for it to be instantiated.
|
||||||
// TODO: figure out how to do this correctly once Dependency.get() is gone.
|
// TODO: figure out how to do this correctly once Dependency.get() is gone.
|
||||||
@@ -232,24 +219,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateNotificationViews(final String reason) {
|
|
||||||
if (!mNotifPipelineFlags.checkLegacyPipelineEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// The function updateRowStates depends on both of these being non-null, so check them here.
|
|
||||||
// We may be called before they are set from DeviceProvisionedController's callback.
|
|
||||||
if (mScrimController == null) return;
|
|
||||||
|
|
||||||
// Do not modify the notifications during collapse.
|
|
||||||
if (isCollapsing()) {
|
|
||||||
mShadeController.addPostCollapseAction(() -> updateNotificationViews(reason));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
|
||||||
mNotificationPanel.updateNotificationViews(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUserSwitched(int newUserId) {
|
public void onUserSwitched(int newUserId) {
|
||||||
// Begin old BaseStatusBar.userSwitched
|
// Begin old BaseStatusBar.userSwitched
|
||||||
@@ -303,11 +272,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation);
|
mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdateRowStates() {
|
|
||||||
mNotificationPanel.onUpdateRowStates();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExpandClicked(NotificationEntry clickedEntry, View clickedView,
|
public void onExpandClicked(NotificationEntry clickedEntry, View clickedView,
|
||||||
boolean nowExpanded) {
|
boolean nowExpanded) {
|
||||||
|
|||||||
@@ -30,13 +30,11 @@ import com.android.systemui.SysuiTestCase;
|
|||||||
import com.android.systemui.shade.ShadeController;
|
import com.android.systemui.shade.ShadeController;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
|
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
|
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
|
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
@@ -55,11 +53,8 @@ import org.mockito.MockitoAnnotations;
|
|||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||||
public class NonPhoneDependencyTest extends SysuiTestCase {
|
public class NonPhoneDependencyTest extends SysuiTestCase {
|
||||||
@Mock private NotificationPresenter mPresenter;
|
@Mock private NotificationPresenter mPresenter;
|
||||||
@Mock private NotifStackController mStackController;
|
|
||||||
@Mock private NotificationListContainer mListContainer;
|
@Mock private NotificationListContainer mListContainer;
|
||||||
@Mock
|
@Mock private NotificationEntryListener mEntryListener;
|
||||||
private NotificationEntryListener mEntryListener;
|
|
||||||
@Mock private HeadsUpManager mHeadsUpManager;
|
|
||||||
@Mock private RemoteInputController.Delegate mDelegate;
|
@Mock private RemoteInputController.Delegate mDelegate;
|
||||||
@Mock private NotificationRemoteInputManager.Callback mRemoteInputManagerCallback;
|
@Mock private NotificationRemoteInputManager.Callback mRemoteInputManagerCallback;
|
||||||
@Mock private CheckSaveListener mCheckSaveListener;
|
@Mock private CheckSaveListener mCheckSaveListener;
|
||||||
@@ -79,25 +74,20 @@ public class NonPhoneDependencyTest extends SysuiTestCase {
|
|||||||
mDependency.injectMockDependency(ShadeController.class);
|
mDependency.injectMockDependency(ShadeController.class);
|
||||||
NotificationEntryManager entryManager = Dependency.get(NotificationEntryManager.class);
|
NotificationEntryManager entryManager = Dependency.get(NotificationEntryManager.class);
|
||||||
NotificationGutsManager gutsManager = Dependency.get(NotificationGutsManager.class);
|
NotificationGutsManager gutsManager = Dependency.get(NotificationGutsManager.class);
|
||||||
NotificationListener notificationListener = Dependency.get(NotificationListener.class);
|
|
||||||
NotificationLogger notificationLogger = Dependency.get(NotificationLogger.class);
|
NotificationLogger notificationLogger = Dependency.get(NotificationLogger.class);
|
||||||
NotificationMediaManager mediaManager = Dependency.get(NotificationMediaManager.class);
|
NotificationMediaManager mediaManager = Dependency.get(NotificationMediaManager.class);
|
||||||
NotificationRemoteInputManager remoteInputManager =
|
NotificationRemoteInputManager remoteInputManager =
|
||||||
Dependency.get(NotificationRemoteInputManager.class);
|
Dependency.get(NotificationRemoteInputManager.class);
|
||||||
NotificationLockscreenUserManager lockscreenUserManager =
|
NotificationLockscreenUserManager lockscreenUserManager =
|
||||||
Dependency.get(NotificationLockscreenUserManager.class);
|
Dependency.get(NotificationLockscreenUserManager.class);
|
||||||
NotificationViewHierarchyManager viewHierarchyManager =
|
|
||||||
Dependency.get(NotificationViewHierarchyManager.class);
|
|
||||||
entryManager.setUpWithPresenter(mPresenter);
|
|
||||||
entryManager.addNotificationEntryListener(mEntryListener);
|
entryManager.addNotificationEntryListener(mEntryListener);
|
||||||
gutsManager.setUpWithPresenter(mPresenter, mListContainer,
|
gutsManager.setUpWithPresenter(mPresenter, mListContainer,
|
||||||
mCheckSaveListener, mOnSettingsClickListener);
|
mOnSettingsClickListener);
|
||||||
notificationLogger.setUpWithContainer(mListContainer);
|
notificationLogger.setUpWithContainer(mListContainer);
|
||||||
mediaManager.setUpWithPresenter(mPresenter);
|
mediaManager.setUpWithPresenter(mPresenter);
|
||||||
remoteInputManager.setUpWithCallback(mRemoteInputManagerCallback,
|
remoteInputManager.setUpWithCallback(mRemoteInputManagerCallback,
|
||||||
mDelegate);
|
mDelegate);
|
||||||
lockscreenUserManager.setUpWithPresenter(mPresenter);
|
lockscreenUserManager.setUpWithPresenter(mPresenter);
|
||||||
viewHierarchyManager.setUpWithPresenter(mPresenter, mStackController, mListContainer);
|
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertFalse(mDependency.hasInstantiatedDependency(NotificationShadeWindowController.class));
|
assertFalse(mDependency.hasInstantiatedDependency(NotificationShadeWindowController.class));
|
||||||
|
|||||||
@@ -1,375 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 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;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.mockito.Mockito.clearInvocations;
|
|
||||||
import static org.mockito.Mockito.doAnswer;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.testing.AndroidTestingRunner;
|
|
||||||
import android.testing.TestableLooper;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
|
||||||
|
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
|
|
||||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
|
||||||
import com.android.systemui.statusbar.notification.DynamicChildBindController;
|
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
|
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
|
||||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|
||||||
import com.android.wm.shell.bubbles.Bubbles;
|
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.mockito.Spy;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@SmallTest
|
|
||||||
@RunWith(AndroidTestingRunner.class)
|
|
||||||
@TestableLooper.RunWithLooper
|
|
||||||
public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
|
|
||||||
@Mock private NotificationPresenter mPresenter;
|
|
||||||
@Mock private NotifStackController mStackController;
|
|
||||||
@Spy private FakeListContainer mListContainer = new FakeListContainer();
|
|
||||||
|
|
||||||
// Dependency mocks:
|
|
||||||
@Mock private FeatureFlags mFeatureFlags;
|
|
||||||
@Mock private NotifPipelineFlags mNotifPipelineFlags;
|
|
||||||
@Mock private NotificationEntryManager mEntryManager;
|
|
||||||
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
|
||||||
@Mock private NotificationGroupManagerLegacy mGroupManager;
|
|
||||||
@Mock private VisualStabilityManager mVisualStabilityManager;
|
|
||||||
|
|
||||||
private TestableLooper mTestableLooper;
|
|
||||||
private Handler mHandler;
|
|
||||||
private NotificationViewHierarchyManager mViewHierarchyManager;
|
|
||||||
private NotificationTestHelper mHelper;
|
|
||||||
private boolean mMadeReentrantCall = false;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mTestableLooper = TestableLooper.get(this);
|
|
||||||
allowTestableLooperAsMainThread();
|
|
||||||
mHandler = Handler.createAsync(mTestableLooper.getLooper());
|
|
||||||
|
|
||||||
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
|
|
||||||
mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
|
|
||||||
mLockscreenUserManager);
|
|
||||||
mDependency.injectTestDependency(NotificationGroupManagerLegacy.class, mGroupManager);
|
|
||||||
mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
|
|
||||||
when(mVisualStabilityManager.areGroupChangesAllowed()).thenReturn(true);
|
|
||||||
when(mVisualStabilityManager.isReorderingAllowed()).thenReturn(true);
|
|
||||||
|
|
||||||
when(mNotifPipelineFlags.checkLegacyPipelineEnabled()).thenReturn(true);
|
|
||||||
when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
|
|
||||||
|
|
||||||
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
|
|
||||||
|
|
||||||
mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
|
|
||||||
mHandler, mFeatureFlags, mLockscreenUserManager, mGroupManager,
|
|
||||||
mVisualStabilityManager,
|
|
||||||
mock(StatusBarStateControllerImpl.class), mEntryManager,
|
|
||||||
mock(KeyguardBypassController.class),
|
|
||||||
Optional.of(mock(Bubbles.class)),
|
|
||||||
mock(DynamicPrivacyController.class),
|
|
||||||
mock(DynamicChildBindController.class),
|
|
||||||
mock(LowPriorityInflationHelper.class),
|
|
||||||
mock(AssistantFeedbackController.class),
|
|
||||||
mNotifPipelineFlags,
|
|
||||||
mock(KeyguardUpdateMonitor.class),
|
|
||||||
mock(KeyguardStateController.class));
|
|
||||||
mViewHierarchyManager.setUpWithPresenter(mPresenter, mStackController, mListContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private NotificationEntry createEntry() throws Exception {
|
|
||||||
ExpandableNotificationRow row = mHelper.createRow();
|
|
||||||
return row.getEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNotificationsBecomingBundled() throws Exception {
|
|
||||||
// Tests 3 top level notifications becoming a single bundled notification with |entry0| as
|
|
||||||
// the summary.
|
|
||||||
NotificationEntry entry0 = createEntry();
|
|
||||||
NotificationEntry entry1 = createEntry();
|
|
||||||
NotificationEntry entry2 = createEntry();
|
|
||||||
|
|
||||||
// Set up the prior state to look like three top level notifications.
|
|
||||||
mListContainer.addContainerView(entry0.getRow());
|
|
||||||
mListContainer.addContainerView(entry1.getRow());
|
|
||||||
mListContainer.addContainerView(entry2.getRow());
|
|
||||||
when(mEntryManager.getVisibleNotifications()).thenReturn(
|
|
||||||
Lists.newArrayList(entry0, entry1, entry2));
|
|
||||||
|
|
||||||
// Set up group manager to report that they should be bundled now.
|
|
||||||
when(mGroupManager.isChildInGroup(entry0)).thenReturn(false);
|
|
||||||
when(mGroupManager.isChildInGroup(entry1)).thenReturn(true);
|
|
||||||
when(mGroupManager.isChildInGroup(entry2)).thenReturn(true);
|
|
||||||
when(mGroupManager.getGroupSummary(entry1)).thenReturn(entry0);
|
|
||||||
when(mGroupManager.getGroupSummary(entry2)).thenReturn(entry0);
|
|
||||||
|
|
||||||
// Run updateNotifications - the view hierarchy should be reorganized.
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
|
||||||
|
|
||||||
verify(mListContainer).notifyGroupChildAdded(entry1.getRow());
|
|
||||||
verify(mListContainer).notifyGroupChildAdded(entry2.getRow());
|
|
||||||
assertTrue(Lists.newArrayList(entry0.getRow()).equals(mListContainer.mRows));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNotificationsBecomingUnbundled() throws Exception {
|
|
||||||
// Tests a bundled notification becoming three top level notifications.
|
|
||||||
NotificationEntry entry0 = createEntry();
|
|
||||||
NotificationEntry entry1 = createEntry();
|
|
||||||
NotificationEntry entry2 = createEntry();
|
|
||||||
entry0.getRow().addChildNotification(entry1.getRow());
|
|
||||||
entry0.getRow().addChildNotification(entry2.getRow());
|
|
||||||
|
|
||||||
// Set up the prior state to look like one top level notification.
|
|
||||||
mListContainer.addContainerView(entry0.getRow());
|
|
||||||
when(mEntryManager.getVisibleNotifications()).thenReturn(
|
|
||||||
Lists.newArrayList(entry0, entry1, entry2));
|
|
||||||
|
|
||||||
// Set up group manager to report that they should not be bundled now.
|
|
||||||
when(mGroupManager.isChildInGroup(entry0)).thenReturn(false);
|
|
||||||
when(mGroupManager.isChildInGroup(entry1)).thenReturn(false);
|
|
||||||
when(mGroupManager.isChildInGroup(entry2)).thenReturn(false);
|
|
||||||
|
|
||||||
// Run updateNotifications - the view hierarchy should be reorganized.
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
|
||||||
|
|
||||||
verify(mListContainer).notifyGroupChildRemoved(
|
|
||||||
entry1.getRow(), entry0.getRow().getChildrenContainer());
|
|
||||||
verify(mListContainer).notifyGroupChildRemoved(
|
|
||||||
entry2.getRow(), entry0.getRow().getChildrenContainer());
|
|
||||||
assertTrue(
|
|
||||||
Lists.newArrayList(entry0.getRow(), entry1.getRow(), entry2.getRow())
|
|
||||||
.equals(mListContainer.mRows));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNotificationsBecomingSuppressed() throws Exception {
|
|
||||||
// Tests two top level notifications becoming a suppressed summary and a child.
|
|
||||||
NotificationEntry entry0 = createEntry();
|
|
||||||
NotificationEntry entry1 = createEntry();
|
|
||||||
entry0.getRow().addChildNotification(entry1.getRow());
|
|
||||||
|
|
||||||
// Set up the prior state to look like a top level notification.
|
|
||||||
mListContainer.addContainerView(entry0.getRow());
|
|
||||||
when(mEntryManager.getVisibleNotifications()).thenReturn(
|
|
||||||
Lists.newArrayList(entry0, entry1));
|
|
||||||
|
|
||||||
// Set up group manager to report a suppressed summary now.
|
|
||||||
when(mGroupManager.isChildInGroup(entry0)).thenReturn(false);
|
|
||||||
when(mGroupManager.isChildInGroup(entry1)).thenReturn(false);
|
|
||||||
when(mGroupManager.isSummaryOfSuppressedGroup(entry0.getSbn())).thenReturn(true);
|
|
||||||
|
|
||||||
// Run updateNotifications - the view hierarchy should be reorganized.
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
|
||||||
|
|
||||||
verify(mListContainer).notifyGroupChildRemoved(
|
|
||||||
entry1.getRow(), entry0.getRow().getChildrenContainer());
|
|
||||||
assertTrue(Lists.newArrayList(entry0.getRow(), entry1.getRow()).equals(mListContainer.mRows));
|
|
||||||
assertEquals(View.GONE, entry0.getRow().getVisibility());
|
|
||||||
assertEquals(View.VISIBLE, entry1.getRow().getVisibility());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() {
|
|
||||||
// GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews()
|
|
||||||
mMadeReentrantCall = false;
|
|
||||||
doAnswer((invocation) -> {
|
|
||||||
if (!mMadeReentrantCall) {
|
|
||||||
mMadeReentrantCall = true;
|
|
||||||
mViewHierarchyManager.onDynamicPrivacyChanged();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}).when(mListContainer).onNotificationViewUpdateFinished();
|
|
||||||
|
|
||||||
// WHEN we call updateNotificationViews()
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
|
||||||
|
|
||||||
// THEN onNotificationViewUpdateFinished() is only called once
|
|
||||||
verify(mListContainer).onNotificationViewUpdateFinished();
|
|
||||||
|
|
||||||
// WHEN we drain the looper
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
// THEN updateNotificationViews() is called a second time (for the reentrant call)
|
|
||||||
verify(mListContainer, times(2)).onNotificationViewUpdateFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultipleReentrantCallsToOnDynamicPrivacyChangedOnlyPostOnce() {
|
|
||||||
// GIVEN a ListContainer that will make many re-entrant calls to updateNotificationViews()
|
|
||||||
mMadeReentrantCall = false;
|
|
||||||
doAnswer((invocation) -> {
|
|
||||||
if (!mMadeReentrantCall) {
|
|
||||||
mMadeReentrantCall = true;
|
|
||||||
mViewHierarchyManager.onDynamicPrivacyChanged();
|
|
||||||
mViewHierarchyManager.onDynamicPrivacyChanged();
|
|
||||||
mViewHierarchyManager.onDynamicPrivacyChanged();
|
|
||||||
mViewHierarchyManager.onDynamicPrivacyChanged();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}).when(mListContainer).onNotificationViewUpdateFinished();
|
|
||||||
|
|
||||||
// WHEN we call updateNotificationViews() and drain the looper
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
|
||||||
verify(mListContainer).onNotificationViewUpdateFinished();
|
|
||||||
clearInvocations(mListContainer);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
// THEN updateNotificationViews() is called only one more time
|
|
||||||
verify(mListContainer).onNotificationViewUpdateFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FakeListContainer implements NotificationListContainer {
|
|
||||||
final LinearLayout mLayout = new LinearLayout(mContext);
|
|
||||||
final List<View> mRows = Lists.newArrayList();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setChildTransferInProgress(boolean childTransferInProgress) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changeViewPosition(ExpandableView child, int newIndex) {
|
|
||||||
mRows.remove(child);
|
|
||||||
mRows.add(newIndex, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyGroupChildAdded(ExpandableView row) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateChildOrderChangedEvent() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReset(ExpandableView view) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getContainerChildCount() {
|
|
||||||
return mRows.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getContainerChildAt(int i) {
|
|
||||||
return mRows.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeContainerView(View v) {
|
|
||||||
mLayout.removeView(v);
|
|
||||||
mRows.remove(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNotificationActivityStarter(
|
|
||||||
NotificationActivityStarter notificationActivityStarter) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addContainerView(View v) {
|
|
||||||
mLayout.addView(v);
|
|
||||||
mRows.add(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addContainerViewAt(View v, int index) {
|
|
||||||
mLayout.addView(v, index);
|
|
||||||
mRows.add(index, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMaxDisplayedNotifications(int maxNotifications) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ViewGroup getViewParentForNotification(NotificationEntry entry) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onHeightChanged(ExpandableView view, boolean animate) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetExposedMenuView(boolean animate, boolean force) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NotificationSwipeActionHelper getSwipeActionHelper() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanUpViewStateForEntry(NotificationEntry entry) { }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInVisibleLocation(NotificationEntry entry) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setChildLocationsChangedListener(
|
|
||||||
NotificationLogger.OnChildLocationsChangedListener listener) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasPulsingNotifications() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotificationViewUpdateFinished() { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -77,10 +77,8 @@ import com.android.systemui.statusbar.NotificationMediaManager;
|
|||||||
import com.android.systemui.statusbar.NotificationPresenter;
|
import com.android.systemui.statusbar.NotificationPresenter;
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
|
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
|
||||||
import com.android.systemui.statusbar.RankingBuilder;
|
|
||||||
import com.android.systemui.statusbar.SmartReplyController;
|
import com.android.systemui.statusbar.SmartReplyController;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreMocksKt;
|
|
||||||
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.NotificationRankingManager;
|
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
|
||||||
@@ -91,7 +89,6 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
|
|||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
|
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationEntryManagerInflationTest;
|
|
||||||
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
|
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||||
@@ -115,9 +112,7 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link NotificationEntryManager}. This test will not test any interactions with
|
* Unit tests for {@link NotificationEntryManager}.
|
||||||
* inflation. Instead, for functional inflation tests, see
|
|
||||||
* {@link NotificationEntryManagerInflationTest}.
|
|
||||||
*/
|
*/
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@@ -205,7 +200,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
mStats = defaultStats(mEntry);
|
mStats = defaultStats(mEntry);
|
||||||
mSbn = mEntry.getSbn();
|
mSbn = mEntry.getSbn();
|
||||||
|
|
||||||
when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
|
|
||||||
mEntryManager = new NotificationEntryManager(
|
mEntryManager = new NotificationEntryManager(
|
||||||
mLogger,
|
mLogger,
|
||||||
mGroupManager,
|
mGroupManager,
|
||||||
@@ -214,7 +208,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
() -> mRemoteInputManager,
|
() -> mRemoteInputManager,
|
||||||
mLeakDetector,
|
mLeakDetector,
|
||||||
mStatusBarService,
|
mStatusBarService,
|
||||||
NotifLiveDataStoreMocksKt.createNotifLiveDataStoreImplMock(),
|
|
||||||
mock(DumpManager.class),
|
mock(DumpManager.class),
|
||||||
mBgExecutor
|
mBgExecutor
|
||||||
);
|
);
|
||||||
@@ -230,7 +223,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
mock(PeopleNotificationIdentifier.class),
|
mock(PeopleNotificationIdentifier.class),
|
||||||
mock(HighPriorityProvider.class),
|
mock(HighPriorityProvider.class),
|
||||||
mEnvironment));
|
mEnvironment));
|
||||||
mEntryManager.setUpWithPresenter(mPresenter);
|
|
||||||
mEntryManager.addNotificationEntryListener(mEntryListener);
|
mEntryManager.addNotificationEntryListener(mEntryListener);
|
||||||
mEntryManager.addCollectionListener(mNotifCollectionListener);
|
mEntryManager.addCollectionListener(mNotifCollectionListener);
|
||||||
mEntryManager.addNotificationRemoveInterceptor(mRemoveInterceptor);
|
mEntryManager.addNotificationRemoveInterceptor(mRemoveInterceptor);
|
||||||
@@ -272,17 +264,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
assertEquals(entry.getUserSentiment(), Ranking.USER_SENTIMENT_NEUTRAL);
|
assertEquals(entry.getUserSentiment(), Ranking.USER_SENTIMENT_NEUTRAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateNotification_updatesUserSentiment() {
|
|
||||||
mEntryManager.addActiveNotificationForTest(mEntry);
|
|
||||||
setUserSentiment(
|
|
||||||
mEntry.getKey(), Ranking.USER_SENTIMENT_NEGATIVE);
|
|
||||||
|
|
||||||
mEntryManager.updateNotification(mSbn, mRankingMap);
|
|
||||||
|
|
||||||
assertEquals(Ranking.USER_SENTIMENT_NEGATIVE, mEntry.getUserSentiment());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateNotification_prePostEntryOrder() throws Exception {
|
public void testUpdateNotification_prePostEntryOrder() throws Exception {
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
@@ -294,7 +275,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
// Ensure that update callbacks happen in correct order
|
// Ensure that update callbacks happen in correct order
|
||||||
InOrder order = inOrder(mEntryListener, mPresenter, mEntryListener);
|
InOrder order = inOrder(mEntryListener, mPresenter, mEntryListener);
|
||||||
order.verify(mEntryListener).onPreEntryUpdated(mEntry);
|
order.verify(mEntryListener).onPreEntryUpdated(mEntry);
|
||||||
order.verify(mPresenter).updateNotificationViews(any());
|
|
||||||
order.verify(mEntryListener).onPostEntryUpdated(mEntry);
|
order.verify(mEntryListener).onPostEntryUpdated(mEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +285,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mEntryManager.removeNotification(mSbn.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
|
mEntryManager.removeNotification(mSbn.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
|
||||||
|
|
||||||
verify(mPresenter).updateNotificationViews(any());
|
|
||||||
verify(mEntryListener).onEntryRemoved(
|
verify(mEntryListener).onEntryRemoved(
|
||||||
argThat(matchEntryOnKey()), any(),
|
argThat(matchEntryOnKey()), any(),
|
||||||
eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON));
|
eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON));
|
||||||
@@ -378,23 +357,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
argThat(matchEntryOnKey()), anyInt());
|
argThat(matchEntryOnKey()), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateNotificationRanking() {
|
|
||||||
when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
|
|
||||||
when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
|
|
||||||
when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
|
|
||||||
|
|
||||||
mEntry.setRow(mRow);
|
|
||||||
mEntry.setInflationTask(mAsyncInflationTask);
|
|
||||||
mEntryManager.addActiveNotificationForTest(mEntry);
|
|
||||||
setSmartActions(mEntry.getKey(), new ArrayList<>(Arrays.asList(createAction())));
|
|
||||||
|
|
||||||
mEntryManager.updateNotificationRanking(mRankingMap);
|
|
||||||
assertEquals(1, mEntry.getSmartActions().size());
|
|
||||||
assertEquals("action", mEntry.getSmartActions().get(0).title);
|
|
||||||
verify(mEntryListener).onNotificationRankingUpdated(mRankingMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateNotificationRanking_noChange() {
|
public void testUpdateNotificationRanking_noChange() {
|
||||||
when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
|
when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
|
||||||
@@ -408,20 +370,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
assertThat(mEntry.getSmartActions()).isEmpty();
|
assertThat(mEntry.getSmartActions()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateNotificationRanking_rowNotInflatedYet() {
|
|
||||||
when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
|
|
||||||
when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
|
|
||||||
|
|
||||||
mEntry.setRow(null);
|
|
||||||
mEntryManager.addActiveNotificationForTest(mEntry);
|
|
||||||
setSmartActions(mEntry.getKey(), new ArrayList<>(Arrays.asList(createAction())));
|
|
||||||
|
|
||||||
mEntryManager.updateNotificationRanking(mRankingMap);
|
|
||||||
assertEquals(1, mEntry.getSmartActions().size());
|
|
||||||
assertEquals("action", mEntry.getSmartActions().get(0).title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateNotificationRanking_pendingNotification() {
|
public void testUpdateNotificationRanking_pendingNotification() {
|
||||||
when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
|
when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
|
||||||
@@ -613,31 +561,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
/* Tests annexed from NotificationDataTest go here */
|
/* Tests annexed from NotificationDataTest go here */
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testChannelIsSetWhenAdded() {
|
|
||||||
NotificationChannel nc = new NotificationChannel(
|
|
||||||
"testId",
|
|
||||||
"testName",
|
|
||||||
IMPORTANCE_DEFAULT);
|
|
||||||
|
|
||||||
Ranking r = new RankingBuilder()
|
|
||||||
.setKey(mEntry.getKey())
|
|
||||||
.setChannel(nc)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
RankingMap rm = new RankingMap(new Ranking[] { r });
|
|
||||||
|
|
||||||
// GIVEN: a notification is added, and the ranking updated
|
|
||||||
mEntryManager.addActiveNotificationForTest(mEntry);
|
|
||||||
mEntryManager.updateRanking(rm, "testReason");
|
|
||||||
|
|
||||||
// THEN the notification entry better have a channel on it
|
|
||||||
assertEquals(
|
|
||||||
"Channel must be set when adding a notification",
|
|
||||||
nc.getName(),
|
|
||||||
mEntry.getChannel().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetNotificationsForCurrentUser_shouldFilterNonCurrentUserNotifications() {
|
public void testGetNotificationsForCurrentUser_shouldFilterNonCurrentUserNotifications() {
|
||||||
Notification.Builder n = new Notification.Builder(mContext, "di")
|
Notification.Builder n = new Notification.Builder(mContext, "di")
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
|
|||||||
mPowerManager,
|
mPowerManager,
|
||||||
mDreamManager,
|
mDreamManager,
|
||||||
mAmbientDisplayConfiguration,
|
mAmbientDisplayConfiguration,
|
||||||
mNotificationFilter,
|
|
||||||
mBatteryController,
|
mBatteryController,
|
||||||
mStatusBarStateController,
|
mStatusBarStateController,
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
|
|||||||
@@ -1,467 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 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.row;
|
|
||||||
|
|
||||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
|
||||||
|
|
||||||
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.LauncherApps;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.service.notification.NotificationListenerService;
|
|
||||||
import android.service.notification.NotificationListenerService.Ranking;
|
|
||||||
import android.service.notification.StatusBarNotification;
|
|
||||||
import android.testing.AndroidTestingRunner;
|
|
||||||
import android.testing.TestableLooper;
|
|
||||||
|
|
||||||
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
|
|
||||||
import androidx.test.filters.SmallTest;
|
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
|
||||||
import com.android.internal.statusbar.IStatusBarService;
|
|
||||||
import com.android.internal.util.NotificationMessagingUtil;
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
|
||||||
import com.android.systemui.classifier.FalsingCollectorFake;
|
|
||||||
import com.android.systemui.classifier.FalsingManagerFake;
|
|
||||||
import com.android.systemui.dump.DumpManager;
|
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.media.MediaFeatureFlag;
|
|
||||||
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|
||||||
import com.android.systemui.shared.plugins.PluginManager;
|
|
||||||
import com.android.systemui.statusbar.NotificationListener;
|
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|
||||||
import com.android.systemui.statusbar.NotificationMediaManager;
|
|
||||||
import com.android.systemui.statusbar.NotificationPresenter;
|
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
|
||||||
import com.android.systemui.statusbar.SbnBuilder;
|
|
||||||
import com.android.systemui.statusbar.SmartReplyController;
|
|
||||||
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
|
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationClicker;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreMocksKt;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
|
||||||
import com.android.systemui.statusbar.notification.icon.IconBuilder;
|
|
||||||
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.people.PeopleNotificationIdentifier;
|
|
||||||
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
|
|
||||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
|
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
|
||||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
|
||||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
|
||||||
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
|
|
||||||
import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
|
|
||||||
import com.android.systemui.statusbar.policy.SmartReplyConstants;
|
|
||||||
import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
|
|
||||||
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
|
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
|
||||||
import com.android.systemui.util.leak.LeakDetector;
|
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
|
||||||
import com.android.systemui.wmshell.BubblesManager;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Answers;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functional tests for notification inflation from {@link NotificationEntryManager}.
|
|
||||||
*/
|
|
||||||
@SmallTest
|
|
||||||
@RunWith(AndroidTestingRunner.class)
|
|
||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
|
||||||
public class NotificationEntryManagerInflationTest extends SysuiTestCase {
|
|
||||||
|
|
||||||
private static final String TEST_TITLE = "Title";
|
|
||||||
private static final String TEST_TEXT = "Text";
|
|
||||||
private static final long TIMEOUT_TIME = 10000;
|
|
||||||
private static final Runnable TIMEOUT_RUNNABLE = () -> {
|
|
||||||
throw new RuntimeException("Timed out waiting to inflate");
|
|
||||||
};
|
|
||||||
|
|
||||||
@Mock private NotificationListener mNotificationListener;
|
|
||||||
@Mock private NotificationPresenter mPresenter;
|
|
||||||
@Mock private NotificationEntryManager.KeyguardEnvironment mEnvironment;
|
|
||||||
@Mock private NotificationListContainer mListContainer;
|
|
||||||
@Mock private NotificationEntryListener mEntryListener;
|
|
||||||
@Mock private NotificationRowBinderImpl.BindRowCallback mBindCallback;
|
|
||||||
@Mock private HeadsUpManager mHeadsUpManager;
|
|
||||||
@Mock private NotificationInterruptStateProvider mNotificationInterruptionStateProvider;
|
|
||||||
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
|
||||||
@Mock private NotificationGutsManager mGutsManager;
|
|
||||||
@Mock private NotificationRemoteInputManager mRemoteInputManager;
|
|
||||||
@Mock private NotificationMediaManager mNotificationMediaManager;
|
|
||||||
@Mock(answer = Answers.RETURNS_SELF)
|
|
||||||
private ExpandableNotificationRowComponent.Builder mExpandableNotificationRowComponentBuilder;
|
|
||||||
@Mock private ExpandableNotificationRowComponent mExpandableNotificationRowComponent;
|
|
||||||
@Mock private KeyguardBypassController mKeyguardBypassController;
|
|
||||||
@Mock private StatusBarStateController mStatusBarStateController;
|
|
||||||
|
|
||||||
@Mock private NotificationGroupManagerLegacy mGroupMembershipManager;
|
|
||||||
@Mock private NotificationGroupManagerLegacy mGroupExpansionManager;
|
|
||||||
@Mock private NotifPipelineFlags mNotifPipelineFlags;
|
|
||||||
@Mock private LeakDetector mLeakDetector;
|
|
||||||
|
|
||||||
@Mock private ActivatableNotificationViewController mActivatableNotificationViewController;
|
|
||||||
@Mock private NotificationRowComponent.Builder mNotificationRowComponentBuilder;
|
|
||||||
@Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
|
|
||||||
@Mock private InflatedSmartReplyState mInflatedSmartReplyState;
|
|
||||||
@Mock private InflatedSmartReplyViewHolder mInflatedSmartReplies;
|
|
||||||
|
|
||||||
private StatusBarNotification mSbn;
|
|
||||||
private NotificationListenerService.RankingMap mRankingMap;
|
|
||||||
private NotificationEntryManager mEntryManager;
|
|
||||||
private NotificationRowBinderImpl mRowBinder;
|
|
||||||
private Handler mHandler;
|
|
||||||
private FakeExecutor mBgExecutor;
|
|
||||||
private RowContentBindStage mRowContentBindStage;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mDependency.injectMockDependency(SmartReplyController.class);
|
|
||||||
mDependency.injectMockDependency(MediaOutputDialogFactory.class);
|
|
||||||
|
|
||||||
mHandler = Handler.createAsync(TestableLooper.get(this).getLooper());
|
|
||||||
|
|
||||||
// Add an action so heads up content views are made
|
|
||||||
Notification.Action action = new Notification.Action.Builder(null, null, null).build();
|
|
||||||
Notification notification = new Notification.Builder(mContext)
|
|
||||||
.setSmallIcon(R.drawable.ic_person)
|
|
||||||
.setContentTitle(TEST_TITLE)
|
|
||||||
.setContentText(TEST_TEXT)
|
|
||||||
.setActions(action)
|
|
||||||
.build();
|
|
||||||
mSbn = new SbnBuilder()
|
|
||||||
.setNotification(notification)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
when(mNotifPipelineFlags.checkLegacyPipelineEnabled()).thenReturn(true);
|
|
||||||
when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
|
|
||||||
|
|
||||||
mEntryManager = new NotificationEntryManager(
|
|
||||||
mock(NotificationEntryManagerLogger.class),
|
|
||||||
mGroupMembershipManager,
|
|
||||||
mNotifPipelineFlags,
|
|
||||||
() -> mRowBinder,
|
|
||||||
() -> mRemoteInputManager,
|
|
||||||
mLeakDetector,
|
|
||||||
mock(IStatusBarService.class),
|
|
||||||
NotifLiveDataStoreMocksKt.createNotifLiveDataStoreImplMock(),
|
|
||||||
mock(DumpManager.class),
|
|
||||||
mBgExecutor
|
|
||||||
);
|
|
||||||
mEntryManager.initialize(
|
|
||||||
mNotificationListener,
|
|
||||||
new NotificationRankingManager(
|
|
||||||
() -> mock(NotificationMediaManager.class),
|
|
||||||
mGroupMembershipManager,
|
|
||||||
mHeadsUpManager,
|
|
||||||
mock(NotificationFilter.class),
|
|
||||||
mock(NotificationEntryManagerLogger.class),
|
|
||||||
mock(NotificationSectionsFeatureManager.class),
|
|
||||||
mock(PeopleNotificationIdentifier.class),
|
|
||||||
mock(HighPriorityProvider.class),
|
|
||||||
mEnvironment));
|
|
||||||
|
|
||||||
NotifRemoteViewCache cache = new NotifRemoteViewCacheImpl(mEntryManager);
|
|
||||||
NotifBindPipeline pipeline = new NotifBindPipeline(
|
|
||||||
mEntryManager,
|
|
||||||
mock(NotifBindPipelineLogger.class),
|
|
||||||
TestableLooper.get(this).getLooper());
|
|
||||||
mBgExecutor = new FakeExecutor(new FakeSystemClock());
|
|
||||||
NotificationContentInflater binder = new NotificationContentInflater(
|
|
||||||
cache,
|
|
||||||
mRemoteInputManager,
|
|
||||||
mock(ConversationNotificationProcessor.class),
|
|
||||||
mock(MediaFeatureFlag.class),
|
|
||||||
mBgExecutor,
|
|
||||||
new SmartReplyStateInflater() {
|
|
||||||
@Override
|
|
||||||
public InflatedSmartReplyState inflateSmartReplyState(NotificationEntry entry) {
|
|
||||||
return mInflatedSmartReplyState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InflatedSmartReplyViewHolder inflateSmartReplyViewHolder(
|
|
||||||
Context sysuiContext, Context notifPackageContext,
|
|
||||||
NotificationEntry entry,
|
|
||||||
InflatedSmartReplyState existingSmartReplyState,
|
|
||||||
InflatedSmartReplyState newSmartReplyState) {
|
|
||||||
return mInflatedSmartReplies;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mRowContentBindStage = new RowContentBindStage(
|
|
||||||
binder,
|
|
||||||
mock(NotifInflationErrorManager.class),
|
|
||||||
mock(RowContentBindStageLogger.class));
|
|
||||||
pipeline.setStage(mRowContentBindStage);
|
|
||||||
|
|
||||||
ArgumentCaptor<ExpandableNotificationRow> viewCaptor =
|
|
||||||
ArgumentCaptor.forClass(ExpandableNotificationRow.class);
|
|
||||||
when(mExpandableNotificationRowComponentBuilder
|
|
||||||
.expandableNotificationRow(viewCaptor.capture()))
|
|
||||||
.thenReturn(mExpandableNotificationRowComponentBuilder);
|
|
||||||
when(mExpandableNotificationRowComponentBuilder.build())
|
|
||||||
.thenReturn(mExpandableNotificationRowComponent);
|
|
||||||
|
|
||||||
when(mExpandableNotificationRowComponent.getExpandableNotificationRowController())
|
|
||||||
.thenAnswer((Answer<ExpandableNotificationRowController>) invocation ->
|
|
||||||
new ExpandableNotificationRowController(
|
|
||||||
viewCaptor.getValue(),
|
|
||||||
mock(ActivatableNotificationViewController.class),
|
|
||||||
mock(RemoteInputViewSubcomponent.Factory.class),
|
|
||||||
mock(MetricsLogger.class),
|
|
||||||
mListContainer,
|
|
||||||
mNotificationMediaManager,
|
|
||||||
mock(SmartReplyConstants.class),
|
|
||||||
mock(SmartReplyController.class),
|
|
||||||
mock(PluginManager.class),
|
|
||||||
new FakeSystemClock(),
|
|
||||||
"FOOBAR",
|
|
||||||
"FOOBAR",
|
|
||||||
mKeyguardBypassController,
|
|
||||||
mGroupMembershipManager,
|
|
||||||
mGroupExpansionManager,
|
|
||||||
mRowContentBindStage,
|
|
||||||
mock(NotificationLogger.class),
|
|
||||||
mHeadsUpManager,
|
|
||||||
mPresenter,
|
|
||||||
mStatusBarStateController,
|
|
||||||
mGutsManager,
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
new FalsingManagerFake(),
|
|
||||||
new FalsingCollectorFake(),
|
|
||||||
mock(FeatureFlags.class),
|
|
||||||
mPeopleNotificationIdentifier,
|
|
||||||
Optional.of(mock(BubblesManager.class)),
|
|
||||||
mock(ExpandableNotificationRowDragController.class)));
|
|
||||||
|
|
||||||
when(mNotificationRowComponentBuilder.activatableNotificationView(any()))
|
|
||||||
.thenReturn(mNotificationRowComponentBuilder);
|
|
||||||
when(mNotificationRowComponentBuilder.build()).thenReturn(
|
|
||||||
() -> mActivatableNotificationViewController);
|
|
||||||
|
|
||||||
mRowBinder = new NotificationRowBinderImpl(
|
|
||||||
mContext,
|
|
||||||
new NotificationMessagingUtil(mContext),
|
|
||||||
mRemoteInputManager,
|
|
||||||
mLockscreenUserManager,
|
|
||||||
pipeline,
|
|
||||||
mRowContentBindStage,
|
|
||||||
RowInflaterTask::new,
|
|
||||||
mExpandableNotificationRowComponentBuilder,
|
|
||||||
new IconManager(
|
|
||||||
mEntryManager,
|
|
||||||
mock(LauncherApps.class),
|
|
||||||
new IconBuilder(mContext)),
|
|
||||||
mock(LowPriorityInflationHelper.class),
|
|
||||||
mNotifPipelineFlags);
|
|
||||||
|
|
||||||
mEntryManager.setUpWithPresenter(mPresenter);
|
|
||||||
mEntryManager.addNotificationEntryListener(mEntryListener);
|
|
||||||
|
|
||||||
mRowBinder.setUpWithPresenter(mPresenter, mListContainer, mBindCallback);
|
|
||||||
mRowBinder.setNotificationClicker(mock(NotificationClicker.class));
|
|
||||||
|
|
||||||
Ranking ranking = new Ranking();
|
|
||||||
ranking.populate(
|
|
||||||
mSbn.getKey(),
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true,
|
|
||||||
Ranking.USER_SENTIMENT_NEUTRAL,
|
|
||||||
false,
|
|
||||||
-1,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
0,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
mRankingMap = new NotificationListenerService.RankingMap(new Ranking[] {ranking});
|
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void cleanUp() {
|
|
||||||
// Don't leave anything on main thread
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddNotification() {
|
|
||||||
// WHEN a notification is added
|
|
||||||
mEntryManager.addNotification(mSbn, mRankingMap);
|
|
||||||
ArgumentCaptor<NotificationEntry> entryCaptor = ArgumentCaptor.forClass(
|
|
||||||
NotificationEntry.class);
|
|
||||||
verify(mEntryListener).onPendingEntryAdded(entryCaptor.capture());
|
|
||||||
NotificationEntry entry = entryCaptor.getValue();
|
|
||||||
|
|
||||||
waitForInflation();
|
|
||||||
|
|
||||||
// THEN the notification has its row inflated
|
|
||||||
assertNotNull(entry.getRow());
|
|
||||||
assertNotNull(entry.getRow().getPrivateLayout().getContractedChild());
|
|
||||||
|
|
||||||
// THEN inflation callbacks are called
|
|
||||||
verify(mBindCallback).onBindRow(entry.getRow());
|
|
||||||
verify(mEntryListener, never()).onInflationError(any(), any());
|
|
||||||
verify(mEntryListener).onEntryInflated(entry);
|
|
||||||
verify(mEntryListener).onNotificationAdded(entry);
|
|
||||||
|
|
||||||
// THEN the notification is active
|
|
||||||
assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
|
|
||||||
|
|
||||||
// THEN we update the presenter
|
|
||||||
verify(mPresenter).updateNotificationViews(any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateNotification() {
|
|
||||||
// GIVEN a notification already added
|
|
||||||
mEntryManager.addNotification(mSbn, mRankingMap);
|
|
||||||
ArgumentCaptor<NotificationEntry> entryCaptor = ArgumentCaptor.forClass(
|
|
||||||
NotificationEntry.class);
|
|
||||||
verify(mEntryListener).onPendingEntryAdded(entryCaptor.capture());
|
|
||||||
NotificationEntry entry = entryCaptor.getValue();
|
|
||||||
waitForInflation();
|
|
||||||
|
|
||||||
Mockito.reset(mEntryListener);
|
|
||||||
Mockito.reset(mPresenter);
|
|
||||||
|
|
||||||
// WHEN the notification is updated
|
|
||||||
mEntryManager.updateNotification(mSbn, mRankingMap);
|
|
||||||
|
|
||||||
waitForInflation();
|
|
||||||
|
|
||||||
// THEN the notification has its row and inflated
|
|
||||||
assertNotNull(entry.getRow());
|
|
||||||
|
|
||||||
// THEN inflation callbacks are called
|
|
||||||
verify(mEntryListener, never()).onInflationError(any(), any());
|
|
||||||
verify(mEntryListener).onEntryReinflated(entry);
|
|
||||||
|
|
||||||
// THEN we update the presenter
|
|
||||||
verify(mPresenter).updateNotificationViews(any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testContentViewInflationDuringRowInflationInflatesCorrectViews() {
|
|
||||||
// GIVEN a notification is added and the row is inflating
|
|
||||||
mEntryManager.addNotification(mSbn, mRankingMap);
|
|
||||||
ArgumentCaptor<NotificationEntry> entryCaptor = ArgumentCaptor.forClass(
|
|
||||||
NotificationEntry.class);
|
|
||||||
verify(mEntryListener).onPendingEntryAdded(entryCaptor.capture());
|
|
||||||
NotificationEntry entry = entryCaptor.getValue();
|
|
||||||
|
|
||||||
// WHEN we try to bind a content view
|
|
||||||
mRowContentBindStage.getStageParams(entry).requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP);
|
|
||||||
mRowContentBindStage.requestRebind(entry, null);
|
|
||||||
|
|
||||||
waitForInflation();
|
|
||||||
|
|
||||||
// THEN the notification has its row and all relevant content views inflated
|
|
||||||
assertNotNull(entry.getRow());
|
|
||||||
assertNotNull(entry.getRow().getPrivateLayout().getContractedChild());
|
|
||||||
assertNotNull(entry.getRow().getPrivateLayout().getHeadsUpChild());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for inflation to finish.
|
|
||||||
*
|
|
||||||
* A few things to note
|
|
||||||
* 1) Row inflation is done via {@link AsyncLayoutInflater} on its own background thread that
|
|
||||||
* calls back to main thread which is why we wait on main thread.
|
|
||||||
* 2) Row *content* inflation is done on the {@link FakeExecutor} we pass in in this test class
|
|
||||||
* so we control when that work is done. The callback is still always on the main thread.
|
|
||||||
*/
|
|
||||||
private void waitForInflation() {
|
|
||||||
mHandler.postDelayed(TIMEOUT_RUNNABLE, TIMEOUT_TIME);
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
NotificationEntryListener inflationListener = new NotificationEntryListener() {
|
|
||||||
@Override
|
|
||||||
public void onEntryInflated(NotificationEntry entry) {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEntryReinflated(NotificationEntry entry) {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onInflationError(StatusBarNotification notification, Exception exception) {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mEntryManager.addNotificationEntryListener(inflationListener);
|
|
||||||
while (latch.getCount() != 0) {
|
|
||||||
mBgExecutor.runAllReady();
|
|
||||||
TestableLooper.get(this).processMessages(1);
|
|
||||||
}
|
|
||||||
mHandler.removeCallbacks(TIMEOUT_RUNNABLE);
|
|
||||||
mEntryManager.removeNotificationEntryListener(inflationListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -156,13 +156,13 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mGutsManager = new NotificationGutsManager(mContext,
|
mGutsManager = new NotificationGutsManager(mContext,
|
||||||
() -> Optional.of(mCentralSurfaces), mHandler, mHandler, mAccessibilityManager,
|
() -> Optional.of(mCentralSurfaces), mHandler, mHandler, mAccessibilityManager,
|
||||||
mHighPriorityProvider, mINotificationManager, mNotificationEntryManager,
|
mHighPriorityProvider, mINotificationManager,
|
||||||
mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
|
mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
|
||||||
mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
|
mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
|
||||||
Optional.of(mBubblesManager), new UiEventLoggerFake(), mOnUserInteractionCallback,
|
Optional.of(mBubblesManager), new UiEventLoggerFake(), mOnUserInteractionCallback,
|
||||||
mShadeController, mock(DumpManager.class));
|
mShadeController, mock(DumpManager.class));
|
||||||
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
|
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
|
||||||
mCheckSaveListener, mOnSettingsClickListener);
|
mOnSettingsClickListener);
|
||||||
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
|
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ import com.android.systemui.statusbar.NotificationMediaManager;
|
|||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
|
|
||||||
import com.android.systemui.statusbar.OperatorNameViewController;
|
import com.android.systemui.statusbar.OperatorNameViewController;
|
||||||
import com.android.systemui.statusbar.PulseExpansionHandler;
|
import com.android.systemui.statusbar.PulseExpansionHandler;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
@@ -129,7 +128,6 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
|||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
|
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
@@ -220,7 +218,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
@Mock private BatteryController mBatteryController;
|
@Mock private BatteryController mBatteryController;
|
||||||
@Mock private DeviceProvisionedController mDeviceProvisionedController;
|
@Mock private DeviceProvisionedController mDeviceProvisionedController;
|
||||||
@Mock private StatusBarNotificationPresenter mNotificationPresenter;
|
@Mock private StatusBarNotificationPresenter mNotificationPresenter;
|
||||||
@Mock private NotificationFilter mNotificationFilter;
|
|
||||||
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
||||||
@Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
|
@Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
|
||||||
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
@@ -242,7 +239,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
@Mock private AutoHideController mAutoHideController;
|
@Mock private AutoHideController mAutoHideController;
|
||||||
@Mock private StatusBarWindowController mStatusBarWindowController;
|
@Mock private StatusBarWindowController mStatusBarWindowController;
|
||||||
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
|
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
|
||||||
@Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
|
|
||||||
@Mock private UserSwitcherController mUserSwitcherController;
|
@Mock private UserSwitcherController mUserSwitcherController;
|
||||||
@Mock private Bubbles mBubbles;
|
@Mock private Bubbles mBubbles;
|
||||||
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
|
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
|
||||||
@@ -283,7 +279,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
@Mock private OperatorNameViewController mOperatorNameViewController;
|
@Mock private OperatorNameViewController mOperatorNameViewController;
|
||||||
@Mock private OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
|
@Mock private OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
|
||||||
@Mock private ActivityLaunchAnimator mActivityLaunchAnimator;
|
@Mock private ActivityLaunchAnimator mActivityLaunchAnimator;
|
||||||
@Mock private NotifPipelineFlags mNotifPipelineFlags;
|
|
||||||
@Mock private NotifLiveDataStore mNotifLiveDataStore;
|
@Mock private NotifLiveDataStore mNotifLiveDataStore;
|
||||||
@Mock private InteractionJankMonitor mJankMonitor;
|
@Mock private InteractionJankMonitor mJankMonitor;
|
||||||
@Mock private DeviceStateManager mDeviceStateManager;
|
@Mock private DeviceStateManager mDeviceStateManager;
|
||||||
@@ -298,7 +293,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mDependency.injectTestDependency(NotificationFilter.class, mNotificationFilter);
|
|
||||||
|
|
||||||
IPowerManager powerManagerService = mock(IPowerManager.class);
|
IPowerManager powerManagerService = mock(IPowerManager.class);
|
||||||
IThermalService thermalService = mock(IThermalService.class);
|
IThermalService thermalService = mock(IThermalService.class);
|
||||||
@@ -310,7 +304,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
mPowerManager,
|
mPowerManager,
|
||||||
mDreamManager,
|
mDreamManager,
|
||||||
mAmbientDisplayConfiguration,
|
mAmbientDisplayConfiguration,
|
||||||
mNotificationFilter,
|
|
||||||
mStatusBarStateController,
|
mStatusBarStateController,
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mBatteryController,
|
mBatteryController,
|
||||||
@@ -410,7 +403,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
mNotificationGutsManager,
|
mNotificationGutsManager,
|
||||||
notificationLogger,
|
notificationLogger,
|
||||||
mNotificationInterruptStateProvider,
|
mNotificationInterruptStateProvider,
|
||||||
mNotificationViewHierarchyManager,
|
|
||||||
new PanelExpansionStateManager(),
|
new PanelExpansionStateManager(),
|
||||||
mKeyguardViewMediator,
|
mKeyguardViewMediator,
|
||||||
new DisplayMetrics(),
|
new DisplayMetrics(),
|
||||||
@@ -472,7 +464,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
mWallpaperManager,
|
mWallpaperManager,
|
||||||
Optional.of(mStartingSurface),
|
Optional.of(mStartingSurface),
|
||||||
mActivityLaunchAnimator,
|
mActivityLaunchAnimator,
|
||||||
mNotifPipelineFlags,
|
|
||||||
mJankMonitor,
|
mJankMonitor,
|
||||||
mDeviceStateManager,
|
mDeviceStateManager,
|
||||||
mWiredChargingRippleController, mDreamManager);
|
mWiredChargingRippleController, mDreamManager);
|
||||||
@@ -659,7 +650,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
public void testShouldHeadsUp_nonSuppressedGroupSummary() throws Exception {
|
public void testShouldHeadsUp_nonSuppressedGroupSummary() throws Exception {
|
||||||
when(mPowerManager.isScreenOn()).thenReturn(true);
|
when(mPowerManager.isScreenOn()).thenReturn(true);
|
||||||
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
||||||
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
|
|
||||||
when(mDreamManager.isDreaming()).thenReturn(false);
|
when(mDreamManager.isDreaming()).thenReturn(false);
|
||||||
|
|
||||||
Notification n = new Notification.Builder(getContext(), "a")
|
Notification n = new Notification.Builder(getContext(), "a")
|
||||||
@@ -683,7 +673,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
public void testShouldHeadsUp_suppressedGroupSummary() throws Exception {
|
public void testShouldHeadsUp_suppressedGroupSummary() throws Exception {
|
||||||
when(mPowerManager.isScreenOn()).thenReturn(true);
|
when(mPowerManager.isScreenOn()).thenReturn(true);
|
||||||
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
||||||
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
|
|
||||||
when(mDreamManager.isDreaming()).thenReturn(false);
|
when(mDreamManager.isDreaming()).thenReturn(false);
|
||||||
|
|
||||||
Notification n = new Notification.Builder(getContext(), "a")
|
Notification n = new Notification.Builder(getContext(), "a")
|
||||||
@@ -707,7 +696,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
public void testShouldHeadsUp_suppressedHeadsUp() throws Exception {
|
public void testShouldHeadsUp_suppressedHeadsUp() throws Exception {
|
||||||
when(mPowerManager.isScreenOn()).thenReturn(true);
|
when(mPowerManager.isScreenOn()).thenReturn(true);
|
||||||
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
||||||
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
|
|
||||||
when(mDreamManager.isDreaming()).thenReturn(false);
|
when(mDreamManager.isDreaming()).thenReturn(false);
|
||||||
|
|
||||||
Notification n = new Notification.Builder(getContext(), "a").build();
|
Notification n = new Notification.Builder(getContext(), "a").build();
|
||||||
@@ -729,7 +717,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
public void testShouldHeadsUp_noSuppressedHeadsUp() throws Exception {
|
public void testShouldHeadsUp_noSuppressedHeadsUp() throws Exception {
|
||||||
when(mPowerManager.isScreenOn()).thenReturn(true);
|
when(mPowerManager.isScreenOn()).thenReturn(true);
|
||||||
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
|
||||||
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
|
|
||||||
when(mDreamManager.isDreaming()).thenReturn(false);
|
when(mDreamManager.isDreaming()).thenReturn(false);
|
||||||
|
|
||||||
Notification n = new Notification.Builder(getContext(), "a").build();
|
Notification n = new Notification.Builder(getContext(), "a").build();
|
||||||
@@ -1041,7 +1028,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
PowerManager powerManager,
|
PowerManager powerManager,
|
||||||
IDreamManager dreamManager,
|
IDreamManager dreamManager,
|
||||||
AmbientDisplayConfiguration ambientDisplayConfiguration,
|
AmbientDisplayConfiguration ambientDisplayConfiguration,
|
||||||
NotificationFilter filter,
|
|
||||||
StatusBarStateController controller,
|
StatusBarStateController controller,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
BatteryController batteryController,
|
BatteryController batteryController,
|
||||||
@@ -1055,7 +1041,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
|||||||
powerManager,
|
powerManager,
|
||||||
dreamManager,
|
dreamManager,
|
||||||
ambientDisplayConfiguration,
|
ambientDisplayConfiguration,
|
||||||
filter,
|
|
||||||
batteryController,
|
batteryController,
|
||||||
controller,
|
controller,
|
||||||
keyguardStateController,
|
keyguardStateController,
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|||||||
import com.android.systemui.shade.NotificationPanelViewController;
|
import com.android.systemui.shade.NotificationPanelViewController;
|
||||||
import com.android.systemui.shade.NotificationShadeWindowView;
|
import com.android.systemui.shade.NotificationShadeWindowView;
|
||||||
import com.android.systemui.shade.ShadeController;
|
import com.android.systemui.shade.ShadeController;
|
||||||
import com.android.systemui.shade.ShadeControllerImpl;
|
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.KeyguardIndicationController;
|
import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
@@ -51,7 +50,6 @@ 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;
|
||||||
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
|
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
@@ -77,16 +75,17 @@ import org.mockito.ArgumentCaptor;
|
|||||||
@RunWithLooper()
|
@RunWithLooper()
|
||||||
public class StatusBarNotificationPresenterTest extends SysuiTestCase {
|
public class StatusBarNotificationPresenterTest extends SysuiTestCase {
|
||||||
private StatusBarNotificationPresenter mStatusBarNotificationPresenter;
|
private StatusBarNotificationPresenter mStatusBarNotificationPresenter;
|
||||||
private NotificationInterruptStateProvider mNotificationInterruptStateProvider =
|
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider =
|
||||||
mock(NotificationInterruptStateProvider.class);
|
mock(NotificationInterruptStateProvider.class);
|
||||||
private NotificationInterruptSuppressor mInterruptSuppressor;
|
private NotificationInterruptSuppressor mInterruptSuppressor;
|
||||||
private CommandQueue mCommandQueue;
|
private CommandQueue mCommandQueue;
|
||||||
private FakeMetricsLogger mMetricsLogger;
|
private FakeMetricsLogger mMetricsLogger;
|
||||||
private ShadeController mShadeController = mock(ShadeController.class);
|
private final ShadeController mShadeController = mock(ShadeController.class);
|
||||||
private CentralSurfaces mCentralSurfaces = mock(CentralSurfaces.class);
|
private final CentralSurfaces mCentralSurfaces = mock(CentralSurfaces.class);
|
||||||
private KeyguardStateController mKeyguardStateController = mock(KeyguardStateController.class);
|
private final KeyguardStateController mKeyguardStateController =
|
||||||
private NotifPipelineFlags mNotifPipelineFlags = mock(NotifPipelineFlags.class);
|
mock(KeyguardStateController.class);
|
||||||
private InitController mInitController = new InitController();
|
private final NotifPipelineFlags mNotifPipelineFlags = mock(NotifPipelineFlags.class);
|
||||||
|
private final InitController mInitController = new InitController();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@@ -117,16 +116,13 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
|
|||||||
mock(ActivityStarter.class),
|
mock(ActivityStarter.class),
|
||||||
stackScrollLayoutController,
|
stackScrollLayoutController,
|
||||||
mock(DozeScrimController.class),
|
mock(DozeScrimController.class),
|
||||||
mock(ScrimController.class),
|
|
||||||
mock(NotificationShadeWindowController.class),
|
mock(NotificationShadeWindowController.class),
|
||||||
mock(DynamicPrivacyController.class),
|
mock(DynamicPrivacyController.class),
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mock(KeyguardIndicationController.class),
|
mock(KeyguardIndicationController.class),
|
||||||
mCentralSurfaces,
|
mCentralSurfaces,
|
||||||
mock(ShadeControllerImpl.class),
|
|
||||||
mock(LockscreenShadeTransitionController.class),
|
mock(LockscreenShadeTransitionController.class),
|
||||||
mCommandQueue,
|
mCommandQueue,
|
||||||
mock(NotificationViewHierarchyManager.class),
|
|
||||||
mock(NotificationLockscreenUserManager.class),
|
mock(NotificationLockscreenUserManager.class),
|
||||||
mock(SysuiStatusBarStateController.class),
|
mock(SysuiStatusBarStateController.class),
|
||||||
mock(NotifShadeEventSource.class),
|
mock(NotifShadeEventSource.class),
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|||||||
import com.android.systemui.statusbar.RankingBuilder;
|
import com.android.systemui.statusbar.RankingBuilder;
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
|
||||||
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;
|
||||||
@@ -328,7 +327,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
mock(PowerManager.class),
|
mock(PowerManager.class),
|
||||||
mock(IDreamManager.class),
|
mock(IDreamManager.class),
|
||||||
mock(AmbientDisplayConfiguration.class),
|
mock(AmbientDisplayConfiguration.class),
|
||||||
mock(NotificationFilter.class),
|
|
||||||
mock(StatusBarStateController.class),
|
mock(StatusBarStateController.class),
|
||||||
mock(KeyguardStateController.class),
|
mock(KeyguardStateController.class),
|
||||||
mock(BatteryController.class),
|
mock(BatteryController.class),
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import android.service.dreams.IDreamManager;
|
|||||||
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
|
||||||
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
|
||||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
|
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
|
||||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
|
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
|
||||||
@@ -40,7 +39,6 @@ public class TestableNotificationInterruptStateProviderImpl
|
|||||||
PowerManager powerManager,
|
PowerManager powerManager,
|
||||||
IDreamManager dreamManager,
|
IDreamManager dreamManager,
|
||||||
AmbientDisplayConfiguration ambientDisplayConfiguration,
|
AmbientDisplayConfiguration ambientDisplayConfiguration,
|
||||||
NotificationFilter filter,
|
|
||||||
StatusBarStateController statusBarStateController,
|
StatusBarStateController statusBarStateController,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
BatteryController batteryController,
|
BatteryController batteryController,
|
||||||
@@ -53,7 +51,6 @@ public class TestableNotificationInterruptStateProviderImpl
|
|||||||
powerManager,
|
powerManager,
|
||||||
dreamManager,
|
dreamManager,
|
||||||
ambientDisplayConfiguration,
|
ambientDisplayConfiguration,
|
||||||
filter,
|
|
||||||
batteryController,
|
batteryController,
|
||||||
statusBarStateController,
|
statusBarStateController,
|
||||||
keyguardStateController,
|
keyguardStateController,
|
||||||
|
|||||||
Reference in New Issue
Block a user