summaryrefslogtreecommitdiff
path: root/media/lib
diff options
context:
space:
mode:
Diffstat (limited to 'media/lib')
-rw-r--r--media/lib/tvremote/Android.mk48
-rw-r--r--media/lib/tvremote/README.txt26
-rw-r--r--media/lib/tvremote/com.android.media.tv.remoteprovider.xml20
-rw-r--r--media/lib/tvremote/java/com/android/media/tv/remoteprovider/TvRemoteProvider.java303
4 files changed, 397 insertions, 0 deletions
diff --git a/media/lib/tvremote/Android.mk b/media/lib/tvremote/Android.mk
new file mode 100644
index 000000000000..06838c2dbf97
--- /dev/null
+++ b/media/lib/tvremote/Android.mk
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2016 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)
+
+# the tvremoteprovider library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= com.android.media.tv.remoteprovider
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, java) \
+ $(call all-aidl-files-under, java)
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_JAVA_LIBRARY)
+
+
+# ==== com.android.media.tvremote.xml lib def ========================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := com.android.media.tv.remoteprovider.xml
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_CLASS := ETC
+
+# This will install the file in /system/etc/permissions
+#
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT) \ No newline at end of file
diff --git a/media/lib/tvremote/README.txt b/media/lib/tvremote/README.txt
new file mode 100644
index 000000000000..9375f02e1cc8
--- /dev/null
+++ b/media/lib/tvremote/README.txt
@@ -0,0 +1,26 @@
+This library (com.android.media.tv.remoteprovider.jar) is a shared java library
+containing classes required by unbundled atv remote providers.
+
+--- Rules of this library ---
+o This library is effectively a System API for unbundled emote service provider
+ that may be distributed outside the system image. So it MUST BE API STABLE.
+ You can add but not remove. The rules are the same as for the
+ public platform SDK API.
+o This library can see and instantiate internal platform classes, but it must not
+ expose them in any public method (or by extending them via inheritance). This would
+ break clients of the library because they cannot see the internal platform classes.
+
+This library is distributed in the system image, and loaded as
+a shared library. So you can change the implementation, but not
+the interface. In this way it is like framework.jar.
+
+--- Why does this library exist? ---
+
+Unbundled atv remote providers (such as Emote app) cannot use internal
+platform classes.
+
+This library will eventually be replaced when the inputmanager
+infrastructure is ready with APIs allowing unbundled system apps to
+inject events into uhid.
+That API isn't ready yet so this library is a compromise to
+make new capabilities available to the system. \ No newline at end of file
diff --git a/media/lib/tvremote/com.android.media.tv.remoteprovider.xml b/media/lib/tvremote/com.android.media.tv.remoteprovider.xml
new file mode 100644
index 000000000000..dcf479ac78b3
--- /dev/null
+++ b/media/lib/tvremote/com.android.media.tv.remoteprovider.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<permissions>
+ <library name="com.android.media.tv.remoteprovider"
+ file="/system/framework/com.android.media.tv.remoteprovider.jar" />
+</permissions> \ No newline at end of file
diff --git a/media/lib/tvremote/java/com/android/media/tv/remoteprovider/TvRemoteProvider.java b/media/lib/tvremote/java/com/android/media/tv/remoteprovider/TvRemoteProvider.java
new file mode 100644
index 000000000000..35322ad8ee6b
--- /dev/null
+++ b/media/lib/tvremote/java/com/android/media/tv/remoteprovider/TvRemoteProvider.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2016 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.tv.remoteprovider;
+
+import android.content.Context;
+import android.media.tv.ITvRemoteProvider;
+import android.media.tv.ITvRemoteServiceInput;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Base class for emote providers implemented in unbundled service.
+ * <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 system API for unbundled emote service, and
+ * must remain API stable. See README.txt in the root of this package for more information.
+ * </p>
+ */
+
+
+public abstract class TvRemoteProvider {
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ * The service must also require the {@link android.Manifest.permission#BIND_TV_REMOTE_SERVICE}
+ * permission so that other applications cannot abuse it.
+ */
+ public static final String SERVICE_INTERFACE =
+ "com.android.media.tv.remoteprovider.TvRemoteProvider";
+
+ private static final String TAG = "TvRemoteProvider";
+ private static final boolean DEBUG_KEYS = false;
+ private static final int MSG_SET_SERVICE_INPUT = 1;
+ private static final int MSG_SEND_INPUTBRIDGE_CONNECTED = 2;
+ private final Context mContext;
+ private final ProviderStub mStub;
+ private final ProviderHandler mHandler;
+ private ITvRemoteServiceInput mRemoteServiceInput;
+
+ /**
+ * Creates a provider for an unbundled emote controller
+ * service allowing it to interface with the tv remote controller
+ * system service.
+ *
+ * @param context The application context for the remote provider.
+ */
+ public TvRemoteProvider(Context context) {
+ mContext = context.getApplicationContext();
+ mStub = new ProviderStub();
+ mHandler = new ProviderHandler(mContext.getMainLooper());
+ }
+
+ /**
+ * Gets the context of the remote service 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 provider service.
+ * </p>
+ *
+ * @return The IBinder instance associated with the provider.
+ */
+ public IBinder getBinder() {
+ return mStub;
+ }
+
+ /**
+ * Information about the InputBridge connected status.
+ *
+ * @param token Identifier for the connection. Null, if failed.
+ */
+ public void onInputBridgeConnected(IBinder token) {
+ }
+
+ /**
+ * Set a sink for sending events to framework service.
+ *
+ * @param tvServiceInput sink defined in framework service
+ */
+ private void setRemoteServiceInputSink(ITvRemoteServiceInput tvServiceInput) {
+ mRemoteServiceInput = tvServiceInput;
+ }
+
+ /**
+ * openRemoteInputBridge : Open an input bridge for a particular device.
+ * Clients should pass in a token that can be used to match this request with a token that
+ * will be returned by {@link TvRemoteProvider#onInputBridgeConnected(IBinder token)}
+ * <p>
+ * The token should be used for subsequent calls.
+ * </p>
+ *
+ * @param name Device name
+ * @param token Identifier for this connection
+ * @param width Width of the device's virtual touchpad
+ * @param height Height of the device's virtual touchpad
+ * @param maxPointers Maximum supported pointers
+ * @throws RuntimeException
+ */
+ public void openRemoteInputBridge(IBinder token, String name, int width, int height,
+ int maxPointers) throws RuntimeException {
+ try {
+ mRemoteServiceInput.openInputBridge(token, name, width, height, maxPointers);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * closeInputBridge : Close input bridge for a device
+ *
+ * @param token identifier for this connection
+ * @throws RuntimeException
+ */
+ public void closeInputBridge(IBinder token) throws RuntimeException {
+ try {
+ mRemoteServiceInput.closeInputBridge(token);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * clearInputBridge : Clear out any existing key or pointer events in queue for this device by
+ * dropping them on the floor and sending an UP to all keys and pointer
+ * slots.
+ *
+ * @param token identifier for this connection
+ * @throws RuntimeException
+ */
+ public void clearInputBridge(IBinder token) throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "clearInputBridge() token " + token);
+ try {
+ mRemoteServiceInput.clearInputBridge(token);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * sendTimestamp : Send a timestamp for a set of pointer events
+ *
+ * @param token identifier for the device
+ * @param timestamp Timestamp to be used in
+ * {@link android.os.SystemClock#uptimeMillis} time base
+ * @throws RuntimeException
+ */
+ public void sendTimestamp(IBinder token, long timestamp) throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "sendTimestamp() token: " + token +
+ ", timestamp: " + timestamp);
+ try {
+ mRemoteServiceInput.sendTimestamp(token, timestamp);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * sendKeyUp : Send key up event for a device
+ *
+ * @param token identifier for this connection
+ * @param keyCode Key code to be sent
+ * @throws RuntimeException
+ */
+ public void sendKeyUp(IBinder token, int keyCode) throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "sendKeyUp() token: " + token + ", keyCode: " + keyCode);
+ try {
+ mRemoteServiceInput.sendKeyUp(token, keyCode);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * sendKeyDown : Send key down event for a device
+ *
+ * @param token identifier for this connection
+ * @param keyCode Key code to be sent
+ * @throws RuntimeException
+ */
+ public void sendKeyDown(IBinder token, int keyCode) throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "sendKeyDown() token: " + token +
+ ", keyCode: " + keyCode);
+ try {
+ mRemoteServiceInput.sendKeyDown(token, keyCode);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * sendPointerUp : Send pointer up event for a device
+ *
+ * @param token identifier for the device
+ * @param pointerId Pointer id to be used. Value may be from 0
+ * to {@link MotionEvent#getPointerCount()} -1
+ * @throws RuntimeException
+ */
+ public void sendPointerUp(IBinder token, int pointerId) throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "sendPointerUp() token: " + token +
+ ", pointerId: " + pointerId);
+ try {
+ mRemoteServiceInput.sendPointerUp(token, pointerId);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * sendPointerDown : Send pointer down event for a device
+ *
+ * @param token identifier for the device
+ * @param pointerId Pointer id to be used. Value may be from 0
+ * to {@link MotionEvent#getPointerCount()} -1
+ * @param x X co-ordinates in display pixels
+ * @param y Y co-ordinates in display pixels
+ * @throws RuntimeException
+ */
+ public void sendPointerDown(IBinder token, int pointerId, int x, int y)
+ throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "sendPointerDown() token: " + token +
+ ", pointerId: " + pointerId);
+ try {
+ mRemoteServiceInput.sendPointerDown(token, pointerId, x, y);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * sendPointerSync : Send pointer sync event for a device
+ *
+ * @param token identifier for the device
+ * @throws RuntimeException
+ */
+ public void sendPointerSync(IBinder token) throws RuntimeException {
+ if (DEBUG_KEYS) Log.d(TAG, "sendPointerSync() token: " + token);
+ try {
+ mRemoteServiceInput.sendPointerSync(token);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ private final class ProviderStub extends ITvRemoteProvider.Stub {
+ @Override
+ public void setRemoteServiceInputSink(ITvRemoteServiceInput tvServiceInput) {
+ mHandler.obtainMessage(MSG_SET_SERVICE_INPUT, tvServiceInput).sendToTarget();
+ }
+
+ @Override
+ public void onInputBridgeConnected(IBinder token) {
+ mHandler.obtainMessage(MSG_SEND_INPUTBRIDGE_CONNECTED, 0, 0,
+ (IBinder) token).sendToTarget();
+ }
+ }
+
+ private 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_SERVICE_INPUT: {
+ setRemoteServiceInputSink((ITvRemoteServiceInput) msg.obj);
+ break;
+ }
+ case MSG_SEND_INPUTBRIDGE_CONNECTED: {
+ onInputBridgeConnected((IBinder) msg.obj);
+ break;
+ }
+ }
+ }
+ }
+}