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
This commit is contained in:
Marta Białka
2011-03-10 10:27:24 +01:00
committed by Dan Sandler
parent 7cf5f74f3f
commit 39c992f100
3 changed files with 65 additions and 4 deletions

View File

@@ -2876,4 +2876,7 @@
<!-- Handle volume keys directly in Window Manager without passing them to the foreground app -->
<bool name="config_handleVolumeKeysInWindowManager">false</bool>
<!-- Volume level of in-call notification tone playback,
relative to the overall voice call stream volume [0..100] -->
<integer name="config_inCallNotificationVolumeRelative">67</integer>
</resources>

View File

@@ -3011,4 +3011,6 @@
<java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
<java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
<java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
</resources>

View File

@@ -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<NotificationRecord> 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) {