summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2015-04-30 17:26:29 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-04-30 17:26:29 +0000
commite36846cbf1d1d2f349289ed4764875c3ee9087be (patch)
tree79e74c283c1831c7471b58508cfd36209e11fa48 /media
parent662f9df99e2f1fdda79da7eda43a13c52ff5b5d0 (diff)
parentc8efc4490df6fb58bf333540cf746c68070345f5 (diff)
downloadframeworks_base-e36846cbf1d1d2f349289ed4764875c3ee9087be.zip
frameworks_base-e36846cbf1d1d2f349289ed4764875c3ee9087be.tar.gz
frameworks_base-e36846cbf1d1d2f349289ed4764875c3ee9087be.tar.bz2
am c8efc449: am 3d42d238: am f764d219: Merge "AudioService receives callback for dynamic policy mix state changes" into mnc-dev
* commit 'c8efc4490df6fb58bf333540cf746c68070345f5': AudioService receives callback for dynamic policy mix state changes
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/AudioSystem.java47
-rw-r--r--media/java/android/media/audiopolicy/AudioMix.java35
-rw-r--r--media/java/android/media/audiopolicy/AudioPolicy.java24
-rw-r--r--media/java/android/media/audiopolicy/AudioPolicyConfig.java8
-rw-r--r--media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl3
5 files changed, 113 insertions, 4 deletions
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 25e6594..3dae543 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -19,6 +19,7 @@ package android.media;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.audiopolicy.AudioMix;
+import android.util.Log;
import java.util.ArrayList;
@@ -32,6 +33,7 @@ import java.util.ArrayList;
*/
public class AudioSystem
{
+ private static final String TAG = "AudioSystem";
/* These values must be kept in sync with system/audio.h */
/*
* If these are modified, please also update Settings.System.VOLUME_SETTINGS
@@ -224,6 +226,48 @@ public class AudioSystem
}
}
+ /**
+ * Handles events for the audio policy manager about dynamic audio policies
+ * @see android.media.audiopolicy.AudioPolicy
+ */
+ public interface DynamicPolicyCallback
+ {
+ void onDynamicPolicyMixStateUpdate(String regId, int state);
+ }
+
+ //keep in sync with include/media/AudioPolicy.h
+ private final static int DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE = 0;
+
+ private static DynamicPolicyCallback sDynPolicyCallback;
+
+ public static void setDynamicPolicyCallback(DynamicPolicyCallback cb)
+ {
+ synchronized (AudioSystem.class) {
+ sDynPolicyCallback = cb;
+ native_register_dynamic_policy_callback();
+ }
+ }
+
+ private static void dynamicPolicyCallbackFromNative(int event, String regId, int val)
+ {
+ DynamicPolicyCallback cb = null;
+ synchronized (AudioSystem.class) {
+ if (sDynPolicyCallback != null) {
+ cb = sDynPolicyCallback;
+ }
+ }
+ if (cb != null) {
+ switch(event) {
+ case DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE:
+ cb.onDynamicPolicyMixStateUpdate(regId, val);
+ break;
+ default:
+ Log.e(TAG, "dynamicPolicyCallbackFromNative: unknown event " + event);
+ }
+ }
+ }
+
+
/*
* Error codes used by public APIs (AudioTrack, AudioRecord, AudioManager ...)
* Must be kept in sync with frameworks/base/core/jni/android_media_AudioErrors.h
@@ -580,6 +624,9 @@ public class AudioSystem
public static native int listAudioPatches(ArrayList<AudioPatch> patches, int[] generation);
public static native int setAudioPortConfig(AudioPortConfig config);
+ // declare this instance as having a dynamic policy callback handler
+ private static native final void native_register_dynamic_policy_callback();
+
// must be kept in sync with value in include/system/audio.h
public static final int AUDIO_HW_SYNC_INVALID = 0;
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 6aa4d8a..4ffac6d 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -36,20 +36,30 @@ public class AudioMix {
private int mRouteFlags;
private String mRegistrationId;
private int mMixType = MIX_TYPE_INVALID;
- private int mMixState = MIX_STATE_DISABLED;
+ int mMixState = MIX_STATE_DISABLED;
+ int mCallbackFlags;
/**
* All parameters are guaranteed valid through the Builder.
*/
- private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags) {
+ private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags) {
mRule = rule;
mFormat = format;
mRouteFlags = routeFlags;
mRegistrationId = null;
mMixType = rule.getTargetMixType();
+ mCallbackFlags = callbackFlags;
}
- // ROUTE_FLAG_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h
+ // CALLBACK_FLAG_* values: keep in sync with AudioMix::kCbFlag* values defined
+ // in frameworks/av/include/media/AudioPolicy.h
+ /** @hide */
+ public final static int CALLBACK_FLAG_NOTIFY_ACTIVITY = 0x1;
+ // when adding new MIX_FLAG_* flags, add them to this mask of authorized masks:
+ private final static int CALLBACK_FLAGS_ALL = CALLBACK_FLAG_NOTIFY_ACTIVITY;
+
+ // ROUTE_FLAG_* values: keep in sync with MIX_ROUTE_FLAG_* values defined
+ // in frameworks/av/include/media/AudioPolicy.h
/**
* An audio mix behavior where the output of the mix is sent to the original destination of
* the audio signal, i.e. an output device for an output mix, or a recording for an input mix.
@@ -161,6 +171,7 @@ public class AudioMix {
private AudioMixingRule mRule = null;
private AudioFormat mFormat = null;
private int mRouteFlags = 0;
+ private int mCallbackFlags = 0;
/**
* @hide
@@ -199,6 +210,22 @@ public class AudioMix {
}
/**
+ * @hide
+ * Only used by AudioPolicyConfig, not a public API.
+ * @param callbackFlags which callbacks are called from native
+ * @return the same Builder instance.
+ * @throws IllegalArgumentException
+ */
+ public Builder setCallbackFlags(int flags) throws IllegalArgumentException {
+ if ((flags != 0) && ((flags & CALLBACK_FLAGS_ALL) == 0)) {
+ throw new IllegalArgumentException("Illegal callback flags 0x"
+ + Integer.toHexString(flags).toUpperCase());
+ }
+ mCallbackFlags = flags;
+ return this;
+ }
+
+ /**
* Sets the {@link AudioFormat} for the mix.
* @param format a non-null {@link AudioFormat} instance.
* @return the same Builder instance.
@@ -256,7 +283,7 @@ public class AudioMix {
}
mFormat = new AudioFormat.Builder().setSampleRate(rate).build();
}
- return new AudioMix(mRule, mFormat, mRouteFlags);
+ return new AudioMix(mRule, mFormat, mRouteFlags, mCallbackFlags);
}
}
}
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index f128044..423b467 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -189,6 +189,12 @@ public class AudioPolicy {
@SystemApi
public AudioPolicy build() {
+ if (mStatusListener != null) {
+ // the AudioPolicy status listener includes updates on each mix activity state
+ for (AudioMix mix : mMixes) {
+ mix.mCallbackFlags |= AudioMix.CALLBACK_FLAG_NOTIFY_ACTIVITY;
+ }
+ }
return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper,
mFocusListener, mStatusListener);
}
@@ -432,6 +438,18 @@ public class AudioPolicy {
+ afi.getClientId() + "wasNotified=" + wasNotified);
}
}
+
+ public void notifyMixStateUpdate(String regId, int state) {
+ for (AudioMix mix : mConfig.getMixes()) {
+ if (mix.getRegistration().equals(regId)) {
+ mix.mMixState = state;
+ sendMsg(MSG_MIX_STATE_UPDATE, mix, 0/*ignored*/);
+ if (DEBUG) {
+ Log.v(TAG, "notifyMixStateUpdate: regId=" + regId + " state=" + state);
+ }
+ }
+ }
+ }
};
//==================================================
@@ -440,6 +458,7 @@ public class AudioPolicy {
private final static int MSG_POLICY_STATUS_CHANGE = 0;
private final static int MSG_FOCUS_GRANT = 1;
private final static int MSG_FOCUS_LOSS = 2;
+ private final static int MSG_MIX_STATE_UPDATE = 3;
private class EventHandler extends Handler {
public EventHandler(AudioPolicy ap, Looper looper) {
@@ -464,6 +483,11 @@ public class AudioPolicy {
(AudioFocusInfo) msg.obj, msg.arg1 != 0);
}
break;
+ case MSG_MIX_STATE_UPDATE:
+ if (mStatusListener != null) {
+ mStatusListener.onMixStateUpdate((AudioMix) msg.obj);
+ }
+ break;
default:
Log.e(TAG, "Unknown event " + msg.what);
}
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index 917e07b..252f5f4 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -59,6 +59,10 @@ public class AudioPolicyConfig implements Parcelable {
mMixes.add(mix);
}
+ public ArrayList<AudioMix> getMixes() {
+ return mMixes;
+ }
+
@Override
public int hashCode() {
return Objects.hash(mMixes);
@@ -75,6 +79,8 @@ public class AudioPolicyConfig implements Parcelable {
for (AudioMix mix : mMixes) {
// write mix route flags
dest.writeInt(mix.getRouteFlags());
+ // write callback flags
+ dest.writeInt(mix.mCallbackFlags);
// write mix format
dest.writeInt(mix.getFormat().getSampleRate());
dest.writeInt(mix.getFormat().getEncoding());
@@ -96,6 +102,8 @@ public class AudioPolicyConfig implements Parcelable {
// read mix route flags
int routeFlags = in.readInt();
mixBuilder.setRouteFlags(routeFlags);
+ // read callback flags
+ mixBuilder.setCallbackFlags(in.readInt());
// read mix format
int sampleRate = in.readInt();
int encoding = in.readInt();
diff --git a/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl b/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl
index c777c58..ad8af15 100644
--- a/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl
+++ b/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl
@@ -25,4 +25,7 @@ oneway interface IAudioPolicyCallback {
// callbacks for audio focus
void notifyAudioFocusGrant(in AudioFocusInfo afi, int requestResult);
void notifyAudioFocusLoss(in AudioFocusInfo afi, boolean wasNotified);
+
+ // callback for mix activity status update
+ void notifyMixStateUpdate(in String regId, int state);
}