1b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan/* 2b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * Copyright (C) 2016 The Android Open Source Project 3b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * 4b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * Licensed under the Apache License, Version 2.0 (the "License"); 5b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * you may not use this file except in compliance with the License. 6b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * You may obtain a copy of the License at 7b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * 8b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * http://www.apache.org/licenses/LICENSE-2.0 9b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * 10b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * Unless required by applicable law or agreed to in writing, software 11b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * distributed under the License is distributed on an "AS IS" BASIS, 12b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * See the License for the specific language governing permissions and 14b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * limitations under the License. 15b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan */ 16b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 17b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanpackage com.android.server.tv; 18b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 19b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.content.Context; 20b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.os.Handler; 21b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.os.IBinder; 22b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.os.Looper; 23b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.os.Message; 24b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.util.ArrayMap; 25b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport android.util.Slog; 26b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 27b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport com.android.server.SystemService; 28b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport com.android.server.Watchdog; 29b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 30b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport java.io.IOException; 31b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport java.util.ArrayList; 32b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanimport java.util.Map; 33b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 34b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan/** 35b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * TvRemoteService represents a system service that allows a connected 36b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * remote control (emote) service to inject white-listed input events 37b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * and call other specified methods for functioning as an emote service. 38b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * <p/> 39b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * This service is intended for use only by white-listed packages. 40b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan */ 41b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnanpublic class TvRemoteService extends SystemService implements Watchdog.Monitor { 42b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private static final String TAG = "TvRemoteService"; 43b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private static final boolean DEBUG = false; 44b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private static final boolean DEBUG_KEYS = false; 45b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 46b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private Map<IBinder, UinputBridge> mBridgeMap = new ArrayMap(); 47b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private Map<IBinder, TvRemoteProviderProxy> mProviderMap = new ArrayMap(); 48b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private ArrayList<TvRemoteProviderProxy> mProviderList = new ArrayList<>(); 49b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 50b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan /** 51b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * State guarded by mLock. 52b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * This is the second lock in sequence for an incoming call. 53b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * The first lock is always {@link TvRemoteProviderProxy#mLock} 54b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * 55b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * There are currently no methods that break this sequence. 56b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * Special note: 57b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * Outgoing call informInputBridgeConnected(), which is called from 58b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan * openInputBridgeInternalLocked() uses a handler thereby relinquishing held locks. 59b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan */ 60b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private final Object mLock = new Object(); 61b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 62b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public final UserHandler mHandler; 63b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 64b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public TvRemoteService(Context context) { 65b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan super(context); 66b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mHandler = new UserHandler(new UserProvider(TvRemoteService.this), context); 67b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Watchdog.getInstance().addMonitor(this); 68b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 69b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 70b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 71b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void onStart() { 72b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "onStart()"); 73b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 74b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 75b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 76b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void monitor() { 77b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { /* check for deadlock */ } 78b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 79b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 80b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 81b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void onBootPhase(int phase) { 82b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 83b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "PHASE_THIRD_PARTY_APPS_CAN_START"); 84b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mHandler.sendEmptyMessage(UserHandler.MSG_START); 85b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 86b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 87b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 88b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan //Outgoing calls. 89b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void informInputBridgeConnected(IBinder token) { 90b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mHandler.obtainMessage(UserHandler.MSG_INPUT_BRIDGE_CONNECTED, 0, 0, token).sendToTarget(); 91b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 92b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 93b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan // Incoming calls. 94b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void openInputBridgeInternalLocked(TvRemoteProviderProxy provider, IBinder token, 95b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan String name, int width, int height, 96b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan int maxPointers) { 97b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) { 98b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "openInputBridgeInternalLocked(), token: " + token + ", name: " + name + 99b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan ", width: " + width + ", height: " + height + ", maxPointers: " + maxPointers); 100b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 101b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 102b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan try { 103b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan //Create a new bridge, if one does not exist already 104b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mBridgeMap.containsKey(token)) { 105b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "RemoteBridge already exists"); 106b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan // Respond back with success. 107b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan informInputBridgeConnected(token); 108b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan return; 109b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 110b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 111b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = new UinputBridge(token, name, width, height, maxPointers); 112b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 113b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mBridgeMap.put(token, inputBridge); 114b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mProviderMap.put(token, provider); 115b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 116b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan // Respond back with success. 117b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan informInputBridgeConnected(token); 118b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 119b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } catch (IOException ioe) { 120b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.e(TAG, "Cannot create device for " + name); 121b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 122b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 123b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 124b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void closeInputBridgeInternalLocked(IBinder token) { 125b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) { 126b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "closeInputBridgeInternalLocked(), token: " + token); 127b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 128b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 129b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan // Close an existing RemoteBridge 130b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 131b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 132b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.close(token); 133b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 134b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 135b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mBridgeMap.remove(token); 136b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 137b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 138b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 139b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void clearInputBridgeInternalLocked(IBinder token) { 140b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) { 141b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "clearInputBridgeInternalLocked(), token: " + token); 142b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 143b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 144b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 145b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 146b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.clear(token); 147b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 148b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 149b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 150b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void sendTimeStampInternalLocked(IBinder token, long timestamp) { 151b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 152b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 153b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.sendTimestamp(token, timestamp); 154b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 155b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 156b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 157b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void sendKeyDownInternalLocked(IBinder token, int keyCode) { 158b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 159b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendKeyDownInternalLocked(), token: " + token + ", keyCode: " + keyCode); 160b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 161b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 162b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 163b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 164b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.sendKeyDown(token, keyCode); 165b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 166b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 167b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 168b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void sendKeyUpInternalLocked(IBinder token, int keyCode) { 169b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 170b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendKeyUpInternalLocked(), token: " + token + ", keyCode: " + keyCode); 171b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 172b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 173b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 174b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 175b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.sendKeyUp(token, keyCode); 176b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 177b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 178b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 179b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void sendPointerDownInternalLocked(IBinder token, int pointerId, int x, int y) { 180b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 181b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendPointerDownInternalLocked(), token: " + token + ", pointerId: " + 182b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan pointerId + ", x: " + x + ", y: " + y); 183b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 184b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 185b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 186b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 187b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.sendPointerDown(token, pointerId, x, y); 188b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 189b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 190b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 191b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void sendPointerUpInternalLocked(IBinder token, int pointerId) { 192b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 193b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendPointerUpInternalLocked(), token: " + token + ", pointerId: " + 194b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan pointerId); 195b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 196b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 197b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 198b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 199b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.sendPointerUp(token, pointerId); 200b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 201b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 202b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 203b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void sendPointerSyncInternalLocked(IBinder token) { 204b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 205b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendPointerSyncInternalLocked(), token: " + token); 206b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 207b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 208b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan UinputBridge inputBridge = mBridgeMap.get(token); 209b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (inputBridge != null) { 210b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan inputBridge.sendPointerSync(token); 211b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 212b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 213b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 214b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private final class UserHandler extends Handler { 215b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 216b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public static final int MSG_START = 1; 217b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public static final int MSG_INPUT_BRIDGE_CONNECTED = 2; 218b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 219b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private final TvRemoteProviderWatcher mWatcher; 220b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private boolean mRunning; 221b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 222b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public UserHandler(UserProvider provider, Context context) { 223b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan super(Looper.getMainLooper(), null, true); 224b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mWatcher = new TvRemoteProviderWatcher(context, provider, this); 225b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 226b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 227b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 228b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void handleMessage(Message msg) { 229b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan switch (msg.what) { 230b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan case MSG_START: { 231b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan start(); 232b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan break; 233b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 234b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan case MSG_INPUT_BRIDGE_CONNECTED: { 235b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan IBinder token = (IBinder) msg.obj; 236b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan TvRemoteProviderProxy provider = mProviderMap.get(token); 237b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (provider != null) { 238b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan provider.inputBridgeConnected(token); 239b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 240b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan break; 241b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 242b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 243b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 244b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 245b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private void start() { 246b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (!mRunning) { 247b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mRunning = true; 248b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mWatcher.start(); // also starts all providers 249b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 250b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 251b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 252b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 253b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private final class UserProvider implements TvRemoteProviderWatcher.ProviderMethods, 254b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan TvRemoteProviderProxy.ProviderMethods { 255b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 256b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan private final TvRemoteService mService; 257b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 258b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public UserProvider(TvRemoteService service) { 259b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService = service; 260b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 261b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 262b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 263b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, 264b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan int width, int height, int maxPointers) { 265b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) { 266b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "openInputBridge(), token: " + token + 267b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan ", name: " + name + ", width: " + width + 268b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan ", height: " + height + ", maxPointers: " + maxPointers); 269b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 270b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 271b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 272b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 273b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.openInputBridgeInternalLocked(provider, token, name, width, height, 274b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan maxPointers); 275b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 276b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 277b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 278b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 279b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 280b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void closeInputBridge(TvRemoteProviderProxy provider, IBinder token) { 281b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "closeInputBridge(), token: " + token); 282b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 283b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 284b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.closeInputBridgeInternalLocked(token); 285b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mProviderMap.remove(token); 286b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 287b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 288b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 289b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 290b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 291b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void clearInputBridge(TvRemoteProviderProxy provider, IBinder token) { 292b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "clearInputBridge(), token: " + token); 293b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 294b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 295b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.clearInputBridgeInternalLocked(token); 296b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 297b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 298b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 299b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 300b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 301b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void sendTimeStamp(TvRemoteProviderProxy provider, IBinder token, long timestamp) { 302b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 303b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 304b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.sendTimeStampInternalLocked(token, timestamp); 305b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 306b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 307b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 308b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 309b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 310b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void sendKeyDown(TvRemoteProviderProxy provider, IBinder token, int keyCode) { 311b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 312b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendKeyDown(), token: " + token + ", keyCode: " + keyCode); 313b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 314b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 315b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 316b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.sendKeyDownInternalLocked(token, keyCode); 317b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 318b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 319b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 320b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 321b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 322b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void sendKeyUp(TvRemoteProviderProxy provider, IBinder token, int keyCode) { 323b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 324b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendKeyUp(), token: " + token + ", keyCode: " + keyCode); 325b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 326b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 327b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 328b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.sendKeyUpInternalLocked(token, keyCode); 329b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 330b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 331b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 332b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 333b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 334b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void sendPointerDown(TvRemoteProviderProxy provider, IBinder token, int pointerId, 335b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan int x, int y) { 336b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 337b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendPointerDown(), token: " + token + ", pointerId: " + pointerId); 338b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 339b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 340b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 341b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.sendPointerDownInternalLocked(token, pointerId, x, y); 342b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 343b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 344b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 345b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 346b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 347b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void sendPointerUp(TvRemoteProviderProxy provider, IBinder token, int pointerId) { 348b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) { 349b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "sendPointerUp(), token: " + token + ", pointerId: " + pointerId); 350b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 351b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 352b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 353b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.sendPointerUpInternalLocked(token, pointerId); 354b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 355b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 356b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 357b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 358b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 359b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void sendPointerSync(TvRemoteProviderProxy provider, IBinder token) { 360b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG_KEYS) Slog.d(TAG, "sendPointerSync(), token: " + token); 361b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 362b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.contains(provider)) { 363b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mService.sendPointerSyncInternalLocked(token); 364b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 365b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 366b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 367b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 368b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 369b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void addProvider(TvRemoteProviderProxy provider) { 370b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "addProvider " + provider); 371b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 372b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan provider.setProviderSink(this); 373b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan mProviderList.add(provider); 374b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.d(TAG, "provider: " + provider.toString()); 375b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 376b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 377b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan 378b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan @Override 379b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan public void removeProvider(TvRemoteProviderProxy provider) { 380b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (DEBUG) Slog.d(TAG, "removeProvider " + provider); 381b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan synchronized (mLock) { 382b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan if (mProviderList.remove(provider) == false) { 383b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan Slog.e(TAG, "Unknown provider " + provider); 384b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 385b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 386b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 387b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan } 388b5b86c11008422ac4bf5af5fed736f04ebbaa858Sujith Ramakrishnan} 389