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();
method public int getNotificationMarkerPosition();
method public int getPositionNotificationPeriod();
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);
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 void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener);
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();
method public int getPlaybackRate();
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();
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);
method public abstract void onAudioDeviceConnection();
}
+ 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();
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();
method public int getNotificationMarkerPosition();
method public int getPositionNotificationPeriod();
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);
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 void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener);
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();
method public int getPlaybackRate();
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();
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);
method public abstract void onAudioDeviceConnection();
}
+ 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();
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;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.ArrayMap;
import android.util.Log;
/**
*/
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 */
* 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.
*/
}
+ //--------------------------------------------------------------------------
+ // (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
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.nio.NioUtils;
+import java.util.Collection;
import android.annotation.IntDef;
import android.annotation.NonNull;
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;
*/
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";
/**
* Handler for events coming from the native code.
*/
- private NativeEventHandlerDelegate mEventHandlerDelegate;
+ private NativePositionEventHandlerDelegate mEventHandlerDelegate;
/**
* Looper associated with the thread that creates the AudioTrack instance.
*/
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;
}
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
//--------------------
* 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
}
}
+ /**
+ * 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
return;
}
- NativeEventHandlerDelegate delegate = track.mEventHandlerDelegate;
+ NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate;
if (delegate != null) {
Handler handler = delegate.getHandler();
if (handler != null) {
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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 OnAudioTrackRoutingListener {
+ /**
+ * Called when the routing of an AudioTrack changes from either and explicit or
+ * policy rerouting.
+ */
+ public void onAudioTrackRouting(AudioTrack audioTrack);
+}