Removes dependency of NotificationEntryManager on IStatusBarService.

This change moves the logic in NotificationEntryManager which logs
notification removal and inflation errors via the IStatusBarService to
the NotificationLogger, which is already logging visibility changes to
that service.

Test: atest SystemUITests, manual
Change-Id: I895a36db505a165c4e6684d1d6e66592e62ef1f7
This commit is contained in:
Gus Prevas
2018-12-28 10:53:11 -05:00
parent 18e35038be
commit ca1b6f74f3
12 changed files with 117 additions and 65 deletions

View File

@@ -42,6 +42,7 @@ import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.Interpolators;
@@ -159,6 +160,7 @@ public class NotificationMediaManager implements Dumpable {
Entry entry,
String key,
StatusBarNotification old,
NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
if (!lifetimeExtended) {

View File

@@ -255,6 +255,7 @@ public class NotificationRemoteInputManager implements Dumpable {
NotificationData.Entry entry,
String key,
StatusBarNotification old,
NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
if (removedByUser) {

View File

@@ -24,6 +24,7 @@ import android.app.Notification;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.NotificationListener;
@@ -84,6 +85,7 @@ public class NotificationAlertingManager {
NotificationData.Entry entry,
String key,
StatusBarNotification old,
NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
stopAlerting(key);

View File

@@ -15,8 +15,10 @@
*/
package com.android.systemui.statusbar.notification;
import android.annotation.Nullable;
import android.service.notification.StatusBarNotification;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.row.NotificationInflater;
/**
@@ -58,6 +60,12 @@ public interface NotificationEntryListener {
default void onEntryReinflated(NotificationData.Entry entry) {
}
/**
* Called when an error occurred inflating the views for a notification.
*/
default void onInflationError(StatusBarNotification notification, Exception exception) {
}
/**
* Called when a notification has been removed (either because the user swiped it away or
* because the developer retracted it).
@@ -65,6 +73,9 @@ public interface NotificationEntryListener {
* removed key at the time of removal.
* @param key key of notification that was removed
* @param old StatusBarNotification of the notification before it was removed
* @param visibility logging data related to the visibility of the notification at the time of
* removal, if it was removed by a user action. Null if it was not removed by
* a user action.
* @param lifetimeExtended true if something is artificially extending how long the notification
* @param removedByUser true if the notification was removed by a user action
*/
@@ -72,6 +83,7 @@ public interface NotificationEntryListener {
NotificationData.Entry entry,
String key,
StatusBarNotification old,
@Nullable NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
}

View File

@@ -22,18 +22,14 @@ import android.app.Notification;
import android.content.Context;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
@@ -98,7 +94,6 @@ public class NotificationEntryManager implements
private final Handler mDeferredNotificationViewUpdateHandler;
private Runnable mUpdateNotificationViewsCallback;
protected IStatusBarService mBarService;
private NotificationPresenter mPresenter;
protected PowerManager mPowerManager;
private NotificationListenerService.RankingMap mLatestRankingMap;
@@ -139,8 +134,6 @@ public class NotificationEntryManager implements
public NotificationEntryManager(Context context) {
mContext = context;
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mBubbleController.setDismissListener(this /* bubbleEventListener */);
mNotificationData = new NotificationData();
mDeferredNotificationViewUpdateHandler = new Handler();
@@ -215,26 +208,8 @@ public class NotificationEntryManager implements
final int count = mNotificationData.getActiveNotifications().size();
final NotificationVisibility nv = NotificationVisibility.obtain(n.getKey(), rank, count,
true);
final String pkg = n.getPackageName();
final String tag = n.getTag();
final int id = n.getId();
final int userId = n.getUserId();
try {
int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
if (mHeadsUpManager.isAlerting(n.getKey())) {
dismissalSurface = NotificationStats.DISMISSAL_PEEK;
} else if (mListContainer.hasPulsingNotifications()) {
dismissalSurface = NotificationStats.DISMISSAL_AOD;
}
int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
mBarService.onNotificationClear(pkg, tag, id, userId, n.getKey(), dismissalSurface,
dismissalSentiment, nv);
removeNotificationInternal(
n.getKey(), null, false /* forceRemove */, true /* removedByUser */);
} catch (RemoteException ex) {
// system process is dead if we're here.
}
removeNotificationInternal(
n.getKey(), null, nv, false /* forceRemove */, true /* removedByUser */);
}
@Override
@@ -275,12 +250,9 @@ public class NotificationEntryManager implements
@Override
public void handleInflationException(StatusBarNotification n, Exception e) {
removeNotificationInternal(
n.getKey(), null, true /* forceRemove */, false /* removedByUser */);
try {
mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(),
n.getInitialPid(), e.getMessage(), n.getUserId());
} catch (RemoteException ex) {
// The end is nigh.
n.getKey(), null, null, true /* forceRemove */, false /* removedByUser */);
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onInflationError(n, e);
}
}
@@ -333,12 +305,13 @@ public class NotificationEntryManager implements
@Override
public void removeNotification(String key, NotificationListenerService.RankingMap ranking) {
removeNotificationInternal(
key, ranking, false /* forceRemove */, false /* removedByUser */);
key, ranking, null, false /* forceRemove */, false /* removedByUser */);
}
private void removeNotificationInternal(
String key,
@Nullable NotificationListenerService.RankingMap ranking,
@Nullable NotificationVisibility visibility,
boolean forceRemove,
boolean removedByUser) {
final NotificationData.Entry entry = mNotificationData.get(key);
@@ -385,7 +358,7 @@ public class NotificationEntryManager implements
}
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onEntryRemoved(entry, key, old, lifetimeExtended, removedByUser);
listener.onEntryRemoved(entry, key, old, visibility, lifetimeExtended, removedByUser);
}
}

View File

@@ -21,6 +21,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.Log;
@@ -32,8 +34,10 @@ import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.ArrayList;
import java.util.Collection;
@@ -60,7 +64,8 @@ public class NotificationLogger implements StateListener {
// Dependencies:
private final NotificationListenerService mNotificationListener;
private final UiOffloadThread mUiOffloadThread;
protected NotificationEntryManager mEntryManager;
private final NotificationEntryManager mEntryManager;
private HeadsUpManager mHeadsUpManager;
protected Handler mHandler = new Handler();
protected IStatusBarService mBarService;
@@ -158,12 +163,38 @@ public class NotificationLogger implements StateListener {
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
// Not expected to be destroyed, don't need to unsubscribe
statusBarStateController.addCallback(this);
entryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
public void onEntryRemoved(
NotificationData.Entry entry,
String key,
StatusBarNotification old,
NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
if (removedByUser && visibility != null) {
logNotificationClear(key, entry.notification, visibility);
}
}
@Override
public void onInflationError(
StatusBarNotification notification,
Exception exception) {
logNotificationError(notification, exception);
}
});
}
public void setUpWithContainer(NotificationListContainer listContainer) {
mListContainer = listContainer;
}
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
mHeadsUpManager = headsUpManager;
}
public void stopNotificationLogging() {
// Report all notifications as invisible and turn down the
// reporter.
@@ -193,6 +224,45 @@ public class NotificationLogger implements StateListener {
}
}
private void logNotificationClear(String key, StatusBarNotification notification,
NotificationVisibility nv) {
final String pkg = notification.getPackageName();
final String tag = notification.getTag();
final int id = notification.getId();
final int userId = notification.getUserId();
try {
int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
if (mHeadsUpManager.isAlerting(key)) {
dismissalSurface = NotificationStats.DISMISSAL_PEEK;
} else if (mListContainer.hasPulsingNotifications()) {
dismissalSurface = NotificationStats.DISMISSAL_AOD;
}
int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
mBarService.onNotificationClear(pkg, tag, id, userId, notification.getKey(),
dismissalSurface,
dismissalSentiment, nv);
} catch (RemoteException ex) {
// system process is dead if we're here.
}
}
private void logNotificationError(
StatusBarNotification notification,
Exception exception) {
try {
mBarService.onNotificationError(
notification.getPackageName(),
notification.getTag(),
notification.getId(),
notification.getUid(),
notification.getInitialPid(),
exception.getMessage(),
notification.getUserId());
} catch (RemoteException ex) {
// The end is nigh.
}
}
private void logNotificationVisibilityChanges(
Collection<NotificationVisibility> newlyVisible,
Collection<NotificationVisibility> noLongerVisible) {

View File

@@ -22,6 +22,7 @@ import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AmbientPulseManager;
@@ -220,6 +221,7 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
Entry entry,
String key,
StatusBarNotification old,
NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
// Removes any alerts pending on this entry. Note that this will not stop any inflation

View File

@@ -868,6 +868,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setHeadsUpManager(mHeadsUpManager);
mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
mNotificationLogger.setHeadsUpManager(mHeadsUpManager);
putComponent(HeadsUpManager.class, mHeadsUpManager);
createNavigationBar();

View File

@@ -37,6 +37,7 @@ import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.MessagingGroup;
import com.android.internal.widget.MessagingMessage;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -195,6 +196,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
Entry entry,
String key,
StatusBarNotification old,
NotificationVisibility visibility,
boolean lifetimeExtended,
boolean removedByUser) {
if (!lifetimeExtended) {

View File

@@ -52,7 +52,6 @@ import android.util.ArraySet;
import android.widget.FrameLayout;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
@@ -109,7 +108,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
@Mock private HeadsUpManager mHeadsUpManager;
@Mock private NotificationListenerService.RankingMap mRankingMap;
@Mock private RemoteInputController mRemoteInputController;
@Mock private IStatusBarService mBarService;
// Dependency mocks:
@Mock private ForegroundServiceController mForegroundServiceController;
@@ -132,9 +130,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
private class TestableNotificationEntryManager extends NotificationEntryManager {
private final CountDownLatch mCountDownLatch;
public TestableNotificationEntryManager(Context context, IStatusBarService barService) {
TestableNotificationEntryManager(Context context) {
super(context);
mBarService = barService;
mCountDownLatch = new CountDownLatch(1);
}
@@ -227,7 +224,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mEntry = new NotificationData.Entry(mSbn);
mEntry.expandedIcon = mock(StatusBarIconView.class);
mEntryManager = new TestableNotificationEntryManager(mContext, mBarService);
mEntryManager = new TestableNotificationEntryManager(mContext);
Dependency.get(InitController.class).executePostInitTasks();
mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mHeadsUpManager);
mEntryManager.addNotificationEntryListener(mEntryListener);
@@ -258,8 +255,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
assertTrue(mEntryManager.getCountDownLatch().await(10, TimeUnit.SECONDS));
// Check that no inflation error occurred.
verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(),
any(), anyInt());
verify(mEntryListener, never()).onInflationError(any(), any());
verify(mForegroundServiceController).addNotification(eq(mSbn), anyInt());
// Row inflation:
@@ -293,8 +289,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
// Wait for content update.
assertTrue(mEntryManager.getCountDownLatch().await(10, TimeUnit.SECONDS));
verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(),
any(), anyInt());
verify(mEntryListener, never()).onInflationError(any(), any());
verify(mPresenter).updateNotificationViews();
verify(mForegroundServiceController).updateNotification(eq(mSbn), anyInt());
@@ -313,14 +308,13 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mEntryManager.removeNotification(mSbn.getKey(), mRankingMap);
verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(),
any(), anyInt());
verify(mEntryListener, never()).onInflationError(any(), any());
verify(mForegroundServiceController).removeNotification(mSbn);
verify(mListContainer).cleanUpViewStateForEntry(mEntry);
verify(mPresenter).updateNotificationViews();
verify(mEntryListener).onEntryRemoved(mEntry, mSbn.getKey(), mSbn,
false /* lifetimeExtended */, false /* removedByUser */);
null, false /* lifetimeExtended */, false /* removedByUser */);
verify(mRow).setRemoved();
assertNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
@@ -345,7 +339,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
assertNotNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
verify(extender).setShouldManageLifetime(mEntry, true /* shouldManage */);
verify(mEntryListener).onEntryRemoved(mEntry, mSbn.getKey(), null,
true /* lifetimeExtended */, false /* removedByUser */);
null, true /* lifetimeExtended */, false /* removedByUser */);
}
@Test

View File

@@ -28,7 +28,6 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
@@ -41,7 +40,6 @@ import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -56,7 +54,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -67,7 +64,6 @@ public class NotificationLoggerTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
private static final int TEST_UID = 0;
@Mock private NotificationPresenter mPresenter;
@Mock private NotificationListContainer mListContainer;
@Mock private IStatusBarService mBarService;
@Mock private NotificationData mNotificationData;
@@ -78,21 +74,21 @@ public class NotificationLoggerTest extends SysuiTestCase {
@Mock private NotificationListener mListener;
private NotificationData.Entry mEntry;
private StatusBarNotification mSbn;
private TestableNotificationLogger mLogger;
private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>();
@Before
public void setUp() throws RemoteException {
public void setUp() {
MockitoAnnotations.initMocks(this);
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
mDependency.injectTestDependency(NotificationListener.class, mListener);
when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, TEST_UID,
0, new Notification(), UserHandle.CURRENT, null, 0);
mEntry = new NotificationData.Entry(mSbn);
mEntry = new NotificationData.Entry(sbn);
mEntry.setRow(mRow);
mLogger = new TestableNotificationLogger(mListener, Dependency.get(UiOffloadThread.class),
@@ -106,7 +102,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
NotificationVisibility.obtain(mEntry.key, 0, 1, true)
};
NotificationVisibility[] noLongerVisibleKeys = {};
doAnswer((Answer) invocation -> {
doAnswer(invocation -> {
try {
assertArrayEquals(newlyVisibleKeys,
(NotificationVisibility[]) invocation.getArguments()[0]);
@@ -158,7 +154,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
private class TestableNotificationLogger extends NotificationLogger {
public TestableNotificationLogger(NotificationListener notificationListener,
TestableNotificationLogger(NotificationListener notificationListener,
UiOffloadThread uiOffloadThread,
NotificationEntryManager entryManager,
StatusBarStateController statusBarStateController,
@@ -169,13 +165,9 @@ public class NotificationLoggerTest extends SysuiTestCase {
mHandler = Handler.createAsync(Looper.myLooper());
}
public OnChildLocationsChangedListener
OnChildLocationsChangedListener
getChildLocationsChangedListenerForTest() {
return mNotificationLocationsChangedListener;
}
public Handler getHandlerForTest() {
return mHandler;
}
}
}

View File

@@ -237,7 +237,8 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
mGroupManager.onEntryAdded(summaryEntry);
mGroupManager.onEntryAdded(childEntry);
mNotificationEntryListener.onEntryRemoved(childEntry, childEntry.key, null, false, false);
mNotificationEntryListener.onEntryRemoved(childEntry, childEntry.key, null, null,
false, false);
assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
}