Loading api/current.txt +14 −0 Original line number Diff line number Diff line Loading @@ -14924,6 +14924,7 @@ package android.media { public class AudioRecord { ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener, android.os.Handler); method public int getAudioFormat(); method public int getAudioSessionId(); method public int getAudioSource(); Loading @@ -14935,6 +14936,7 @@ package android.media { method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredInputDevice(); method public int getRecordingState(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int read(byte[], int, int); Loading @@ -14945,6 +14947,7 @@ package android.media { method public int read(java.nio.ByteBuffer, int); method public int read(java.nio.ByteBuffer, int, int); method public void release(); method public void removeOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener); method public int setNotificationMarkerPosition(int); method public int setPositionNotificationPeriod(int); method public boolean setPreferredInputDevice(android.media.AudioDeviceInfo); Loading Loading @@ -14988,6 +14991,7 @@ package android.media { ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener, android.os.Handler); method public int attachAuxEffect(int); method public void flush(); method public int getAudioFormat(); Loading @@ -15006,6 +15010,7 @@ package android.media { method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int getStreamType(); Loading @@ -15014,6 +15019,7 @@ package android.media { method public void play() throws java.lang.IllegalStateException; method public void release(); method public int reloadStaticData(); method public void removeOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener); method public int setAuxEffectSendLevel(float); method public int setLoopPoints(int, int, int); method public int setNotificationMarkerPosition(int); Loading Loading @@ -16427,6 +16433,14 @@ package android.media { field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public abstract interface OnAudioRecordRoutingListener { method public abstract void onAudioRecordRouting(android.media.AudioRecord); } public abstract interface OnAudioTrackRoutingListener { method public abstract void onAudioTrackRouting(android.media.AudioTrack); } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating(); api/system-current.txt +14 −0 Original line number Diff line number Diff line Loading @@ -16135,6 +16135,7 @@ package android.media { public class AudioRecord { ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener, android.os.Handler); method public int getAudioFormat(); method public int getAudioSessionId(); method public int getAudioSource(); Loading @@ -16146,6 +16147,7 @@ package android.media { method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredInputDevice(); method public int getRecordingState(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int read(byte[], int, int); Loading @@ -16156,6 +16158,7 @@ package android.media { method public int read(java.nio.ByteBuffer, int); method public int read(java.nio.ByteBuffer, int, int); method public void release(); method public void removeOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener); method public int setNotificationMarkerPosition(int); method public int setPositionNotificationPeriod(int); method public boolean setPreferredInputDevice(android.media.AudioDeviceInfo); Loading Loading @@ -16201,6 +16204,7 @@ package android.media { ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener, android.os.Handler); method public int attachAuxEffect(int); method public void flush(); method public int getAudioFormat(); Loading @@ -16219,6 +16223,7 @@ package android.media { method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int getStreamType(); Loading @@ -16227,6 +16232,7 @@ package android.media { method public void play() throws java.lang.IllegalStateException; method public void release(); method public int reloadStaticData(); method public void removeOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener); method public int setAuxEffectSendLevel(float); method public int setLoopPoints(int, int, int); method public int setNotificationMarkerPosition(int); Loading Loading @@ -17643,6 +17649,14 @@ package android.media { field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public abstract interface OnAudioRecordRoutingListener { method public abstract void onAudioRecordRouting(android.media.AudioRecord); } public abstract interface OnAudioTrackRoutingListener { method public abstract void onAudioTrackRouting(android.media.AudioTrack); } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating(); media/java/android/media/AudioRecord.java +117 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Iterator; import android.annotation.IntDef; Loading @@ -32,6 +33,7 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; /** Loading Loading @@ -113,6 +115,11 @@ public class AudioRecord */ private static final int NATIVE_EVENT_NEW_POS = 3; /** * Event id denotes when the routing changes. */ private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; private final static String TAG = "android.media.AudioRecord"; /** @hide */ Loading Loading @@ -1127,7 +1134,7 @@ public class AudioRecord * Sets the listener the AudioRecord notifies when a previously set marker is reached or * for each periodic record head position update. * Use this method to receive AudioRecord events in the Handler associated with another * thread than the one in which you created the AudioTrack instance. * thread than the one in which you created the AudioRecord instance. * @param listener * @param handler the Handler that will receive the event notification messages. */ Loading Loading @@ -1168,6 +1175,115 @@ public class AudioRecord } //-------------------------------------------------------------------------- // (Re)Routing Info //-------------------- /** * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord. */ public AudioDeviceInfo getRoutedDevice() { return null; } /** * The message sent to apps when the routing of this AudioRecord changes if they provide * a {#link Handler} object to addOnAudioRecordRoutingListener(). */ private ArrayMap<OnAudioRecordRoutingListener, NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<OnAudioRecordRoutingListener, NativeRoutingEventHandlerDelegate>(); /** * Adds an {@link OnAudioRecordRoutingListener} to receive notifications of routing changes * on this AudioRecord. */ public void addOnAudioRecordRoutingListener(OnAudioRecordRoutingListener listener, android.os.Handler handler) { if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { synchronized (mRoutingChangeListeners) { mRoutingChangeListeners.put( listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); } } } /** * Removes an {@link OnAudioRecordRoutingListener} which has been previously added * to receive notifications of changes to the set of connected audio devices. */ public void removeOnAudioRecordRoutingListener(OnAudioRecordRoutingListener listener) { synchronized (mRoutingChangeListeners) { if (mRoutingChangeListeners.containsKey(listener)) { mRoutingChangeListeners.remove(listener); } } } /** * Helper class to handle the forwarding of native events to the appropriate listener * (potentially) handled in a different thread */ private class NativeRoutingEventHandlerDelegate { private final Handler mHandler; NativeRoutingEventHandlerDelegate(final AudioRecord record, final OnAudioRecordRoutingListener listener, Handler handler) { // find the looper for our new event handler Looper looper; if (handler != null) { looper = handler.getLooper(); } else { // no given handler, use the looper the AudioRecord was created in looper = mInitializationLooper; } // construct the event handler with this looper if (looper != null) { // implement the event handler delegate mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { if (record == null) { return; } switch(msg.what) { case NATIVE_EVENT_ROUTING_CHANGE: if (listener != null) { listener.onAudioRecordRouting(record); } break; default: loge("Unknown native event type: " + msg.what); break; } } }; } else { mHandler = null; } } Handler getHandler() { return mHandler; } } /** * Sends device list change notification to all listeners. */ private void broadcastRoutingChange() { Collection<NativeRoutingEventHandlerDelegate> values; synchronized (mRoutingChangeListeners) { values = mRoutingChangeListeners.values(); } for(NativeRoutingEventHandlerDelegate delegate : values) { Handler handler = delegate.getHandler(); if (handler != null) { handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE); } } } /** * Sets the period at which the listener is called, if set with * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or Loading media/java/android/media/AudioTrack.java +122 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import java.lang.Math; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.NioUtils; import java.util.Collection; import android.annotation.IntDef; import android.annotation.NonNull; Loading @@ -37,6 +38,7 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; import com.android.internal.app.IAppOpsService; Loading Loading @@ -176,6 +178,12 @@ public class AudioTrack */ private static final int NATIVE_EVENT_NEW_POS = 4; /** * Event id denotes when the routing changes. */ private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; private final static String TAG = "android.media.AudioTrack"; Loading Loading @@ -224,7 +232,7 @@ public class AudioTrack /** * Handler for events coming from the native code. */ private NativeEventHandlerDelegate mEventHandlerDelegate; private NativePositionEventHandlerDelegate mEventHandlerDelegate; /** * Looper associated with the thread that creates the AudioTrack instance. */ Loading Loading @@ -1243,7 +1251,7 @@ public class AudioTrack public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener, Handler handler) { if (listener != null) { mEventHandlerDelegate = new NativeEventHandlerDelegate(this, listener, handler); mEventHandlerDelegate = new NativePositionEventHandlerDelegate(this, listener, handler); } else { mEventHandlerDelegate = null; } Loading Loading @@ -2109,6 +2117,66 @@ public class AudioTrack return mPreferredDevice; } //-------------------------------------------------------------------------- // (Re)Routing Info //-------------------- /** * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack. */ public AudioDeviceInfo getRoutedDevice() { return null; } /** * The message sent to apps when the routing of this AudioTrack changes if they provide * a {#link Handler} object to addOnAudioTrackRoutingListener(). */ private ArrayMap<OnAudioTrackRoutingListener, NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<OnAudioTrackRoutingListener, NativeRoutingEventHandlerDelegate>(); /** * Adds an {@link OnAudioTrackRoutingListener} to receive notifications of routing changes * on this AudioTrack. */ public void addOnAudioTrackRoutingListener(OnAudioTrackRoutingListener listener, android.os.Handler handler) { if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { synchronized (mRoutingChangeListeners) { mRoutingChangeListeners.put( listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); } } } /** * Removes an {@link OnAudioTrackRoutingListener} which has been previously added * to receive notifications of changes to the set of connected audio devices. */ public void removeOnAudioTrackRoutingListener(OnAudioTrackRoutingListener listener) { synchronized (mRoutingChangeListeners) { if (mRoutingChangeListeners.containsKey(listener)) { mRoutingChangeListeners.remove(listener); } } } /** * Sends device list change notification to all listeners. */ private void broadcastRoutingChange() { Collection<NativeRoutingEventHandlerDelegate> values; synchronized (mRoutingChangeListeners) { values = mRoutingChangeListeners.values(); } for(NativeRoutingEventHandlerDelegate delegate : values) { Handler handler = delegate.getHandler(); if (handler != null) { handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE); } } } //--------------------------------------------------------- // Interface definitions //-------------------- Loading Loading @@ -2137,10 +2205,10 @@ public class AudioTrack * Helper class to handle the forwarding of native events to the appropriate listener * (potentially) handled in a different thread */ private class NativeEventHandlerDelegate { private class NativePositionEventHandlerDelegate { private final Handler mHandler; NativeEventHandlerDelegate(final AudioTrack track, NativePositionEventHandlerDelegate(final AudioTrack track, final OnPlaybackPositionUpdateListener listener, Handler handler) { // find the looper for our new event handler Loading Loading @@ -2188,6 +2256,55 @@ public class AudioTrack } } /** * Helper class to handle the forwarding of native events to the appropriate listener * (potentially) handled in a different thread */ private class NativeRoutingEventHandlerDelegate { private final Handler mHandler; NativeRoutingEventHandlerDelegate(final AudioTrack track, final OnAudioTrackRoutingListener listener, Handler handler) { // find the looper for our new event handler Looper looper; if (handler != null) { looper = handler.getLooper(); } else { // no given handler, use the looper the AudioTrack was created in looper = mInitializationLooper; } // construct the event handler with this looper if (looper != null) { // implement the event handler delegate mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { if (track == null) { return; } switch(msg.what) { case NATIVE_EVENT_ROUTING_CHANGE: if (listener != null) { listener.onAudioTrackRouting(track); } break; default: loge("Unknown native event type: " + msg.what); break; } } }; } else { mHandler = null; } } Handler getHandler() { return mHandler; } } //--------------------------------------------------------- // Java methods called from the native side Loading @@ -2201,7 +2318,7 @@ public class AudioTrack return; } NativeEventHandlerDelegate delegate = track.mEventHandlerDelegate; NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate; if (delegate != null) { Handler handler = delegate.getHandler(); if (handler != null) { Loading media/java/android/media/OnAudioRecordRoutingListener.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; /** * OnAudioDeviceConnectionListener defines the interface for notification listeners in the * {@link AudioDevicesManager} */ public interface OnAudioRecordRoutingListener { /** * Called when the routing of an AudioRecord changes from either and explicit or * policy rerouting. */ public void onAudioRecordRouting(AudioRecord audioRecord); } Loading
api/current.txt +14 −0 Original line number Diff line number Diff line Loading @@ -14924,6 +14924,7 @@ package android.media { public class AudioRecord { ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener, android.os.Handler); method public int getAudioFormat(); method public int getAudioSessionId(); method public int getAudioSource(); Loading @@ -14935,6 +14936,7 @@ package android.media { method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredInputDevice(); method public int getRecordingState(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int read(byte[], int, int); Loading @@ -14945,6 +14947,7 @@ package android.media { method public int read(java.nio.ByteBuffer, int); method public int read(java.nio.ByteBuffer, int, int); method public void release(); method public void removeOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener); method public int setNotificationMarkerPosition(int); method public int setPositionNotificationPeriod(int); method public boolean setPreferredInputDevice(android.media.AudioDeviceInfo); Loading Loading @@ -14988,6 +14991,7 @@ package android.media { ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener, android.os.Handler); method public int attachAuxEffect(int); method public void flush(); method public int getAudioFormat(); Loading @@ -15006,6 +15010,7 @@ package android.media { method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int getStreamType(); Loading @@ -15014,6 +15019,7 @@ package android.media { method public void play() throws java.lang.IllegalStateException; method public void release(); method public int reloadStaticData(); method public void removeOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener); method public int setAuxEffectSendLevel(float); method public int setLoopPoints(int, int, int); method public int setNotificationMarkerPosition(int); Loading Loading @@ -16427,6 +16433,14 @@ package android.media { field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public abstract interface OnAudioRecordRoutingListener { method public abstract void onAudioRecordRouting(android.media.AudioRecord); } public abstract interface OnAudioTrackRoutingListener { method public abstract void onAudioTrackRouting(android.media.AudioTrack); } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating();
api/system-current.txt +14 −0 Original line number Diff line number Diff line Loading @@ -16135,6 +16135,7 @@ package android.media { public class AudioRecord { ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener, android.os.Handler); method public int getAudioFormat(); method public int getAudioSessionId(); method public int getAudioSource(); Loading @@ -16146,6 +16147,7 @@ package android.media { method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredInputDevice(); method public int getRecordingState(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int read(byte[], int, int); Loading @@ -16156,6 +16158,7 @@ package android.media { method public int read(java.nio.ByteBuffer, int); method public int read(java.nio.ByteBuffer, int, int); method public void release(); method public void removeOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener); method public int setNotificationMarkerPosition(int); method public int setPositionNotificationPeriod(int); method public boolean setPreferredInputDevice(android.media.AudioDeviceInfo); Loading Loading @@ -16201,6 +16204,7 @@ package android.media { ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener, android.os.Handler); method public int attachAuxEffect(int); method public void flush(); method public int getAudioFormat(); Loading @@ -16219,6 +16223,7 @@ package android.media { method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); method public int getSampleRate(); method public int getState(); method public int getStreamType(); Loading @@ -16227,6 +16232,7 @@ package android.media { method public void play() throws java.lang.IllegalStateException; method public void release(); method public int reloadStaticData(); method public void removeOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener); method public int setAuxEffectSendLevel(float); method public int setLoopPoints(int, int, int); method public int setNotificationMarkerPosition(int); Loading Loading @@ -17643,6 +17649,14 @@ package android.media { field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public abstract interface OnAudioRecordRoutingListener { method public abstract void onAudioRecordRouting(android.media.AudioRecord); } public abstract interface OnAudioTrackRoutingListener { method public abstract void onAudioTrackRouting(android.media.AudioTrack); } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating();
media/java/android/media/AudioRecord.java +117 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Iterator; import android.annotation.IntDef; Loading @@ -32,6 +33,7 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; /** Loading Loading @@ -113,6 +115,11 @@ public class AudioRecord */ private static final int NATIVE_EVENT_NEW_POS = 3; /** * Event id denotes when the routing changes. */ private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; private final static String TAG = "android.media.AudioRecord"; /** @hide */ Loading Loading @@ -1127,7 +1134,7 @@ public class AudioRecord * Sets the listener the AudioRecord notifies when a previously set marker is reached or * for each periodic record head position update. * Use this method to receive AudioRecord events in the Handler associated with another * thread than the one in which you created the AudioTrack instance. * thread than the one in which you created the AudioRecord instance. * @param listener * @param handler the Handler that will receive the event notification messages. */ Loading Loading @@ -1168,6 +1175,115 @@ public class AudioRecord } //-------------------------------------------------------------------------- // (Re)Routing Info //-------------------- /** * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord. */ public AudioDeviceInfo getRoutedDevice() { return null; } /** * The message sent to apps when the routing of this AudioRecord changes if they provide * a {#link Handler} object to addOnAudioRecordRoutingListener(). */ private ArrayMap<OnAudioRecordRoutingListener, NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<OnAudioRecordRoutingListener, NativeRoutingEventHandlerDelegate>(); /** * Adds an {@link OnAudioRecordRoutingListener} to receive notifications of routing changes * on this AudioRecord. */ public void addOnAudioRecordRoutingListener(OnAudioRecordRoutingListener listener, android.os.Handler handler) { if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { synchronized (mRoutingChangeListeners) { mRoutingChangeListeners.put( listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); } } } /** * Removes an {@link OnAudioRecordRoutingListener} which has been previously added * to receive notifications of changes to the set of connected audio devices. */ public void removeOnAudioRecordRoutingListener(OnAudioRecordRoutingListener listener) { synchronized (mRoutingChangeListeners) { if (mRoutingChangeListeners.containsKey(listener)) { mRoutingChangeListeners.remove(listener); } } } /** * Helper class to handle the forwarding of native events to the appropriate listener * (potentially) handled in a different thread */ private class NativeRoutingEventHandlerDelegate { private final Handler mHandler; NativeRoutingEventHandlerDelegate(final AudioRecord record, final OnAudioRecordRoutingListener listener, Handler handler) { // find the looper for our new event handler Looper looper; if (handler != null) { looper = handler.getLooper(); } else { // no given handler, use the looper the AudioRecord was created in looper = mInitializationLooper; } // construct the event handler with this looper if (looper != null) { // implement the event handler delegate mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { if (record == null) { return; } switch(msg.what) { case NATIVE_EVENT_ROUTING_CHANGE: if (listener != null) { listener.onAudioRecordRouting(record); } break; default: loge("Unknown native event type: " + msg.what); break; } } }; } else { mHandler = null; } } Handler getHandler() { return mHandler; } } /** * Sends device list change notification to all listeners. */ private void broadcastRoutingChange() { Collection<NativeRoutingEventHandlerDelegate> values; synchronized (mRoutingChangeListeners) { values = mRoutingChangeListeners.values(); } for(NativeRoutingEventHandlerDelegate delegate : values) { Handler handler = delegate.getHandler(); if (handler != null) { handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE); } } } /** * Sets the period at which the listener is called, if set with * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or Loading
media/java/android/media/AudioTrack.java +122 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import java.lang.Math; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.NioUtils; import java.util.Collection; import android.annotation.IntDef; import android.annotation.NonNull; Loading @@ -37,6 +38,7 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; import com.android.internal.app.IAppOpsService; Loading Loading @@ -176,6 +178,12 @@ public class AudioTrack */ private static final int NATIVE_EVENT_NEW_POS = 4; /** * Event id denotes when the routing changes. */ private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000; private final static String TAG = "android.media.AudioTrack"; Loading Loading @@ -224,7 +232,7 @@ public class AudioTrack /** * Handler for events coming from the native code. */ private NativeEventHandlerDelegate mEventHandlerDelegate; private NativePositionEventHandlerDelegate mEventHandlerDelegate; /** * Looper associated with the thread that creates the AudioTrack instance. */ Loading Loading @@ -1243,7 +1251,7 @@ public class AudioTrack public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener, Handler handler) { if (listener != null) { mEventHandlerDelegate = new NativeEventHandlerDelegate(this, listener, handler); mEventHandlerDelegate = new NativePositionEventHandlerDelegate(this, listener, handler); } else { mEventHandlerDelegate = null; } Loading Loading @@ -2109,6 +2117,66 @@ public class AudioTrack return mPreferredDevice; } //-------------------------------------------------------------------------- // (Re)Routing Info //-------------------- /** * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack. */ public AudioDeviceInfo getRoutedDevice() { return null; } /** * The message sent to apps when the routing of this AudioTrack changes if they provide * a {#link Handler} object to addOnAudioTrackRoutingListener(). */ private ArrayMap<OnAudioTrackRoutingListener, NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<OnAudioTrackRoutingListener, NativeRoutingEventHandlerDelegate>(); /** * Adds an {@link OnAudioTrackRoutingListener} to receive notifications of routing changes * on this AudioTrack. */ public void addOnAudioTrackRoutingListener(OnAudioTrackRoutingListener listener, android.os.Handler handler) { if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { synchronized (mRoutingChangeListeners) { mRoutingChangeListeners.put( listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); } } } /** * Removes an {@link OnAudioTrackRoutingListener} which has been previously added * to receive notifications of changes to the set of connected audio devices. */ public void removeOnAudioTrackRoutingListener(OnAudioTrackRoutingListener listener) { synchronized (mRoutingChangeListeners) { if (mRoutingChangeListeners.containsKey(listener)) { mRoutingChangeListeners.remove(listener); } } } /** * Sends device list change notification to all listeners. */ private void broadcastRoutingChange() { Collection<NativeRoutingEventHandlerDelegate> values; synchronized (mRoutingChangeListeners) { values = mRoutingChangeListeners.values(); } for(NativeRoutingEventHandlerDelegate delegate : values) { Handler handler = delegate.getHandler(); if (handler != null) { handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE); } } } //--------------------------------------------------------- // Interface definitions //-------------------- Loading Loading @@ -2137,10 +2205,10 @@ public class AudioTrack * Helper class to handle the forwarding of native events to the appropriate listener * (potentially) handled in a different thread */ private class NativeEventHandlerDelegate { private class NativePositionEventHandlerDelegate { private final Handler mHandler; NativeEventHandlerDelegate(final AudioTrack track, NativePositionEventHandlerDelegate(final AudioTrack track, final OnPlaybackPositionUpdateListener listener, Handler handler) { // find the looper for our new event handler Loading Loading @@ -2188,6 +2256,55 @@ public class AudioTrack } } /** * Helper class to handle the forwarding of native events to the appropriate listener * (potentially) handled in a different thread */ private class NativeRoutingEventHandlerDelegate { private final Handler mHandler; NativeRoutingEventHandlerDelegate(final AudioTrack track, final OnAudioTrackRoutingListener listener, Handler handler) { // find the looper for our new event handler Looper looper; if (handler != null) { looper = handler.getLooper(); } else { // no given handler, use the looper the AudioTrack was created in looper = mInitializationLooper; } // construct the event handler with this looper if (looper != null) { // implement the event handler delegate mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { if (track == null) { return; } switch(msg.what) { case NATIVE_EVENT_ROUTING_CHANGE: if (listener != null) { listener.onAudioTrackRouting(track); } break; default: loge("Unknown native event type: " + msg.what); break; } } }; } else { mHandler = null; } } Handler getHandler() { return mHandler; } } //--------------------------------------------------------- // Java methods called from the native side Loading @@ -2201,7 +2318,7 @@ public class AudioTrack return; } NativeEventHandlerDelegate delegate = track.mEventHandlerDelegate; NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate; if (delegate != null) { Handler handler = delegate.getHandler(); if (handler != null) { Loading
media/java/android/media/OnAudioRecordRoutingListener.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; /** * OnAudioDeviceConnectionListener defines the interface for notification listeners in the * {@link AudioDevicesManager} */ public interface OnAudioRecordRoutingListener { /** * Called when the routing of an AudioRecord changes from either and explicit or * policy rerouting. */ public void onAudioRecordRouting(AudioRecord audioRecord); }