Loading media/java/android/media/AudioAttributes.java +46 −10 Original line number Diff line number Diff line Loading @@ -412,16 +412,6 @@ public final class AudioAttributes implements Parcelable { } }; /** @hide */ @Override public String toString () { return new String("AudioAttributes:" + " usage=" + mUsage + " content=" + mContentType + " flags=0x" + Integer.toHexString(mFlags) + " tags=" + mTags); } @Override public int describeContents() { return 0; Loading Loading @@ -486,6 +476,52 @@ public final class AudioAttributes implements Parcelable { } }; /** @hide */ @Override public String toString () { return new String("AudioAttributes:" + " usage=" + mUsage + " content=" + mContentType + " flags=0x" + Integer.toHexString(mFlags).toUpperCase() + " tags=" + mTags); } public String usageToString() { switch(mUsage) { case USAGE_UNKNOWN: return new String("USAGE_UNKNOWN"); case USAGE_MEDIA: return new String("USAGE_MEDIA"); case USAGE_VOICE_COMMUNICATION: return new String("USAGE_VOICE_COMMUNICATION"); case USAGE_VOICE_COMMUNICATION_SIGNALLING: return new String("USAGE_VOICE_COMMUNICATION"); case USAGE_ALARM: return new String("USAGE_ALARM"); case USAGE_NOTIFICATION: return new String("USAGE_NOTIFICATION"); case USAGE_NOTIFICATION_TELEPHONY_RINGTONE: return new String("USAGE_NOTIFICATION"); case USAGE_NOTIFICATION_COMMUNICATION_REQUEST: return new String("USAGE_NOTIFICATION"); case USAGE_NOTIFICATION_COMMUNICATION_INSTANT: return new String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT"); case USAGE_NOTIFICATION_COMMUNICATION_DELAYED: return new String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED"); case USAGE_NOTIFICATION_EVENT: return new String("USAGE_NOTIFICATION_EVENT"); case USAGE_ASSISTANCE_ACCESSIBILITY: return new String("USAGE_ASSISTANCE_ACCESSIBILITY"); case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: return new String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"); case USAGE_ASSISTANCE_SONIFICATION: return new String("USAGE_ASSISTANCE_SONIFICATION"); case USAGE_GAME: return new String("USAGE_GAME"); default: return new String("unknown usage " + mUsage); } } /** @hide */ @IntDef({ Loading media/java/android/media/AudioFormat.java +9 −5 Original line number Diff line number Diff line Loading @@ -227,19 +227,23 @@ public class AudioFormat { private int mChannelMask; private int mPropertySetMask; int getEncoding() { /** @hide */ public int getEncoding() { return mEncoding; } int getSampleRate() { /** @hide */ public int getSampleRate() { return mSampleRate; } int getChannelMask() { /** @hide */ public int getChannelMask() { return mChannelMask; } int getPropertySetMask() { /** @hide */ public int getPropertySetMask() { return mPropertySetMask; } Loading @@ -248,7 +252,7 @@ public class AudioFormat { * Builder class for {@link AudioFormat} objects. */ public static class Builder { private int mEncoding = ENCODING_DEFAULT; private int mEncoding = ENCODING_PCM_16BIT; private int mSampleRate = 0; private int mChannelMask = CHANNEL_INVALID; private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE; Loading media/java/android/media/AudioManager.java +50 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.media.RemoteController.OnClientUpdateListener; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicyConfig; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; import android.os.Handler; Loading Loading @@ -2448,6 +2450,52 @@ public class AudioManager { } } /** * @hide * CANDIDATE FOR PUBLIC API * Register the given {@link AudioPolicy}. * This call is synchronous and blocks until the registration process successfully completed * or failed to complete. * @param policy the {@link AudioPolicy} to register. * @return {@link #ERROR} if there was an error communicating with the registration service * or if the user doesn't have the required * {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission, * {@link #SUCCESS} otherwise. */ public int registerAudioPolicy(AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } IAudioService service = getService(); try { if (!service.registerAudioPolicy(policy.getConfig(), policy.token())) { return ERROR; } } catch (RemoteException e) { Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e); return ERROR; } return SUCCESS; } /** * @hide * CANDIDATE FOR PUBLIC API * @param policy the {@link AudioPolicy} to unregister. */ public void unregisterAudioPolicyAsync(AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } IAudioService service = getService(); try { service.unregisterAudioPolicyAsync(policy.token()); } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterAudioPolicyAsync()", e); } } /** * @hide * Reload audio settings. This method is called by Settings backup Loading Loading @@ -2912,6 +2960,7 @@ public class AudioManager { */ /** @hide * CANDIDATE FOR PUBLIC API */ public static final int SUCCESS = AudioSystem.SUCCESS; /** Loading @@ -2919,6 +2968,7 @@ public class AudioManager { */ public static final int ERROR = AudioSystem.ERROR; /** @hide * CANDIDATE FOR PUBLIC API */ public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE; /** @hide Loading media/java/android/media/AudioService.java +63 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.hardware.hdmi.HdmiTvClient; import android.hardware.usb.UsbManager; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.audiopolicy.AudioPolicyConfig; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; import android.os.Build; Loading @@ -68,6 +69,7 @@ import android.provider.Settings.System; import android.telecomm.TelecommManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import android.view.KeyEvent; import android.view.Surface; import android.view.WindowManager; Loading Loading @@ -5041,4 +5043,65 @@ public class AudioService extends IAudioService.Stub { } } } //========================================================================================== // Audio policy management //========================================================================================== public boolean registerAudioPolicy(AudioPolicyConfig policyConfig, IBinder cb) { //Log.v(TAG, "registerAudioPolicy for " + cb + " got policy:" + policyConfig); boolean hasPermissionForPolicy = (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( android.Manifest.permission.MODIFY_AUDIO_ROUTING)); if (!hasPermissionForPolicy) { Slog.w(TAG, "Can't register audio policy for pid " + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); return false; } synchronized (mAudioPolicies) { AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, cb); try { cb.linkToDeath(app, 0/*flags*/); mAudioPolicies.put(cb, app); } catch (RemoteException e) { // audio policy owner has already died! Slog.w(TAG, "Audio policy registration failed, could not link to " + cb + " binder death", e); return false; } } // TODO implement registration with native audio policy (including permission check) return true; } public void unregisterAudioPolicyAsync(IBinder cb) { synchronized (mAudioPolicies) { AudioPolicyProxy app = mAudioPolicies.remove(cb); if (app == null) { Slog.w(TAG, "Trying to unregister unknown audio policy for pid " + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); } else { cb.unlinkToDeath(app, 0/*flags*/); } } // TODO implement registration with native audio policy } public class AudioPolicyProxy implements IBinder.DeathRecipient { private static final String TAG = "AudioPolicyProxy"; AudioPolicyConfig mConfig; IBinder mToken; AudioPolicyProxy(AudioPolicyConfig config, IBinder token) { mConfig = config; mToken = token; } public void binderDied() { synchronized (mAudioPolicies) { Log.v(TAG, "audio policy " + mToken + " died"); mAudioPolicies.remove(mToken); } } }; private HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = new HashMap<IBinder, AudioPolicyProxy>(); } media/java/android/media/IAudioService.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.media.IRemoteVolumeObserver; import android.media.IRingtonePlayer; import android.media.IVolumeController; import android.media.Rating; import android.media.audiopolicy.AudioPolicyConfig; import android.net.Uri; import android.view.KeyEvent; Loading Loading @@ -199,4 +200,7 @@ interface IAudioService { void disableSafeMediaVolume(); int setHdmiSystemAudioSupported(boolean on, int device, String name); boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb); oneway void unregisterAudioPolicyAsync(in IBinder cb); } Loading
media/java/android/media/AudioAttributes.java +46 −10 Original line number Diff line number Diff line Loading @@ -412,16 +412,6 @@ public final class AudioAttributes implements Parcelable { } }; /** @hide */ @Override public String toString () { return new String("AudioAttributes:" + " usage=" + mUsage + " content=" + mContentType + " flags=0x" + Integer.toHexString(mFlags) + " tags=" + mTags); } @Override public int describeContents() { return 0; Loading Loading @@ -486,6 +476,52 @@ public final class AudioAttributes implements Parcelable { } }; /** @hide */ @Override public String toString () { return new String("AudioAttributes:" + " usage=" + mUsage + " content=" + mContentType + " flags=0x" + Integer.toHexString(mFlags).toUpperCase() + " tags=" + mTags); } public String usageToString() { switch(mUsage) { case USAGE_UNKNOWN: return new String("USAGE_UNKNOWN"); case USAGE_MEDIA: return new String("USAGE_MEDIA"); case USAGE_VOICE_COMMUNICATION: return new String("USAGE_VOICE_COMMUNICATION"); case USAGE_VOICE_COMMUNICATION_SIGNALLING: return new String("USAGE_VOICE_COMMUNICATION"); case USAGE_ALARM: return new String("USAGE_ALARM"); case USAGE_NOTIFICATION: return new String("USAGE_NOTIFICATION"); case USAGE_NOTIFICATION_TELEPHONY_RINGTONE: return new String("USAGE_NOTIFICATION"); case USAGE_NOTIFICATION_COMMUNICATION_REQUEST: return new String("USAGE_NOTIFICATION"); case USAGE_NOTIFICATION_COMMUNICATION_INSTANT: return new String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT"); case USAGE_NOTIFICATION_COMMUNICATION_DELAYED: return new String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED"); case USAGE_NOTIFICATION_EVENT: return new String("USAGE_NOTIFICATION_EVENT"); case USAGE_ASSISTANCE_ACCESSIBILITY: return new String("USAGE_ASSISTANCE_ACCESSIBILITY"); case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: return new String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"); case USAGE_ASSISTANCE_SONIFICATION: return new String("USAGE_ASSISTANCE_SONIFICATION"); case USAGE_GAME: return new String("USAGE_GAME"); default: return new String("unknown usage " + mUsage); } } /** @hide */ @IntDef({ Loading
media/java/android/media/AudioFormat.java +9 −5 Original line number Diff line number Diff line Loading @@ -227,19 +227,23 @@ public class AudioFormat { private int mChannelMask; private int mPropertySetMask; int getEncoding() { /** @hide */ public int getEncoding() { return mEncoding; } int getSampleRate() { /** @hide */ public int getSampleRate() { return mSampleRate; } int getChannelMask() { /** @hide */ public int getChannelMask() { return mChannelMask; } int getPropertySetMask() { /** @hide */ public int getPropertySetMask() { return mPropertySetMask; } Loading @@ -248,7 +252,7 @@ public class AudioFormat { * Builder class for {@link AudioFormat} objects. */ public static class Builder { private int mEncoding = ENCODING_DEFAULT; private int mEncoding = ENCODING_PCM_16BIT; private int mSampleRate = 0; private int mChannelMask = CHANNEL_INVALID; private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE; Loading
media/java/android/media/AudioManager.java +50 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.media.RemoteController.OnClientUpdateListener; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicyConfig; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; import android.os.Handler; Loading Loading @@ -2448,6 +2450,52 @@ public class AudioManager { } } /** * @hide * CANDIDATE FOR PUBLIC API * Register the given {@link AudioPolicy}. * This call is synchronous and blocks until the registration process successfully completed * or failed to complete. * @param policy the {@link AudioPolicy} to register. * @return {@link #ERROR} if there was an error communicating with the registration service * or if the user doesn't have the required * {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission, * {@link #SUCCESS} otherwise. */ public int registerAudioPolicy(AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } IAudioService service = getService(); try { if (!service.registerAudioPolicy(policy.getConfig(), policy.token())) { return ERROR; } } catch (RemoteException e) { Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e); return ERROR; } return SUCCESS; } /** * @hide * CANDIDATE FOR PUBLIC API * @param policy the {@link AudioPolicy} to unregister. */ public void unregisterAudioPolicyAsync(AudioPolicy policy) { if (policy == null) { throw new IllegalArgumentException("Illegal null AudioPolicy argument"); } IAudioService service = getService(); try { service.unregisterAudioPolicyAsync(policy.token()); } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterAudioPolicyAsync()", e); } } /** * @hide * Reload audio settings. This method is called by Settings backup Loading Loading @@ -2912,6 +2960,7 @@ public class AudioManager { */ /** @hide * CANDIDATE FOR PUBLIC API */ public static final int SUCCESS = AudioSystem.SUCCESS; /** Loading @@ -2919,6 +2968,7 @@ public class AudioManager { */ public static final int ERROR = AudioSystem.ERROR; /** @hide * CANDIDATE FOR PUBLIC API */ public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE; /** @hide Loading
media/java/android/media/AudioService.java +63 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.hardware.hdmi.HdmiTvClient; import android.hardware.usb.UsbManager; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.audiopolicy.AudioPolicyConfig; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; import android.os.Build; Loading @@ -68,6 +69,7 @@ import android.provider.Settings.System; import android.telecomm.TelecommManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import android.view.KeyEvent; import android.view.Surface; import android.view.WindowManager; Loading Loading @@ -5041,4 +5043,65 @@ public class AudioService extends IAudioService.Stub { } } } //========================================================================================== // Audio policy management //========================================================================================== public boolean registerAudioPolicy(AudioPolicyConfig policyConfig, IBinder cb) { //Log.v(TAG, "registerAudioPolicy for " + cb + " got policy:" + policyConfig); boolean hasPermissionForPolicy = (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( android.Manifest.permission.MODIFY_AUDIO_ROUTING)); if (!hasPermissionForPolicy) { Slog.w(TAG, "Can't register audio policy for pid " + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); return false; } synchronized (mAudioPolicies) { AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, cb); try { cb.linkToDeath(app, 0/*flags*/); mAudioPolicies.put(cb, app); } catch (RemoteException e) { // audio policy owner has already died! Slog.w(TAG, "Audio policy registration failed, could not link to " + cb + " binder death", e); return false; } } // TODO implement registration with native audio policy (including permission check) return true; } public void unregisterAudioPolicyAsync(IBinder cb) { synchronized (mAudioPolicies) { AudioPolicyProxy app = mAudioPolicies.remove(cb); if (app == null) { Slog.w(TAG, "Trying to unregister unknown audio policy for pid " + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); } else { cb.unlinkToDeath(app, 0/*flags*/); } } // TODO implement registration with native audio policy } public class AudioPolicyProxy implements IBinder.DeathRecipient { private static final String TAG = "AudioPolicyProxy"; AudioPolicyConfig mConfig; IBinder mToken; AudioPolicyProxy(AudioPolicyConfig config, IBinder token) { mConfig = config; mToken = token; } public void binderDied() { synchronized (mAudioPolicies) { Log.v(TAG, "audio policy " + mToken + " died"); mAudioPolicies.remove(mToken); } } }; private HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = new HashMap<IBinder, AudioPolicyProxy>(); }
media/java/android/media/IAudioService.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.media.IRemoteVolumeObserver; import android.media.IRingtonePlayer; import android.media.IVolumeController; import android.media.Rating; import android.media.audiopolicy.AudioPolicyConfig; import android.net.Uri; import android.view.KeyEvent; Loading Loading @@ -199,4 +200,7 @@ interface IAudioService { void disableSafeMediaVolume(); int setHdmiSystemAudioSupported(boolean on, int device, String name); boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb); oneway void unregisterAudioPolicyAsync(in IBinder cb); }