use of android.media.IRingtonePlayer in project android_frameworks_base by crdroidandroid.
the class NotificationManagerService method buzzBeepBlinkLocked.
@VisibleForTesting
void buzzBeepBlinkLocked(NotificationRecord record) {
boolean buzz = false;
boolean beep = false;
boolean blink = false;
final Notification notification = record.sbn.getNotification();
final String key = record.getKey();
final String pkg = record.sbn.getPackageName();
// Should this notification make noise, vibe, or use the LED?
final boolean aboveThreshold = importanceToLevel(record.getImportance()) >= importanceToLevel(IMPORTANCE_DEFAULT);
final boolean canInterrupt = aboveThreshold && !record.isIntercepted();
if (DBG || record.isIntercepted())
Slog.v(TAG, "pkg=" + pkg + " canInterrupt=" + canInterrupt + " intercept=" + record.isIntercepted());
final int currentUser;
final long token = Binder.clearCallingIdentity();
try {
currentUser = ActivityManager.getCurrentUser();
} finally {
Binder.restoreCallingIdentity(token);
}
// If we're not supposed to beep, vibrate, etc. then don't.
final String disableEffects = disableNotificationEffects(record);
if (disableEffects != null) {
ZenLog.traceDisableEffects(record, disableEffects);
}
// Remember if this notification already owns the notification channels.
boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey);
// These are set inside the conditional if the notification is allowed to make noise.
boolean hasValidVibrate = false;
boolean hasValidSound = false;
boolean readyForBeepOrBuzz = disableEffects == null && (record.getUserId() == UserHandle.USER_ALL || record.getUserId() == currentUser || mUserProfiles.isCurrentProfile(record.getUserId())) && !isInSoundTimeoutPeriod(record) && mSystemReady && !notificationIsAnnoying(pkg) && mAudioManager != null;
boolean canBeep = readyForBeepOrBuzz && canInterrupt;
boolean canBuzz = readyForBeepOrBuzz && (canInterrupt || (aboveThreshold && mZenModeHelper.allowVibrationForNotifications()));
if (canBeep || canBuzz) {
if (DBG)
Slog.v(TAG, "Interrupting!");
// 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;
if (useDefaultSound) {
soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
// check to see if the default notification sound is silent
hasValidSound = mSystemNotificationSound != null;
} else if (notification.sound != null) {
soundUri = notification.sound;
hasValidSound = (soundUri != null);
}
// 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 && hasValidSound && (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
// The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
final boolean useDefaultVibrate = (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
hasValidVibrate = useDefaultVibrate || convertSoundToVibration || hasCustomVibrate;
// it once, and we already have, then don't.
if (!(record.isUpdate && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) {
sendAccessibilityEvent(notification, record.sbn.getPackageName());
if (canBeep && hasValidSound) {
boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
AudioAttributes audioAttributes = audioAttributesForNotification(notification);
mSoundNotificationKey = key;
// ringer mode is silent) or if there is a user of exclusive audio focus
if ((mAudioManager.getStreamVolume(AudioAttributes.toLegacyStreamType(audioAttributes)) != 0) && !mAudioManager.isAudioFocusExclusive()) {
final long identity = Binder.clearCallingIdentity();
try {
final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
if (player != null) {
if (DBG)
Slog.v(TAG, "Playing sound " + soundUri + " with attributes " + audioAttributes);
player.playAsync(soundUri, record.sbn.getUser(), looping, audioAttributes);
beep = true;
}
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
if (canBuzz && hasValidVibrate && mAudioManager.getRingerModeInternal() != AudioManager.RINGER_MODE_SILENT) {
mVibrateNotificationKey = key;
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(record.sbn.getUid(), record.sbn.getOpPkg(), useDefaultVibrate ? mDefaultVibrationPattern : mFallbackVibrationPattern, ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1, audioAttributesForNotification(notification));
buzz = true;
} finally {
Binder.restoreCallingIdentity(identity);
}
} else if (notification.vibrate.length > 1) {
// If you want your own vibration pattern, you need the VIBRATE
// permission
mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), notification.vibrate, ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1, audioAttributesForNotification(notification));
buzz = true;
}
}
}
}
// cancel that feedback now
if (wasBeep && !hasValidSound) {
clearSoundLocked();
}
if (wasBuzz && !hasValidVibrate) {
clearVibrateLocked();
}
// light
// release the light
boolean wasShowLights = mLights.remove(key);
final boolean canInterruptWithLight = canInterrupt || isLedNotificationForcedOn(record) || (!canInterrupt && mZenModeHelper.getAllowLights());
if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterruptWithLight && ((record.getSuppressedVisualEffects() & NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) == 0)) {
mLights.add(key);
updateLightsLocked();
if (mUseAttentionLight) {
mAttentionLight.pulse();
}
blink = true;
} else if (wasShowLights) {
updateLightsLocked();
}
if (buzz || beep) {
mLastSoundTimestamps.put(generateLastSoundTimeoutKey(record), SystemClock.elapsedRealtime());
}
if (buzz || beep || blink) {
if (((record.getSuppressedVisualEffects() & NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) != 0)) {
if (DBG)
Slog.v(TAG, "Suppressed SystemUI from triggering screen on");
} else {
EventLogTags.writeNotificationAlert(key, buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
mHandler.post(mBuzzBeepBlinked);
}
}
}
use of android.media.IRingtonePlayer in project android_frameworks_base by crdroidandroid.
the class NotificationManagerService method cancelNotificationLocked.
private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, int reason) {
// Record caller.
recordCallerLocked(r);
// tell the app
if (sendDelete) {
if (r.getNotification().deleteIntent != null) {
try {
r.getNotification().deleteIntent.send();
} catch (PendingIntent.CanceledException ex) {
// do nothing - there's no relevant way to recover, and
// no reason to let this propagate
Slog.w(TAG, "canceled PendingIntent for " + r.sbn.getPackageName(), ex);
}
}
}
// status bar
if (r.getNotification().getSmallIcon() != null) {
r.isCanceled = true;
mListeners.notifyRemoved(r.sbn);
}
final String canceledKey = r.getKey();
// sound
if (canceledKey.equals(mSoundNotificationKey)) {
mSoundNotificationKey = null;
final long identity = Binder.clearCallingIdentity();
try {
final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
if (player != null) {
player.stopAsync();
}
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(identity);
}
}
// vibrate
if (canceledKey.equals(mVibrateNotificationKey)) {
mVibrateNotificationKey = null;
long identity = Binder.clearCallingIdentity();
try {
mVibrator.cancel();
} finally {
Binder.restoreCallingIdentity(identity);
}
}
// light
mLights.remove(canceledKey);
// TODO: add unbundling stats?
switch(reason) {
case REASON_DELEGATE_CANCEL:
case REASON_DELEGATE_CANCEL_ALL:
case REASON_LISTENER_CANCEL:
case REASON_LISTENER_CANCEL_ALL:
mUsageStats.registerDismissedByUser(r);
break;
case REASON_APP_CANCEL:
case REASON_APP_CANCEL_ALL:
mUsageStats.registerRemovedByApp(r);
break;
}
mNotificationsByKey.remove(r.sbn.getKey());
String groupKey = r.getGroupKey();
NotificationRecord groupSummary = mSummaryByGroupKey.get(groupKey);
if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) {
mSummaryByGroupKey.remove(groupKey);
}
final ArrayMap<String, String> summaries = mAutobundledSummaries.get(r.sbn.getUserId());
if (summaries != null && r.sbn.getKey().equals(summaries.get(r.sbn.getPackageName()))) {
summaries.remove(r.sbn.getPackageName());
}
// Save it for users of getHistoricalNotifications()
mArchive.record(r.sbn);
final long now = System.currentTimeMillis();
EventLogTags.writeNotificationCanceled(canceledKey, reason, r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now));
}
Aggregations