From 39c992f10047bdfe1c95a8bf578beab36d117ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Bia=C5=82ka?= Date: Thu, 10 Mar 2011 10:27:24 +0100 Subject: [PATCH] Enable notifications during an ongoing call If a phone call is ongoing, the alert will be allowed but only using a special incall notification tone and no vibration. The tone will be played on the voice call audio stream. Also enable customization of the relative volume of the in call notification volume. This allows the level to be changed for different operators using overlays. The requirement behind this is to allow audible SMS/MMS notifications during phone calls, something that is requested by a number of European operators. Bug: 28688969 Change-Id: Ia8ce5c784a847e6759b55e6a78ac2100db47df19 Test: manual --- core/res/res/values/config.xml | 3 + core/res/res/values/symbols.xml | 2 + .../NotificationManagerService.java | 64 +++++++++++++++++-- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index aeb564b49ea8b..8b9b0e2134fa3 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2876,4 +2876,7 @@ false + + 67 diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index cff6eb198473e..658ba57613208 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3011,4 +3011,6 @@ + + diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 70766f907df5f..23a1a78855d56 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -96,6 +96,7 @@ import android.database.ContentObserver; import android.media.AudioManager; import android.media.AudioManagerInternal; import android.media.IRingtonePlayer; +import android.media.ToneGenerator; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -301,6 +302,10 @@ public class NotificationManagerService extends SystemService { private boolean mInCall = false; private boolean mNotificationPulseEnabled; + // for generating notification tones in-call + private ToneGenerator mInCallToneGenerator; + private final Object mInCallToneGeneratorLock = new Object(); + // used as a mutex for access to all active notifications & listeners final Object mNotificationLock = new Object(); final ArrayList mNotificationList = @@ -854,6 +859,30 @@ public class NotificationManagerService extends SystemService { mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE)); updateNotificationPulse(); + synchronized (mInCallToneGeneratorLock) { + if (mInCall) { + if (mInCallToneGenerator == null) { + int relativeToneVolume = getContext().getResources().getInteger( + R.integer.config_inCallNotificationVolumeRelative); + if (relativeToneVolume < ToneGenerator.MIN_VOLUME + || relativeToneVolume > ToneGenerator.MAX_VOLUME) { + relativeToneVolume = ToneGenerator.MAX_VOLUME; + } + try { + mInCallToneGenerator = new ToneGenerator( + AudioManager.STREAM_VOICE_CALL, relativeToneVolume); + } catch (RuntimeException e) { + Log.e(TAG, "Error creating local tone generator: " + e); + mInCallToneGenerator = null; + } + } + } else { + if (mInCallToneGenerator != null) { + mInCallToneGenerator.release(); + mInCallToneGenerator = null; + } + } + } } else if (action.equals(Intent.ACTION_USER_STOPPED)) { int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userHandle >= 0) { @@ -3723,14 +3752,21 @@ public class NotificationManagerService extends SystemService { hasValidVibrate = vibration != null; if (!shouldMuteNotificationLocked(record)) { - sendAccessibilityEvent(notification, record.sbn.getPackageName()); + if (hasValidSound) { mSoundNotificationKey = key; - beep = playSound(record, soundUri); + if (mInCall) { + playInCallNotification(); + beep = true; + } else { + beep = playSound(record, soundUri); + } } - if (hasValidVibrate && !(mAudioManager.getRingerModeInternal() - == AudioManager.RINGER_MODE_SILENT)) { + + final boolean ringerModeSilent = + mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT; + if (!mInCall && hasValidVibrate && !ringerModeSilent) { mVibrateNotificationKey = key; buzz = playVibration(record, vibration); @@ -3839,6 +3875,26 @@ public class NotificationManagerService extends SystemService { } } + private void playInCallNotification() { + new Thread() { + @Override + public void run() { + // If toneGenerator creation fails, just continue the call + // without playing the notification sound. + try { + synchronized (mInCallToneGeneratorLock) { + if (mInCallToneGenerator != null) { + // limit this tone to 1 second; BEEP2 should in fact be much shorter + mInCallToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2, 1000); + } + } + } catch (RuntimeException e) { + Log.w(TAG, "Exception from ToneGenerator: " + e); + } + } + }.start(); + } + void showNextToastLocked() { ToastRecord record = mToastQueue.get(0); while (record != null) {