diff options
author | Jeff Brown <jeffbrown@google.com> | 2013-11-07 00:30:16 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2013-11-07 03:25:37 -0800 |
commit | 69b07161bebdb2c726e3a826c2268866f1a94517 (patch) | |
tree | 8d9c94f32a045a8f5c48ca0f1380abc760eac807 /tests/RemoteDisplayProvider | |
parent | f3c99e883f46c56e5e2877e844b902b6eb45545b (diff) | |
download | frameworks_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.mk | 25 | ||||
-rw-r--r-- | tests/RemoteDisplayProvider/AndroidManifest.xml | 37 | ||||
-rw-r--r-- | tests/RemoteDisplayProvider/README | 16 | ||||
-rwxr-xr-x | tests/RemoteDisplayProvider/res/drawable-hdpi/ic_app.png | bin | 0 -> 3608 bytes | |||
-rw-r--r-- | tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png | bin | 0 -> 5198 bytes | |||
-rw-r--r-- | tests/RemoteDisplayProvider/res/values/strings.xml | 19 | ||||
-rw-r--r-- | tests/RemoteDisplayProvider/src/com/android/media/remotedisplay/test/RemoteDisplayProviderService.java | 240 |
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 Binary files differnew file mode 100755 index 0000000..66a1984 --- /dev/null +++ b/tests/RemoteDisplayProvider/res/drawable-hdpi/ic_app.png diff --git a/tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png b/tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png Binary files differnew file mode 100644 index 0000000..5ae7701 --- /dev/null +++ b/tests/RemoteDisplayProvider/res/drawable-mdpi/ic_app.png 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); + } + } + } + }; + } +} |