Loading packages/SystemUI/src/com/android/systemui/Dependency.java +3 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationRowBinder; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; Loading Loading @@ -254,6 +255,7 @@ public class Dependency extends SystemUI { @Inject Lazy<NotificationListener> mNotificationListener; @Inject Lazy<NotificationLogger> mNotificationLogger; @Inject Lazy<NotificationViewHierarchyManager> mNotificationViewHierarchyManager; @Inject Lazy<NotificationRowBinder> mNotificationRowBinder; @Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil; @Inject Lazy<SmartReplyController> mSmartReplyController; @Inject Lazy<RemoteInputQuickSettingsDisabler> mRemoteInputQuickSettingsDisabler; Loading Loading @@ -422,6 +424,7 @@ public class Dependency extends SystemUI { mProviders.put(NotificationLogger.class, mNotificationLogger::get); mProviders.put(NotificationViewHierarchyManager.class, mNotificationViewHierarchyManager::get); mProviders.put(NotificationRowBinder.class, mNotificationRowBinder::get); mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get); mProviders.put(SmartReplyController.class, mSmartReplyController::get); mProviders.put(RemoteInputQuickSettingsDisabler.class, Loading packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationRowBinder; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl; Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java +3 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationRowBinder; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; Loading @@ -28,7 +29,8 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow */ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpandClickListener, ActivatableNotificationView.OnActivatedListener, NotificationEntryManager.Callback { NotificationEntryManager.Callback, NotificationRowBinder.BindRowCallback { /** * Returns true if the presenter is not visible. For example, it may not be necessary to do * animations if this returns true. Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java +2 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ public class NotificationData { public NotificationChannel channel; public long lastAudiblyAlertedMs; public boolean noisy; public boolean ambient; public int importance; public StatusBarIconView icon; public StatusBarIconView expandedIcon; Loading Loading @@ -174,6 +175,7 @@ public class NotificationData { channel = ranking.getChannel(); lastAudiblyAlertedMs = ranking.getLastAudiblyAlertedMillis(); importance = ranking.getImportance(); ambient = ranking.isAmbient(); snoozeCriteria = ranking.getSnoozeCriteria(); userSentiment = ranking.getUserSentiment(); systemGeneratedSmartActions = ranking.getSmartActions() == null Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +56 −175 Original line number Diff line number Diff line Loading @@ -15,9 +15,7 @@ */ package com.android.systemui.statusbar.notification; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.systemui.bubbles.BubbleController.DEBUG_DEMOTE_TO_NOTIF; import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY; import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT; Loading @@ -28,10 +26,7 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.PowerManager; Loading @@ -49,25 +44,21 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Log; import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.EventLogTags; import com.android.systemui.ForegroundServiceController; import com.android.systemui.R; import com.android.systemui.UiOffloadThread; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.NotificationLifetimeExtender; 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; Loading @@ -79,11 +70,9 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationInflater; import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag; import com.android.systemui.statusbar.notification.row.RowInflaterTask; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.leak.LeakDetector; Loading @@ -100,9 +89,12 @@ import java.util.concurrent.TimeUnit; * It also handles tasks such as their inflation and their interaction with other * Notification.*Manager objects. */ public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback, ExpandableNotificationRow.ExpansionLogger, NotificationUpdateHandler, VisualStabilityManager.Callback, BubbleController.BubbleDismissListener { public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback, NotificationUpdateHandler, VisualStabilityManager.Callback, BubbleController.BubbleDismissListener { private static final String TAG = "NotificationEntryMgr"; protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean ENABLE_HEADS_UP = true; Loading @@ -110,7 +102,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. public static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30); private final NotificationMessagingUtil mMessagingUtil; protected final Context mContext; protected final HashMap<String, NotificationData.Entry> mPendingNotifications = new HashMap<>(); Loading @@ -123,7 +114,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. Dependency.get(DeviceProvisionedController.class); private final VisualStabilityManager mVisualStabilityManager = Dependency.get(VisualStabilityManager.class); private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); private final ForegroundServiceController mForegroundServiceController = Dependency.get(ForegroundServiceController.class); private final AmbientPulseManager mAmbientPulseManager = Loading @@ -135,6 +125,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. private NotificationMediaManager mMediaManager; private NotificationListener mNotificationListener; private ShadeController mShadeController; private NotificationRowBinder mNotificationRowBinder; private final Handler mDeferredNotificationViewUpdateHandler; private Runnable mUpdateNotificationViewsCallback; Loading @@ -154,10 +145,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. @VisibleForTesting final ArrayList<NotificationLifetimeExtender> mNotificationLifetimeExtenders = new ArrayList<>(); private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener; private NotificationViewHierarchyManager.StatusBarStateListener mStatusBarStateListener; @Nullable private AlertTransferListener mAlertTransferListener; @Nullable private NotificationClicker mNotificationClicker; private final DeviceProvisionedController.DeviceProvisionedListener mDeviceProvisionedListener = Loading Loading @@ -199,7 +188,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); mMessagingUtil = new NotificationMessagingUtil(context); mBubbleController.setDismissListener(this /* bubbleEventListener */); mNotificationData = new NotificationData(); mDeferredNotificationViewUpdateHandler = new Handler(); Loading @@ -209,10 +197,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mAlertTransferListener = listener; } public void setNotificationClicker(NotificationClicker clicker) { mNotificationClicker = clicker; } /** * Our dependencies can have cyclic references, so some need to be lazy */ Loading Loading @@ -244,6 +228,13 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return mShadeController; } private NotificationRowBinder getRowBinder() { if (mNotificationRowBinder == null) { mNotificationRowBinder = Dependency.get(NotificationRowBinder.class); } return mNotificationRowBinder; } public void setUpWithPresenter(NotificationPresenter presenter, NotificationListContainer listContainer, Callback callback, HeadsUpManager headsUpManager) { Loading Loading @@ -296,7 +287,18 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mDeviceProvisionedController.addCallback(mDeviceProvisionedListener); mHeadsUpObserver.onChange(true); // set up mOnAppOpsClickListener = mGutsManager::openGuts; getRowBinder().setInterruptionStateProvider(new InterruptionStateProvider() { @Override public boolean shouldHeadsUp(NotificationData.Entry entry) { return NotificationEntryManager.this.shouldHeadsUp(entry); } @Override public boolean shouldPulse(NotificationData.Entry entry) { return NotificationEntryManager.this.shouldPulse(entry); } }); } public NotificationData getNotificationData() { Loading @@ -312,18 +314,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. } public ExpandableNotificationRow.LongPressListener getNotificationLongClicker() { return mGutsManager::openGuts; } @Override public void logNotificationExpansion(String key, boolean userAction, boolean expanded) { mUiOffloadThread.submit(() -> { try { mBarService.onNotificationExpansionChanged(key, userAction, expanded); } catch (RemoteException e) { // Ignore. } }); return getRowBinder().getNotificationLongClicker(); } @Override Loading @@ -339,64 +330,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return mNotificationData.shouldSuppressFullScreenIntent(entry); } private void inflateViews(NotificationData.Entry entry, ViewGroup parent) { PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, entry.notification.getUser().getIdentifier()); final StatusBarNotification sbn = entry.notification; if (entry.rowExists()) { entry.reset(); updateNotification(entry, pmUser, sbn, entry.getRow()); } else { new RowInflaterTask().inflate(mContext, parent, entry, row -> { bindRow(entry, pmUser, sbn, row); updateNotification(entry, pmUser, sbn, row); }); } } private void bindRow(NotificationData.Entry entry, PackageManager pmUser, StatusBarNotification sbn, ExpandableNotificationRow row) { row.setExpansionLogger(this, entry.notification.getKey()); row.setGroupManager(mGroupManager); row.setHeadsUpManager(mHeadsUpManager); row.setOnExpandClickListener(mPresenter); row.setInflationCallback(this); row.setLongPressListener(getNotificationLongClicker()); mListContainer.bindRow(row); getRemoteInputManager().bindRow(row); // Get the app name. // Note that Notification.Builder#bindHeaderAppName has similar logic // but since this field is used in the guts, it must be accurate. // Therefore we will only show the application label, or, failing that, the // package name. No substitutions. final String pkg = sbn.getPackageName(); String appname = pkg; try { final ApplicationInfo info = pmUser.getApplicationInfo(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS); if (info != null) { appname = String.valueOf(pmUser.getApplicationLabel(info)); } } catch (PackageManager.NameNotFoundException e) { // Do nothing } row.setAppName(appname); row.setOnDismissRunnable(() -> performRemoveNotification(row.getStatusBarNotification())); row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); if (ENABLE_REMOTE_INPUT) { row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); } row.setAppOpsOnClickListener(mOnAppOpsClickListener); mCallback.onBindRow(entry, pmUser, sbn, row); } public void performRemoveNotification(StatusBarNotification n) { final int rank = mNotificationData.getRank(n.getKey()); final int count = mNotificationData.getActiveNotifications().size(); Loading Loading @@ -687,56 +620,11 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. } } //TODO: This method associates a row with an entry, but eventually needs to not do that protected void updateNotification(NotificationData.Entry entry, PackageManager pmUser, StatusBarNotification sbn, ExpandableNotificationRow row) { boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey()); boolean isUpdate = mNotificationData.get(entry.key) != null; boolean wasLowPriority = row.isLowPriority(); row.setIsLowPriority(isLowPriority); row.setLowPriorityStateUpdated(isUpdate && (wasLowPriority != isLowPriority)); // bind the click event to the content area checkNotNull(mNotificationClicker).register(row, sbn); // Extract target SDK version. try { ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0); entry.targetSdk = info.targetSdkVersion; } catch (PackageManager.NameNotFoundException ex) { Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex); } row.setLegacy(entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP); entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP); entry.autoRedacted = entry.notification.getNotification().publicVersion == null; entry.setRow(row); row.setOnActivatedListener(mPresenter); boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn, mNotificationData.getImportance(sbn.getKey())); boolean useIncreasedHeadsUp = useIncreasedCollapsedHeight && !mPresenter.isPresenterFullyCollapsed(); row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight); row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp); row.setEntry(entry); if (shouldHeadsUp(entry)) { row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, true /* shouldInflate */); } if (shouldPulse(entry)) { row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true /* shouldInflate */); } row.setNeedsRedaction( Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry)); row.inflateViews(); } private NotificationData.Entry createNotificationViews( private NotificationData.Entry createNotificationEntry( StatusBarNotification sbn, NotificationListenerService.Ranking ranking) throws InflationException { if (DEBUG) { Log.d(TAG, "createNotificationViews(notification=" + sbn + " " + ranking); Log.d(TAG, "createNotificationEntry(notification=" + sbn + " " + ranking); } NotificationData.Entry entry = new NotificationData.Entry(sbn, ranking); Loading @@ -747,7 +635,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. Dependency.get(LeakDetector.class).trackInstance(entry); entry.createIcons(mContext, sbn); // Construct the expanded view. inflateViews(entry, mListContainer.getViewParentForNotification(entry)); getRowBinder().inflateViews(entry, () -> performRemoveNotification(sbn), mNotificationData.get(entry.key) != null); return entry; } Loading @@ -761,7 +650,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mNotificationData.updateRanking(rankingMap); NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); rankingMap.getRanking(key, ranking); NotificationData.Entry shadeEntry = createNotificationViews(notification, ranking); NotificationData.Entry shadeEntry = createNotificationEntry(notification, ranking); boolean isHeadsUped = shouldHeadsUp(shadeEntry); if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) { if (shouldSuppressFullScreenIntent(shadeEntry)) { Loading Loading @@ -870,7 +759,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mGroupManager.onEntryUpdated(entry, oldNotification); entry.updateIcons(mContext, notification); inflateViews(entry, mListContainer.getViewParentForNotification(entry)); getRowBinder().inflateViews(entry, () -> performRemoveNotification(notification), mNotificationData.get(entry.key) != null); mForegroundServiceController.updateNotification(notification, mNotificationData.getImportance(key)); Loading Loading @@ -938,26 +828,12 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. // By comparing the old and new UI adjustments, reinflate the view accordingly. for (NotificationData.Entry entry : entries) { NotificationUiAdjustment newAdjustment = NotificationUiAdjustment.extractFromNotificationEntry(entry); if (NotificationUiAdjustment.needReinflate( oldAdjustments.get(entry.key), newAdjustment)) { if (entry.rowExists()) { entry.reset(); PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, entry.notification.getUser().getIdentifier()); updateNotification(entry, pmUser, entry.notification, entry.getRow()); } else { // Once the RowInflaterTask is done, it will pick up the updated entry, so // no-op here. } } else if (oldImportances.containsKey(entry.key) && entry.importance != oldImportances.get(entry.key)) { if (entry.rowExists()) { entry.getRow().onNotificationRankingUpdated(); } } mNotificationRowBinder.onNotificationRankingUpdated( entry, oldImportances.get(entry.key), oldAdjustments.get(entry.key), NotificationUiAdjustment.extractFromNotificationEntry(entry), mNotificationData.get(entry.key) != null); } updateNotifications(); Loading Loading @@ -1201,6 +1077,22 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return mPendingNotifications.values(); } /** * Interface for retrieving heads-up and pulsing state for an entry. */ public interface InterruptionStateProvider { /** * Whether the provided entry should be marked as heads-up when inflated. */ boolean shouldHeadsUp(NotificationData.Entry entry); /** * Whether the provided entry should be marked as pulsing (displayed in ambient) when * inflated. */ boolean shouldPulse(NotificationData.Entry entry); } /** * Callback for NotificationEntryManager. */ Loading Loading @@ -1228,17 +1120,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. */ void onNotificationRemoved(String key, StatusBarNotification old); /** * Called when a new notification and row is created. * * @param entry entry for the notification * @param pmUser package manager for user * @param sbn notification * @param row row for the notification */ void onBindRow(NotificationData.Entry entry, PackageManager pmUser, StatusBarNotification sbn, ExpandableNotificationRow row); /** * Removes a notification immediately. * Loading Loading
packages/SystemUI/src/com/android/systemui/Dependency.java +3 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationRowBinder; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; Loading Loading @@ -254,6 +255,7 @@ public class Dependency extends SystemUI { @Inject Lazy<NotificationListener> mNotificationListener; @Inject Lazy<NotificationLogger> mNotificationLogger; @Inject Lazy<NotificationViewHierarchyManager> mNotificationViewHierarchyManager; @Inject Lazy<NotificationRowBinder> mNotificationRowBinder; @Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil; @Inject Lazy<SmartReplyController> mSmartReplyController; @Inject Lazy<RemoteInputQuickSettingsDisabler> mRemoteInputQuickSettingsDisabler; Loading Loading @@ -422,6 +424,7 @@ public class Dependency extends SystemUI { mProviders.put(NotificationLogger.class, mNotificationLogger::get); mProviders.put(NotificationViewHierarchyManager.class, mNotificationViewHierarchyManager::get); mProviders.put(NotificationRowBinder.class, mNotificationRowBinder::get); mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get); mProviders.put(SmartReplyController.class, mSmartReplyController::get); mProviders.put(RemoteInputQuickSettingsDisabler.class, Loading
packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationRowBinder; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl; Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java +3 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationRowBinder; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; Loading @@ -28,7 +29,8 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow */ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpandClickListener, ActivatableNotificationView.OnActivatedListener, NotificationEntryManager.Callback { NotificationEntryManager.Callback, NotificationRowBinder.BindRowCallback { /** * Returns true if the presenter is not visible. For example, it may not be necessary to do * animations if this returns true. Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java +2 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ public class NotificationData { public NotificationChannel channel; public long lastAudiblyAlertedMs; public boolean noisy; public boolean ambient; public int importance; public StatusBarIconView icon; public StatusBarIconView expandedIcon; Loading Loading @@ -174,6 +175,7 @@ public class NotificationData { channel = ranking.getChannel(); lastAudiblyAlertedMs = ranking.getLastAudiblyAlertedMillis(); importance = ranking.getImportance(); ambient = ranking.isAmbient(); snoozeCriteria = ranking.getSnoozeCriteria(); userSentiment = ranking.getUserSentiment(); systemGeneratedSmartActions = ranking.getSmartActions() == null Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +56 −175 Original line number Diff line number Diff line Loading @@ -15,9 +15,7 @@ */ package com.android.systemui.statusbar.notification; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.systemui.bubbles.BubbleController.DEBUG_DEMOTE_TO_NOTIF; import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY; import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT; Loading @@ -28,10 +26,7 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.PowerManager; Loading @@ -49,25 +44,21 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Log; import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.EventLogTags; import com.android.systemui.ForegroundServiceController; import com.android.systemui.R; import com.android.systemui.UiOffloadThread; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.NotificationLifetimeExtender; 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; Loading @@ -79,11 +70,9 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationInflater; import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag; import com.android.systemui.statusbar.notification.row.RowInflaterTask; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.leak.LeakDetector; Loading @@ -100,9 +89,12 @@ import java.util.concurrent.TimeUnit; * It also handles tasks such as their inflation and their interaction with other * Notification.*Manager objects. */ public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback, ExpandableNotificationRow.ExpansionLogger, NotificationUpdateHandler, VisualStabilityManager.Callback, BubbleController.BubbleDismissListener { public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback, NotificationUpdateHandler, VisualStabilityManager.Callback, BubbleController.BubbleDismissListener { private static final String TAG = "NotificationEntryMgr"; protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean ENABLE_HEADS_UP = true; Loading @@ -110,7 +102,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. public static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30); private final NotificationMessagingUtil mMessagingUtil; protected final Context mContext; protected final HashMap<String, NotificationData.Entry> mPendingNotifications = new HashMap<>(); Loading @@ -123,7 +114,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. Dependency.get(DeviceProvisionedController.class); private final VisualStabilityManager mVisualStabilityManager = Dependency.get(VisualStabilityManager.class); private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); private final ForegroundServiceController mForegroundServiceController = Dependency.get(ForegroundServiceController.class); private final AmbientPulseManager mAmbientPulseManager = Loading @@ -135,6 +125,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. private NotificationMediaManager mMediaManager; private NotificationListener mNotificationListener; private ShadeController mShadeController; private NotificationRowBinder mNotificationRowBinder; private final Handler mDeferredNotificationViewUpdateHandler; private Runnable mUpdateNotificationViewsCallback; Loading @@ -154,10 +145,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. @VisibleForTesting final ArrayList<NotificationLifetimeExtender> mNotificationLifetimeExtenders = new ArrayList<>(); private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener; private NotificationViewHierarchyManager.StatusBarStateListener mStatusBarStateListener; @Nullable private AlertTransferListener mAlertTransferListener; @Nullable private NotificationClicker mNotificationClicker; private final DeviceProvisionedController.DeviceProvisionedListener mDeviceProvisionedListener = Loading Loading @@ -199,7 +188,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); mMessagingUtil = new NotificationMessagingUtil(context); mBubbleController.setDismissListener(this /* bubbleEventListener */); mNotificationData = new NotificationData(); mDeferredNotificationViewUpdateHandler = new Handler(); Loading @@ -209,10 +197,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mAlertTransferListener = listener; } public void setNotificationClicker(NotificationClicker clicker) { mNotificationClicker = clicker; } /** * Our dependencies can have cyclic references, so some need to be lazy */ Loading Loading @@ -244,6 +228,13 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return mShadeController; } private NotificationRowBinder getRowBinder() { if (mNotificationRowBinder == null) { mNotificationRowBinder = Dependency.get(NotificationRowBinder.class); } return mNotificationRowBinder; } public void setUpWithPresenter(NotificationPresenter presenter, NotificationListContainer listContainer, Callback callback, HeadsUpManager headsUpManager) { Loading Loading @@ -296,7 +287,18 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mDeviceProvisionedController.addCallback(mDeviceProvisionedListener); mHeadsUpObserver.onChange(true); // set up mOnAppOpsClickListener = mGutsManager::openGuts; getRowBinder().setInterruptionStateProvider(new InterruptionStateProvider() { @Override public boolean shouldHeadsUp(NotificationData.Entry entry) { return NotificationEntryManager.this.shouldHeadsUp(entry); } @Override public boolean shouldPulse(NotificationData.Entry entry) { return NotificationEntryManager.this.shouldPulse(entry); } }); } public NotificationData getNotificationData() { Loading @@ -312,18 +314,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. } public ExpandableNotificationRow.LongPressListener getNotificationLongClicker() { return mGutsManager::openGuts; } @Override public void logNotificationExpansion(String key, boolean userAction, boolean expanded) { mUiOffloadThread.submit(() -> { try { mBarService.onNotificationExpansionChanged(key, userAction, expanded); } catch (RemoteException e) { // Ignore. } }); return getRowBinder().getNotificationLongClicker(); } @Override Loading @@ -339,64 +330,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return mNotificationData.shouldSuppressFullScreenIntent(entry); } private void inflateViews(NotificationData.Entry entry, ViewGroup parent) { PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, entry.notification.getUser().getIdentifier()); final StatusBarNotification sbn = entry.notification; if (entry.rowExists()) { entry.reset(); updateNotification(entry, pmUser, sbn, entry.getRow()); } else { new RowInflaterTask().inflate(mContext, parent, entry, row -> { bindRow(entry, pmUser, sbn, row); updateNotification(entry, pmUser, sbn, row); }); } } private void bindRow(NotificationData.Entry entry, PackageManager pmUser, StatusBarNotification sbn, ExpandableNotificationRow row) { row.setExpansionLogger(this, entry.notification.getKey()); row.setGroupManager(mGroupManager); row.setHeadsUpManager(mHeadsUpManager); row.setOnExpandClickListener(mPresenter); row.setInflationCallback(this); row.setLongPressListener(getNotificationLongClicker()); mListContainer.bindRow(row); getRemoteInputManager().bindRow(row); // Get the app name. // Note that Notification.Builder#bindHeaderAppName has similar logic // but since this field is used in the guts, it must be accurate. // Therefore we will only show the application label, or, failing that, the // package name. No substitutions. final String pkg = sbn.getPackageName(); String appname = pkg; try { final ApplicationInfo info = pmUser.getApplicationInfo(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS); if (info != null) { appname = String.valueOf(pmUser.getApplicationLabel(info)); } } catch (PackageManager.NameNotFoundException e) { // Do nothing } row.setAppName(appname); row.setOnDismissRunnable(() -> performRemoveNotification(row.getStatusBarNotification())); row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); if (ENABLE_REMOTE_INPUT) { row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); } row.setAppOpsOnClickListener(mOnAppOpsClickListener); mCallback.onBindRow(entry, pmUser, sbn, row); } public void performRemoveNotification(StatusBarNotification n) { final int rank = mNotificationData.getRank(n.getKey()); final int count = mNotificationData.getActiveNotifications().size(); Loading Loading @@ -687,56 +620,11 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. } } //TODO: This method associates a row with an entry, but eventually needs to not do that protected void updateNotification(NotificationData.Entry entry, PackageManager pmUser, StatusBarNotification sbn, ExpandableNotificationRow row) { boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey()); boolean isUpdate = mNotificationData.get(entry.key) != null; boolean wasLowPriority = row.isLowPriority(); row.setIsLowPriority(isLowPriority); row.setLowPriorityStateUpdated(isUpdate && (wasLowPriority != isLowPriority)); // bind the click event to the content area checkNotNull(mNotificationClicker).register(row, sbn); // Extract target SDK version. try { ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0); entry.targetSdk = info.targetSdkVersion; } catch (PackageManager.NameNotFoundException ex) { Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex); } row.setLegacy(entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP); entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP); entry.autoRedacted = entry.notification.getNotification().publicVersion == null; entry.setRow(row); row.setOnActivatedListener(mPresenter); boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn, mNotificationData.getImportance(sbn.getKey())); boolean useIncreasedHeadsUp = useIncreasedCollapsedHeight && !mPresenter.isPresenterFullyCollapsed(); row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight); row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp); row.setEntry(entry); if (shouldHeadsUp(entry)) { row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, true /* shouldInflate */); } if (shouldPulse(entry)) { row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true /* shouldInflate */); } row.setNeedsRedaction( Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry)); row.inflateViews(); } private NotificationData.Entry createNotificationViews( private NotificationData.Entry createNotificationEntry( StatusBarNotification sbn, NotificationListenerService.Ranking ranking) throws InflationException { if (DEBUG) { Log.d(TAG, "createNotificationViews(notification=" + sbn + " " + ranking); Log.d(TAG, "createNotificationEntry(notification=" + sbn + " " + ranking); } NotificationData.Entry entry = new NotificationData.Entry(sbn, ranking); Loading @@ -747,7 +635,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. Dependency.get(LeakDetector.class).trackInstance(entry); entry.createIcons(mContext, sbn); // Construct the expanded view. inflateViews(entry, mListContainer.getViewParentForNotification(entry)); getRowBinder().inflateViews(entry, () -> performRemoveNotification(sbn), mNotificationData.get(entry.key) != null); return entry; } Loading @@ -761,7 +650,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mNotificationData.updateRanking(rankingMap); NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); rankingMap.getRanking(key, ranking); NotificationData.Entry shadeEntry = createNotificationViews(notification, ranking); NotificationData.Entry shadeEntry = createNotificationEntry(notification, ranking); boolean isHeadsUped = shouldHeadsUp(shadeEntry); if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) { if (shouldSuppressFullScreenIntent(shadeEntry)) { Loading Loading @@ -870,7 +759,8 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mGroupManager.onEntryUpdated(entry, oldNotification); entry.updateIcons(mContext, notification); inflateViews(entry, mListContainer.getViewParentForNotification(entry)); getRowBinder().inflateViews(entry, () -> performRemoveNotification(notification), mNotificationData.get(entry.key) != null); mForegroundServiceController.updateNotification(notification, mNotificationData.getImportance(key)); Loading Loading @@ -938,26 +828,12 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. // By comparing the old and new UI adjustments, reinflate the view accordingly. for (NotificationData.Entry entry : entries) { NotificationUiAdjustment newAdjustment = NotificationUiAdjustment.extractFromNotificationEntry(entry); if (NotificationUiAdjustment.needReinflate( oldAdjustments.get(entry.key), newAdjustment)) { if (entry.rowExists()) { entry.reset(); PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, entry.notification.getUser().getIdentifier()); updateNotification(entry, pmUser, entry.notification, entry.getRow()); } else { // Once the RowInflaterTask is done, it will pick up the updated entry, so // no-op here. } } else if (oldImportances.containsKey(entry.key) && entry.importance != oldImportances.get(entry.key)) { if (entry.rowExists()) { entry.getRow().onNotificationRankingUpdated(); } } mNotificationRowBinder.onNotificationRankingUpdated( entry, oldImportances.get(entry.key), oldAdjustments.get(entry.key), NotificationUiAdjustment.extractFromNotificationEntry(entry), mNotificationData.get(entry.key) != null); } updateNotifications(); Loading Loading @@ -1201,6 +1077,22 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. return mPendingNotifications.values(); } /** * Interface for retrieving heads-up and pulsing state for an entry. */ public interface InterruptionStateProvider { /** * Whether the provided entry should be marked as heads-up when inflated. */ boolean shouldHeadsUp(NotificationData.Entry entry); /** * Whether the provided entry should be marked as pulsing (displayed in ambient) when * inflated. */ boolean shouldPulse(NotificationData.Entry entry); } /** * Callback for NotificationEntryManager. */ Loading Loading @@ -1228,17 +1120,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. */ void onNotificationRemoved(String key, StatusBarNotification old); /** * Called when a new notification and row is created. * * @param entry entry for the notification * @param pmUser package manager for user * @param sbn notification * @param row row for the notification */ void onBindRow(NotificationData.Entry entry, PackageManager pmUser, StatusBarNotification sbn, ExpandableNotificationRow row); /** * Removes a notification immediately. * Loading