summaryrefslogtreecommitdiffstats
path: root/tests/RemoteDisplayProvider
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2013-11-07 00:30:16 -0800
committerJeff Brown <jeffbrown@google.com>2013-11-07 03:25:37 -0800
commit69b07161bebdb2c726e3a826c2268866f1a94517 (patch)
tree8d9c94f32a045a8f5c48ca0f1380abc760eac807 /tests/RemoteDisplayProvider
parentf3c99e883f46c56e5e2877e844b902b6eb45545b (diff)
downloadframeworks_base-69b07161bebdb2c726e3a826c2268866f1a94517.zip
frameworks_base-69b07161bebdb2c726e3a826c2268866f1a94517.tar.gz
frameworks_base-69b07161bebdb2c726e3a826c2268866f1a94517.tar.bz2
Add media router service and integrate with remote displays.
This change adds a new media router service whose purpose is to track global state information associated with media routes. This service publishes routes to the media router instance in application processes and handles requested state changes such as selecting or unselecting global routes. The service also binds to remote display provider services which can offer new remote display routes to the system. Includes a test application for manually verifying certain aspects of the operation of the media router service. The remote display provider interface is essentially a stripped down media route provider interface as defined in the support library media router implementation. For now, it is designed to be used only by first parties to publish remote display routes to the system so it is not exposed as public API in the SDK. In the future, the remote display provider interface will most likely be deprecated and replaced with a more featureful media route provider interface for third party integration, similar to what is in the support library today. Further patch sets integrate these new capabilities into the System UI and Settings for connecting remote displays. Bug: 11257292 Change-Id: I31109f23f17b474d17534d0f5f4503e388b081c2
Diffstat (limited to 'tests/RemoteDisplayProvider')
-rw-r--r--tests/RemoteDisplayProvider/Android.mk25
-rw-r--r--tests/RemoteDisplayProvider/AndroidManifest.xml37
-rw-r--r--tests/RemoteDisplayProvider/README16
-rwxr-xr-xtests/RemoteDisplayProvider/res/drawable-hdpi/ic_app.pngbin0 -> 3608 bytes
-rw-r--r--tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.pngbin0 -> 5198 bytes
-rw-r--r--tests/RemoteDisplayProvider/res/values/strings.xml19
-rw-r--r--tests/RemoteDisplayProvider/src/com/android/media/remotedisplay/test/RemoteDisplayProviderService.java240
7 files changed, 337 insertions, 0 deletions
diff --git a/tests/RemoteDisplayProvider/Android.mk b/tests/RemoteDisplayProvider/Android.mk
new file mode 100644
index 0000000..77e9815
--- /dev/null
+++ b/tests/RemoteDisplayProvider/Android.mk
@@ -0,0 +1,25 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the application.
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := RemoteDisplayProviderTest
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_RESOURCE_DIR = $(LOCAL_PATH)/res
+LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay
+include $(BUILD_PACKAGE)
diff --git a/tests/RemoteDisplayProvider/AndroidManifest.xml b/tests/RemoteDisplayProvider/AndroidManifest.xml
new file mode 100644
index 0000000..e8e31da
--- /dev/null
+++ b/tests/RemoteDisplayProvider/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.media.remotedisplay.test" >
+
+ <uses-sdk android:minSdkVersion="19" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_app">
+ <uses-library android:name="com.android.media.remotedisplay"
+ android:required="true" />
+
+ <service android:name=".RemoteDisplayProviderService"
+ android:label="@string/app_name"
+ android:exported="true"
+ android:permission="android.permission.BIND_REMOTE_DISPLAY">
+ <intent-filter>
+ <action android:name="com.android.media.remotedisplay.RemoteDisplayProvider"/>
+ </intent-filter>
+ </service>
+
+ </application>
+</manifest>
diff --git a/tests/RemoteDisplayProvider/README b/tests/RemoteDisplayProvider/README
new file mode 100644
index 0000000..8bf0130
--- /dev/null
+++ b/tests/RemoteDisplayProvider/README
@@ -0,0 +1,16 @@
+This directory contains sample code to test system integration with
+remote display providers using the API declared by the
+com.android.media.remotedisplay.jar library.
+
+--- DESCRIPTION ---
+
+The application registers a service that publishes a few different
+remote display routes. Behavior can be controlled by modifying the
+code.
+
+To exercise the provider, use System UI features for connecting to
+wireless displays or launch an activity that uses the MediaRouter,
+such as the PresentationWithMediaRouterActivity in ApiDemos.
+
+This code is mainly intended for development and not meant to be
+used as an example implementation of a robust remote display provider.
diff --git a/tests/RemoteDisplayProvider/res/drawable-hdpi/ic_app.png b/tests/RemoteDisplayProvider/res/drawable-hdpi/ic_app.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/tests/RemoteDisplayProvider/res/drawable-hdpi/ic_app.png
Binary files differ
diff --git a/tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png b/tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png
Binary files differ
diff --git a/tests/RemoteDisplayProvider/res/values/strings.xml b/tests/RemoteDisplayProvider/res/values/strings.xml
new file mode 100644
index 0000000..dd82d2c
--- /dev/null
+++ b/tests/RemoteDisplayProvider/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name">Remote Display Provider Test</string>
+</resources>
diff --git a/tests/RemoteDisplayProvider/src/com/android/media/remotedisplay/test/RemoteDisplayProviderService.java b/tests/RemoteDisplayProvider/src/com/android/media/remotedisplay/test/RemoteDisplayProviderService.java
new file mode 100644
index 0000000..bf84631
--- /dev/null
+++ b/tests/RemoteDisplayProvider/src/com/android/media/remotedisplay/test/RemoteDisplayProviderService.java
@@ -0,0 +1,240 @@
+/*
+ * 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.test;
+
+import com.android.media.remotedisplay.RemoteDisplay;
+import com.android.media.remotedisplay.RemoteDisplayProvider;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Remote display provider implementation that publishes working routes.
+ */
+public class RemoteDisplayProviderService extends Service {
+ private static final String TAG = "RemoteDisplayProviderTest";
+
+ private Provider mProvider;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (intent.getAction().equals(RemoteDisplayProvider.SERVICE_INTERFACE)) {
+ if (mProvider == null) {
+ mProvider = new Provider();
+ return mProvider.getBinder();
+ }
+ }
+ return null;
+ }
+
+ final class Provider extends RemoteDisplayProvider {
+ private RemoteDisplay mTestDisplay1; // variable volume
+ private RemoteDisplay mTestDisplay2; // fixed volume
+ private RemoteDisplay mTestDisplay3; // not available
+ private RemoteDisplay mTestDisplay4; // in use
+ private RemoteDisplay mTestDisplay5; // available but ignores request to connect
+ private RemoteDisplay mTestDisplay6; // available but never finishes connecting
+ private RemoteDisplay mTestDisplay7; // blinks in and out of existence
+
+ private final Handler mHandler;
+ private boolean mBlinking;
+
+ public Provider() {
+ super(RemoteDisplayProviderService.this);
+ mHandler = new Handler(getMainLooper());
+ }
+
+ @Override
+ public void onDiscoveryModeChanged(int mode) {
+ Log.d(TAG, "onDiscoveryModeChanged: mode=" + mode);
+
+ if (mode != DISCOVERY_MODE_NONE) {
+ // When discovery begins, go find all of the routes.
+ if (mTestDisplay1 == null) {
+ mTestDisplay1 = new RemoteDisplay("testDisplay1",
+ "Test Display 1 (variable)");
+ mTestDisplay1.setDescription("Variable volume");
+ mTestDisplay1.setStatus(RemoteDisplay.STATUS_AVAILABLE);
+ mTestDisplay1.setVolume(10);
+ mTestDisplay1.setVolumeHandling(RemoteDisplay.PLAYBACK_VOLUME_VARIABLE);
+ mTestDisplay1.setVolumeMax(15);
+ addDisplay(mTestDisplay1);
+ }
+ if (mTestDisplay2 == null) {
+ mTestDisplay2 = new RemoteDisplay("testDisplay2",
+ "Test Display 2 (fixed)");
+ mTestDisplay2.setDescription("Fixed volume");
+ mTestDisplay2.setStatus(RemoteDisplay.STATUS_AVAILABLE);
+ addDisplay(mTestDisplay2);
+ }
+ if (mTestDisplay3 == null) {
+ mTestDisplay3 = new RemoteDisplay("testDisplay3",
+ "Test Display 3 (unavailable)");
+ mTestDisplay3.setDescription("Always unavailable");
+ mTestDisplay3.setStatus(RemoteDisplay.STATUS_NOT_AVAILABLE);
+ addDisplay(mTestDisplay3);
+ }
+ if (mTestDisplay4 == null) {
+ mTestDisplay4 = new RemoteDisplay("testDisplay4",
+ "Test Display 4 (in-use)");
+ mTestDisplay4.setDescription("Always in-use");
+ mTestDisplay4.setStatus(RemoteDisplay.STATUS_IN_USE);
+ addDisplay(mTestDisplay4);
+ }
+ if (mTestDisplay5 == null) {
+ mTestDisplay5 = new RemoteDisplay("testDisplay5",
+ "Test Display 5 (connect ignored)");
+ mTestDisplay5.setDescription("Ignores connect");
+ mTestDisplay5.setStatus(RemoteDisplay.STATUS_AVAILABLE);
+ addDisplay(mTestDisplay5);
+ }
+ if (mTestDisplay6 == null) {
+ mTestDisplay6 = new RemoteDisplay("testDisplay6",
+ "Test Display 6 (connect hangs)");
+ mTestDisplay6.setDescription("Never finishes connecting");
+ mTestDisplay6.setStatus(RemoteDisplay.STATUS_AVAILABLE);
+ addDisplay(mTestDisplay6);
+ }
+ } else {
+ // When discovery ends, go hide some of the routes we can't actually use.
+ // This isn't something a normal route provider would do though.
+ // The routes will usually stay published.
+ if (mTestDisplay3 != null) {
+ removeDisplay(mTestDisplay3);
+ mTestDisplay3 = null;
+ }
+ if (mTestDisplay4 != null) {
+ removeDisplay(mTestDisplay4);
+ mTestDisplay4 = null;
+ }
+ }
+
+ // When active discovery is on, pretend there's a route that we can't quite
+ // reach that blinks in and out of existence.
+ if (mode == DISCOVERY_MODE_ACTIVE) {
+ if (!mBlinking) {
+ mBlinking = true;
+ mHandler.post(mBlink);
+ }
+ } else {
+ mBlinking = false;
+ }
+ }
+
+ @Override
+ public void onConnect(final RemoteDisplay display) {
+ Log.d(TAG, "onConnect: display.getId()=" + display.getId());
+
+ if (display == mTestDisplay1 || display == mTestDisplay2) {
+ display.setStatus(RemoteDisplay.STATUS_CONNECTING);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if ((display == mTestDisplay1 || display == mTestDisplay2)
+ && display.getStatus() == RemoteDisplay.STATUS_CONNECTING) {
+ display.setStatus(RemoteDisplay.STATUS_CONNECTED);
+ updateDisplay(display);
+ }
+ }
+ }, 2000);
+ updateDisplay(display);
+ }
+ if (display == mTestDisplay6 || display == mTestDisplay7) {
+ // never finishes connecting
+ display.setStatus(RemoteDisplay.STATUS_CONNECTING);
+ updateDisplay(display);
+ }
+ }
+
+ @Override
+ public void onDisconnect(RemoteDisplay display) {
+ Log.d(TAG, "onDisconnect: display.getId()=" + display.getId());
+
+ if (display == mTestDisplay1 || display == mTestDisplay2
+ || display == mTestDisplay6) {
+ display.setStatus(RemoteDisplay.STATUS_AVAILABLE);
+ updateDisplay(display);
+ }
+ }
+
+ @Override
+ public void onSetVolume(RemoteDisplay display, int volume) {
+ Log.d(TAG, "onSetVolume: display.getId()=" + display.getId()
+ + ", volume=" + volume);
+
+ if (display == mTestDisplay1) {
+ display.setVolume(Math.max(0, Math.min(display.getVolumeMax(), volume)));
+ updateDisplay(display);
+ }
+ }
+
+ @Override
+ public void onAdjustVolume(RemoteDisplay display, int delta) {
+ Log.d(TAG, "onAdjustVolume: display.getId()=" + display.getId()
+ + ", delta=" + delta);
+
+ if (display == mTestDisplay1) {
+ display.setVolume(Math.max(0, Math.min(display.getVolumeMax(),
+ display .getVolume() + delta)));
+ updateDisplay(display);
+ }
+ }
+
+ @Override
+ public void addDisplay(RemoteDisplay display) {
+ Log.d(TAG, "addDisplay: display=" + display);
+ super.addDisplay(display);
+ }
+
+ @Override
+ public void removeDisplay(RemoteDisplay display) {
+ Log.d(TAG, "removeDisplay: display=" + display);
+ super.removeDisplay(display);
+ }
+
+ @Override
+ public void updateDisplay(RemoteDisplay display) {
+ Log.d(TAG, "updateDisplay: display=" + display);
+ super.updateDisplay(display);
+ }
+
+ private final Runnable mBlink = new Runnable() {
+ @Override
+ public void run() {
+ if (mTestDisplay7 == null) {
+ if (mBlinking) {
+ mTestDisplay7 = new RemoteDisplay("testDisplay7",
+ "Test Display 7 (blinky)");
+ mTestDisplay7.setDescription("Comes and goes but can't connect");
+ mTestDisplay7.setStatus(RemoteDisplay.STATUS_AVAILABLE);
+ addDisplay(mTestDisplay7);
+ mHandler.postDelayed(this, 7000);
+ }
+ } else {
+ removeDisplay(mTestDisplay7);
+ mTestDisplay7 = null;
+ if (mBlinking) {
+ mHandler.postDelayed(this, 4000);
+ }
+ }
+ }
+ };
+ }
+}