diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2015-06-30 12:34:48 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2015-07-06 10:06:02 -0700 |
commit | 462045e89aed0163a4681b8221f0df3f26900136 (patch) | |
tree | d435515943f68016e7dc376a619dc17a43500b4c | |
parent | 3a0d77f42aa8bbc3e3f81bb80a55324fc686e2a7 (diff) | |
download | frameworks_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.aidl | 3 | ||||
-rw-r--r-- | media/java/android/media/Ringtone.java | 64 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java | 18 |
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) { |