summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2015-06-30 12:34:48 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2015-07-06 10:06:02 -0700
commit462045e89aed0163a4681b8221f0df3f26900136 (patch)
treed435515943f68016e7dc376a619dc17a43500b4c
parent3a0d77f42aa8bbc3e3f81bb80a55324fc686e2a7 (diff)
downloadframeworks_base-462045e89aed0163a4681b8221f0df3f26900136.zip
frameworks_base-462045e89aed0163a4681b8221f0df3f26900136.tar.gz
frameworks_base-462045e89aed0163a4681b8221f0df3f26900136.tar.bz2
Ringtone: add support for volume control and looping
Bug 22182606 Change-Id: Ied910b9fe02a5da9c4822a107ee884677c8b4991
-rw-r--r--media/java/android/media/IRingtonePlayer.aidl3
-rw-r--r--media/java/android/media/Ringtone.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java18
3 files changed, 82 insertions, 3 deletions
diff --git a/media/java/android/media/IRingtonePlayer.aidl b/media/java/android/media/IRingtonePlayer.aidl
index 7c011e6..aa5fde3 100644
--- a/media/java/android/media/IRingtonePlayer.aidl
+++ b/media/java/android/media/IRingtonePlayer.aidl
@@ -25,9 +25,10 @@ import android.os.UserHandle;
*/
interface IRingtonePlayer {
/** Used for Ringtone.java playback */
- void play(IBinder token, in Uri uri, in AudioAttributes aa);
+ void play(IBinder token, in Uri uri, in AudioAttributes aa, float volume, boolean looping);
void stop(IBinder token);
boolean isPlaying(IBinder token);
+ void setPlaybackProperties(IBinder token, float volume, boolean looping);
/** Used for Notification sound playback. */
void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa);
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 166ff38..faeebe6 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -76,6 +76,10 @@ public class Ringtone {
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
+ // playback properties, use synchronized with mPlaybackSettingsLock
+ private boolean mIsLooping = false;
+ private float mVolume = 1.0f;
+ private final Object mPlaybackSettingsLock = new Object();
/** {@hide} */
public Ringtone(Context context, boolean allowRemote) {
@@ -136,6 +140,52 @@ public class Ringtone {
}
/**
+ * @hide
+ * Sets the player to be looping or non-looping.
+ * @param looping whether to loop or not
+ */
+ public void setLooping(boolean looping) {
+ synchronized (mPlaybackSettingsLock) {
+ mIsLooping = looping;
+ applyPlaybackProperties_sync();
+ }
+ }
+
+ /**
+ * @hide
+ * Sets the volume on this player.
+ * @param volume a raw scalar in range 0.0 to 1.0, where 0.0 mutes this player, and 1.0
+ * corresponds to no attenuation being applied.
+ */
+ public void setVolume(float volume) {
+ synchronized (mPlaybackSettingsLock) {
+ if (volume < 0.0f) { volume = 0.0f; }
+ if (volume > 1.0f) { volume = 1.0f; }
+ mVolume = volume;
+ applyPlaybackProperties_sync();
+ }
+ }
+
+ /**
+ * Must be called synchronized on mPlaybackSettingsLock
+ */
+ private void applyPlaybackProperties_sync() {
+ if (mLocalPlayer != null) {
+ mLocalPlayer.setVolume(mVolume);
+ mLocalPlayer.setLooping(mIsLooping);
+ } else if (mAllowRemote && (mRemotePlayer != null)) {
+ try {
+ mRemotePlayer.setPlaybackProperties(mRemoteToken, mVolume, mIsLooping);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Problem setting playback properties: ", e);
+ }
+ } else {
+ Log.w(TAG,
+ "Neither local nor remote player available when applying playback properties");
+ }
+ }
+
+ /**
* Returns a human-presentable title for ringtone. Looks in media
* content provider. If not in either, uses the filename
*
@@ -221,6 +271,9 @@ public class Ringtone {
try {
mLocalPlayer.setDataSource(mContext, mUri);
mLocalPlayer.setAudioAttributes(mAudioAttributes);
+ synchronized (mPlaybackSettingsLock) {
+ applyPlaybackProperties_sync();
+ }
mLocalPlayer.prepare();
} catch (SecurityException | IOException e) {
@@ -257,8 +310,14 @@ public class Ringtone {
}
} else if (mAllowRemote && (mRemotePlayer != null)) {
final Uri canonicalUri = mUri.getCanonicalUri();
+ final boolean looping;
+ final float volume;
+ synchronized (mPlaybackSettingsLock) {
+ looping = mIsLooping;
+ volume = mVolume;
+ }
try {
- mRemotePlayer.play(mRemoteToken, canonicalUri, mAudioAttributes);
+ mRemotePlayer.play(mRemoteToken, canonicalUri, mAudioAttributes, volume, looping);
} catch (RemoteException e) {
if (!playFallbackRingtone()) {
Log.w(TAG, "Problem playing ringtone: " + e);
@@ -349,6 +408,9 @@ public class Ringtone {
afd.getDeclaredLength());
}
mLocalPlayer.setAudioAttributes(mAudioAttributes);
+ synchronized (mPlaybackSettingsLock) {
+ applyPlaybackProperties_sync();
+ }
mLocalPlayer.prepare();
startLocalPlayer();
afd.close();
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index 7eed7f2..e9a256c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -92,7 +92,8 @@ public class RingtonePlayer extends SystemUI {
private IRingtonePlayer mCallback = new IRingtonePlayer.Stub() {
@Override
- public void play(IBinder token, Uri uri, AudioAttributes aa) throws RemoteException {
+ public void play(IBinder token, Uri uri, AudioAttributes aa, float volume, boolean looping)
+ throws RemoteException {
if (LOGD) {
Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
+ Binder.getCallingUid() + ")");
@@ -107,6 +108,8 @@ public class RingtonePlayer extends SystemUI {
mClients.put(token, client);
}
}
+ client.mRingtone.setLooping(looping);
+ client.mRingtone.setVolume(volume);
client.mRingtone.play();
}
@@ -138,6 +141,19 @@ public class RingtonePlayer extends SystemUI {
}
@Override
+ public void setPlaybackProperties(IBinder token, float volume, boolean looping) {
+ Client client;
+ synchronized (mClients) {
+ client = mClients.get(token);
+ }
+ if (client != null) {
+ client.mRingtone.setVolume(volume);
+ client.mRingtone.setLooping(looping);
+ }
+ // else no client for token when setting playback properties but will be set at play()
+ }
+
+ @Override
public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) {
if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
if (Binder.getCallingUid() != Process.SYSTEM_UID) {