Merge "Don't hold clients lock while initializing Ringtone." into udc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index 2a8168b..05e04a1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -88,18 +88,9 @@
private final IBinder mToken;
private final Ringtone mRingtone;
- public Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa) {
- this(token, uri, user, aa, null);
- }
-
- Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa,
- @Nullable VolumeShaper.Configuration volumeShaperConfig) {
+ Client(IBinder token, Ringtone ringtone) {
mToken = token;
-
- mRingtone = new Ringtone(getContextForUser(user), false);
- mRingtone.setAudioAttributesField(aa);
- mRingtone.setUri(uri, volumeShaperConfig);
- mRingtone.createLocalMediaPlayer();
+ mRingtone = ringtone;
}
@Override
@@ -129,11 +120,28 @@
Client client;
synchronized (mClients) {
client = mClients.get(token);
- if (client == null) {
- final UserHandle user = Binder.getCallingUserHandle();
- client = new Client(token, uri, user, aa, volumeShaperConfig);
- token.linkToDeath(client, 0);
- mClients.put(token, client);
+ }
+ // Don't hold the lock while constructing the ringtone, since it can be slow. The caller
+ // shouldn't call play on the same ringtone from 2 threads, so this shouldn't race and
+ // waste the build.
+ if (client == null) {
+ final UserHandle user = Binder.getCallingUserHandle();
+ Ringtone ringtone = new Ringtone(getContextForUser(user), false);
+ ringtone.setAudioAttributesField(aa);
+ ringtone.setUri(uri, volumeShaperConfig);
+ ringtone.createLocalMediaPlayer();
+ synchronized (mClients) {
+ client = mClients.get(token);
+ if (client == null) {
+ client = new Client(token, ringtone);
+ token.linkToDeath(client, 0);
+ mClients.put(token, client);
+ ringtone = null; // "owned" by the client now.
+ }
+ }
+ // Clean up ringtone if it was abandoned (a client already existed).
+ if (ringtone != null) {
+ ringtone.stop();
}
}
client.mRingtone.setLooping(looping);