use of android.service.notification.StatusBarNotification in project platform_frameworks_base by android.
the class PhoneStatusBar method maybeEscalateHeadsUp.
@Override
public void maybeEscalateHeadsUp() {
Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
for (HeadsUpManager.HeadsUpEntry entry : entries) {
final StatusBarNotification sbn = entry.entry.notification;
final Notification notification = sbn.getNotification();
if (notification.fullScreenIntent != null) {
if (DEBUG) {
Log.d(TAG, "converting a heads up to fullScreen");
}
try {
EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION, sbn.getKey());
notification.fullScreenIntent.send();
entry.entry.notifyFullScreenIntentLaunched();
} catch (PendingIntent.CanceledException e) {
}
}
}
mHeadsUpManager.releaseAllImmediately();
}
use of android.service.notification.StatusBarNotification in project platform_frameworks_base by android.
the class PhoneStatusBar method removeNotification.
@Override
public void removeNotification(String key, RankingMap ranking) {
boolean deferRemoval = false;
if (mHeadsUpManager.isHeadsUp(key)) {
// A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
// sending look longer than it takes.
boolean ignoreEarliestRemovalTime = mRemoteInputController.isSpinning(key) && !FORCE_REMOTE_INPUT_HISTORY;
deferRemoval = !mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
}
if (key.equals(mMediaNotificationKey)) {
clearCurrentMediaNotification();
updateMediaMetaData(true, true);
}
if (FORCE_REMOTE_INPUT_HISTORY && mRemoteInputController.isSpinning(key)) {
Entry entry = mNotificationData.get(key);
StatusBarNotification sbn = entry.notification;
Notification.Builder b = Notification.Builder.recoverBuilder(mContext, sbn.getNotification().clone());
CharSequence[] oldHistory = sbn.getNotification().extras.getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
CharSequence[] newHistory;
if (oldHistory == null) {
newHistory = new CharSequence[1];
} else {
newHistory = new CharSequence[oldHistory.length + 1];
for (int i = 0; i < oldHistory.length; i++) {
newHistory[i + 1] = oldHistory[i];
}
}
newHistory[0] = String.valueOf(entry.remoteInputText);
b.setRemoteInputHistory(newHistory);
Notification newNotification = b.build();
// Undo any compatibility view inflation
newNotification.contentView = sbn.getNotification().contentView;
newNotification.bigContentView = sbn.getNotification().bigContentView;
newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(), sbn.getOpPkg(), sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(), 0, newNotification, sbn.getUser(), sbn.getPostTime());
updateNotification(newSbn, null);
mKeysKeptForRemoteInput.add(entry.key);
return;
}
if (deferRemoval) {
mLatestRankingMap = ranking;
mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
return;
}
Entry entry = mNotificationData.get(key);
if (entry != null && mRemoteInputController.isRemoteInputActive(entry) && (entry.row != null && !entry.row.isDismissed())) {
mLatestRankingMap = ranking;
mRemoteInputEntriesToRemoveOnCollapse.add(entry);
return;
}
if (entry != null && entry.row != null) {
entry.row.setRemoved();
}
// Let's remove the children if this was a summary
handleGroupSummaryRemoved(key, ranking);
StatusBarNotification old = removeNotificationViews(key, ranking);
if (SPEW)
Log.d(TAG, "removeNotification key=" + key + " old=" + old);
if (old != null) {
if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications() && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
if (mState == StatusBarState.SHADE) {
animateCollapsePanels();
} else if (mState == StatusBarState.SHADE_LOCKED && !isCollapsing()) {
goToKeyguard();
}
}
}
setAreThereNotifications();
}
use of android.service.notification.StatusBarNotification in project platform_frameworks_base by android.
the class NotificationManagerService method maybeAddAutobundleSummary.
// Posts a 'fake' summary for a package that has exceeded the solo-notification limit.
private void maybeAddAutobundleSummary(Adjustment adjustment) {
if (adjustment.getSignals() != null) {
Bundle.setDefusable(adjustment.getSignals(), true);
if (adjustment.getSignals().getBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false)) {
final String newAutoBundleKey = adjustment.getSignals().getString(Adjustment.GROUP_KEY_OVERRIDE_KEY, null);
int userId = -1;
NotificationRecord summaryRecord = null;
synchronized (mNotificationList) {
NotificationRecord notificationRecord = mNotificationsByKey.get(adjustment.getKey());
if (notificationRecord == null) {
// adjustment will post a summary if needed.
return;
}
final StatusBarNotification adjustedSbn = notificationRecord.sbn;
userId = adjustedSbn.getUser().getIdentifier();
ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
if (summaries == null) {
summaries = new ArrayMap<>();
}
mAutobundledSummaries.put(userId, summaries);
if (!summaries.containsKey(adjustment.getPackage()) && newAutoBundleKey != null) {
// Add summary
final ApplicationInfo appInfo = adjustedSbn.getNotification().extras.getParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO);
final Bundle extras = new Bundle();
extras.putParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO, appInfo);
final Notification summaryNotification = new Notification.Builder(getContext()).setSmallIcon(adjustedSbn.getNotification().getSmallIcon()).setGroupSummary(true).setGroup(newAutoBundleKey).setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true).setFlag(Notification.FLAG_GROUP_SUMMARY, true).setColor(adjustedSbn.getNotification().color).setLocalOnly(true).build();
summaryNotification.extras.putAll(extras);
Intent appIntent = getContext().getPackageManager().getLaunchIntentForPackage(adjustment.getPackage());
if (appIntent != null) {
summaryNotification.contentIntent = PendingIntent.getActivityAsUser(getContext(), 0, appIntent, 0, null, UserHandle.of(userId));
}
final StatusBarNotification summarySbn = new StatusBarNotification(adjustedSbn.getPackageName(), adjustedSbn.getOpPkg(), Integer.MAX_VALUE, Adjustment.GROUP_KEY_OVERRIDE_KEY, adjustedSbn.getUid(), adjustedSbn.getInitialPid(), summaryNotification, adjustedSbn.getUser(), newAutoBundleKey, System.currentTimeMillis());
summaryRecord = new NotificationRecord(getContext(), summarySbn);
summaries.put(adjustment.getPackage(), summarySbn.getKey());
}
}
if (summaryRecord != null) {
mHandler.post(new EnqueueNotificationRunnable(userId, summaryRecord));
}
}
}
}
use of android.service.notification.StatusBarNotification in project platform_frameworks_base by android.
the class NotificationManagerService method enqueueNotificationInternal.
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid, final int callingPid, final String tag, final int id, final Notification notification, int[] idOut, int incomingUserId) {
if (DBG) {
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
checkCallerIsSystemOrSameApp(pkg);
final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
final int userId = ActivityManager.handleIncomingUser(callingPid, callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
final UserHandle user = new UserHandle(userId);
// Fix the notification as best we can.
try {
final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfoAsUser(pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
Notification.addFieldsFromContext(ai, userId, notification);
} catch (NameNotFoundException e) {
Slog.e(TAG, "Cannot create a context for sending app", e);
return;
}
mUsageStats.registerEnqueuedByApp(pkg);
if (pkg == null || notification == null) {
throw new IllegalArgumentException("null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
final StatusBarNotification n = new StatusBarNotification(pkg, opPkg, id, tag, callingUid, callingPid, 0, notification, user);
// package or a registered listener can enqueue. Prevents DOS attacks and deals with leaks.
if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
if (mNotificationsByKey.get(n.getKey()) != null) {
// this is an update, rate limit updates only
final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
if (appEnqueueRate > mMaxPackageEnqueueRate) {
mUsageStats.registerOverRateQuota(pkg);
final long now = SystemClock.elapsedRealtime();
if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
Slog.e(TAG, "Package enqueue rate is " + appEnqueueRate + ". Shedding events. package=" + pkg);
mLastOverRateLogTime = now;
}
return;
}
}
int count = 0;
final int N = mNotificationList.size();
for (int i = 0; i < N; i++) {
final NotificationRecord r = mNotificationList.get(i);
if (r.sbn.getPackageName().equals(pkg) && r.sbn.getUserId() == userId) {
if (r.sbn.getId() == id && TextUtils.equals(r.sbn.getTag(), tag)) {
// Allow updating existing notification
break;
}
count++;
if (count >= MAX_PACKAGE_NOTIFICATIONS) {
mUsageStats.registerOverCountQuota(pkg);
Slog.e(TAG, "Package has already posted " + count + " notifications. Not showing more. package=" + pkg);
return;
}
}
}
}
}
// Whitelist pending intents.
if (notification.allPendingIntents != null) {
final int intentCount = notification.allPendingIntents.size();
if (intentCount > 0) {
final ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
final long duration = LocalServices.getService(DeviceIdleController.LocalService.class).getNotificationWhitelistDuration();
for (int i = 0; i < intentCount; i++) {
PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
if (pendingIntent != null) {
am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(), duration);
}
}
}
}
// Sanitize inputs
notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN, Notification.PRIORITY_MAX);
// setup local book-keeping
final NotificationRecord r = new NotificationRecord(getContext(), n);
mHandler.post(new EnqueueNotificationRunnable(userId, r));
idOut[0] = id;
}
use of android.service.notification.StatusBarNotification in project platform_frameworks_base by android.
the class NotificationManagerService method cancelGroupChildrenLocked.
// Warning: The caller is responsible for invoking updateLightsLocked().
private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid, String listenerName, int reason, boolean sendDelete) {
Notification n = r.getNotification();
if (!n.isGroupSummary()) {
return;
}
String pkg = r.sbn.getPackageName();
int userId = r.getUserId();
if (pkg == null) {
if (DBG)
Log.e(TAG, "No package for group summary: " + r.getKey());
return;
}
final int N = mNotificationList.size();
for (int i = N - 1; i >= 0; i--) {
NotificationRecord childR = mNotificationList.get(i);
StatusBarNotification childSbn = childR.sbn;
if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) && childR.getGroupKey().equals(r.getGroupKey())) {
EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(), childSbn.getTag(), userId, 0, 0, reason, listenerName);
mNotificationList.remove(i);
cancelNotificationLocked(childR, sendDelete, reason);
}
}
}
Aggregations