Search in sources :

Example 1 with AudioAttributes

use of android.media.AudioAttributes in project android_frameworks_base by ResurrectionRemix.

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);
        }
    }
}
Also used : AudioAttributes(android.media.AudioAttributes) IRingtonePlayer(android.media.IRingtonePlayer) RemoteException(android.os.RemoteException) Uri(android.net.Uri) ITransientNotification(android.app.ITransientNotification) Notification(android.app.Notification) StatusBarNotification(android.service.notification.StatusBarNotification) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 2 with AudioAttributes

use of android.media.AudioAttributes in project android_frameworks_base by DirtyUnicorns.

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 = record.getImportance() >= 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;
    if (disableEffects == null && (record.getUserId() == UserHandle.USER_ALL || record.getUserId() == currentUser || mUserProfiles.isCurrentProfile(record.getUserId())) && canInterrupt && mSystemReady && !notificationIsAnnoying(pkg) && mAudioManager != null) {
        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 (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 (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.getAreLightsAllowed());
    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 || 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);
        }
    }
}
Also used : AudioAttributes(android.media.AudioAttributes) IRingtonePlayer(android.media.IRingtonePlayer) RemoteException(android.os.RemoteException) Uri(android.net.Uri) ITransientNotification(android.app.ITransientNotification) Notification(android.app.Notification) StatusBarNotification(android.service.notification.StatusBarNotification) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 3 with AudioAttributes

use of android.media.AudioAttributes in project android_frameworks_base by DirtyUnicorns.

the class VibratorService method doVibratorOn.

private void doVibratorOn(long millis, int uid, int usageHint) {
    synchronized (mInputDeviceVibrators) {
        if (DEBUG) {
            Slog.d(TAG, "Turning vibrator on for " + millis + " ms.");
        }
        try {
            mBatteryStatsService.noteVibratorOn(uid, millis);
            mCurVibUid = uid;
        } catch (RemoteException e) {
        }
        final int vibratorCount = mInputDeviceVibrators.size();
        if (vibratorCount != 0) {
            final AudioAttributes attributes = new AudioAttributes.Builder().setUsage(usageHint).build();
            for (int i = 0; i < vibratorCount; i++) {
                mInputDeviceVibrators.get(i).vibrate(millis, attributes);
            }
        } else {
            vibratorOn(millis);
        }
    }
}
Also used : AudioAttributes(android.media.AudioAttributes) RemoteException(android.os.RemoteException)

Example 4 with AudioAttributes

use of android.media.AudioAttributes in project Applozic-Android-SDK by AppLozic.

the class RegisterUserClientService method createNotificationChannel.

@RequiresApi(api = Build.VERSION_CODES.O)
void createNotificationChannel(Context context) {
    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    CharSequence name = MobiComKitConstants.PUSH_NOTIFICATION_NAME;
    ;
    int importance = NotificationManager.IMPORTANCE_HIGH;
    if (mNotificationManager.getNotificationChannel(MobiComKitConstants.AL_PUSH_NOTIFICATION) == null) {
        NotificationChannel mChannel = new NotificationChannel(MobiComKitConstants.AL_PUSH_NOTIFICATION, name, importance);
        mChannel.enableLights(true);
        mChannel.setLightColor(Color.GREEN);
        if (ApplozicClient.getInstance(context).isUnreadCountBadgeEnabled()) {
            mChannel.setShowBadge(true);
        } else {
            mChannel.setShowBadge(false);
        }
        if (ApplozicClient.getInstance(context).getVibrationOnNotification()) {
            mChannel.enableVibration(true);
            mChannel.setVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
        }
        AudioAttributes audioAttributes = new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE).build();
        mChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), audioAttributes);
        mNotificationManager.createNotificationChannel(mChannel);
    }
}
Also used : NotificationChannel(android.app.NotificationChannel) NotificationManager(android.app.NotificationManager) AudioAttributes(android.media.AudioAttributes) RequiresApi(android.support.annotation.RequiresApi)

Example 5 with AudioAttributes

use of android.media.AudioAttributes in project android_packages_apps_Dialer by LineageOS.

the class StatusBarNotifier method buildAndSendNotification.

/**
 * Sets up the main Ui for the notification
 */
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
private void buildAndSendNotification(CallList callList, DialerCall originalCall, ContactCacheEntry contactInfo) {
    // This can get called to update an existing notification after contact information has come
    // back. However, it can happen much later. Before we continue, we need to make sure that
    // the call being passed in is still the one we want to show in the notification.
    final DialerCall call = getCallToShow(callList);
    if (call == null || !call.getId().equals(originalCall.getId())) {
        return;
    }
    final int callState = call.getState();
    // Check if data has changed; if nothing is different, don't issue another notification.
    final int iconResId = getIconToDisplay(call);
    Bitmap largeIcon = getLargeIconToDisplay(mContext, contactInfo, call);
    final String content = getContentString(call, contactInfo.userType);
    final String contentTitle = getContentTitle(contactInfo, call);
    final boolean isVideoUpgradeRequest = call.getVideoTech().getSessionModificationState() == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
    final int notificationType;
    if (callState == DialerCall.State.INCOMING || callState == DialerCall.State.CALL_WAITING || isVideoUpgradeRequest) {
        if (ConfigProviderBindings.get(mContext).getBoolean("quiet_incoming_call_if_ui_showing", true)) {
            notificationType = InCallPresenter.getInstance().isShowingInCallUi() ? NOTIFICATION_INCOMING_CALL_QUIET : NOTIFICATION_INCOMING_CALL;
        } else {
            boolean alreadyActive = callList.getActiveOrBackgroundCall() != null && InCallPresenter.getInstance().isShowingInCallUi();
            notificationType = alreadyActive ? NOTIFICATION_INCOMING_CALL_QUIET : NOTIFICATION_INCOMING_CALL;
        }
    } else {
        notificationType = NOTIFICATION_IN_CALL;
    }
    if (!checkForChangeAndSaveData(iconResId, content, largeIcon, contentTitle, callState, notificationType, contactInfo.contactRingtoneUri)) {
        return;
    }
    if (largeIcon != null) {
        largeIcon = getRoundedIcon(largeIcon);
    }
    // This builder is used for the notification shown when the device is locked and the user
    // has set their notification settings to 'hide sensitive content'
    // {@see Notification.Builder#setPublicVersion}.
    Notification.Builder publicBuilder = new Notification.Builder(mContext);
    publicBuilder.setSmallIcon(iconResId).setColor(mContext.getResources().getColor(R.color.dialer_theme_color, mContext.getTheme())).setContentTitle(getContentString(call, ContactsUtils.USER_TYPE_CURRENT));
    setNotificationWhen(call, callState, publicBuilder);
    // Builder for the notification shown when the device is unlocked or the user has set their
    // notification settings to 'show all notification content'.
    final Notification.Builder builder = getNotificationBuilder();
    builder.setPublicVersion(publicBuilder.build());
    // Set up the main intent to send the user to the in-call screen
    builder.setContentIntent(createLaunchPendingIntent(false));
    // Set the intent as a full screen intent as well if a call is incoming
    PhoneAccountHandle accountHandle = call.getAccountHandle();
    if (accountHandle == null) {
        accountHandle = getAnyPhoneAccount();
    }
    LogUtil.i("StatusBarNotifier.buildAndSendNotification", "notificationType=" + notificationType);
    switch(notificationType) {
        case NOTIFICATION_INCOMING_CALL:
            if (BuildCompat.isAtLeastO()) {
                builder.setChannelId(NotificationChannelId.INCOMING_CALL);
            }
            configureFullScreenIntent(builder, createLaunchPendingIntent(true));
            // Set the notification category and bump the priority for incoming calls
            builder.setCategory(Notification.CATEGORY_CALL);
            // This will be ignored on O+ and handled by the channel
            builder.setPriority(Notification.PRIORITY_MAX);
            if (mCurrentNotification != NOTIFICATION_INCOMING_CALL) {
                LogUtil.i("StatusBarNotifier.buildAndSendNotification", "Canceling old notification so this one can be noisy");
                // Moving from a non-interuptive notification (or none) to a noisy one. Cancel the old
                // notification (if there is one) so the fullScreenIntent or HUN will show
                mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
            }
            break;
        case NOTIFICATION_INCOMING_CALL_QUIET:
            if (BuildCompat.isAtLeastO()) {
                builder.setChannelId(NotificationChannelId.ONGOING_CALL);
            }
            break;
        case NOTIFICATION_IN_CALL:
            if (BuildCompat.isAtLeastO()) {
                publicBuilder.setColorized(true);
                builder.setColorized(true);
                builder.setChannelId(NotificationChannelId.ONGOING_CALL);
            }
            break;
    }
    // Set the content
    builder.setContentText(content);
    builder.setSmallIcon(iconResId);
    builder.setContentTitle(contentTitle);
    builder.setLargeIcon(largeIcon);
    builder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color, mContext.getTheme()));
    if (isVideoUpgradeRequest) {
        builder.setUsesChronometer(false);
        addDismissUpgradeRequestAction(builder);
        addAcceptUpgradeRequestAction(builder);
    } else {
        createIncomingCallNotification(call, callState, builder);
    }
    addPersonReference(builder, contactInfo, call);
    // Fire off the notification
    Notification notification = builder.build();
    if (mDialerRingtoneManager.shouldPlayRingtone(callState, contactInfo.contactRingtoneUri)) {
        notification.flags |= Notification.FLAG_INSISTENT;
        notification.sound = contactInfo.contactRingtoneUri;
        AudioAttributes.Builder audioAttributes = new AudioAttributes.Builder();
        audioAttributes.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC);
        audioAttributes.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
        notification.audioAttributes = audioAttributes.build();
        if (mDialerRingtoneManager.shouldVibrate(mContext.getContentResolver())) {
            notification.vibrate = VIBRATE_PATTERN;
        }
    }
    if (mDialerRingtoneManager.shouldPlayCallWaitingTone(callState)) {
        LogUtil.v("StatusBarNotifier.buildAndSendNotification", "playing call waiting tone");
        mDialerRingtoneManager.playCallWaitingTone();
    }
    LogUtil.i("StatusBarNotifier.buildAndSendNotification", "displaying notification for " + notificationType);
    try {
        mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notification);
    } catch (RuntimeException e) {
        // TODO(b/34744003): Move the memory stats into silent feedback PSD.
        ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        activityManager.getMemoryInfo(memoryInfo);
        throw new RuntimeException(String.format(Locale.US, "Error displaying notification with photo type: %d (low memory? %b, availMem: %d)", contactInfo.photoType, memoryInfo.lowMemory, memoryInfo.availMem), e);
    }
    call.getLatencyReport().onNotificationShown();
    mCurrentNotification = notificationType;
}
Also used : PhoneAccountHandle(android.telecom.PhoneAccountHandle) AudioAttributes(android.media.AudioAttributes) SpannableString(android.text.SpannableString) ActivityManager(android.app.ActivityManager) Notification(android.app.Notification) Bitmap(android.graphics.Bitmap) DialerCall(com.android.incallui.call.DialerCall) RequiresPermission(android.support.annotation.RequiresPermission)

Aggregations

AudioAttributes (android.media.AudioAttributes)42 NotificationChannel (android.app.NotificationChannel)10 RemoteException (android.os.RemoteException)10 Notification (android.app.Notification)9 Uri (android.net.Uri)9 TargetApi (android.annotation.TargetApi)7 NotificationManager (android.app.NotificationManager)6 Test (org.junit.Test)6 Config (org.robolectric.annotation.Config)6 ITransientNotification (android.app.ITransientNotification)5 IRingtonePlayer (android.media.IRingtonePlayer)5 StatusBarNotification (android.service.notification.StatusBarNotification)5 VisibleForTesting (com.android.internal.annotations.VisibleForTesting)5 SoundPool (android.media.SoundPool)4 PendingIntent (android.app.PendingIntent)3 AudioManager (android.media.AudioManager)3 AudioPlaybackConfiguration (android.media.AudioPlaybackConfiguration)3 RequiresApi (android.support.annotation.RequiresApi)3 NotificationChannelGroup (android.app.NotificationChannelGroup)2 Intent (android.content.Intent)2