use of android.service.notification.StatusBarNotification in project android_frameworks_base by ParanoidAndroid.
the class NotificationManagerService method dump.
// ======================================================================
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump NotificationManager from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
return;
}
pw.println("Current Notification Manager state:");
pw.println(" Listeners (" + mEnabledListenersForCurrentUser.size() + ") enabled for current user:");
for (ComponentName cmpt : mEnabledListenersForCurrentUser) {
pw.println(" " + cmpt);
}
pw.println(" Live listeners (" + mListeners.size() + "):");
for (NotificationListenerInfo info : mListeners) {
pw.println(" " + info.component + " (user " + info.userid + "): " + info.listener + (info.isSystem ? " SYSTEM" : ""));
}
int N;
synchronized (mToastQueue) {
N = mToastQueue.size();
if (N > 0) {
pw.println(" Toast Queue:");
for (int i = 0; i < N; i++) {
mToastQueue.get(i).dump(pw, " ");
}
pw.println(" ");
}
}
synchronized (mNotificationList) {
N = mNotificationList.size();
if (N > 0) {
pw.println(" Notification List:");
for (int i = 0; i < N; i++) {
mNotificationList.get(i).dump(pw, " ", mContext);
}
pw.println(" ");
}
N = mLights.size();
if (N > 0) {
pw.println(" Lights List:");
for (int i = 0; i < N; i++) {
pw.println(" " + mLights.get(i));
}
pw.println(" ");
}
pw.println(" mSoundNotification=" + mSoundNotification);
pw.println(" mVibrateNotification=" + mVibrateNotification);
pw.println(" mLedNotification=" + mLedNotification);
pw.println(" mDisabledNotifications=0x" + Integer.toHexString(mDisabledNotifications));
pw.println(" mSystemReady=" + mSystemReady);
pw.println(" mArchive=" + mArchive.toString());
Iterator<StatusBarNotification> iter = mArchive.descendingIterator();
int i = 0;
while (iter.hasNext()) {
pw.println(" " + iter.next());
if (++i >= 5) {
if (iter.hasNext())
pw.println(" ...");
break;
}
}
}
}
use of android.service.notification.StatusBarNotification in project android_frameworks_base by ParanoidAndroid.
the class NotificationManagerService method enqueueNotificationInternal.
// Not exposed via Binder; for system use only (otherwise malicious apps could spoof the
// uid/pid of another application)
public void enqueueNotificationInternal(String pkg, String basePkg, int callingUid, int callingPid, String tag, int id, Notification notification, int[] idOut, int userId) {
if (DBG) {
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
checkCallerIsSystemOrSameApp(pkg);
final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
userId = ActivityManager.handleIncomingUser(callingPid, callingUid, userId, true, false, "enqueueNotification", pkg);
final UserHandle user = new UserHandle(userId);
// package can enqueue. Prevents DOS attacks and deals with leaks.
if (!isSystemNotification) {
synchronized (mNotificationList) {
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) {
count++;
if (count >= MAX_PACKAGE_NOTIFICATIONS) {
Slog.e(TAG, "Package has already posted " + count + " notifications. Not showing more. package=" + pkg);
return;
}
}
}
}
}
// behalf of the download manager without affecting other apps.
if (!pkg.equals("com.android.providers.downloads") || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId, notification.toString());
}
if (pkg == null || notification == null) {
throw new IllegalArgumentException("null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
if (notification.icon != 0) {
if (notification.contentView == null) {
throw new IllegalArgumentException("contentView required: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
}
// === Scoring ===
// 0. Sanitize inputs
notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN, Notification.PRIORITY_MAX);
// Migrate notification flags to scores
if (0 != (notification.flags & Notification.FLAG_HIGH_PRIORITY)) {
if (notification.priority < Notification.PRIORITY_MAX)
notification.priority = Notification.PRIORITY_MAX;
} else if (SCORE_ONGOING_HIGHER && 0 != (notification.flags & Notification.FLAG_ONGOING_EVENT)) {
if (notification.priority < Notification.PRIORITY_HIGH)
notification.priority = Notification.PRIORITY_HIGH;
}
// 1. initial score: buckets of 10, around the app
//[-20..20]
int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER;
// blocked apps
if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
if (!isSystemNotification) {
score = JUNK_SCORE;
Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
}
}
if (DBG) {
Slog.v(TAG, "Assigned score=" + score + " to " + notification);
}
if (score < SCORE_DISPLAY_THRESHOLD) {
// Notification will be blocked because the score is too low.
return;
}
// Should this notification make noise, vibe, or use the LED?
final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
synchronized (mNotificationList) {
final boolean inQuietHours = inQuietHours();
final StatusBarNotification n = new StatusBarNotification(pkg, id, tag, callingUid, callingPid, score, notification, user);
NotificationRecord r = new NotificationRecord(n);
NotificationRecord old = null;
int index = indexOfNotificationLocked(pkg, tag, id, userId);
if (index < 0) {
mNotificationList.add(r);
} else {
old = mNotificationList.remove(index);
mNotificationList.add(index, r);
// Make sure we don't lose the foreground service state.
if (old != null) {
notification.flags |= old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
}
}
// flags are set.
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
}
final int currentUser;
final long token = Binder.clearCallingIdentity();
try {
currentUser = ActivityManager.getCurrentUser();
} finally {
Binder.restoreCallingIdentity(token);
}
if (notification.icon != 0) {
if (old != null && old.statusBarKey != null) {
r.statusBarKey = old.statusBarKey;
long identity = Binder.clearCallingIdentity();
try {
mStatusBar.updateNotification(r.statusBarKey, n);
} finally {
Binder.restoreCallingIdentity(identity);
}
} else {
long identity = Binder.clearCallingIdentity();
try {
r.statusBarKey = mStatusBar.addNotification(n);
if ((n.getNotification().flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterrupt) {
mAttentionLight.pulse();
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
// Send accessibility events only for the current user.
if (currentUser == userId) {
sendAccessibilityEvent(notification, pkg);
}
notifyPostedLocked(r);
} else {
Slog.e(TAG, "Not posting notification with icon==0: " + notification);
if (old != null && old.statusBarKey != null) {
long identity = Binder.clearCallingIdentity();
try {
mStatusBar.removeNotification(old.statusBarKey);
} finally {
Binder.restoreCallingIdentity(identity);
}
notifyRemovedLocked(r);
}
// ATTENTION: in a future release we will bail out here
// so that we do not play sounds, show lights, etc. for invalid notifications
Slog.e(TAG, "WARNING: In a future release this will crash the app: " + n.getPackageName());
}
// If we're not supposed to beep, vibrate, etc. then don't.
if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0) && (!(old != null && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) && !isOverNotifSoundThreshold(pkg) && (r.getUserId() == UserHandle.USER_ALL || (r.getUserId() == userId && r.getUserId() == currentUser)) && canInterrupt && mSystemReady) {
final AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
// sound
// should we use the default notification sound? (indicated either by DEFAULT_SOUND
// or because notification.sound is pointing at Settings.System.NOTIFICATION_SOUND)
final boolean useDefaultSound = (notification.defaults & Notification.DEFAULT_SOUND) != 0 || Settings.System.DEFAULT_NOTIFICATION_URI.equals(notification.sound);
Uri soundUri = null;
boolean hasValidSound = false;
if (!(inQuietHours && mQuietHoursMute) && useDefaultSound) {
soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
// check to see if the default notification sound is silent
ContentResolver resolver = mContext.getContentResolver();
hasValidSound = Settings.System.getString(resolver, Settings.System.NOTIFICATION_SOUND) != null;
} else if (!(inQuietHours && mQuietHoursMute) && notification.sound != null) {
soundUri = notification.sound;
hasValidSound = (soundUri != null);
}
if (hasValidSound) {
boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
int audioStreamType;
if (notification.audioStreamType >= 0) {
audioStreamType = notification.audioStreamType;
} else {
audioStreamType = DEFAULT_STREAM_TYPE;
}
mSoundNotification = r;
// (typically because ringer mode is silent) or if speech recognition is active.
if ((audioManager.getStreamVolume(audioStreamType) != 0) && !audioManager.isSpeechRecognitionActive()) {
final long identity = Binder.clearCallingIdentity();
try {
final IRingtonePlayer player = mAudioService.getRingtonePlayer();
if (player != null) {
player.playAsync(soundUri, user, looping, audioStreamType);
}
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
// vibrate
// Does the notification want to specify its own vibration?
final boolean hasCustomVibrate = notification.vibrate != null;
// new in 4.2: if there was supposed to be a sound and we're in vibrate mode,
// and no other vibration is specified, we fall back to vibration
final boolean convertSoundToVibration = !hasCustomVibrate && (useDefaultSound || notification.sound != null) && (audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) && (Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIFICATION_CONVERT_SOUND_TO_VIBRATION, 1) != 0);
// The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
final boolean useDefaultVibrate = (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
if (!(inQuietHours && mQuietHoursStill) && (useDefaultVibrate || convertSoundToVibration || hasCustomVibrate) && !(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) {
mVibrateNotification = r;
if (useDefaultVibrate || convertSoundToVibration) {
// Escalate privileges so we can use the vibrator even if the notifying app
// does not have the VIBRATE permission.
long identity = Binder.clearCallingIdentity();
try {
mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(), useDefaultVibrate ? mDefaultVibrationPattern : mFallbackVibrationPattern, ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1);
} finally {
Binder.restoreCallingIdentity(identity);
}
} else if (notification.vibrate.length > 1) {
// If you want your own vibration pattern, you need the VIBRATE permission
mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(), notification.vibrate, ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1);
}
}
}
// light
// the most recent thing gets the light
mLights.remove(old);
if (mLedNotification == old) {
mLedNotification = null;
}
// + ((old.notification.lights.flags & Notification.FLAG_SHOW_LIGHTS) != 0));
if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterrupt) {
mLights.add(r);
// force reevaluation of active light
mLedNotification = null;
updateLightsLocked();
} else {
if (old != null && ((old.getFlags() & Notification.FLAG_SHOW_LIGHTS) != 0)) {
updateLightsLocked();
}
}
}
idOut[0] = id;
}
use of android.service.notification.StatusBarNotification in project android-common by litesuits.
the class NotificationService method onNotificationPosted.
/*----------------- 通知回调 -----------------*/
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
if (Log.isPrint) {
Log.i(TAG, sbn.toString());
Notification notification = sbn.getNotification();
Log.i(TAG, "tickerText : " + notification.tickerText);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Bundle bundle = notification.extras;
for (String key : bundle.keySet()) {
Log.i(TAG, key + ": " + bundle.get(key));
}
}
}
if (self != null && notificationListener != null) {
notificationListener.onNotificationPosted(sbn);
}
}
use of android.service.notification.StatusBarNotification in project NotificationPeekPort by lzanita09.
the class NotificationPeekActivity method updateNotification.
/**
* Update notification views upon each swipe, moving the next latest notification to 'Current
* Notification' spot, and remove it from the small icon container.
*
* @param description Description of the StatusBarNotification we just swiped.
* @return True if the update is successful, i.e there is more than one unread notification.
* False if the notification we just swipe away is the last unread notification.
*/
private boolean updateNotification(String description) {
int currentNotificationIdex = getCurrentNotificationIndex(mNotificationsContainer, description);
// Remove the current notification from container.
mNotificationsContainer.removeViewAt(currentNotificationIdex);
int nextNotificationIndex = mNotificationsContainer.getChildCount() - 1;
// We have more than one unread notification.
if (nextNotificationIndex >= 0) {
StatusBarNotification nextNotification = (StatusBarNotification) mNotificationsContainer.getChildAt(nextNotificationIndex).getTag();
if (nextNotification.getNotification().largeIcon != null) {
mNotificationIcon.setImageDrawable(NotificationPeekViewUtils.getRoundedShape(getResources(), nextNotification.getNotification().largeIcon));
} else {
mNotificationIcon.setImageDrawable(NotificationPeekViewUtils.getIconFromResource(this, nextNotification));
}
mNotificationText.setText(NotificationPeekViewUtils.getNotificationDisplayText(this, nextNotification));
// Animate back icon and text.
mNotificationView.setTranslationX(0);
mNotificationView.animate().alpha(1f).start();
// Set new tag.
mNotificationView.setTag(nextNotification);
mPeek.getNotificationHub().setCurrentNotification(nextNotification);
final PendingIntent contentIntent = nextNotification.getNotification().contentIntent;
if (contentIntent != null) {
NotificationClicker mNotificationClicker = new NotificationClicker(this, contentIntent, mPeek);
mNotificationIcon.setOnClickListener(mNotificationClicker);
} else {
mNotificationIcon.setOnClickListener(null);
}
if (nextNotificationIndex == 0) {
// As we already moved the next notification to 'Current Notification' spot, we need
// to hide it too if there is only one unread notification left.
mNotificationsContainer.getChildAt(nextNotificationIndex).setVisibility(View.GONE);
} else {
// Otherwise, highlight that icon.
mNotificationsContainer.getChildAt(nextNotificationIndex).setAlpha(1);
}
// Recover TextView alpha, because we will still have notification(s) to show.
mPeek.updateNotificationTextAlpha(1);
return true;
}
// The only unread notification is swiped away.
return false;
}
use of android.service.notification.StatusBarNotification in project NotificationPeekPort by lzanita09.
the class NotificationPeekActivity method updateNotificationIcons.
/**
* Update small notification icons when there is new notification coming, and the
* Activity is in foreground.
*/
private void updateNotificationIcons() {
if (mNotificationsContainer.getVisibility() != View.VISIBLE) {
mNotificationsContainer.setVisibility(View.VISIBLE);
}
NotificationHub notificationHub = NotificationHub.getInstance();
int iconSize = getResources().getDimensionPixelSize(R.dimen.small_notification_icon_size);
int padding = getResources().getDimensionPixelSize(R.dimen.small_notification_icon_padding);
final StatusBarNotification n = notificationHub.getCurrentNotification();
ImageView icon = new ImageView(this);
icon.setAlpha(NotificationPeek.ICON_LOW_OPACITY);
icon.setPadding(padding, 0, padding, 0);
icon.setImageDrawable(NotificationPeekViewUtils.getIconFromResource(this, n));
icon.setTag(n);
restoreFirstIconVisibility();
int oldIndex = getOldIconViewIndex(notificationHub);
if (oldIndex >= 0) {
mNotificationsContainer.removeViewAt(oldIndex);
}
mNotificationsContainer.addView(icon);
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(iconSize, iconSize);
// Wrap LayoutParams to GridLayout.LayoutParams.
GridLayout.LayoutParams gridLayoutParams = new GridLayout.LayoutParams(linearLayoutParams);
icon.setLayoutParams(gridLayoutParams);
}
Aggregations