Merge "Clean up AudioRouting API internals." into nyc-dev

am: 0e2e780

* commit '0e2e7806b7092519a1f97364d5c7256251ad03d5':
  Clean up AudioRouting API internals.

Change-Id: I2c1758d8843fc603623cf1ac4c698823ec589111
This commit is contained in:
Jeff Sharkey
2016-04-11 20:46:14 +00:00
committed by android-build-merger
6 changed files with 153 additions and 282 deletions

View File

@@ -19857,8 +19857,8 @@ package android.media {
public class AudioRecord implements android.media.AudioRouting {
ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public int getAudioFormat();
method public int getAudioSessionId();
method public int getAudioSource();
@@ -19883,8 +19883,8 @@ 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 removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public deprecated void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public int setNotificationMarkerPosition(int);
method public int setPositionNotificationPeriod(int);
method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -19918,8 +19918,9 @@ package android.media {
method public abstract void onPeriodicNotification(android.media.AudioRecord);
}
public static abstract interface AudioRecord.OnRoutingChangedListener {
public static abstract deprecated interface AudioRecord.OnRoutingChangedListener implements android.media.AudioRouting.OnRoutingChangedListener {
method public abstract void onRoutingChanged(android.media.AudioRecord);
method public default void onRoutingChanged(android.media.AudioRouting);
}
public final class AudioRecordingConfiguration implements android.os.Parcelable {
@@ -19934,10 +19935,10 @@ package android.media {
}
public abstract interface AudioRouting {
method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public abstract void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public abstract android.media.AudioDeviceInfo getPreferredDevice();
method public abstract android.media.AudioDeviceInfo getRoutedDevice();
method public abstract void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public abstract void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public abstract boolean setPreferredDevice(android.media.AudioDeviceInfo);
}
@@ -19957,8 +19958,8 @@ 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 addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public int attachAuxEffect(int);
method public void flush();
method public int getAudioFormat();
@@ -19990,8 +19991,8 @@ package android.media {
method public void play() throws java.lang.IllegalStateException;
method public void release();
method public int reloadStaticData();
method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public int setAuxEffectSendLevel(float);
method public int setBufferSizeInFrames(int);
method public int setLoopPoints(int, int, int);
@@ -20045,8 +20046,9 @@ package android.media {
method public abstract void onPeriodicNotification(android.media.AudioTrack);
}
public static abstract deprecated interface AudioTrack.OnRoutingChangedListener {
method public abstract deprecated void onRoutingChanged(android.media.AudioTrack);
public static abstract deprecated interface AudioTrack.OnRoutingChangedListener implements android.media.AudioRouting.OnRoutingChangedListener {
method public abstract void onRoutingChanged(android.media.AudioTrack);
method public default void onRoutingChanged(android.media.AudioRouting);
}
public class CamcorderProfile {

View File

@@ -21336,8 +21336,8 @@ package android.media {
public class AudioRecord implements android.media.AudioRouting {
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 addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public int getAudioFormat();
method public int getAudioSessionId();
method public int getAudioSource();
@@ -21362,8 +21362,8 @@ 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 removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public deprecated void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public int setNotificationMarkerPosition(int);
method public int setPositionNotificationPeriod(int);
method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -21399,8 +21399,9 @@ package android.media {
method public abstract void onPeriodicNotification(android.media.AudioRecord);
}
public static abstract interface AudioRecord.OnRoutingChangedListener {
public static abstract deprecated interface AudioRecord.OnRoutingChangedListener implements android.media.AudioRouting.OnRoutingChangedListener {
method public abstract void onRoutingChanged(android.media.AudioRecord);
method public default void onRoutingChanged(android.media.AudioRouting);
}
public final class AudioRecordingConfiguration implements android.os.Parcelable {
@@ -21415,10 +21416,10 @@ package android.media {
}
public abstract interface AudioRouting {
method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public abstract void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public abstract android.media.AudioDeviceInfo getPreferredDevice();
method public abstract android.media.AudioDeviceInfo getRoutedDevice();
method public abstract void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public abstract void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public abstract boolean setPreferredDevice(android.media.AudioDeviceInfo);
}
@@ -21438,8 +21439,8 @@ 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 addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public int attachAuxEffect(int);
method public void flush();
method public int getAudioFormat();
@@ -21471,8 +21472,8 @@ package android.media {
method public void play() throws java.lang.IllegalStateException;
method public void release();
method public int reloadStaticData();
method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public int setAuxEffectSendLevel(float);
method public int setBufferSizeInFrames(int);
method public int setLoopPoints(int, int, int);
@@ -21526,8 +21527,9 @@ package android.media {
method public abstract void onPeriodicNotification(android.media.AudioTrack);
}
public static abstract deprecated interface AudioTrack.OnRoutingChangedListener {
method public abstract deprecated void onRoutingChanged(android.media.AudioTrack);
public static abstract deprecated interface AudioTrack.OnRoutingChangedListener implements android.media.AudioRouting.OnRoutingChangedListener {
method public abstract void onRoutingChanged(android.media.AudioTrack);
method public default void onRoutingChanged(android.media.AudioRouting);
}
public class CamcorderProfile {

View File

@@ -19923,8 +19923,8 @@ package android.media {
public class AudioRecord implements android.media.AudioRouting {
ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public int getAudioFormat();
method public int getAudioSessionId();
method public int getAudioSource();
@@ -19949,8 +19949,8 @@ 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 removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public deprecated void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public int setNotificationMarkerPosition(int);
method public int setPositionNotificationPeriod(int);
method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -19984,8 +19984,9 @@ package android.media {
method public abstract void onPeriodicNotification(android.media.AudioRecord);
}
public static abstract interface AudioRecord.OnRoutingChangedListener {
public static abstract deprecated interface AudioRecord.OnRoutingChangedListener implements android.media.AudioRouting.OnRoutingChangedListener {
method public abstract void onRoutingChanged(android.media.AudioRecord);
method public default void onRoutingChanged(android.media.AudioRouting);
}
public final class AudioRecordingConfiguration implements android.os.Parcelable {
@@ -20000,10 +20001,10 @@ package android.media {
}
public abstract interface AudioRouting {
method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public abstract void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public abstract android.media.AudioDeviceInfo getPreferredDevice();
method public abstract android.media.AudioDeviceInfo getRoutedDevice();
method public abstract void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public abstract void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public abstract boolean setPreferredDevice(android.media.AudioDeviceInfo);
}
@@ -20023,8 +20024,8 @@ 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 addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public int attachAuxEffect(int);
method public void flush();
method public int getAudioFormat();
@@ -20056,8 +20057,8 @@ package android.media {
method public void play() throws java.lang.IllegalStateException;
method public void release();
method public int reloadStaticData();
method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
method public int setAuxEffectSendLevel(float);
method public int setBufferSizeInFrames(int);
method public int setLoopPoints(int, int, int);
@@ -20111,8 +20112,9 @@ package android.media {
method public abstract void onPeriodicNotification(android.media.AudioTrack);
}
public static abstract deprecated interface AudioTrack.OnRoutingChangedListener {
method public abstract deprecated void onRoutingChanged(android.media.AudioTrack);
public static abstract deprecated interface AudioTrack.OnRoutingChangedListener implements android.media.AudioRouting.OnRoutingChangedListener {
method public abstract void onRoutingChanged(android.media.AudioTrack);
method public default void onRoutingChanged(android.media.AudioRouting);
}
public class CamcorderProfile {

View File

@@ -37,6 +37,8 @@ import android.os.ServiceManager;
import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
/**
* The AudioRecord class manages the audio resources for Java applications
* to record audio from the audio input hardware of the platform. This is
@@ -1320,6 +1322,7 @@ public class AudioRecord implements AudioRouting
* Note: The query is only valid if the AudioRecord is currently recording. If it is not,
* <code>getRoutedDevice()</code> will return null.
*/
@Override
public AudioDeviceInfo getRoutedDevice() {
int deviceId = native_getRoutedDeviceId();
if (deviceId == 0) {
@@ -1338,8 +1341,8 @@ public class AudioRecord implements AudioRouting
/*
* Call BEFORE adding a routing callback handler.
*/
private void testEnableNativeRoutingCallbacks() {
if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
private void testEnableNativeRoutingCallbacksLocked() {
if (mRoutingChangeListeners.size() == 0) {
native_enableDeviceCallback();
}
}
@@ -1347,24 +1350,23 @@ public class AudioRecord implements AudioRouting
/*
* Call AFTER removing a routing callback handler.
*/
private void testDisableNativeRoutingCallbacks() {
if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
private void testDisableNativeRoutingCallbacksLocked() {
if (mRoutingChangeListeners.size() == 0) {
native_disableDeviceCallback();
}
}
//--------------------------------------------------------------------------
// >= "N" (Re)Routing Info
// (Re)Routing Info
//--------------------
/**
* The list of AudioRouting.OnRoutingChangedListener interfaces added (with
* {@link AudioRecord#addOnRoutingListener(AudioRouting.OnRoutingChangedListener,
* android.os.Handler)}
* by an app to receive (re)routing notifications.
* {@link AudioRecord#addOnRoutingChangedListener} by an app to receive
* (re)routing notifications.
*/
private ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>
mNewRoutingChangeListeners =
new ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>();
@GuardedBy("mRoutingChangeListeners")
private ArrayMap<AudioRouting.OnRoutingChangedListener,
NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
/**
* Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of
@@ -1375,14 +1377,15 @@ public class AudioRecord implements AudioRouting
* the callback. If <code>null</code>, the {@link Handler} associated with the main
* {@link Looper} will be used.
*/
public void addOnRoutingListener(AudioRouting.OnRoutingChangedListener listener,
@Override
public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
android.os.Handler handler) {
if (listener != null && !mNewRoutingChangeListeners.containsKey(listener)) {
synchronized (mNewRoutingChangeListeners) {
testEnableNativeRoutingCallbacks();
mNewRoutingChangeListeners.put(
listener, new NativeNewRoutingEventHandlerDelegate(this, listener,
handler != null ? handler : new Handler(mInitializationLooper)));
synchronized (mRoutingChangeListeners) {
if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
testEnableNativeRoutingCallbacksLocked();
mRoutingChangeListeners.put(
listener, new NativeRoutingEventHandlerDelegate(this, listener,
handler != null ? handler : new Handler(mInitializationLooper)));
}
}
}
@@ -1393,39 +1396,42 @@ public class AudioRecord implements AudioRouting
* @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
* to remove.
*/
public void removeOnRoutingListener(AudioRouting.OnRoutingChangedListener listener) {
synchronized (mNewRoutingChangeListeners) {
if (mNewRoutingChangeListeners.containsKey(listener)) {
mNewRoutingChangeListeners.remove(listener);
testDisableNativeRoutingCallbacks();
@Override
public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
if (mRoutingChangeListeners.containsKey(listener)) {
mRoutingChangeListeners.remove(listener);
testDisableNativeRoutingCallbacksLocked();
}
}
}
//--------------------------------------------------------------------------
// Marshmallow (Re)Routing Info
// (Re)Routing Info
//--------------------
/**
* Defines the interface by which applications can receive notifications of routing
* changes for the associated {@link AudioRecord}.
* Defines the interface by which applications can receive notifications of
* routing changes for the associated {@link AudioRecord}.
*
* @deprecated users should switch to the general purpose
* {@link AudioRouting.OnRoutingChangedListener} class instead.
*/
public interface OnRoutingChangedListener {
@Deprecated
public interface OnRoutingChangedListener extends AudioRouting.OnRoutingChangedListener {
/**
* Called when the routing of an AudioRecord changes from either and explicit or
* policy rerouting. Use {@link #getRoutedDevice()} to retrieve the newly routed-from
* device.
* Called when the routing of an AudioRecord changes from either and
* explicit or policy rerouting. Use {@link #getRoutedDevice()} to
* retrieve the newly routed-from device.
*/
public void onRoutingChanged(AudioRecord audioRecord);
}
/**
* The list of AudioRecord.OnRoutingChangedListener interface added (with
* {@link AudioRecord#addOnRoutingChangedListener(OnRoutingChangedListener,android.os.Handler)}
* by an app to receive (re)routing notifications.
*/
private ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>
mRoutingChangeListeners =
new ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>();
@Override
default public void onRoutingChanged(AudioRouting router) {
if (router instanceof AudioRecord) {
onRoutingChanged((AudioRecord) router);
}
}
}
/**
* Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
@@ -1435,88 +1441,28 @@ public class AudioRecord implements AudioRouting
* @param handler Specifies the {@link Handler} object for the thread on which to execute
* the callback. If <code>null</code>, the {@link Handler} associated with the main
* {@link Looper} will be used.
* @deprecated users should switch to the general purpose
* {@link AudioRouting.OnRoutingChangedListener} class instead.
*/
@Deprecated
public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
android.os.Handler handler) {
if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
synchronized (mRoutingChangeListeners) {
testEnableNativeRoutingCallbacks();
mRoutingChangeListeners.put(
listener, new NativeRoutingEventHandlerDelegate(this, listener,
handler != null ? handler : new Handler(mInitializationLooper)));
}
}
addOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener, handler);
}
/**
* Removes an {@link OnRoutingChangedListener} which has been previously added
* to receive rerouting notifications.
* @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
* @deprecated users should switch to the general purpose
* {@link AudioRouting.OnRoutingChangedListener} class instead.
*/
@Deprecated
public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
if (mRoutingChangeListeners.containsKey(listener)) {
mRoutingChangeListeners.remove(listener);
testDisableNativeRoutingCallbacks();
}
}
removeOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener);
}
/**
* >= "N" Routing
* Helper class to handle the forwarding of native events to the appropriate listener
* (potentially) handled in a different thread
*/
private class NativeNewRoutingEventHandlerDelegate {
private final Handler mHandler;
NativeNewRoutingEventHandlerDelegate(final AudioRecord record,
final AudioRouting.OnRoutingChangedListener 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 AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
if (listener != null) {
listener.onRoutingChanged(record);
}
break;
default:
loge("Unknown native event type: " + msg.what);
break;
}
}
};
} else {
mHandler = null;
}
}
Handler getHandler() {
return mHandler;
}
}
/**
* Marshmallow Routing
* Helper class to handle the forwarding of native events to the appropriate listener
* (potentially) handled in a different thread
*/
@@ -1524,7 +1470,7 @@ public class AudioRecord implements AudioRouting
private final Handler mHandler;
NativeRoutingEventHandlerDelegate(final AudioRecord record,
final OnRoutingChangedListener listener,
final AudioRouting.OnRoutingChangedListener listener,
Handler handler) {
// find the looper for our new event handler
Looper looper;
@@ -1571,26 +1517,12 @@ public class AudioRecord implements AudioRouting
*/
private void broadcastRoutingChange() {
AudioManager.resetAudioPortGeneration();
// Marshmallow Routing
Collection<NativeRoutingEventHandlerDelegate> values;
synchronized (mRoutingChangeListeners) {
values = mRoutingChangeListeners.values();
}
for(NativeRoutingEventHandlerDelegate delegate : values) {
Handler handler = delegate.getHandler();
if (handler != null) {
handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
}
}
// >= "N" Routing
Collection<NativeNewRoutingEventHandlerDelegate> newValues;
synchronized (mNewRoutingChangeListeners) {
newValues = mNewRoutingChangeListeners.values();
}
for(NativeNewRoutingEventHandlerDelegate delegate : newValues) {
Handler handler = delegate.getHandler();
if (handler != null) {
handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
Handler handler = delegate.getHandler();
if (handler != null) {
handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
}
}
}
}
@@ -1623,6 +1555,7 @@ public class AudioRecord implements AudioRouting
* @return true if successful, false if the specified {@link AudioDeviceInfo} is non-null and
* does not correspond to a valid audio input device.
*/
@Override
public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
// Do some validation....
if (deviceInfo != null && !deviceInfo.isSource()) {
@@ -1643,6 +1576,7 @@ public class AudioRecord implements AudioRouting
* Returns the selected input specified by {@link #setPreferredDevice}. Note that this
* is not guarenteed to correspond to the actual device being used for recording.
*/
@Override
public AudioDeviceInfo getPreferredDevice() {
synchronized (this) {
return mPreferredDevice;
@@ -1683,7 +1617,6 @@ public class AudioRecord implements AudioRouting
* (potentially) handled in a different thread
*/
private class NativeEventHandler extends Handler {
private final AudioRecord mAudioRecord;
NativeEventHandler(AudioRecord recorder, Looper looper) {
@@ -1714,8 +1647,7 @@ public class AudioRecord implements AudioRouting
break;
}
}
};
}
//---------------------------------------------------------
// Java methods called from the native side

View File

@@ -57,7 +57,7 @@ public interface AudioRouting {
* the callback. If <code>null</code>, the {@link Handler} associated with the main
* {@link Looper} will be used.
*/
public void addOnRoutingListener(OnRoutingChangedListener listener,
public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
Handler handler);
/**
@@ -66,7 +66,7 @@ public interface AudioRouting {
* @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
* to remove.
*/
public void removeOnRoutingListener(OnRoutingChangedListener listener);
public void removeOnRoutingChangedListener(OnRoutingChangedListener listener);
/**
* Defines the interface by which applications can receive notifications of routing

View File

@@ -40,6 +40,7 @@ import android.os.ServiceManager;
import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
/**
@@ -1489,6 +1490,7 @@ public class AudioTrack implements AudioRouting
* @deprecated Applications should use {@link #setVolume} instead, as it
* more gracefully scales down to mono, and up to multi-channel content beyond stereo.
*/
@Deprecated
public int setStereoVolume(float leftGain, float rightGain) {
if (isRestricted()) {
return SUCCESS;
@@ -2397,6 +2399,7 @@ public class AudioTrack implements AudioRouting
* @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
* does not correspond to a valid audio output device.
*/
@Override
public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
// Do some validation....
if (deviceInfo != null && !deviceInfo.isSink()) {
@@ -2416,6 +2419,7 @@ public class AudioTrack implements AudioRouting
* Returns the selected output specified by {@link #setPreferredDevice}. Note that this
* is not guaranteed to correspond to the actual device being used for playback.
*/
@Override
public AudioDeviceInfo getPreferredDevice() {
synchronized (this) {
return mPreferredDevice;
@@ -2427,6 +2431,7 @@ public class AudioTrack implements AudioRouting
* Note: The query is only valid if the AudioTrack is currently playing. If it is not,
* <code>getRoutedDevice()</code> will return null.
*/
@Override
public AudioDeviceInfo getRoutedDevice() {
int deviceId = native_getRoutedDeviceId();
if (deviceId == 0) {
@@ -2445,8 +2450,8 @@ public class AudioTrack implements AudioRouting
/*
* Call BEFORE adding a routing callback handler.
*/
private void testEnableNativeRoutingCallbacks() {
if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
private void testEnableNativeRoutingCallbacksLocked() {
if (mRoutingChangeListeners.size() == 0) {
native_enableDeviceCallback();
}
}
@@ -2454,24 +2459,23 @@ public class AudioTrack implements AudioRouting
/*
* Call AFTER removing a routing callback handler.
*/
private void testDisableNativeRoutingCallbacks() {
if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
private void testDisableNativeRoutingCallbacksLocked() {
if (mRoutingChangeListeners.size() == 0) {
native_disableDeviceCallback();
}
}
//--------------------------------------------------------------------------
// >= "N" (Re)Routing Info
// (Re)Routing Info
//--------------------
/**
* The list of AudioRouting.OnRoutingChangedListener interfaces added (with
* {@link AudioTrack#addOnRoutingListener(AudioRouting.OnRoutingChangedListener,
* android.os.Handler)}
* by an app to receive (re)routing notifications.
* {@link AudioRecord#addOnRoutingChangedListener} by an app to receive
* (re)routing notifications.
*/
private ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>
mNewRoutingChangeListeners =
new ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>();
@GuardedBy("mRoutingChangeListeners")
private ArrayMap<AudioRouting.OnRoutingChangedListener,
NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
/**
* Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
@@ -2482,14 +2486,15 @@ public class AudioTrack implements AudioRouting
* the callback. If <code>null</code>, the {@link Handler} associated with the main
* {@link Looper} will be used.
*/
public void addOnRoutingListener(AudioRouting.OnRoutingChangedListener listener,
@Override
public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
Handler handler) {
if (listener != null && !mNewRoutingChangeListeners.containsKey(listener)) {
synchronized (mNewRoutingChangeListeners) {
testEnableNativeRoutingCallbacks();
mNewRoutingChangeListeners.put(
listener, new NativeNewRoutingEventHandlerDelegate(this, listener,
handler != null ? handler : new Handler(mInitializationLooper)));
synchronized (mRoutingChangeListeners) {
if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
testEnableNativeRoutingCallbacksLocked();
mRoutingChangeListeners.put(
listener, new NativeRoutingEventHandlerDelegate(this, listener,
handler != null ? handler : new Handler(mInitializationLooper)));
}
}
}
@@ -2500,39 +2505,42 @@ public class AudioTrack implements AudioRouting
* @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
* to remove.
*/
public void removeOnRoutingListener(AudioRouting.OnRoutingChangedListener listener) {
if (mNewRoutingChangeListeners.containsKey(listener)) {
mNewRoutingChangeListeners.remove(listener);
@Override
public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
if (mRoutingChangeListeners.containsKey(listener)) {
mRoutingChangeListeners.remove(listener);
}
testDisableNativeRoutingCallbacksLocked();
}
testDisableNativeRoutingCallbacks();
}
//--------------------------------------------------------------------------
// Marshmallow (Re)Routing Info
// (Re)Routing Info
//--------------------
/**
* Defines the interface by which applications can receive notifications of routing
* changes for the associated {@link AudioTrack}.
* Defines the interface by which applications can receive notifications of
* routing changes for the associated {@link AudioTrack}.
*
* @deprecated users should switch to the general purpose
* {@link AudioRouting.OnRoutingChangedListener} class instead.
*/
@Deprecated
public interface OnRoutingChangedListener {
public interface OnRoutingChangedListener extends AudioRouting.OnRoutingChangedListener {
/**
* Called when the routing of an AudioTrack changes from either and explicit or
* policy rerouting. Use {@link #getRoutedDevice()} to retrieve the newly routed-to
* device.
* Called when the routing of an AudioTrack changes from either and
* explicit or policy rerouting. Use {@link #getRoutedDevice()} to
* retrieve the newly routed-to device.
*/
@Deprecated
public void onRoutingChanged(AudioTrack audioTrack);
}
/**
* The list of AudioTrack.OnRoutingChangedListener interfaces added (with
* {@link AudioTrack#addOnRoutingChangedListener(OnRoutingChangedListener, android.os.Handler)}
* by an app to receive (re)routing notifications.
*/
private ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>
mRoutingChangeListeners =
new ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>();
@Override
default public void onRoutingChanged(AudioRouting router) {
if (router instanceof AudioTrack) {
onRoutingChanged((AudioTrack) router);
}
}
}
/**
* Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
@@ -2542,33 +2550,25 @@ public class AudioTrack implements AudioRouting
* @param handler Specifies the {@link Handler} object for the thread on which to execute
* the callback. If <code>null</code>, the {@link Handler} associated with the main
* {@link Looper} will be used.
* @deprecated users should switch to the general purpose
* {@link AudioRouting.OnRoutingChangedListener} class instead.
*/
@Deprecated
public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
android.os.Handler handler) {
if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
synchronized (mRoutingChangeListeners) {
testEnableNativeRoutingCallbacks();
mRoutingChangeListeners.put(
listener, new NativeRoutingEventHandlerDelegate(this, listener,
handler != null ? handler : new Handler(mInitializationLooper)));
}
}
addOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener, handler);
}
/**
* Removes an {@link OnRoutingChangedListener} which has been previously added
* to receive rerouting notifications.
* @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
* @deprecated users should switch to the general purpose
* {@link AudioRouting.OnRoutingChangedListener} class instead.
*/
@Deprecated
public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
if (mRoutingChangeListeners.containsKey(listener)) {
mRoutingChangeListeners.remove(listener);
}
testDisableNativeRoutingCallbacks();
}
removeOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener);
}
/**
@@ -2576,27 +2576,12 @@ public class AudioTrack implements AudioRouting
*/
private void broadcastRoutingChange() {
AudioManager.resetAudioPortGeneration();
// Marshmallow Routing
Collection<NativeRoutingEventHandlerDelegate> values;
synchronized (mRoutingChangeListeners) {
values = mRoutingChangeListeners.values();
}
for(NativeRoutingEventHandlerDelegate delegate : values) {
Handler handler = delegate.getHandler();
if (handler != null) {
handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
}
}
// >= "N" Routing
Collection<NativeNewRoutingEventHandlerDelegate> newValues;
synchronized (mNewRoutingChangeListeners) {
newValues = mNewRoutingChangeListeners.values();
}
for(NativeNewRoutingEventHandlerDelegate delegate : newValues) {
Handler handler = delegate.getHandler();
if (handler != null) {
handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
Handler handler = delegate.getHandler();
if (handler != null) {
handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
}
}
}
}
@@ -2681,7 +2666,6 @@ public class AudioTrack implements AudioRouting
}
/**
* Marshmallow Routing API.
* Helper class to handle the forwarding of native events to the appropriate listener
* (potentially) handled in a different thread
*/
@@ -2689,57 +2673,6 @@ public class AudioTrack implements AudioRouting
private final Handler mHandler;
NativeRoutingEventHandlerDelegate(final AudioTrack track,
final OnRoutingChangedListener 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 AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
if (listener != null) {
listener.onRoutingChanged(track);
}
break;
default:
loge("Unknown native event type: " + msg.what);
break;
}
}
};
} else {
mHandler = null;
}
}
Handler getHandler() {
return mHandler;
}
}
/**
* Marshmallow Routing API.
* Helper class to handle the forwarding of native events to the appropriate listener
* (potentially) handled in a different thread
*/
private class NativeNewRoutingEventHandlerDelegate {
private final Handler mHandler;
NativeNewRoutingEventHandlerDelegate(final AudioTrack track,
final AudioRouting.OnRoutingChangedListener listener,
Handler handler) {
// find the looper for our new event handler