summaryrefslogtreecommitdiffstats
path: root/media/lib/remotedisplay/java
diff options
context:
space:
mode:
authorJeff Tinker <jtinker@google.com>2014-04-01 22:23:21 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-04-01 22:23:21 +0000
commit53c90cf916ddd1151f042a61a569ea75a220b26e (patch)
tree1ee36092a3872180a55a2c75bd177d942e2ae8fb /media/lib/remotedisplay/java
parent74ee938dcc5e1ab0309dd87278e26f604c756b26 (diff)
parent6dc8063d2a06017f249181b4b5b07c54ce645943 (diff)
downloadframeworks_base-53c90cf916ddd1151f042a61a569ea75a220b26e.zip
frameworks_base-53c90cf916ddd1151f042a61a569ea75a220b26e.tar.gz
frameworks_base-53c90cf916ddd1151f042a61a569ea75a220b26e.tar.bz2
am 6dc8063d: am 433a0633: Merge "Support CAST V2 Authentication in MediaDrm" into klp-modular-dev
* commit '6dc8063d2a06017f249181b4b5b07c54ce645943': Support CAST V2 Authentication in MediaDrm
Diffstat (limited to 'media/lib/remotedisplay/java')
-rw-r--r--media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java172
-rw-r--r--media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java407
2 files changed, 579 insertions, 0 deletions
diff --git a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
new file mode 100644
index 0000000..dc9dd79
--- /dev/null
+++ b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2013 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 com.android.media.remotedisplay;
+
+import android.media.RemoteDisplayState.RemoteDisplayInfo;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * Represents a remote display that has been discovered.
+ */
+public class RemoteDisplay {
+ private final RemoteDisplayInfo mMutableInfo;
+ private RemoteDisplayInfo mImmutableInfo;
+
+ /**
+ * Status code: Indicates that the remote display is not available.
+ */
+ public static final int STATUS_NOT_AVAILABLE = RemoteDisplayInfo.STATUS_NOT_AVAILABLE;
+
+ /**
+ * Status code: Indicates that the remote display is in use by someone else.
+ */
+ public static final int STATUS_IN_USE = RemoteDisplayInfo.STATUS_IN_USE;
+
+ /**
+ * Status code: Indicates that the remote display is available for new connections.
+ */
+ public static final int STATUS_AVAILABLE = RemoteDisplayInfo.STATUS_AVAILABLE;
+
+ /**
+ * Status code: Indicates that the remote display is current connecting.
+ */
+ public static final int STATUS_CONNECTING = RemoteDisplayInfo.STATUS_CONNECTING;
+
+ /**
+ * Status code: Indicates that the remote display is connected and is mirroring
+ * display contents.
+ */
+ public static final int STATUS_CONNECTED = RemoteDisplayInfo.STATUS_CONNECTED;
+
+ /**
+ * Volume handling: Output volume can be changed.
+ */
+ public static final int PLAYBACK_VOLUME_VARIABLE =
+ RemoteDisplayInfo.PLAYBACK_VOLUME_VARIABLE;
+
+ /**
+ * Volume handling: Output volume is fixed.
+ */
+ public static final int PLAYBACK_VOLUME_FIXED =
+ RemoteDisplayInfo.PLAYBACK_VOLUME_FIXED;
+
+ /**
+ * Creates a remote display with the specified name and id.
+ */
+ public RemoteDisplay(String id, String name) {
+ if (TextUtils.isEmpty(id)) {
+ throw new IllegalArgumentException("id must not be null or empty");
+ }
+ mMutableInfo = new RemoteDisplayInfo(id);
+ setName(name);
+ }
+
+ public String getId() {
+ return mMutableInfo.id;
+ }
+
+ public String getName() {
+ return mMutableInfo.name;
+ }
+
+ public void setName(String name) {
+ if (!Objects.equals(mMutableInfo.name, name)) {
+ mMutableInfo.name = name;
+ mImmutableInfo = null;
+ }
+ }
+
+ public String getDescription() {
+ return mMutableInfo.description;
+ }
+
+ public void setDescription(String description) {
+ if (!Objects.equals(mMutableInfo.description, description)) {
+ mMutableInfo.description = description;
+ mImmutableInfo = null;
+ }
+ }
+
+ public int getStatus() {
+ return mMutableInfo.status;
+ }
+
+ public void setStatus(int status) {
+ if (mMutableInfo.status != status) {
+ mMutableInfo.status = status;
+ mImmutableInfo = null;
+ }
+ }
+
+ public int getVolume() {
+ return mMutableInfo.volume;
+ }
+
+ public void setVolume(int volume) {
+ if (mMutableInfo.volume != volume) {
+ mMutableInfo.volume = volume;
+ mImmutableInfo = null;
+ }
+ }
+
+ public int getVolumeMax() {
+ return mMutableInfo.volumeMax;
+ }
+
+ public void setVolumeMax(int volumeMax) {
+ if (mMutableInfo.volumeMax != volumeMax) {
+ mMutableInfo.volumeMax = volumeMax;
+ mImmutableInfo = null;
+ }
+ }
+
+ public int getVolumeHandling() {
+ return mMutableInfo.volumeHandling;
+ }
+
+ public void setVolumeHandling(int volumeHandling) {
+ if (mMutableInfo.volumeHandling != volumeHandling) {
+ mMutableInfo.volumeHandling = volumeHandling;
+ mImmutableInfo = null;
+ }
+ }
+
+ public int getPresentationDisplayId() {
+ return mMutableInfo.presentationDisplayId;
+ }
+
+ public void setPresentationDisplayId(int presentationDisplayId) {
+ if (mMutableInfo.presentationDisplayId != presentationDisplayId) {
+ mMutableInfo.presentationDisplayId = presentationDisplayId;
+ mImmutableInfo = null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "RemoteDisplay{" + mMutableInfo.toString() + "}";
+ }
+
+ RemoteDisplayInfo getInfo() {
+ if (mImmutableInfo == null) {
+ mImmutableInfo = new RemoteDisplayInfo(mMutableInfo);
+ }
+ return mImmutableInfo;
+ }
+}
diff --git a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
new file mode 100644
index 0000000..e2df77c
--- /dev/null
+++ b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2013 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 com.android.media.remotedisplay;
+
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.media.IRemoteDisplayCallback;
+import android.media.IRemoteDisplayProvider;
+import android.media.RemoteDisplayState;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import java.util.Collection;
+
+/**
+ * Base class for remote display providers implemented as unbundled services.
+ * <p>
+ * To implement your remote display provider service, create a subclass of
+ * {@link Service} and override the {@link Service#onBind Service.onBind()} method
+ * to return the provider's binder when the {@link #SERVICE_INTERFACE} is requested.
+ * </p>
+ * <pre>
+ * public class SampleRemoteDisplayProviderService extends Service {
+ * private SampleProvider mProvider;
+ *
+ * public IBinder onBind(Intent intent) {
+ * if (intent.getAction().equals(RemoteDisplayProvider.SERVICE_INTERFACE)) {
+ * if (mProvider == null) {
+ * mProvider = new SampleProvider(this);
+ * }
+ * return mProvider.getBinder();
+ * }
+ * return null;
+ * }
+ *
+ * class SampleProvider extends RemoteDisplayProvider {
+ * public SampleProvider() {
+ * super(SampleRemoteDisplayProviderService.this);
+ * }
+ *
+ * // --- Implementation goes here ---
+ * }
+ * }
+ * </pre>
+ * <p>
+ * Declare your remote display provider service in your application manifest
+ * like this:
+ * </p>
+ * <pre>
+ * &lt;application>
+ * &lt;uses-library android:name="com.android.media.remotedisplay" />
+ *
+ * &lt;service android:name=".SampleRemoteDisplayProviderService"
+ * android:label="@string/sample_remote_display_provider_service"
+ * android:exported="true"
+ * android:permission="android.permission.BIND_REMOTE_DISPLAY">
+ * &lt;intent-filter>
+ * &lt;action android:name="com.android.media.remotedisplay.RemoteDisplayProvider" />
+ * &lt;/intent-filter>
+ * &lt;/service>
+ * &lt;/application>
+ * </pre>
+ * <p>
+ * This object is not thread safe. It is only intended to be accessed on the
+ * {@link Context#getMainLooper main looper thread} of an application.
+ * </p><p>
+ * IMPORTANT: This class is effectively a public API for unbundled applications, and
+ * must remain API stable. See README.txt in the root of this package for more information.
+ * </p>
+ */
+public abstract class RemoteDisplayProvider {
+ private static final int MSG_SET_CALLBACK = 1;
+ private static final int MSG_SET_DISCOVERY_MODE = 2;
+ private static final int MSG_CONNECT = 3;
+ private static final int MSG_DISCONNECT = 4;
+ private static final int MSG_SET_VOLUME = 5;
+ private static final int MSG_ADJUST_VOLUME = 6;
+
+ private final Context mContext;
+ private final ProviderStub mStub;
+ private final ProviderHandler mHandler;
+ private final ArrayMap<String, RemoteDisplay> mDisplays =
+ new ArrayMap<String, RemoteDisplay>();
+ private IRemoteDisplayCallback mCallback;
+ private int mDiscoveryMode = DISCOVERY_MODE_NONE;
+
+ private PendingIntent mSettingsPendingIntent;
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ * Put this in your manifest.
+ */
+ public static final String SERVICE_INTERFACE = RemoteDisplayState.SERVICE_INTERFACE;
+
+ /**
+ * Discovery mode: Do not perform any discovery.
+ */
+ public static final int DISCOVERY_MODE_NONE = RemoteDisplayState.DISCOVERY_MODE_NONE;
+
+ /**
+ * Discovery mode: Passive or low-power periodic discovery.
+ * <p>
+ * This mode indicates that an application is interested in knowing whether there
+ * are any remote displays paired or available but doesn't need the latest or
+ * most detailed information. The provider may scan at a lower rate or rely on
+ * knowledge of previously paired devices.
+ * </p>
+ */
+ public static final int DISCOVERY_MODE_PASSIVE = RemoteDisplayState.DISCOVERY_MODE_PASSIVE;
+
+ /**
+ * Discovery mode: Active discovery.
+ * <p>
+ * This mode indicates that the user is actively trying to connect to a route
+ * and we should perform continuous scans. This mode may use significantly more
+ * power but is intended to be short-lived.
+ * </p>
+ */
+ public static final int DISCOVERY_MODE_ACTIVE = RemoteDisplayState.DISCOVERY_MODE_ACTIVE;
+
+ /**
+ * Creates a remote display provider.
+ *
+ * @param context The application context for the remote display provider.
+ */
+ public RemoteDisplayProvider(Context context) {
+ mContext = context;
+ mStub = new ProviderStub();
+ mHandler = new ProviderHandler(context.getMainLooper());
+ }
+
+ /**
+ * Gets the context of the remote display provider.
+ */
+ public final Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * Gets the Binder associated with the provider.
+ * <p>
+ * This is intended to be used for the onBind() method of a service that implements
+ * a remote display provider service.
+ * </p>
+ *
+ * @return The IBinder instance associated with the provider.
+ */
+ public IBinder getBinder() {
+ return mStub;
+ }
+
+ /**
+ * Called when the current discovery mode changes.
+ *
+ * @param mode The new discovery mode.
+ */
+ public void onDiscoveryModeChanged(int mode) {
+ }
+
+ /**
+ * Called when the system would like to connect to a display.
+ *
+ * @param display The remote display.
+ */
+ public void onConnect(RemoteDisplay display) {
+ }
+
+ /**
+ * Called when the system would like to disconnect from a display.
+ *
+ * @param display The remote display.
+ */
+ public void onDisconnect(RemoteDisplay display) {
+ }
+
+ /**
+ * Called when the system would like to set the volume of a display.
+ *
+ * @param display The remote display.
+ * @param volume The desired volume.
+ */
+ public void onSetVolume(RemoteDisplay display, int volume) {
+ }
+
+ /**
+ * Called when the system would like to adjust the volume of a display.
+ *
+ * @param display The remote display.
+ * @param delta An increment to add to the current volume, such as +1 or -1.
+ */
+ public void onAdjustVolume(RemoteDisplay display, int delta) {
+ }
+
+ /**
+ * Gets the current discovery mode.
+ *
+ * @return The current discovery mode.
+ */
+ public int getDiscoveryMode() {
+ return mDiscoveryMode;
+ }
+
+ /**
+ * Gets the current collection of displays.
+ *
+ * @return The current collection of displays, which must not be modified.
+ */
+ public Collection<RemoteDisplay> getDisplays() {
+ return mDisplays.values();
+ }
+
+ /**
+ * Adds the specified remote display and notifies the system.
+ *
+ * @param display The remote display that was added.
+ * @throws IllegalStateException if there is already a display with the same id.
+ */
+ public void addDisplay(RemoteDisplay display) {
+ if (display == null || mDisplays.containsKey(display.getId())) {
+ throw new IllegalArgumentException("display");
+ }
+ mDisplays.put(display.getId(), display);
+ publishState();
+ }
+
+ /**
+ * Updates information about the specified remote display and notifies the system.
+ *
+ * @param display The remote display that was added.
+ * @throws IllegalStateException if the display was n
+ */
+ public void updateDisplay(RemoteDisplay display) {
+ if (display == null || mDisplays.get(display.getId()) != display) {
+ throw new IllegalArgumentException("display");
+ }
+ publishState();
+ }
+
+ /**
+ * Removes the specified remote display and tells the system about it.
+ *
+ * @param display The remote display that was removed.
+ */
+ public void removeDisplay(RemoteDisplay display) {
+ if (display == null || mDisplays.get(display.getId()) != display) {
+ throw new IllegalArgumentException("display");
+ }
+ mDisplays.remove(display.getId());
+ publishState();
+ }
+
+ /**
+ * Finds the remote display with the specified id, returns null if not found.
+ *
+ * @param id Id of the remote display.
+ * @return The display, or null if none.
+ */
+ public RemoteDisplay findRemoteDisplay(String id) {
+ return mDisplays.get(id);
+ }
+
+ /**
+ * Gets a pending intent to launch the remote display settings activity.
+ *
+ * @return A pending intent to launch the settings activity.
+ */
+ public PendingIntent getSettingsPendingIntent() {
+ if (mSettingsPendingIntent == null) {
+ Intent settingsIntent = new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS);
+ settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mSettingsPendingIntent = PendingIntent.getActivity(
+ mContext, 0, settingsIntent, 0, null);
+ }
+ return mSettingsPendingIntent;
+ }
+
+ void setCallback(IRemoteDisplayCallback callback) {
+ mCallback = callback;
+ publishState();
+ }
+
+ void setDiscoveryMode(int mode) {
+ if (mDiscoveryMode != mode) {
+ mDiscoveryMode = mode;
+ onDiscoveryModeChanged(mode);
+ }
+ }
+
+ void publishState() {
+ if (mCallback != null) {
+ RemoteDisplayState state = new RemoteDisplayState();
+ final int count = mDisplays.size();
+ for (int i = 0; i < count; i++) {
+ final RemoteDisplay display = mDisplays.valueAt(i);
+ state.displays.add(display.getInfo());
+ }
+ try {
+ mCallback.onStateChanged(state);
+ } catch (RemoteException ex) {
+ // system server died?
+ }
+ }
+ }
+
+ final class ProviderStub extends IRemoteDisplayProvider.Stub {
+ @Override
+ public void setCallback(IRemoteDisplayCallback callback) {
+ mHandler.obtainMessage(MSG_SET_CALLBACK, callback).sendToTarget();
+ }
+
+ @Override
+ public void setDiscoveryMode(int mode) {
+ mHandler.obtainMessage(MSG_SET_DISCOVERY_MODE, mode, 0).sendToTarget();
+ }
+
+ @Override
+ public void connect(String id) {
+ mHandler.obtainMessage(MSG_CONNECT, id).sendToTarget();
+ }
+
+ @Override
+ public void disconnect(String id) {
+ mHandler.obtainMessage(MSG_DISCONNECT, id).sendToTarget();
+ }
+
+ @Override
+ public void setVolume(String id, int volume) {
+ mHandler.obtainMessage(MSG_SET_VOLUME, volume, 0, id).sendToTarget();
+ }
+
+ @Override
+ public void adjustVolume(String id, int delta) {
+ mHandler.obtainMessage(MSG_ADJUST_VOLUME, delta, 0, id).sendToTarget();
+ }
+ }
+
+ final class ProviderHandler extends Handler {
+ public ProviderHandler(Looper looper) {
+ super(looper, null, true);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SET_CALLBACK: {
+ setCallback((IRemoteDisplayCallback)msg.obj);
+ break;
+ }
+ case MSG_SET_DISCOVERY_MODE: {
+ setDiscoveryMode(msg.arg1);
+ break;
+ }
+ case MSG_CONNECT: {
+ RemoteDisplay display = findRemoteDisplay((String)msg.obj);
+ if (display != null) {
+ onConnect(display);
+ }
+ break;
+ }
+ case MSG_DISCONNECT: {
+ RemoteDisplay display = findRemoteDisplay((String)msg.obj);
+ if (display != null) {
+ onDisconnect(display);
+ }
+ break;
+ }
+ case MSG_SET_VOLUME: {
+ RemoteDisplay display = findRemoteDisplay((String)msg.obj);
+ if (display != null) {
+ onSetVolume(display, msg.arg1);
+ }
+ break;
+ }
+ case MSG_ADJUST_VOLUME: {
+ RemoteDisplay display = findRemoteDisplay((String)msg.obj);
+ if (display != null) {
+ onAdjustVolume(display, msg.arg1);
+ }
+ break;
+ }
+ }
+ }
+ }
+}