diff options
author | Jeff Brown <jeffbrown@google.com> | 2014-07-10 22:50:50 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2014-07-14 04:06:44 -0700 |
commit | 01a500ed1c6ae3fff66678144ae637aa8cad0ecc (patch) | |
tree | 579571453290b6824da22fa9748286bfc3acb727 /media/java | |
parent | 9fb7b07c6cbdd1c6f394bfc456ccc034619b6727 (diff) | |
download | frameworks_base-01a500ed1c6ae3fff66678144ae637aa8cad0ecc.zip frameworks_base-01a500ed1c6ae3fff66678144ae637aa8cad0ecc.tar.gz frameworks_base-01a500ed1c6ae3fff66678144ae637aa8cad0ecc.tar.bz2 |
Delete first draft of media routing APIs.
The new APIs will not be as tightly integrated into MediaSession.
Change-Id: I5cfd37d9d8d0c5d46c55edb5cf0772a8f1ef13ab
Diffstat (limited to 'media/java')
28 files changed, 29 insertions, 2613 deletions
diff --git a/media/java/android/media/routeprovider/IRouteConnection.aidl b/media/java/android/media/routeprovider/IRouteConnection.aidl deleted file mode 100644 index 15c8039..0000000 --- a/media/java/android/media/routeprovider/IRouteConnection.aidl +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2014 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.routeprovider; - -import android.media.session.RouteCommand; -import android.os.ResultReceiver; - -/** - * Interface for a specific connected route. - * @hide - */ -oneway interface IRouteConnection { - void onCommand(in RouteCommand command, in ResultReceiver cb); - void disconnect(); -}
\ No newline at end of file diff --git a/media/java/android/media/routeprovider/IRouteProvider.aidl b/media/java/android/media/routeprovider/IRouteProvider.aidl deleted file mode 100644 index c36f6a7..0000000 --- a/media/java/android/media/routeprovider/IRouteProvider.aidl +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2014 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.routeprovider; - -import android.media.routeprovider.IRouteConnection; -import android.media.routeprovider.IRouteProviderCallback; -import android.media.routeprovider.RouteRequest; -import android.media.session.RouteInfo; -import android.os.Bundle; -import android.os.ResultReceiver; - -/** - * Interface to an app's RouteProviderService. - * @hide - */ -oneway interface IRouteProvider { - void registerCallback(in IRouteProviderCallback cb); - void unregisterCallback(in IRouteProviderCallback cb); - void updateDiscoveryRequests(in List<RouteRequest> requests); - - void getAvailableRoutes(in List<RouteRequest> requests, in ResultReceiver cb); - void connect(in RouteInfo route, in RouteRequest request, in ResultReceiver cb); -}
\ No newline at end of file diff --git a/media/java/android/media/routeprovider/IRouteProviderCallback.aidl b/media/java/android/media/routeprovider/IRouteProviderCallback.aidl deleted file mode 100644 index 9185347..0000000 --- a/media/java/android/media/routeprovider/IRouteProviderCallback.aidl +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2014 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.routeprovider; - -import android.media.routeprovider.IRouteConnection; -import android.media.session.RouteEvent; -import android.os.Bundle; -import android.os.ResultReceiver; - -/** - * System's provider callback interface. - * @hide - */ -oneway interface IRouteProviderCallback { - void onRoutesChanged(); - void onConnectionStateChanged(in IRouteConnection connection, int state); - void onConnectionTerminated(in IRouteConnection connection); - void onRouteEvent(in RouteEvent event); -}
\ No newline at end of file diff --git a/media/java/android/media/routeprovider/RouteConnection.java b/media/java/android/media/routeprovider/RouteConnection.java deleted file mode 100644 index 43692c1..0000000 --- a/media/java/android/media/routeprovider/RouteConnection.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2014 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.routeprovider; - -import android.media.routeprovider.IRouteConnection; -import android.media.session.RouteCommand; -import android.media.session.RouteEvent; -import android.media.session.RouteInfo; -import android.media.session.RouteInterface; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.text.TextUtils; -import android.util.ArrayMap; -import android.util.Log; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; - -/** - * Represents an ongoing connection between an application and a media route - * offered by a media route provider. - * <p> - * The media route provider should add interfaces to the connection before - * returning it to the system in order to receive commands from clients on those - * interfaces. Use {@link #addRouteInterface(String)} to add an interface and - * {@link #getRouteInterface(String)} to retrieve the interface's handle anytime - * after it has been added. - * @hide - */ -public final class RouteConnection { - private static final String TAG = "RouteConnection"; - private final ConnectionStub mBinder; - private final ArrayList<String> mIfaceNames = new ArrayList<String>(); - private final ArrayMap<String, RouteInterfaceHandler> mIfaces - = new ArrayMap<String, RouteInterfaceHandler>(); - private final RouteProviderService mProvider; - private final RouteInfo mRoute; - - private boolean mPublished; - - /** - * Create a new connection for the given Provider and Route. - * - * @param provider The provider this route is associated with. - * @param route The route this is a connection to. - */ - public RouteConnection(RouteProviderService provider, RouteInfo route) { - if (provider == null) { - throw new IllegalArgumentException("provider may not be null."); - } - if (route == null) { - throw new IllegalArgumentException("route may not be null."); - } - mBinder = new ConnectionStub(this); - mProvider = provider; - mRoute = route; - } - - /** - * Add an interface to this route connection. All interfaces must be added - * to the connection before the connection is returned to the system. - * - * @param ifaceName The name of the interface to add - * @return The route interface that was registered - */ - public RouteInterfaceHandler addRouteInterface(String ifaceName) { - if (TextUtils.isEmpty(ifaceName)) { - throw new IllegalArgumentException("The interface's name may not be empty"); - } - if (mPublished) { - throw new IllegalStateException( - "Connection has already been published to the system."); - } - RouteInterfaceHandler iface = mIfaces.get(ifaceName); - if (iface == null) { - iface = new RouteInterfaceHandler(this, ifaceName); - mIfaceNames.add(ifaceName); - mIfaces.put(ifaceName, iface); - } else { - Log.w(TAG, "Attempted to add an interface that already exists"); - } - return iface; - } - - /** - * Get the interface instance for the specified interface name. If the - * interface was not added to this connection null will be returned. - * - * @param ifaceName The name of the interface to get. - * @return The route interface with that name or null. - */ - public RouteInterfaceHandler getRouteInterface(String ifaceName) { - return mIfaces.get(ifaceName); - } - - /** - * Close the connection and inform the system that it may no longer be used. - */ - public void shutDown() { - mProvider.disconnect(this); - } - - /** - * @hide - */ - public void sendEvent(String iface, String event, Bundle extras) { - RouteEvent e = new RouteEvent(mBinder, iface, event, extras); - mProvider.sendRouteEvent(e); - } - - /** - * @hide - */ - IRouteConnection.Stub getBinder() { - return mBinder; - } - - /** - * @hide - */ - void publish() { - mPublished = true; - } - - private static class ConnectionStub extends IRouteConnection.Stub { - private final WeakReference<RouteConnection> mConnection; - - public ConnectionStub(RouteConnection connection) { - mConnection = new WeakReference<RouteConnection>(connection); - } - - @Override - public void onCommand(RouteCommand command, ResultReceiver cb) { - RouteConnection connection = mConnection.get(); - if (connection != null) { - RouteInterfaceHandler iface = connection.mIfaces.get(command.getIface()); - if (iface != null) { - iface.onCommand(command.getEvent(), command.getExtras(), cb); - } else if (cb != null) { - cb.send(RouteInterface.RESULT_INTERFACE_NOT_SUPPORTED, null); - } - } - } - - @Override - public void disconnect() { - // TODO - } - } -} diff --git a/media/java/android/media/routeprovider/RouteInterfaceHandler.java b/media/java/android/media/routeprovider/RouteInterfaceHandler.java deleted file mode 100644 index e7f8bbf..0000000 --- a/media/java/android/media/routeprovider/RouteInterfaceHandler.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2014 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.routeprovider; - -import android.media.session.Route; -import android.media.session.MediaSession; -import android.media.session.RouteInterface; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.ResultReceiver; -import android.text.TextUtils; -import android.util.Log; - -import java.util.ArrayList; - -/** - * Represents an interface that an application may use to send requests to a - * connected media route. - * <p> - * A {@link RouteProviderService} may expose multiple interfaces on a - * {@link RouteConnection} for a {@link MediaSession} to interact with. A - * provider creates an interface with - * {@link RouteConnection#addRouteInterface(String)} to allow messages to be - * routed appropriately. Events are then sent through a specific interface and - * all commands being sent on the interface will be sent to any registered - * {@link CommandListener}s. - * <p> - * An interface instance can only be registered on one {@link RouteConnection}. - * To use the same interface on multiple connections a new instance must be - * created for each connection. - * <p> - * It is recommended you wrap this interface with a standard implementation to - * avoid errors, but for simple interfaces this class may be used directly. TODO - * add link to sample code. - * @hide - */ -public final class RouteInterfaceHandler { - private static final String TAG = "RouteInterfaceHandler"; - - private final Object mLock = new Object(); - private final RouteConnection mConnection; - private final String mName; - - private ArrayList<MessageHandler> mListeners = new ArrayList<MessageHandler>(); - - /** - * Create a new RouteInterface for a given connection. This can be used to - * send events on the given interface and register listeners for commands - * from the connected session. - * - * @param connection The connection this interface sends events on - * @param ifaceName The name of this interface - * @hide - */ - public RouteInterfaceHandler(RouteConnection connection, String ifaceName) { - if (connection == null) { - throw new IllegalArgumentException("connection may not be null"); - } - if (TextUtils.isEmpty(ifaceName)) { - throw new IllegalArgumentException("ifaceName can not be empty"); - } - mConnection = connection; - mName = ifaceName; - } - - /** - * Send an event on this interface to the connected session. - * - * @param event The event to send - * @param extras Any extras for the event - */ - public void sendEvent(String event, Bundle extras) { - mConnection.sendEvent(mName, event, extras); - } - - /** - * Send a result from a command to the specified callback. The result codes - * in {@link RouteInterface} must be used. More information - * about the result, whether successful or an error, should be included in - * the extras. - * - * @param cb The callback to send the result to - * @param resultCode The result code for the call - * @param extras Any extras to include - */ - public static void sendResult(ResultReceiver cb, int resultCode, Bundle extras) { - if (cb != null) { - cb.send(resultCode, extras); - } - } - - /** - * Add a listener for this interface. If a handler is specified callbacks - * will be performed on the handler's thread, otherwise the callers thread - * will be used. - * - * @param listener The listener to receive calls on. - * @param handler The handler whose thread to post calls on or null. - */ - public void addListener(CommandListener listener, Handler handler) { - if (listener == null) { - throw new IllegalArgumentException("listener may not be null"); - } - Looper looper = handler != null ? handler.getLooper() : Looper.myLooper(); - synchronized (mLock) { - if (findIndexOfListenerLocked(listener) != -1) { - Log.d(TAG, "Listener is already added, ignoring"); - return; - } - mListeners.add(new MessageHandler(looper, listener)); - } - } - - /** - * Remove a listener from this interface. - * - * @param listener The listener to stop receiving commands on. - */ - public void removeListener(CommandListener listener) { - if (listener == null) { - throw new IllegalArgumentException("listener may not be null"); - } - synchronized (mLock) { - int index = findIndexOfListenerLocked(listener); - if (index != -1) { - mListeners.remove(index); - } - } - } - - /** - * @hide - */ - public void onCommand(String command, Bundle args, ResultReceiver cb) { - synchronized (mLock) { - Command cmd = new Command(command, args, cb); - for (int i = mListeners.size() - 1; i >= 0; i--) { - mListeners.get(i).post(MessageHandler.MSG_COMMAND, cmd); - } - } - } - - /** - * Get the interface name. - * - * @return The name of this interface - */ - public String getName() { - return mName; - } - - private int findIndexOfListenerLocked(CommandListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Callback cannot be null"); - } - for (int i = mListeners.size() - 1; i >= 0; i--) { - MessageHandler handler = mListeners.get(i); - if (listener == handler.mListener) { - return i; - } - } - return -1; - } - - /** - * Handles commands sent to the interface. - * <p> - * Register an InterfaceListener using {@link #addListener}. - */ - public abstract static class CommandListener { - /** - * This is called when a command is received that matches this - * interface. Commands are sent by a {@link MediaSession} that is - * connected to the route this interface is registered with. - * - * @param iface The interface the command was received on. - * @param command The command or method to invoke. - * @param args Any args that were included with the command. May be - * null. - * @param cb The callback provided to send a response on. May be null. - * @return true if the command was handled, false otherwise. If the - * command was not handled an error will be sent automatically. - * true may be returned if the command will be handled - * asynchronously. - * @see Route - * @see MediaSession - */ - public abstract boolean onCommand(RouteInterfaceHandler iface, String command, Bundle args, - ResultReceiver cb); - } - - private class MessageHandler extends Handler { - private static final int MSG_COMMAND = 1; - - private final CommandListener mListener; - - public MessageHandler(Looper looper, CommandListener listener) { - super(looper, null, true /* async */); - mListener = listener; - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_COMMAND: - Command cmd = (Command) msg.obj; - if (!mListener.onCommand(RouteInterfaceHandler.this, cmd.command, cmd.args, cmd.cb)) { - sendResult(cmd.cb, RouteInterface.RESULT_COMMAND_NOT_SUPPORTED, - null); - } - break; - } - } - - public void post(int what, Object obj) { - obtainMessage(what, obj).sendToTarget(); - } - } - - private final static class Command { - public final String command; - public final Bundle args; - public final ResultReceiver cb; - - public Command(String command, Bundle args, ResultReceiver cb) { - this.command = command; - this.args = args; - this.cb = cb; - } - } -} diff --git a/media/java/android/media/routeprovider/RoutePlaybackControlsHandler.java b/media/java/android/media/routeprovider/RoutePlaybackControlsHandler.java deleted file mode 100644 index f2c40d2..0000000 --- a/media/java/android/media/routeprovider/RoutePlaybackControlsHandler.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2014 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.routeprovider; - -import android.media.session.RoutePlaybackControls; -import android.media.session.RouteInterface; -import android.media.session.PlaybackState; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.text.TextUtils; -import android.util.Log; - -/** - * Standard wrapper for using playback controls over a {@link RouteInterfaceHandler}. - * This is the provider half of the interface. Sessions should use - * {@link RoutePlaybackControls} to interact with this interface. - * @hide - */ -public final class RoutePlaybackControlsHandler { - private static final String TAG = "RoutePlaybackControls"; - - private final RouteInterfaceHandler mIface; - - private RoutePlaybackControlsHandler(RouteInterfaceHandler iface) { - mIface = iface; - } - - /** - * Add this interface to the specified route and return a handle for - * communicating on the interface. - * - * @param connection The connection to register this interface on. - * @return A handle for communicating on this interface. - */ - public static RoutePlaybackControlsHandler addTo(RouteConnection connection) { - if (connection == null) { - throw new IllegalArgumentException("connection may not be null"); - } - RouteInterfaceHandler iface = connection - .addRouteInterface(RoutePlaybackControls.NAME); - - return new RoutePlaybackControlsHandler(iface); - } - - /** - * Add a {@link Listener} to this interface. The listener will receive - * commands on the caller's thread. - * - * @param listener The listener to send commands to. - */ - public void addListener(Listener listener) { - addListener(listener, null); - } - - /** - * Add a {@link Listener} to this interface. The listener will receive - * updates on the handler's thread. If no handler is specified the caller's - * thread will be used instead. - * - * @param listener The listener to send commands to. - * @param handler The handler whose thread calls should be posted on. May be - * null. - */ - public void addListener(Listener listener, Handler handler) { - mIface.addListener(listener, handler); - } - - /** - * Remove a {@link Listener} from this interface. - * - * @param listener The Listener to remove. - */ - public void removeListener(Listener listener) { - mIface.removeListener(listener); - } - - /** - * Publish the current playback state to the system and any controllers. - * Valid values are defined in {@link PlaybackState}. TODO create - * RoutePlaybackState. - * - * @param state - */ - public void sendPlaybackChangeEvent(int state) { - Bundle extras = new Bundle(); - extras.putInt(RoutePlaybackControls.KEY_VALUE1, state); - mIface.sendEvent(RoutePlaybackControls.EVENT_PLAYSTATE_CHANGE, extras); - } - - /** - * Command handler for the RoutePlaybackControls interface. You can add a - * Listener to the interface using {@link #addListener}. - */ - public static abstract class Listener extends RouteInterfaceHandler.CommandListener { - - @Override - public final boolean onCommand(RouteInterfaceHandler iface, String method, Bundle extras, - ResultReceiver cb) { - if (RoutePlaybackControls.CMD_FAST_FORWARD.equals(method)) { - boolean success = fastForward(); - // TODO specify type of error - RouteInterfaceHandler.sendResult(cb, success - ? RouteInterface.RESULT_SUCCESS - : RouteInterface.RESULT_ERROR, null); - return true; - } else if (RoutePlaybackControls.CMD_GET_CURRENT_POSITION.equals(method)) { - Bundle result = new Bundle(); - result.putLong(RoutePlaybackControls.KEY_VALUE1, getCurrentPosition()); - RouteInterfaceHandler.sendResult(cb, RouteInterface.RESULT_SUCCESS, - result); - return true; - } else if (RoutePlaybackControls.CMD_GET_CAPABILITIES.equals(method)) { - Bundle result = new Bundle(); - result.putLong(RoutePlaybackControls.KEY_VALUE1, getCapabilities()); - RouteInterfaceHandler.sendResult(cb, RouteInterface.RESULT_SUCCESS, - result); - return true; - } else if (RoutePlaybackControls.CMD_PLAY_NOW.equals(method)) { - playNow(extras.getString(RoutePlaybackControls.KEY_VALUE1, null), cb); - return true; - } else if (RoutePlaybackControls.CMD_RESUME.equals(method)) { - boolean success = resume(); - RouteInterfaceHandler.sendResult(cb, success - ? RouteInterface.RESULT_SUCCESS - : RouteInterface.RESULT_ERROR, null); - return true; - } else if (RoutePlaybackControls.CMD_PAUSE.equals(method)) { - boolean success = pause(); - RouteInterfaceHandler.sendResult(cb, success - ? RouteInterface.RESULT_SUCCESS - : RouteInterface.RESULT_ERROR, null); - return true; - } else { - // The command wasn't recognized - } - return false; - } - - /** - * Override to handle fast forwarding. - * - * @return true if the request succeeded, false otherwise - */ - public boolean fastForward() { - Log.w(TAG, "fastForward is not supported."); - return false; - } - - /** - * Override to handle getting the current position of playback in - * millis. - * - * @return The current position in millis or -1 - */ - public long getCurrentPosition() { - Log.w(TAG, "getCurrentPosition is not supported"); - return -1; - } - - /** - * Override to handle getting the set of capabilities currently - * available. - * - * @return A bit mask of the supported capabilities - */ - public long getCapabilities() { - Log.w(TAG, "getCapabilities is not supported"); - return 0; - } - - /** - * Override to handle play now requests. - * - * @param content The uri of the item to play. - * @param cb The callback to send the result to. - */ - public void playNow(String content, ResultReceiver cb) { - Log.w(TAG, "playNow is not supported"); - if (cb != null) { - // We do this directly since we don't have a reference to the - // iface - cb.send(RouteInterface.RESULT_COMMAND_NOT_SUPPORTED, null); - } - } - - /** - * Override to handle resume requests. Return true if the call was - * handled, even if it was a no-op. - * - * @return true if the call was handled. - */ - public boolean resume() { - Log.w(TAG, "resume is not supported"); - return false; - } - - /** - * Override to handle pause requests. Return true if the call was - * handled, even if it was a no-op. - * - * @return true if the call was handled. - */ - public boolean pause() { - Log.w(TAG, "pause is not supported"); - return false; - } - } -} diff --git a/media/java/android/media/routeprovider/RouteProviderService.java b/media/java/android/media/routeprovider/RouteProviderService.java deleted file mode 100644 index a6ef0bb..0000000 --- a/media/java/android/media/routeprovider/RouteProviderService.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2014 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.routeprovider; - -import android.app.Service; -import android.content.Intent; -import android.media.routeprovider.IRouteProvider; -import android.media.routeprovider.IRouteProviderCallback; -import android.media.session.RouteEvent; -import android.media.session.RouteInfo; -import android.media.session.RouteOptions; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * Base class for defining a route provider service. - * <p> - * A route provider offers media routes which represent destinations to which - * applications may connect, control, and send content. This provides a means - * for Android applications to interact with a variety of media streaming - * devices such as speakers or television sets. - * <p> - * The system will bind to your provider when an active app is interested in - * routes that may be discovered through your provider. After binding, the - * system will send updates on which routes to discover through - * {@link #updateDiscoveryRequests(List)}. The system will call - * {@link #getMatchingRoutes(List)} with a subset of filters when a route is - * needed for a specific app. - * <p> - * TODO add documentation for how the sytem knows an app is interested. Maybe - * interface declarations in the manifest. - * <p> - * The system will only start a provider when an app may discover routes through - * it. If your service needs to run at other times you are responsible for - * managing its lifecycle. - * <p> - * Declare your route provider service in your application manifest like this: - * <p> - * - * <pre> - * <service android:name=".MyRouteProviderService" - * android:label="@string/my_route_provider_service"> - * <intent-filter> - * <action android:name="com.android.media.session.MediaRouteProvider" /> - * </intent-filter> - * </service> - * </pre> - * @hide - */ -public abstract class RouteProviderService extends Service { - private static final String TAG = "RouteProvider"; - /** - * A service that implements a RouteProvider must declare that it handles - * this action in its AndroidManifest. - */ - public static final String SERVICE_INTERFACE = - "com.android.media.session.MediaRouteProvider"; - - /** - * @hide - */ - public static final String KEY_ROUTES = "routes"; - /** - * @hide - */ - public static final String KEY_CONNECTION = "connection"; - /** - * @hide - */ - public static final int RESULT_FAILURE = -1; - /** - * @hide - */ - public static final int RESULT_SUCCESS = 0; - - // The system's callback once it has bound to the service - private IRouteProviderCallback mCb; - - /** - * If your service overrides onBind it must return super.onBind() in - * response to the {@link #SERVICE_INTERFACE} action. - */ - @Override - public IBinder onBind(Intent intent) { - if (intent != null && RouteProviderService.SERVICE_INTERFACE.equals(intent.getAction())) { - return mBinder; - } - return null; - } - - /** - * Disconnect the specified RouteConnection. The system will stop sending - * commands to this connection. - * - * @param connection The connection to disconnect. - * @hide - */ - public final void disconnect(RouteConnection connection) { - if (mCb != null) { - try { - mCb.onConnectionTerminated(connection.getBinder()); - } catch (RemoteException e) { - Log.wtf(TAG, "Error in disconnect.", e); - } - } - } - - /** - * @hide - */ - public final void sendRouteEvent(RouteEvent event) { - if (mCb != null) { - try { - mCb.onRouteEvent(event); - } catch (RemoteException e) { - Log.wtf(TAG, "Unable to send MediaRouteEvent to system", e); - } - } - } - - /** - * Override to handle updates to the routes that are of interest. Each - * {@link RouteRequest} will specify if it is an active or passive request. - * Route discovery may perform more aggressive discovery on behalf of active - * requests but should use low power discovery methods otherwise. - * <p> - * A single app may have more than one request. Your provider is responsible - * for deciding the set of features that are important for discovery given - * the set of requests. If your provider only has one method of discovery it - * may simply verify that one or more requests are valid before starting - * discovery. - * - * @param requests The route requests that are currently relevant. - */ - public void updateDiscoveryRequests(List<RouteRequest> requests) { - } - - /** - * Return a list of matching routes for the given set of requests. Returning - * null or an empty list indicates there are no matches. A route is - * considered matching if it supports one or more of the - * {@link RouteOptions} specified. Each returned {@link RouteInfo} - * should include all the requested connections that it supports. - * - * @param options The set of requests for routes - * @return The routes that this caller may connect to using one or more of - * the route options. - */ - public abstract List<RouteInfo> getMatchingRoutes(List<RouteRequest> options); - - /** - * Handle a request to connect to a specific route with a specific request. - * The {@link RouteConnection} must be fully defined before being returned, - * though the actual connection to the route may be performed in the - * background. - * - * @param route The route to connect to - * @param request The connection request parameters - * @return A MediaRouteConnection representing the connection to the route - */ - public abstract RouteConnection connect(RouteInfo route, RouteRequest request); - - private IRouteProvider.Stub mBinder = new IRouteProvider.Stub() { - - @Override - public void registerCallback(IRouteProviderCallback cb) throws RemoteException { - mCb = cb; - } - - @Override - public void unregisterCallback(IRouteProviderCallback cb) throws RemoteException { - mCb = null; - } - - @Override - public void updateDiscoveryRequests(List<RouteRequest> requests) - throws RemoteException { - RouteProviderService.this.updateDiscoveryRequests(requests); - } - - @Override - public void getAvailableRoutes(List<RouteRequest> requests, ResultReceiver cb) - throws RemoteException { - List<RouteInfo> routes = RouteProviderService.this.getMatchingRoutes(requests); - ArrayList<RouteInfo> routesArray; - if (routes instanceof ArrayList) { - routesArray = (ArrayList<RouteInfo>) routes; - } else { - routesArray = new ArrayList<RouteInfo>(routes); - } - Bundle resultData = new Bundle(); - resultData.putParcelableArrayList(KEY_ROUTES, routesArray); - cb.send(routes == null ? RESULT_FAILURE : RESULT_SUCCESS, resultData); - } - - @Override - public void connect(RouteInfo route, RouteRequest request, ResultReceiver cb) - throws RemoteException { - RouteConnection connection = RouteProviderService.this.connect(route, request); - Bundle resultData = new Bundle(); - if (connection != null) { - connection.publish(); - resultData.putBinder(KEY_CONNECTION, connection.getBinder()); - } - - cb.send(connection == null ? RESULT_FAILURE : RESULT_SUCCESS, resultData); - } - }; -} diff --git a/media/java/android/media/routeprovider/RouteRequest.aidl b/media/java/android/media/routeprovider/RouteRequest.aidl deleted file mode 100644 index 7bc5722..0000000 --- a/media/java/android/media/routeprovider/RouteRequest.aidl +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2014, 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.routeprovider; - -parcelable RouteRequest; diff --git a/media/java/android/media/routeprovider/RouteRequest.java b/media/java/android/media/routeprovider/RouteRequest.java deleted file mode 100644 index 2ba75de..0000000 --- a/media/java/android/media/routeprovider/RouteRequest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 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.routeprovider; - -import android.media.session.RouteOptions; -import android.media.session.MediaSessionInfo; -import android.os.Parcel; -import android.os.Parcelable; - -import java.io.PrintWriter; - -/** - * A request to connect or discover routes with certain capabilities. - * <p> - * Passed to a {@link RouteProviderService} when a request for discovery or to - * connect to a route is made. This identifies the app making the request and - * provides the full set of connection parameters they would like to use for a - * connection. An app that can connect in multiple ways will be represented by - * multiple requests. - * @hide - */ -public final class RouteRequest implements Parcelable { - private final MediaSessionInfo mSessionInfo; - private final RouteOptions mOptions; - private final boolean mActive; - - /** - * @hide - */ - public RouteRequest(MediaSessionInfo info, RouteOptions connRequest, - boolean active) { - mSessionInfo = info; - mOptions = connRequest; - mActive = active; - } - - private RouteRequest(Parcel in) { - mSessionInfo = MediaSessionInfo.CREATOR.createFromParcel(in); - mOptions = RouteOptions.CREATOR.createFromParcel(in); - mActive = in.readInt() != 0; - } - - /** - * Get information about the session making the request. - * - * @return Info on the session making the request - */ - public MediaSessionInfo getSessionInfo() { - return mSessionInfo; - } - - /** - * Get the connection options, which includes the interfaces and other - * connection params the session wants to use with a route. - * - * @return The connection options - */ - public RouteOptions getConnectionOptions() { - return mOptions; - } - - @Override - public String toString() { - StringBuilder bob = new StringBuilder(); - bob.append("RouteRequest {"); - bob.append("active=").append(mActive); - bob.append(", info=").append(mSessionInfo.toString()); - bob.append(", options=").append(mOptions.toString()); - bob.append("}"); - return bob.toString(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - mSessionInfo.writeToParcel(dest, flags); - mOptions.writeToParcel(dest, flags); - dest.writeInt(mActive ? 1 : 0); - } - - public static final Parcelable.Creator<RouteRequest> CREATOR - = new Parcelable.Creator<RouteRequest>() { - @Override - public RouteRequest createFromParcel(Parcel in) { - return new RouteRequest(in); - } - - @Override - public RouteRequest[] newArray(int size) { - return new RouteRequest[size]; - } - }; -} diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl index 5bc0de4..6127dec 100644 --- a/media/java/android/media/session/ISession.aidl +++ b/media/java/android/media/session/ISession.aidl @@ -18,9 +18,6 @@ package android.media.session; import android.content.ComponentName; import android.media.MediaMetadata; import android.media.session.ISessionController; -import android.media.session.RouteOptions; -import android.media.session.RouteCommand; -import android.media.session.RouteInfo; import android.media.session.PlaybackState; import android.os.Bundle; import android.os.ResultReceiver; @@ -37,14 +34,6 @@ interface ISession { void setMediaButtonReceiver(in ComponentName mbr); void destroy(); - // These commands are for setting up and communicating with routes - // Returns true if the route was set for this session - boolean setRoute(in RouteInfo route); - void setRouteOptions(in List<RouteOptions> options); - void connectToRoute(in RouteInfo route, in RouteOptions options); - void disconnectFromRoute(in RouteInfo route); - void sendRouteCommand(in RouteCommand event, in ResultReceiver cb); - // These commands are for the TransportPerformer void setMetadata(in MediaMetadata metadata); void setPlaybackState(in PlaybackState state); @@ -53,4 +42,4 @@ interface ISession { // These commands relate to volume handling void configureVolumeHandling(int type, int arg1, int arg2); void setCurrentVolume(int currentVolume); -}
\ No newline at end of file +} diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl index 0316d1f..e554e27 100644 --- a/media/java/android/media/session/ISessionCallback.aidl +++ b/media/java/android/media/session/ISessionCallback.aidl @@ -16,9 +16,6 @@ package android.media.session; import android.media.Rating; -import android.media.session.RouteEvent; -import android.media.session.RouteInfo; -import android.media.session.RouteOptions; import android.content.Intent; import android.os.Bundle; import android.os.ResultReceiver; @@ -29,11 +26,6 @@ import android.os.ResultReceiver; oneway interface ISessionCallback { void onCommand(String command, in Bundle extras, in ResultReceiver cb); void onMediaButton(in Intent mediaButtonIntent, int sequenceNumber, in ResultReceiver cb); - void onRequestRouteChange(in RouteInfo route); - void onRouteConnected(in RouteInfo route, in RouteOptions options); - void onRouteDisconnected(in RouteInfo route, int reason); - void onRouteStateChange(int state); - void onRouteEvent(in RouteEvent event); // These callbacks are for the TransportPerformer void onPlay(); @@ -49,4 +41,4 @@ oneway interface ISessionCallback { // These callbacks are for volume handling void onAdjustVolumeBy(int delta); void onSetVolumeTo(int value); -}
\ No newline at end of file +} diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl index b4c11f6..5e127e3 100644 --- a/media/java/android/media/session/ISessionController.aidl +++ b/media/java/android/media/session/ISessionController.aidl @@ -36,7 +36,6 @@ interface ISessionController { void registerCallbackListener(in ISessionControllerCallback cb); void unregisterCallbackListener(in ISessionControllerCallback cb); boolean isTransportControlEnabled(); - void showRoutePicker(); MediaSessionInfo getSessionInfo(); long getFlags(); ParcelableVolumeInfo getVolumeAttributes(); @@ -56,4 +55,4 @@ interface ISessionController { MediaMetadata getMetadata(); PlaybackState getPlaybackState(); int getRatingType(); -}
\ No newline at end of file +} diff --git a/media/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl index baa1379..64d2bc7 100644 --- a/media/java/android/media/session/ISessionControllerCallback.aidl +++ b/media/java/android/media/session/ISessionControllerCallback.aidl @@ -16,7 +16,6 @@ package android.media.session; import android.media.MediaMetadata; -import android.media.session.RouteInfo; import android.media.session.ParcelableVolumeInfo; import android.media.session.PlaybackState; import android.os.Bundle; @@ -26,10 +25,9 @@ import android.os.Bundle; */ oneway interface ISessionControllerCallback { void onEvent(String event, in Bundle extras); - void onRouteChanged(in RouteInfo route); // These callbacks are for the TransportController void onPlaybackStateChanged(in PlaybackState state); void onMetadataChanged(in MediaMetadata metadata); void onVolumeInfoChanged(in ParcelableVolumeInfo info); -}
\ No newline at end of file +} diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index edb69bc..a90048d 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -52,8 +52,7 @@ public final class MediaController { private static final int MSG_EVENT = 1; private static final int MSG_UPDATE_PLAYBACK_STATE = 2; private static final int MSG_UPDATE_METADATA = 3; - private static final int MSG_ROUTE = 4; - private static final int MSG_UPDATE_VOLUME = 5; + private static final int MSG_UPDATE_VOLUME = 4; private final ISessionController mSessionBinder; @@ -308,20 +307,6 @@ public final class MediaController { } /** - * Request that the route picker be shown for this session. This should - * generally be called in response to a user action. - * - * @hide - */ - public void showRoutePicker() { - try { - mSessionBinder.showRoutePicker(); - } catch (RemoteException e) { - Log.d(TAG, "Dead object in showRoutePicker", e); - } - } - - /** * Get the info for the session this controller is connected to. * * @return The session info for the connected session. @@ -421,15 +406,6 @@ public final class MediaController { } /** - * Override to handle route changes for this session. - * - * @param route The new route - * @hide - */ - public void onRouteChanged(RouteInfo route) { - } - - /** * Override to handle changes in playback state. * * @param state The new playback state of the session @@ -670,14 +646,6 @@ public final class MediaController { } @Override - public void onRouteChanged(RouteInfo route) { - MediaController controller = mController.get(); - if (controller != null) { - controller.postMessage(MSG_ROUTE, route, null); - } - } - - @Override public void onPlaybackStateChanged(PlaybackState state) { MediaController controller = mController.get(); if (controller != null) { @@ -719,9 +687,6 @@ public final class MediaController { case MSG_EVENT: mCallback.onSessionEvent((String) msg.obj, msg.getData()); break; - case MSG_ROUTE: - mCallback.onRouteChanged((RouteInfo) msg.obj); - break; case MSG_UPDATE_PLAYBACK_STATE: mCallback.onPlaybackStateChanged((PlaybackState) msg.obj); break; diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 2cbdc96..ed1121c 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -93,40 +93,6 @@ public final class MediaSession { public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 1 << 16; /** - * Indicates the session was disconnected because the user that the session - * belonged to is stopping. - * - * @hide - */ - public static final int DISCONNECT_REASON_USER_STOPPING = 1; - - /** - * Indicates the session was disconnected because the provider disconnected - * the route. - * @hide - */ - public static final int DISCONNECT_REASON_PROVIDER_DISCONNECTED = 2; - - /** - * Indicates the session was disconnected because the route has changed. - * @hide - */ - public static final int DISCONNECT_REASON_ROUTE_CHANGED = 3; - - /** - * Indicates the session was disconnected because the session owner - * requested it disconnect. - * @hide - */ - public static final int DISCONNECT_REASON_SESSION_DISCONNECTED = 4; - - /** - * Indicates the session was disconnected because it was destroyed. - * @hide - */ - public static final int DISCONNECT_REASON_SESSION_DESTROYED = 5; - - /** * The session uses local playback. */ public static final int PLAYBACK_TYPE_LOCAL = 1; @@ -146,11 +112,7 @@ public final class MediaSession { = new ArrayList<CallbackMessageHandler>(); private final ArrayList<TransportMessageHandler> mTransportCallbacks = new ArrayList<TransportMessageHandler>(); - // TODO route interfaces - private final ArrayMap<String, RouteInterface.EventListener> mInterfaceListeners - = new ArrayMap<String, RouteInterface.EventListener>(); - private Route mRoute; private VolumeProvider mVolumeProvider; private boolean mActive = false; @@ -377,90 +339,6 @@ public final class MediaSession { } /** - * Connect to the current route using the specified request. - * <p> - * Connection updates will be sent to the callback's - * {@link Callback#onRouteConnected(Route)} and - * {@link Callback#onRouteDisconnected(Route, int)} methods. If the - * connection fails {@link Callback#onRouteDisconnected(Route, int)} will be - * called. - * <p> - * If you already have a connection to this route it will be disconnected - * before the new connection is established. TODO add an easy way to compare - * MediaRouteOptions. - * - * @param route The route the app is trying to connect to. - * @param request The connection request to use. - * @hide - */ - public void connect(RouteInfo route, RouteOptions request) { - if (route == null) { - throw new IllegalArgumentException("Must specify the route"); - } - if (request == null) { - throw new IllegalArgumentException("Must specify the connection request"); - } - try { - mBinder.connectToRoute(route, request); - } catch (RemoteException e) { - Log.wtf(TAG, "Error starting connection to route", e); - } - } - - /** - * Disconnect from the current route. After calling you will be switched - * back to the default route. - * - * @hide - */ - public void disconnect() { - if (mRoute != null) { - try { - mBinder.disconnectFromRoute(mRoute.getRouteInfo()); - } catch (RemoteException e) { - Log.wtf(TAG, "Error disconnecting from route"); - } - } - } - - /** - * Set the list of route options your app is interested in connecting to. It - * will be used for picking valid routes. - * - * @param options The set of route options your app may use to connect. - * @hide - */ - public void setRouteOptions(List<RouteOptions> options) { - try { - mBinder.setRouteOptions(options); - } catch (RemoteException e) { - Log.wtf(TAG, "Error setting route options.", e); - } - } - - /** - * @hide - * TODO allow multiple listeners for the same interface, allow removal - */ - public void addInterfaceListener(String iface, - RouteInterface.EventListener listener) { - mInterfaceListeners.put(iface, listener); - } - - /** - * @hide - */ - public boolean sendRouteCommand(RouteCommand command, ResultReceiver cb) { - try { - mBinder.sendRouteCommand(command, cb); - } catch (RemoteException e) { - Log.wtf(TAG, "Error sending command to route.", e); - return false; - } - return true; - } - - /** * Add a callback to receive transport controls on, such as play, rewind, or * fast forward. * @@ -670,34 +548,6 @@ public final class MediaSession { } } - private void postRequestRouteChange(RouteInfo route) { - synchronized (mLock) { - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - mCallbacks.get(i).post(CallbackMessageHandler.MSG_ROUTE_CHANGE, route); - } - } - } - - private void postRouteConnected(RouteInfo route, RouteOptions options) { - synchronized (mLock) { - mRoute = new Route(route, options, this); - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - mCallbacks.get(i).post(CallbackMessageHandler.MSG_ROUTE_CONNECTED, mRoute); - } - } - } - - private void postRouteDisconnected(RouteInfo route, int reason) { - synchronized (mLock) { - if (mRoute != null && TextUtils.equals(mRoute.getRouteInfo().getId(), route.getId())) { - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - mCallbacks.get(i).post(CallbackMessageHandler.MSG_ROUTE_DISCONNECTED, mRoute, - reason); - } - } - } - } - /** * Return true if this is considered an active playback state. * @@ -796,47 +646,6 @@ public final class MediaSession { public void onControlCommand(@NonNull String command, @Nullable Bundle extras, @Nullable ResultReceiver cb) { } - - /** - * Called when the user has selected a different route to connect to. - * The app is responsible for connecting to the new route and migrating - * ongoing playback if necessary. - * - * @param route - * @hide - */ - public void onRequestRouteChange(RouteInfo route) { - } - - /** - * Called when a route has successfully connected. Calls to the route - * are now valid. - * - * @param route The route that was connected - * @hide - */ - public void onRouteConnected(Route route) { - } - - /** - * Called when a route was disconnected. Further calls to the route will - * fail. If available a reason for being disconnected will be provided. - * <p> - * Valid reasons are: - * <ul> - * <li>{@link #DISCONNECT_REASON_USER_STOPPING}</li> - * <li>{@link #DISCONNECT_REASON_PROVIDER_DISCONNECTED}</li> - * <li>{@link #DISCONNECT_REASON_ROUTE_CHANGED}</li> - * <li>{@link #DISCONNECT_REASON_SESSION_DISCONNECTED}</li> - * <li>{@link #DISCONNECT_REASON_SESSION_DESTROYED}</li> - * </ul> - * - * @param route The route that disconnected - * @param reason The reason for the disconnect - * @hide - */ - public void onRouteDisconnected(Route route, int reason) { - } } /** @@ -902,17 +711,6 @@ public final class MediaSession { */ public void onSetRating(@NonNull Rating rating) { } - - /** - * Report that audio focus has changed on the app. This only happens if - * you have indicated you have started playing with - * {@link #setPlaybackState}. - * - * @param focusChange The type of focus change, TBD. - * @hide - */ - public void onRouteFocusChange(int focusChange) { - } } /** @@ -926,8 +724,7 @@ public final class MediaSession { } @Override - public void onCommand(String command, Bundle extras, ResultReceiver cb) - throws RemoteException { + public void onCommand(String command, Bundle extras, ResultReceiver cb) { MediaSession session = mMediaSession.get(); if (session != null) { session.postCommand(command, extras, cb); @@ -935,8 +732,8 @@ public final class MediaSession { } @Override - public void onMediaButton(Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) - throws RemoteException { + public void onMediaButton(Intent mediaButtonIntent, int sequenceNumber, + ResultReceiver cb) { MediaSession session = mMediaSession.get(); try { if (session != null) { @@ -950,31 +747,7 @@ public final class MediaSession { } @Override - public void onRequestRouteChange(RouteInfo route) throws RemoteException { - MediaSession session = mMediaSession.get(); - if (session != null) { - session.postRequestRouteChange(route); - } - } - - @Override - public void onRouteConnected(RouteInfo route, RouteOptions options) { - MediaSession session = mMediaSession.get(); - if (session != null) { - session.postRouteConnected(route, options); - } - } - - @Override - public void onRouteDisconnected(RouteInfo route, int reason) { - MediaSession session = mMediaSession.get(); - if (session != null) { - session.postRouteDisconnected(route, reason); - } - } - - @Override - public void onPlay() throws RemoteException { + public void onPlay() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPlay(); @@ -982,7 +755,7 @@ public final class MediaSession { } @Override - public void onPause() throws RemoteException { + public void onPause() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPause(); @@ -990,7 +763,7 @@ public final class MediaSession { } @Override - public void onStop() throws RemoteException { + public void onStop() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchStop(); @@ -998,7 +771,7 @@ public final class MediaSession { } @Override - public void onNext() throws RemoteException { + public void onNext() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchNext(); @@ -1006,7 +779,7 @@ public final class MediaSession { } @Override - public void onPrevious() throws RemoteException { + public void onPrevious() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPrevious(); @@ -1014,7 +787,7 @@ public final class MediaSession { } @Override - public void onFastForward() throws RemoteException { + public void onFastForward() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchFastForward(); @@ -1022,7 +795,7 @@ public final class MediaSession { } @Override - public void onRewind() throws RemoteException { + public void onRewind() { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchRewind(); @@ -1030,7 +803,7 @@ public final class MediaSession { } @Override - public void onSeekTo(long pos) throws RemoteException { + public void onSeekTo(long pos) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchSeekTo(pos); @@ -1038,7 +811,7 @@ public final class MediaSession { } @Override - public void onRate(Rating rating) throws RemoteException { + public void onRate(Rating rating) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchRate(rating); @@ -1046,26 +819,7 @@ public final class MediaSession { } @Override - public void onRouteEvent(RouteEvent event) throws RemoteException { - MediaSession session = mMediaSession.get(); - if (session != null) { - RouteInterface.EventListener iface - = session.mInterfaceListeners.get(event.getIface()); - Log.d(TAG, "Received route event on iface " + event.getIface() + ". Listener is " - + iface); - if (iface != null) { - iface.onEvent(event.getEvent(), event.getExtras()); - } - } - } - - @Override - public void onRouteStateChange(int state) throws RemoteException { - // TODO - } - - @Override - public void onAdjustVolumeBy(int delta) throws RemoteException { + public void onAdjustVolumeBy(int delta) { MediaSession session = mMediaSession.get(); if (session != null) { if (session.mVolumeProvider != null) { @@ -1075,7 +829,7 @@ public final class MediaSession { } @Override - public void onSetVolumeTo(int value) throws RemoteException { + public void onSetVolumeTo(int value) { MediaSession session = mMediaSession.get(); if (session != null) { if (session.mVolumeProvider != null) { @@ -1089,9 +843,6 @@ public final class MediaSession { private class CallbackMessageHandler extends Handler { private static final int MSG_MEDIA_BUTTON = 1; private static final int MSG_COMMAND = 2; - private static final int MSG_ROUTE_CHANGE = 3; - private static final int MSG_ROUTE_CONNECTED = 4; - private static final int MSG_ROUTE_DISCONNECTED = 5; private MediaSession.Callback mCallback; @@ -1114,15 +865,6 @@ public final class MediaSession { Command cmd = (Command) msg.obj; mCallback.onControlCommand(cmd.command, cmd.extras, cmd.stub); break; - case MSG_ROUTE_CHANGE: - mCallback.onRequestRouteChange((RouteInfo) msg.obj); - break; - case MSG_ROUTE_CONNECTED: - mCallback.onRouteConnected((Route) msg.obj); - break; - case MSG_ROUTE_DISCONNECTED: - mCallback.onRouteDisconnected((Route) msg.obj, msg.arg1); - break; } } } diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index c73a8d3..c477406 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -35,9 +35,8 @@ import java.util.ArrayList; import java.util.List; /** - * MediaSessionManager allows the creation and control of MediaSessions in the - * system. A MediaSession enables publishing information about ongoing media and - * interacting with MediaControllers and MediaRoutes. + * Provides support for interacting with {@link MediaSession media sessions} + * that applications have published to express their ongoing media playback state. * <p> * Use <code>Context.getSystemService(Context.MEDIA_SESSION_SERVICE)</code> to * get an instance of this class. @@ -256,8 +255,8 @@ public final class MediaSessionManager { } /** - * Dispatch an adjust volume request to the system. It will be routed to the - * most relevant stream/session. + * Dispatch an adjust volume request to the system. It will be sent to the + * most relevant audio stream or media session. * * @param suggestedStream The stream to fall back to if there isn't a * relevant stream @@ -292,8 +291,7 @@ public final class MediaSessionManager { private final IActiveSessionsListener.Stub mStub = new IActiveSessionsListener.Stub() { @Override - public void onActiveSessionsChanged(List<MediaSession.Token> tokens) - throws RemoteException { + public void onActiveSessionsChanged(List<MediaSession.Token> tokens) { ArrayList<MediaController> controllers = new ArrayList<MediaController>(); int size = tokens.size(); for (int i = 0; i < size; i++) { diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java index 6125cb4..9ae2436 100644 --- a/media/java/android/media/session/PlaybackState.java +++ b/media/java/android/media/session/PlaybackState.java @@ -157,10 +157,11 @@ public final class PlaybackState implements Parcelable { /** * State indicating the class doing playback is currently connecting to a - * route. Depending on the implementation you may return to the previous - * state when the connection finishes or enter {@link #STATE_NONE}. If - * the connection failed {@link #STATE_ERROR} should be used. - * @hide + * new destination. Depending on the implementation you may return to the previous + * state when the connection finishes or enter {@link #STATE_NONE}. + * If the connection failed {@link #STATE_ERROR} should be used. + * + * @see #setState */ public final static int STATE_CONNECTING = 8; diff --git a/media/java/android/media/session/Route.java b/media/java/android/media/session/Route.java deleted file mode 100644 index 935eb5b..0000000 --- a/media/java/android/media/session/Route.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.text.TextUtils; -import android.util.Log; - -import java.util.List; - -/** - * Represents a destination which an application has connected to and may send - * media content. - * <p> - * This allows a session owner to interact with a route it has been connected - * to. The MediaRoute must be used to get {@link RouteInterface} - * instances which can be used to communicate over a specific interface on the - * route. - * @hide - */ -public final class Route { - private static final String TAG = "Route"; - private final RouteInfo mInfo; - private final MediaSession mSession; - private final RouteOptions mOptions; - - /** - * @hide - */ - public Route(RouteInfo info, RouteOptions options, MediaSession session) { - if (info == null || options == null) { - throw new IllegalStateException("Route info was not valid!"); - } - mInfo = info; - mOptions = options; - mSession = session; - } - - /** - * Get the {@link RouteInfo} for this route. - * - * @return The info for this route. - */ - public RouteInfo getRouteInfo() { - return mInfo; - } - - /** - * Get the {@link RouteOptions} that were used to connect this route. - * - * @return The options used to connect to this route. - */ - public RouteOptions getOptions() { - return mOptions; - } - - /** - * Gets an interface provided by this route. If the interface is not - * supported by the route, returns null. - * - * @see RouteInterface - * @param iface The name of the interface to create - * @return A {@link RouteInterface} or null if the interface is - * not supported. - */ - public RouteInterface getInterface(String iface) { - if (TextUtils.isEmpty(iface)) { - throw new IllegalArgumentException("iface may not be empty."); - } - List<String> ifaces = mOptions.getInterfaceNames(); - if (ifaces != null) { - for (int i = ifaces.size() - 1; i >= 0; i--) { - if (iface.equals(ifaces.get(i))) { - return new RouteInterface(this, iface, mSession); - } - } - } - Log.e(TAG, "Interface not supported by route"); - return null; - } - - /** - * @hide - */ - MediaSession getSession() { - return mSession; - } -} diff --git a/media/java/android/media/session/RouteCommand.aidl b/media/java/android/media/session/RouteCommand.aidl deleted file mode 100644 index 725b308..0000000 --- a/media/java/android/media/session/RouteCommand.aidl +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2014, 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.session; - -parcelable RouteCommand; diff --git a/media/java/android/media/session/RouteCommand.java b/media/java/android/media/session/RouteCommand.java deleted file mode 100644 index 358bc0a..0000000 --- a/media/java/android/media/session/RouteCommand.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Represents a command that an application may send to a route. - * <p> - * Commands are associated with a specific route and interface supported by that - * route and sent through the session. This class isn't used directly by apps. - * - * @hide - */ -public final class RouteCommand implements Parcelable { - private final String mRoute; - private final String mIface; - private final String mEvent; - private final Bundle mExtras; - - /** - * @param route The id of the route this event is being sent on - * @param iface The interface the sender used - * @param event The event or command - * @param extras Any extras included with the event - */ - public RouteCommand(String route, String iface, String event, Bundle extras) { - mRoute = route; - mIface = iface; - mEvent = event; - mExtras = extras; - } - - private RouteCommand(Parcel in) { - mRoute = in.readString(); - mIface = in.readString(); - mEvent = in.readString(); - mExtras = in.readBundle(); - } - - /** - * Get the id for the route this event was sent on. - * - * @return The route id this event is using - */ - public String getRouteInfo() { - return mRoute; - } - - /** - * Get the interface this event was sent from - * - * @return The interface for this event - */ - public String getIface() { - return mIface; - } - - /** - * Get the action/name of the event. - * - * @return The name of event/command. - */ - public String getEvent() { - return mEvent; - } - - /** - * Get any extras included with the event. - * - * @return The bundle included with the event or null - */ - public Bundle getExtras() { - return mExtras; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mRoute); - dest.writeString(mIface); - dest.writeString(mEvent); - dest.writeBundle(mExtras); - } - - public static final Parcelable.Creator<RouteCommand> CREATOR - = new Parcelable.Creator<RouteCommand>() { - @Override - public RouteCommand createFromParcel(Parcel in) { - return new RouteCommand(in); - } - - @Override - public RouteCommand[] newArray(int size) { - return new RouteCommand[size]; - } - }; -} diff --git a/media/java/android/media/session/RouteEvent.aidl b/media/java/android/media/session/RouteEvent.aidl deleted file mode 100644 index 6966207..0000000 --- a/media/java/android/media/session/RouteEvent.aidl +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2014, 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.session; - -parcelable RouteEvent; diff --git a/media/java/android/media/session/RouteEvent.java b/media/java/android/media/session/RouteEvent.java deleted file mode 100644 index 918e410..0000000 --- a/media/java/android/media/session/RouteEvent.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.media.routeprovider.RouteConnection; -import android.media.routeprovider.RouteProviderService; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Represents an event that a route provider is sending to a particular - * {@link RouteConnection}. Events are associated with a specific interface - * supported by the connection and sent through the {@link RouteProviderService}. - * This class isn't used directly by apps. - * - * @hide - */ -public class RouteEvent implements Parcelable { - private final IBinder mConnection; - private final String mIface; - private final String mEvent; - private final Bundle mExtras; - - /** - * @param connection The connection that this event is for - * @param iface The interface the sender used - * @param event The event or command - * @param extras Any extras included with the event - */ - public RouteEvent(IBinder connection, String iface, String event, Bundle extras) { - mConnection = connection; - mIface = iface; - mEvent = event; - mExtras = extras; - } - - private RouteEvent(Parcel in) { - mConnection = in.readStrongBinder(); - mIface = in.readString(); - mEvent = in.readString(); - mExtras = in.readBundle(); - } - - /** - * Get the connection this event was sent on. - * - * @return The connection this event is using - */ - public IBinder getConnection() { - return mConnection; - } - - /** - * Get the interface this event was sent from - * - * @return The interface for this event - */ - public String getIface() { - return mIface; - } - - /** - * Get the action/name of the event. - * - * @return The name of event/command. - */ - public String getEvent() { - return mEvent; - } - - /** - * Get any extras included with the event. - * - * @return The bundle included with the event or null - */ - public Bundle getExtras() { - return mExtras; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeStrongBinder(mConnection); - dest.writeString(mIface); - dest.writeString(mEvent); - dest.writeBundle(mExtras); - } - - public static final Parcelable.Creator<RouteEvent> CREATOR - = new Parcelable.Creator<RouteEvent>() { - @Override - public RouteEvent createFromParcel(Parcel in) { - return new RouteEvent(in); - } - - @Override - public RouteEvent[] newArray(int size) { - return new RouteEvent[size]; - } - }; -} diff --git a/media/java/android/media/session/RouteInfo.aidl b/media/java/android/media/session/RouteInfo.aidl deleted file mode 100644 index c5f50c8..0000000 --- a/media/java/android/media/session/RouteInfo.aidl +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2014, 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.session; - -parcelable RouteInfo; diff --git a/media/java/android/media/session/RouteInfo.java b/media/java/android/media/session/RouteInfo.java deleted file mode 100644 index 02f78f9..0000000 --- a/media/java/android/media/session/RouteInfo.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * Information about a route, including its display name, a way to identify it, - * and the ways it can be connected to. - * @hide - */ -public final class RouteInfo implements Parcelable { - private final String mName; - private final String mId; - private final String mProviderId; - private final List<RouteOptions> mOptions; - - private RouteInfo(String id, String name, String providerId, - List<RouteOptions> connRequests) { - mId = id; - mName = name; - mProviderId = providerId; - mOptions = connRequests; - } - - private RouteInfo(Parcel in) { - mId = in.readString(); - mName = in.readString(); - mProviderId = in.readString(); - mOptions = new ArrayList<RouteOptions>(); - in.readTypedList(mOptions, RouteOptions.CREATOR); - } - - /** - * Get the displayable name of this route. - * - * @return A short, user readable name for this route - */ - public String getName() { - return mName; - } - - /** - * Get the unique id for this route. - * - * @return A unique route id. - */ - public String getId() { - return mId; - } - - /** - * Get the package name of this route's provider. - * - * @return The package name of this route's provider. - */ - public String getProvider() { - return mProviderId; - } - - /** - * Get the set of connections that may be used with this route. - * - * @return An array of connection requests that may be used to connect - */ - public List<RouteOptions> getConnectionMethods() { - return mOptions; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mId); - dest.writeString(mName); - dest.writeString(mProviderId); - dest.writeTypedList(mOptions); - } - - @Override - public String toString() { - StringBuilder bob = new StringBuilder(); - bob.append("RouteInfo: id=").append(mId).append(", name=").append(mName) - .append(", provider=").append(mProviderId).append(", options={"); - for (int i = 0; i < mOptions.size(); i++) { - if (i != 0) { - bob.append(", "); - } - bob.append(mOptions.get(i).toString()); - } - bob.append("}"); - return bob.toString(); - } - - public static final Parcelable.Creator<RouteInfo> CREATOR - = new Parcelable.Creator<RouteInfo>() { - @Override - public RouteInfo createFromParcel(Parcel in) { - return new RouteInfo(in); - } - - @Override - public RouteInfo[] newArray(int size) { - return new RouteInfo[size]; - } - }; - - /** - * Helper for creating MediaRouteInfos. A route must have a name and an id. - * While options are not strictly required the route cannot be connected to - * without at least one set of options. - */ - public static final class Builder { - private String mName; - private String mId; - private String mProviderPackage; - private ArrayList<RouteOptions> mOptions; - - /** - * Copies an existing route info object. TODO Remove once we have - * helpers for creating route infos. - * - * @param from The existing info to copy. - */ - public Builder(RouteInfo from) { - mOptions = new ArrayList<RouteOptions>(from.getConnectionMethods()); - mName = from.mName; - mId = from.mId; - mProviderPackage = from.mProviderId; - } - - public Builder() { - mOptions = new ArrayList<RouteOptions>(); - } - - /** - * Set the user visible name for this route. - * - * @param name The name of the route - * @return The builder for easy chaining. - */ - public Builder setName(String name) { - mName = name; - return this; - } - - /** - * Set the id of the route. This should be unique to the provider. - * - * @param id The unique id of the route. - * @return The builder for easy chaining. - */ - public Builder setId(String id) { - mId = id; - return this; - } - - /** - * @hide - */ - public Builder setProviderId(String packageName) { - mProviderPackage = packageName; - return this; - } - - /** - * Add a set of {@link RouteOptions} to the route. Multiple options - * may be added to the same route. - * - * @param options The options to add to this route. - * @return The builder for easy chaining. - */ - public Builder addRouteOptions(RouteOptions options) { - mOptions.add(options); - return this; - } - - /** - * Clear the set of {@link RouteOptions} on the route. - * - * @return The builder for easy chaining - */ - public Builder clearRouteOptions() { - mOptions.clear(); - return this; - } - - /** - * Build a new MediaRouteInfo. - * - * @return A new MediaRouteInfo with the values that were set. - */ - public RouteInfo build() { - if (TextUtils.isEmpty(mName)) { - throw new IllegalArgumentException("Must set a name before building"); - } - if (TextUtils.isEmpty(mId)) { - throw new IllegalArgumentException("Must set an id before building"); - } - return new RouteInfo(mId, mName, mProviderPackage, mOptions); - } - - /** - * Get the current number of options that have been added to this - * builder. - * - * @return The number of options that have been added. - */ - public int getOptionsSize() { - return mOptions.size(); - } - } -} diff --git a/media/java/android/media/session/RouteInterface.java b/media/java/android/media/session/RouteInterface.java deleted file mode 100644 index 8de4d89..0000000 --- a/media/java/android/media/session/RouteInterface.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.ResultReceiver; -import android.util.Log; - -import java.util.ArrayList; - -/** - * A route can support multiple interfaces for a {@link MediaSession} to - * interact with. To use a specific interface with a route a - * MediaSessionRouteInterface needs to be retrieved from the route. An - * implementation of the specific interface, like - * {@link RoutePlaybackControls}, should be used to simplify communication - * and reduce errors on that interface. - * - * @see RoutePlaybackControls for an example - * @hide - */ -public final class RouteInterface { - private static final String TAG = "RouteInterface"; - - /** - * Error indicating the route is currently not connected. - */ - public static final int RESULT_NOT_CONNECTED = -5; - /** - * Error indicating the session is no longer using the route this command - * was sent to. - */ - public static final int RESULT_ROUTE_IS_STALE = -4; - /** - * Error indicating that the interface does not support the command. - */ - public static final int RESULT_COMMAND_NOT_SUPPORTED = -3; - /** - * Error indicating that the route does not support the interface. - */ - public static final int RESULT_INTERFACE_NOT_SUPPORTED = -2; - /** - * Generic error. Extra information about the error may be included in the - * result bundle. - */ - public static final int RESULT_ERROR = -1; - /** - * The command was successful. Extra information may be included in the - * result bundle. - */ - public static final int RESULT_SUCCESS = 1; - - private final Route mRoute; - private final String mIface; - private final MediaSession mSession; - - private final Object mLock = new Object(); - private final ArrayList<EventHandler> mListeners = new ArrayList<EventHandler>(); - - /** - * @hide - */ - RouteInterface(Route route, String iface, MediaSession session) { - mRoute = route; - mIface = iface; - mSession = session; - mSession.addInterfaceListener(iface, mEventListener); - } - - /** - * Send a command using this interface. - * - * @param command The command to send. - * @param extras Any extras to include with the command. - * @param cb The callback to receive the result on. - * @return true if the command was sent, false otherwise. - */ - public boolean sendCommand(String command, Bundle extras, ResultReceiver cb) { - RouteCommand cmd = new RouteCommand(mRoute.getRouteInfo().getId(), mIface, - command, extras); - return mSession.sendRouteCommand(cmd, cb); - } - - /** - * Add a listener to this interface. Events will be sent on the caller's - * thread. - * - * @param listener The listener to receive events on. - */ - public void addListener(EventListener listener) { - addListener(listener, null); - } - - /** - * Add a listener for this interface. If a handler is specified events will - * be performed on the handler's thread, otherwise the caller's thread will - * be used. - * - * @param listener The listener to receive events on - * @param handler The handler whose thread to post calls on - */ - public void addListener(EventListener listener, Handler handler) { - if (listener == null) { - throw new IllegalArgumentException("listener may not be null"); - } - if (handler == null) { - handler = new Handler(); - } - synchronized (mLock) { - if (findIndexOfListenerLocked(listener) != -1) { - Log.d(TAG, "Listener is already added, ignoring"); - return; - } - mListeners.add(new EventHandler(handler.getLooper(), listener)); - } - } - - /** - * Remove a listener from this interface. - * - * @param listener The listener to stop receiving events on. - */ - public void removeListener(EventListener listener) { - if (listener == null) { - throw new IllegalArgumentException("listener may not be null"); - } - synchronized (mLock) { - int index = findIndexOfListenerLocked(listener); - if (index != -1) { - mListeners.remove(index); - } - } - } - - private int findIndexOfListenerLocked(EventListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Callback cannot be null"); - } - for (int i = mListeners.size() - 1; i >= 0; i--) { - EventHandler handler = mListeners.get(i); - if (listener == handler.mListener) { - return i; - } - } - return -1; - } - - private EventListener mEventListener = new EventListener() { - @Override - public void onEvent(String event, Bundle args) { - synchronized (mLock) { - for (int i = mListeners.size() - 1; i >= 0; i--) { - mListeners.get(i).postEvent(event, args); - } - } - } - - }; - - /** - * An EventListener can be registered by an app with TODO to handle events - * sent by the session on a specific interface. - */ - public static abstract class EventListener { - /** - * This is called when an event is received from the interface. Events - * are sent by the session owner and will be delivered to all - * controllers that are listening to the interface. - * - * @param event The event that occurred. - * @param args Any extras that were included with the event. May be - * null. - */ - public abstract void onEvent(String event, Bundle args); - } - - private static final class EventHandler extends Handler { - - private final EventListener mListener; - - public EventHandler(Looper looper, EventListener cb) { - super(looper, null, true); - mListener = cb; - } - - @Override - public void handleMessage(Message msg) { - mListener.onEvent((String) msg.obj, msg.getData()); - } - - public void postEvent(String event, Bundle args) { - Message msg = obtainMessage(0, event); - msg.setData(args); - msg.sendToTarget(); - } - } -} diff --git a/media/java/android/media/session/RouteOptions.aidl b/media/java/android/media/session/RouteOptions.aidl deleted file mode 100644 index feaf517..0000000 --- a/media/java/android/media/session/RouteOptions.aidl +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2014, 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.session; - -parcelable RouteOptions; diff --git a/media/java/android/media/session/RouteOptions.java b/media/java/android/media/session/RouteOptions.java deleted file mode 100644 index b4fb341..0000000 --- a/media/java/android/media/session/RouteOptions.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * Specifies options that an application might use when connecting to a route. - * This includes things like interfaces, connection parameters, and required - * features. - * <p> - * An application may create several different route options that describe - * alternative sets of capabilities that it can use and choose the most - * appropriate route options when it is ready to connect to the route. Each - * route options instance must specify a complete set of capabilities to request - * when the connection is established. - * @hide - */ -public final class RouteOptions implements Parcelable { - private static final String TAG = "RouteOptions"; - - private final ArrayList<String> mIfaces; - private final Bundle mConnectionParams; - - private RouteOptions(List<String> ifaces, Bundle params) { - mIfaces = new ArrayList<String>(ifaces); - mConnectionParams = params; - } - - private RouteOptions(Parcel in) { - mIfaces = new ArrayList<String>(); - in.readStringList(mIfaces); - mConnectionParams = in.readBundle(); - } - - /** - * Get the interfaces this connection wants to use. - * - * @return The interfaces for this connection - */ - public List<String> getInterfaceNames() { - return mIfaces; - } - - /** - * Get the parameters that will be used for connecting. - * - * @return The set of connection parameters this connections uses - */ - public Bundle getConnectionParams() { - return mConnectionParams; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeStringList(mIfaces); - dest.writeBundle(mConnectionParams); - } - - @Override - public String toString() { - StringBuilder bob = new StringBuilder(); - bob.append("Options: interfaces={"); - for (int i = 0; i < mIfaces.size(); i++) { - if (i != 0) { - bob.append(", "); - } - bob.append(mIfaces.get(i)); - } - bob.append("}"); - bob.append(", parameters="); - bob.append(mConnectionParams == null ? "null" : mConnectionParams.toString()); - return bob.toString(); - } - - public static final Parcelable.Creator<RouteOptions> CREATOR - = new Parcelable.Creator<RouteOptions>() { - @Override - public RouteOptions createFromParcel(Parcel in) { - return new RouteOptions(in); - } - - @Override - public RouteOptions[] newArray(int size) { - return new RouteOptions[size]; - } - }; - - /** - * Builder for creating {@link RouteOptions}. - */ - public final static class Builder { - private ArrayList<String> mIfaces = new ArrayList<String>(); - private Bundle mConnectionParams; - - public Builder() { - } - - /** - * Add a required interface to the options. - * - * @param interfaceName The name of the interface to add. - * @return The builder to allow chaining commands. - */ - public Builder addInterface(String interfaceName) { - if (TextUtils.isEmpty(interfaceName)) { - throw new IllegalArgumentException("interfaceName cannot be empty"); - } - if (!mIfaces.contains(interfaceName)) { - mIfaces.add(interfaceName); - } else { - Log.w(TAG, "Attempted to add interface that is already added"); - } - return this; - } - - /** - * Set the connection parameters to use with the options. TODO replace - * with more specific calls once we decide on the standard way to - * express parameters. - * - * @param parameters The parameters to use. - * @return The builder to allow chaining commands. - */ - public Builder setParameters(Bundle parameters) { - mConnectionParams = parameters; - return this; - } - - /** - * Generate a set of options. - * - * @return The options with the specified components. - */ - public RouteOptions build() { - return new RouteOptions(mIfaces, mConnectionParams); - } - } -} diff --git a/media/java/android/media/session/RoutePlaybackControls.java b/media/java/android/media/session/RoutePlaybackControls.java deleted file mode 100644 index 8211983..0000000 --- a/media/java/android/media/session/RoutePlaybackControls.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2014 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.session; - -import android.media.MediaMetadata; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; - -/** - * A standard media control interface for Routes that support queueing and - * transport controls. Routes may support multiple interfaces for MediaSessions - * to interact with. - * @hide - */ -public final class RoutePlaybackControls { - private static final String TAG = "RoutePlaybackControls"; - public static final String NAME = "android.media.session.RoutePlaybackControls"; - - /** @hide */ - public static final String KEY_VALUE1 = "value1"; - - /** @hide */ - public static final String CMD_FAST_FORWARD = "fastForward"; - /** @hide */ - public static final String CMD_GET_CURRENT_POSITION = "getCurrentPosition"; - /** @hide */ - public static final String CMD_GET_CAPABILITIES = "getCapabilities"; - /** @hide */ - public static final String CMD_PLAY_NOW = "playNow"; - /** @hide */ - public static final String CMD_RESUME = "resume"; - /** @hide */ - public static final String CMD_PAUSE = "pause"; - - /** @hide */ - public static final String EVENT_PLAYSTATE_CHANGE = "playstateChange"; - /** @hide */ - public static final String EVENT_METADATA_CHANGE = "metadataChange"; - - private final RouteInterface mIface; - - private RoutePlaybackControls(RouteInterface iface) { - mIface = iface; - } - - /** - * Get a new MediaRoutePlaybackControls instance for sending commands using - * this interface. If the provided route doesn't support this interface null - * will be returned. - * - * @param route The route to send commands to. - * @return A MediaRoutePlaybackControls instance or null if not supported. - */ - public static RoutePlaybackControls from(Route route) { - RouteInterface iface = route.getInterface(NAME); - if (iface != null) { - return new RoutePlaybackControls(iface); - } - return null; - } - - /** - * Send a resume command to the route. - */ - public void resume() { - mIface.sendCommand(CMD_RESUME, null, null); - } - - /** - * Send a pause command to the route. - */ - public void pause() { - mIface.sendCommand(CMD_PAUSE, null, null); - } - - /** - * Send a fast forward command. - */ - public void fastForward() { - Bundle b = new Bundle(); - mIface.sendCommand(CMD_FAST_FORWARD, b, null); - } - - /** - * Retrieves the current playback position. - * - * @param cb The callback to receive the result on. - */ - public void getCurrentPosition(ResultReceiver cb) { - mIface.sendCommand(CMD_GET_CURRENT_POSITION, null, cb); - } - - public void getCapabilities(ResultReceiver cb) { - mIface.sendCommand(CMD_GET_CAPABILITIES, null, cb); - } - - public void addListener(Listener listener) { - mIface.addListener(listener); - } - - public void addListener(Listener listener, Handler handler) { - mIface.addListener(listener, handler); - } - - public void removeListener(Listener listener) { - mIface.removeListener(listener); - } - - public void playNow(String content) { - Bundle bundle = new Bundle(); - bundle.putString(KEY_VALUE1, content); - mIface.sendCommand(CMD_PLAY_NOW, bundle, null); - } - - /** - * Register this event listener using {@link #addListener} to receive - * RoutePlaybackControl events from a session. - */ - public static abstract class Listener extends RouteInterface.EventListener { - @Override - public final void onEvent(String event, Bundle args) { - if (EVENT_PLAYSTATE_CHANGE.equals(event)) { - onPlaybackStateChange(args.getInt(KEY_VALUE1, 0)); - } else if (EVENT_METADATA_CHANGE.equals(event)) { - onMetadataUpdate((MediaMetadata) args.getParcelable(KEY_VALUE1)); - } - } - - /** - * Override to handle updates to the playback state. Valid values are in - * {@link TransportPerformer}. TODO put playstate values somewhere more - * generic. - * - * @param state - */ - public void onPlaybackStateChange(int state) { - } - - /** - * Override to handle metadata changes for this session's media. The - * default supported fields are those in {@link MediaMetadata}. - * - * @param metadata - */ - public void onMetadataUpdate(MediaMetadata metadata) { - } - } - -} |