Migrate ringtone playback to SystemUI.
Introduce IRingtonePlayer, which handles playback for both Ringtone
objects and Notifications. SystemUI now hosts this player, which it
registers with AudioService. It also keeps MediaPlayer instances
warm, and cleans them up after stop() or Binder death.
Move both Ringtone and NotificationManagerService to play back audio
through this new interface.
Bug: 6376128, 6350773
Change-Id: I1dcb86d16ee3c4f07cdb2248d33dcff4ead3609a
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 1ba7e79..663a031 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -16,16 +16,15 @@
package com.android.server;
-import com.android.internal.os.AtomicFile;
-import com.android.internal.statusbar.StatusBarNotification;
-import com.android.internal.util.FastXmlSerializer;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
@@ -39,8 +38,8 @@
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
-import android.net.NetworkPolicy;
-import android.net.NetworkTemplate;
+import android.media.IAudioService;
+import android.media.IRingtonePlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
@@ -48,6 +47,7 @@
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserId;
import android.os.Vibrator;
import android.provider.Settings;
@@ -61,6 +61,14 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
+import com.android.internal.os.AtomicFile;
+import com.android.internal.statusbar.StatusBarNotification;
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -74,18 +82,6 @@
import libcore.io.IoUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import static android.net.NetworkPolicyManager.POLICY_NONE;
-import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeBooleanAttribute;
-import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeIntAttribute;
-import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeLongAttribute;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.END_TAG;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
/** {@hide} */
public class NotificationManagerService extends INotificationManager.Stub
@@ -126,12 +122,13 @@
private int mDefaultNotificationLedOn;
private int mDefaultNotificationLedOff;
- private NotificationRecord mSoundNotification;
- private NotificationPlayer mSound;
private boolean mSystemReady;
private int mDisabledNotifications;
+ private NotificationRecord mSoundNotification;
private NotificationRecord mVibrateNotification;
+
+ private IAudioService mAudioService;
private Vibrator mVibrator;
// for enabling and disabling notification pulse behavior
@@ -409,17 +406,19 @@
// cancel whatever's going on
long identity = Binder.clearCallingIdentity();
try {
- mSound.stop();
- }
- finally {
+ final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+ if (player != null) {
+ player.stopAsync();
+ }
+ } catch (RemoteException e) {
+ } finally {
Binder.restoreCallingIdentity(identity);
}
identity = Binder.clearCallingIdentity();
try {
mVibrator.cancel();
- }
- finally {
+ } finally {
Binder.restoreCallingIdentity(identity);
}
}
@@ -445,11 +444,15 @@
synchronized (mNotificationList) {
// sound
mSoundNotification = null;
+
long identity = Binder.clearCallingIdentity();
try {
- mSound.stop();
- }
- finally {
+ final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+ if (player != null) {
+ player.stopAsync();
+ }
+ } catch (RemoteException e) {
+ } finally {
Binder.restoreCallingIdentity(identity);
}
@@ -458,8 +461,7 @@
identity = Binder.clearCallingIdentity();
try {
mVibrator.cancel();
- }
- finally {
+ } finally {
Binder.restoreCallingIdentity(identity);
}
@@ -570,8 +572,6 @@
mContext = context;
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
mAm = ActivityManagerNative.getDefault();
- mSound = new NotificationPlayer(TAG);
- mSound.setUsesWakeLock(context);
mToastQueue = new ArrayList<ToastRecord>();
mHandler = new WorkerHandler();
@@ -622,6 +622,9 @@
}
void systemReady() {
+ mAudioService = IAudioService.Stub.asInterface(
+ ServiceManager.getService(Context.AUDIO_SERVICE));
+
// no beeping until we're basically done booting
mSystemReady = true;
}
@@ -1026,11 +1029,14 @@
// do not play notifications if stream volume is 0
// (typically because ringer mode is silent).
if (audioManager.getStreamVolume(audioStreamType) != 0) {
- long identity = Binder.clearCallingIdentity();
+ final long identity = Binder.clearCallingIdentity();
try {
- mSound.play(mContext, uri, looping, audioStreamType);
- }
- finally {
+ final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+ if (player != null) {
+ player.playAsync(uri, looping, audioStreamType);
+ }
+ } catch (RemoteException e) {
+ } finally {
Binder.restoreCallingIdentity(identity);
}
}
@@ -1121,11 +1127,14 @@
// sound
if (mSoundNotification == r) {
mSoundNotification = null;
- long identity = Binder.clearCallingIdentity();
+ final long identity = Binder.clearCallingIdentity();
try {
- mSound.stop();
- }
- finally {
+ final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+ if (player != null) {
+ player.stopAsync();
+ }
+ } catch (RemoteException e) {
+ } finally {
Binder.restoreCallingIdentity(identity);
}
}
@@ -1386,7 +1395,6 @@
}
pw.println(" mSoundNotification=" + mSoundNotification);
- pw.println(" mSound=" + mSound);
pw.println(" mVibrateNotification=" + mVibrateNotification);
pw.println(" mDisabledNotifications=0x" + Integer.toHexString(mDisabledNotifications));
pw.println(" mSystemReady=" + mSystemReady);