Loading services/core/java/com/android/server/tv/TvRemoteProviderProxy.java +23 −103 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.ServiceConnection; import android.media.tv.ITvRemoteProvider; import android.media.tv.ITvRemoteServiceInput; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; Loading @@ -49,7 +48,6 @@ final class TvRemoteProviderProxy implements ServiceConnection { private final ComponentName mComponentName; private final int mUserId; private final int mUid; private final Handler mHandler; /** * State guarded by mLock. Loading @@ -65,15 +63,14 @@ final class TvRemoteProviderProxy implements ServiceConnection { private boolean mRunning; private boolean mBound; private Connection mActiveConnection; private boolean mConnectionReady; public TvRemoteProviderProxy(Context context, ComponentName componentName, int userId, int uid) { TvRemoteProviderProxy(Context context, ProviderMethods provider, ComponentName componentName, int userId, int uid) { mContext = context; mProviderMethods = provider; mComponentName = componentName; mUserId = userId; mUid = uid; mHandler = new Handler(); } public void dump(PrintWriter pw, String prefix) { Loading @@ -82,11 +79,6 @@ final class TvRemoteProviderProxy implements ServiceConnection { pw.println(prefix + " mRunning=" + mRunning); pw.println(prefix + " mBound=" + mBound); pw.println(prefix + " mActiveConnection=" + mActiveConnection); pw.println(prefix + " mConnectionReady=" + mConnectionReady); } public void setProviderSink(ProviderMethods provider) { mProviderMethods = provider; } public boolean hasComponentName(String packageName, String className) { Loading @@ -101,7 +93,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } mRunning = true; updateBinding(); bind(); } } Loading @@ -112,31 +104,19 @@ final class TvRemoteProviderProxy implements ServiceConnection { } mRunning = false; updateBinding(); unbind(); } } public void rebindIfDisconnected() { synchronized (mLock) { if (mActiveConnection == null && shouldBind()) { if (mActiveConnection == null && mRunning) { unbind(); bind(); } } } private void updateBinding() { if (shouldBind()) { bind(); } else { unbind(); } } private boolean shouldBind() { return mRunning; } private void bind() { if (!mBound) { if (DEBUG) { Loading Loading @@ -208,47 +188,18 @@ final class TvRemoteProviderProxy implements ServiceConnection { disconnect(); } private void onConnectionReady(Connection connection) { synchronized (mLock) { if (DEBUG) Slog.d(TAG, "onConnectionReady"); if (mActiveConnection == connection) { if (DEBUG) Slog.d(TAG, "mConnectionReady = true"); mConnectionReady = true; } } } private void onConnectionDied(Connection connection) { if (mActiveConnection == connection) { if (DEBUG) Slog.d(TAG, this + ": Service connection died"); disconnect(); } } private void disconnect() { synchronized (mLock) { if (mActiveConnection != null) { mConnectionReady = false; mActiveConnection.dispose(); mActiveConnection = null; } } } // Provider helpers public void inputBridgeConnected(IBinder token) { synchronized (mLock) { if (DEBUG) Slog.d(TAG, this + ": inputBridgeConnected token: " + token); if (mConnectionReady) { mActiveConnection.onInputBridgeConnected(token); } } } public interface ProviderMethods { interface ProviderMethods { // InputBridge void openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, boolean openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, int width, int height, int maxPointers); void closeInputBridge(TvRemoteProviderProxy provider, IBinder token); Loading @@ -267,7 +218,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { void sendPointerSync(TvRemoteProviderProxy provider, IBinder token); } private final class Connection implements IBinder.DeathRecipient { private final class Connection { private final ITvRemoteProvider mTvRemoteProvider; private final RemoteServiceInputProvider mServiceInputProvider; Loading @@ -279,24 +230,16 @@ final class TvRemoteProviderProxy implements ServiceConnection { public boolean register() { if (DEBUG) Slog.d(TAG, "Connection::register()"); try { mTvRemoteProvider.asBinder().linkToDeath(this, 0); mTvRemoteProvider.setRemoteServiceInputSink(mServiceInputProvider); mHandler.post(new Runnable() { @Override public void run() { onConnectionReady(Connection.this); } }); return true; } catch (RemoteException ex) { binderDied(); } dispose(); return false; } } public void dispose() { if (DEBUG) Slog.d(TAG, "Connection::dispose()"); mTvRemoteProvider.asBinder().unlinkToDeath(this, 0); mServiceInputProvider.dispose(); } Loading @@ -310,16 +253,6 @@ final class TvRemoteProviderProxy implements ServiceConnection { } } @Override public void binderDied() { mHandler.post(new Runnable() { @Override public void run() { onConnectionDied(Connection.this); } }); } void openInputBridge(final IBinder token, final String name, final int width, final int height, final int maxPointers) { synchronized (mLock) { Loading @@ -330,9 +263,9 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.openInputBridge(TvRemoteProviderProxy.this, token, name, width, height, maxPointers); if (mProviderMethods.openInputBridge(TvRemoteProviderProxy.this, token, name, width, height, maxPointers)) { onInputBridgeConnected(token); } } finally { Binder.restoreCallingIdentity(idToken); Loading @@ -356,9 +289,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.closeInputBridge(TvRemoteProviderProxy.this, token); } } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -381,9 +312,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.clearInputBridge(TvRemoteProviderProxy.this, token); } } finally { Binder.restoreCallingIdentity(idToken); } Loading Loading @@ -412,10 +341,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendKeyDown(TvRemoteProviderProxy.this, token, keyCode); } mProviderMethods.sendKeyDown(TvRemoteProviderProxy.this, token, keyCode); } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -438,9 +364,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendKeyUp(TvRemoteProviderProxy.this, token, keyCode); } } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -463,10 +387,8 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendPointerDown(TvRemoteProviderProxy.this, token, pointerId, x, y); } } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -489,10 +411,8 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendPointerUp(TvRemoteProviderProxy.this, token, pointerId); } } finally { Binder.restoreCallingIdentity(idToken); } Loading services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java +4 −12 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ final class TvRemoteProviderWatcher { private static final boolean DEBUG = Log.isLoggable(TAG, Log.VERBOSE); private final Context mContext; private final ProviderMethods mProvider; private final TvRemoteProviderProxy.ProviderMethods mProvider; private final Handler mHandler; private final PackageManager mPackageManager; private final ArrayList<TvRemoteProviderProxy> mProviderProxies = new ArrayList<>(); Loading @@ -54,10 +54,10 @@ final class TvRemoteProviderWatcher { private boolean mRunning; public TvRemoteProviderWatcher(Context context, ProviderMethods provider, Handler handler) { TvRemoteProviderWatcher(Context context, TvRemoteProviderProxy.ProviderMethods provider) { mContext = context; mProvider = provider; mHandler = handler; mHandler = new Handler(true); mUserId = UserHandle.myUserId(); mPackageManager = context.getPackageManager(); mUnbundledServicePackage = context.getString( Loading Loading @@ -116,12 +116,11 @@ final class TvRemoteProviderWatcher { int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name); if (sourceIndex < 0) { TvRemoteProviderProxy providerProxy = new TvRemoteProviderProxy(mContext, new TvRemoteProviderProxy(mContext, mProvider, new ComponentName(serviceInfo.packageName, serviceInfo.name), mUserId, serviceInfo.applicationInfo.uid); providerProxy.start(); mProviderProxies.add(targetIndex++, providerProxy); mProvider.addProvider(providerProxy); } else if (sourceIndex >= targetIndex) { TvRemoteProviderProxy provider = mProviderProxies.get(sourceIndex); provider.start(); // restart the provider if needed Loading @@ -135,7 +134,6 @@ final class TvRemoteProviderWatcher { if (targetIndex < mProviderProxies.size()) { for (int i = mProviderProxies.size() - 1; i >= targetIndex; i--) { TvRemoteProviderProxy providerProxy = mProviderProxies.get(i); mProvider.removeProvider(providerProxy); mProviderProxies.remove(providerProxy); providerProxy.stop(); } Loading Loading @@ -212,10 +210,4 @@ final class TvRemoteProviderWatcher { scanPackages(); } }; public interface ProviderMethods { void addProvider(TvRemoteProviderProxy providerProxy); void removeProvider(TvRemoteProviderProxy providerProxy); } } services/core/java/com/android/server/tv/TvRemoteService.java +18 −111 Original line number Diff line number Diff line Loading @@ -17,11 +17,8 @@ package com.android.server.tv; import android.content.Context; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.Looper; import android.os.Message; import android.util.ArrayMap; import android.util.Slog; Loading @@ -29,7 +26,6 @@ import com.android.server.SystemService; import com.android.server.Watchdog; import java.io.IOException; import java.util.ArrayList; import java.util.Map; /** Loading @@ -44,9 +40,8 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { private static final boolean DEBUG = false; private static final boolean DEBUG_KEYS = false; private final TvRemoteProviderWatcher mWatcher; private Map<IBinder, UinputBridge> mBridgeMap = new ArrayMap(); private Map<IBinder, TvRemoteProviderProxy> mProviderMap = new ArrayMap(); private ArrayList<TvRemoteProviderProxy> mProviderList = new ArrayList<>(); /** * State guarded by mLock. Loading @@ -60,11 +55,10 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { */ private final Object mLock = new Object(); public final UserHandler mHandler; public TvRemoteService(Context context) { super(context); mHandler = new UserHandler(new UserProvider(TvRemoteService.this), context); mWatcher = new TvRemoteProviderWatcher(context, new UserProvider(TvRemoteService.this)); Watchdog.getInstance().addMonitor(this); } Loading @@ -80,19 +74,15 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { @Override public void onBootPhase(int phase) { // All lifecycle methods are called from the system server's main looper thread. if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { if (DEBUG) Slog.d(TAG, "PHASE_THIRD_PARTY_APPS_CAN_START"); mHandler.sendEmptyMessage(UserHandler.MSG_START); } } //Outgoing calls. private void informInputBridgeConnected(IBinder token) { mHandler.obtainMessage(UserHandler.MSG_INPUT_BRIDGE_CONNECTED, 0, 0, token).sendToTarget(); mWatcher.start(); // Also schedules the start of all providers. } } // Incoming calls. private void openInputBridgeInternalLocked(TvRemoteProviderProxy provider, final IBinder token, private boolean openInputBridgeInternalLocked(final IBinder token, String name, int width, int height, int maxPointers) { if (DEBUG) { Loading @@ -104,15 +94,11 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { //Create a new bridge, if one does not exist already if (mBridgeMap.containsKey(token)) { if (DEBUG) Slog.d(TAG, "RemoteBridge already exists"); // Respond back with success. informInputBridgeConnected(token); return; return true; } UinputBridge inputBridge = new UinputBridge(token, name, width, height, maxPointers); mBridgeMap.put(token, inputBridge); mProviderMap.put(token, provider); try { token.linkToDeath(new IBinder.DeathRecipient() { Loading @@ -126,15 +112,13 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } catch (RemoteException e) { if (DEBUG) Slog.d(TAG, "Token is already dead"); closeInputBridgeInternalLocked(token); return; return false; } // Respond back with success. informInputBridgeConnected(token); } catch (IOException ioe) { Slog.e(TAG, "Cannot create device for " + name); return false; } return true; } private void closeInputBridgeInternalLocked(IBinder token) { Loading @@ -149,7 +133,6 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } mBridgeMap.remove(token); mProviderMap.remove(token); } private void clearInputBridgeInternalLocked(IBinder token) { Loading Loading @@ -220,47 +203,7 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } } private final class UserHandler extends Handler { public static final int MSG_START = 1; public static final int MSG_INPUT_BRIDGE_CONNECTED = 2; private final TvRemoteProviderWatcher mWatcher; private boolean mRunning; public UserHandler(UserProvider provider, Context context) { super(Looper.getMainLooper(), null, true); mWatcher = new TvRemoteProviderWatcher(context, provider, this); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_START: { start(); break; } case MSG_INPUT_BRIDGE_CONNECTED: { IBinder token = (IBinder) msg.obj; TvRemoteProviderProxy provider = mProviderMap.get(token); if (provider != null) { provider.inputBridgeConnected(token); } break; } } } private void start() { if (!mRunning) { mRunning = true; mWatcher.start(); // also starts all providers } } } private final class UserProvider implements TvRemoteProviderWatcher.ProviderMethods, TvRemoteProviderProxy.ProviderMethods { private final class UserProvider implements TvRemoteProviderProxy.ProviderMethods { private final TvRemoteService mService; Loading @@ -269,7 +212,7 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } @Override public void openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, public boolean openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, int width, int height, int maxPointers) { if (DEBUG) { Slog.d(TAG, "openInputBridge(), token: " + token + Loading @@ -278,10 +221,8 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.openInputBridgeInternalLocked(provider, token, name, width, height, maxPointers); } return mService.openInputBridgeInternalLocked(token, name, width, height, maxPointers); } } Loading @@ -289,21 +230,17 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { public void closeInputBridge(TvRemoteProviderProxy provider, IBinder token) { if (DEBUG) Slog.d(TAG, "closeInputBridge(), token: " + token); synchronized (mLock) { if (mProviderList.contains(provider)) { mService.closeInputBridgeInternalLocked(token); } } } @Override public void clearInputBridge(TvRemoteProviderProxy provider, IBinder token) { if (DEBUG) Slog.d(TAG, "clearInputBridge(), token: " + token); synchronized (mLock) { if (mProviderList.contains(provider)) { mService.clearInputBridgeInternalLocked(token); } } } @Override public void sendKeyDown(TvRemoteProviderProxy provider, IBinder token, int keyCode) { Loading @@ -311,11 +248,9 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendKeyDown(), token: " + token + ", keyCode: " + keyCode); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendKeyDownInternalLocked(token, keyCode); } } } @Override public void sendKeyUp(TvRemoteProviderProxy provider, IBinder token, int keyCode) { Loading @@ -323,11 +258,9 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendKeyUp(), token: " + token + ", keyCode: " + keyCode); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendKeyUpInternalLocked(token, keyCode); } } } @Override public void sendPointerDown(TvRemoteProviderProxy provider, IBinder token, int pointerId, Loading @@ -336,11 +269,9 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendPointerDown(), token: " + token + ", pointerId: " + pointerId); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendPointerDownInternalLocked(token, pointerId, x, y); } } } @Override public void sendPointerUp(TvRemoteProviderProxy provider, IBinder token, int pointerId) { Loading @@ -348,40 +279,16 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendPointerUp(), token: " + token + ", pointerId: " + pointerId); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendPointerUpInternalLocked(token, pointerId); } } } @Override public void sendPointerSync(TvRemoteProviderProxy provider, IBinder token) { if (DEBUG_KEYS) Slog.d(TAG, "sendPointerSync(), token: " + token); synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendPointerSyncInternalLocked(token); } } } @Override public void addProvider(TvRemoteProviderProxy provider) { if (DEBUG) Slog.d(TAG, "addProvider " + provider); synchronized (mLock) { provider.setProviderSink(this); mProviderList.add(provider); Slog.d(TAG, "provider: " + provider.toString()); } } @Override public void removeProvider(TvRemoteProviderProxy provider) { if (DEBUG) Slog.d(TAG, "removeProvider " + provider); synchronized (mLock) { if (mProviderList.remove(provider) == false) { Slog.e(TAG, "Unknown provider " + provider); } } } } } Loading
services/core/java/com/android/server/tv/TvRemoteProviderProxy.java +23 −103 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.ServiceConnection; import android.media.tv.ITvRemoteProvider; import android.media.tv.ITvRemoteServiceInput; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; Loading @@ -49,7 +48,6 @@ final class TvRemoteProviderProxy implements ServiceConnection { private final ComponentName mComponentName; private final int mUserId; private final int mUid; private final Handler mHandler; /** * State guarded by mLock. Loading @@ -65,15 +63,14 @@ final class TvRemoteProviderProxy implements ServiceConnection { private boolean mRunning; private boolean mBound; private Connection mActiveConnection; private boolean mConnectionReady; public TvRemoteProviderProxy(Context context, ComponentName componentName, int userId, int uid) { TvRemoteProviderProxy(Context context, ProviderMethods provider, ComponentName componentName, int userId, int uid) { mContext = context; mProviderMethods = provider; mComponentName = componentName; mUserId = userId; mUid = uid; mHandler = new Handler(); } public void dump(PrintWriter pw, String prefix) { Loading @@ -82,11 +79,6 @@ final class TvRemoteProviderProxy implements ServiceConnection { pw.println(prefix + " mRunning=" + mRunning); pw.println(prefix + " mBound=" + mBound); pw.println(prefix + " mActiveConnection=" + mActiveConnection); pw.println(prefix + " mConnectionReady=" + mConnectionReady); } public void setProviderSink(ProviderMethods provider) { mProviderMethods = provider; } public boolean hasComponentName(String packageName, String className) { Loading @@ -101,7 +93,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } mRunning = true; updateBinding(); bind(); } } Loading @@ -112,31 +104,19 @@ final class TvRemoteProviderProxy implements ServiceConnection { } mRunning = false; updateBinding(); unbind(); } } public void rebindIfDisconnected() { synchronized (mLock) { if (mActiveConnection == null && shouldBind()) { if (mActiveConnection == null && mRunning) { unbind(); bind(); } } } private void updateBinding() { if (shouldBind()) { bind(); } else { unbind(); } } private boolean shouldBind() { return mRunning; } private void bind() { if (!mBound) { if (DEBUG) { Loading Loading @@ -208,47 +188,18 @@ final class TvRemoteProviderProxy implements ServiceConnection { disconnect(); } private void onConnectionReady(Connection connection) { synchronized (mLock) { if (DEBUG) Slog.d(TAG, "onConnectionReady"); if (mActiveConnection == connection) { if (DEBUG) Slog.d(TAG, "mConnectionReady = true"); mConnectionReady = true; } } } private void onConnectionDied(Connection connection) { if (mActiveConnection == connection) { if (DEBUG) Slog.d(TAG, this + ": Service connection died"); disconnect(); } } private void disconnect() { synchronized (mLock) { if (mActiveConnection != null) { mConnectionReady = false; mActiveConnection.dispose(); mActiveConnection = null; } } } // Provider helpers public void inputBridgeConnected(IBinder token) { synchronized (mLock) { if (DEBUG) Slog.d(TAG, this + ": inputBridgeConnected token: " + token); if (mConnectionReady) { mActiveConnection.onInputBridgeConnected(token); } } } public interface ProviderMethods { interface ProviderMethods { // InputBridge void openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, boolean openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, int width, int height, int maxPointers); void closeInputBridge(TvRemoteProviderProxy provider, IBinder token); Loading @@ -267,7 +218,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { void sendPointerSync(TvRemoteProviderProxy provider, IBinder token); } private final class Connection implements IBinder.DeathRecipient { private final class Connection { private final ITvRemoteProvider mTvRemoteProvider; private final RemoteServiceInputProvider mServiceInputProvider; Loading @@ -279,24 +230,16 @@ final class TvRemoteProviderProxy implements ServiceConnection { public boolean register() { if (DEBUG) Slog.d(TAG, "Connection::register()"); try { mTvRemoteProvider.asBinder().linkToDeath(this, 0); mTvRemoteProvider.setRemoteServiceInputSink(mServiceInputProvider); mHandler.post(new Runnable() { @Override public void run() { onConnectionReady(Connection.this); } }); return true; } catch (RemoteException ex) { binderDied(); } dispose(); return false; } } public void dispose() { if (DEBUG) Slog.d(TAG, "Connection::dispose()"); mTvRemoteProvider.asBinder().unlinkToDeath(this, 0); mServiceInputProvider.dispose(); } Loading @@ -310,16 +253,6 @@ final class TvRemoteProviderProxy implements ServiceConnection { } } @Override public void binderDied() { mHandler.post(new Runnable() { @Override public void run() { onConnectionDied(Connection.this); } }); } void openInputBridge(final IBinder token, final String name, final int width, final int height, final int maxPointers) { synchronized (mLock) { Loading @@ -330,9 +263,9 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.openInputBridge(TvRemoteProviderProxy.this, token, name, width, height, maxPointers); if (mProviderMethods.openInputBridge(TvRemoteProviderProxy.this, token, name, width, height, maxPointers)) { onInputBridgeConnected(token); } } finally { Binder.restoreCallingIdentity(idToken); Loading @@ -356,9 +289,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.closeInputBridge(TvRemoteProviderProxy.this, token); } } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -381,9 +312,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.clearInputBridge(TvRemoteProviderProxy.this, token); } } finally { Binder.restoreCallingIdentity(idToken); } Loading Loading @@ -412,10 +341,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendKeyDown(TvRemoteProviderProxy.this, token, keyCode); } mProviderMethods.sendKeyDown(TvRemoteProviderProxy.this, token, keyCode); } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -438,9 +364,7 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendKeyUp(TvRemoteProviderProxy.this, token, keyCode); } } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -463,10 +387,8 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendPointerDown(TvRemoteProviderProxy.this, token, pointerId, x, y); } } finally { Binder.restoreCallingIdentity(idToken); } Loading @@ -489,10 +411,8 @@ final class TvRemoteProviderProxy implements ServiceConnection { } final long idToken = Binder.clearCallingIdentity(); try { if (mProviderMethods != null) { mProviderMethods.sendPointerUp(TvRemoteProviderProxy.this, token, pointerId); } } finally { Binder.restoreCallingIdentity(idToken); } Loading
services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java +4 −12 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ final class TvRemoteProviderWatcher { private static final boolean DEBUG = Log.isLoggable(TAG, Log.VERBOSE); private final Context mContext; private final ProviderMethods mProvider; private final TvRemoteProviderProxy.ProviderMethods mProvider; private final Handler mHandler; private final PackageManager mPackageManager; private final ArrayList<TvRemoteProviderProxy> mProviderProxies = new ArrayList<>(); Loading @@ -54,10 +54,10 @@ final class TvRemoteProviderWatcher { private boolean mRunning; public TvRemoteProviderWatcher(Context context, ProviderMethods provider, Handler handler) { TvRemoteProviderWatcher(Context context, TvRemoteProviderProxy.ProviderMethods provider) { mContext = context; mProvider = provider; mHandler = handler; mHandler = new Handler(true); mUserId = UserHandle.myUserId(); mPackageManager = context.getPackageManager(); mUnbundledServicePackage = context.getString( Loading Loading @@ -116,12 +116,11 @@ final class TvRemoteProviderWatcher { int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name); if (sourceIndex < 0) { TvRemoteProviderProxy providerProxy = new TvRemoteProviderProxy(mContext, new TvRemoteProviderProxy(mContext, mProvider, new ComponentName(serviceInfo.packageName, serviceInfo.name), mUserId, serviceInfo.applicationInfo.uid); providerProxy.start(); mProviderProxies.add(targetIndex++, providerProxy); mProvider.addProvider(providerProxy); } else if (sourceIndex >= targetIndex) { TvRemoteProviderProxy provider = mProviderProxies.get(sourceIndex); provider.start(); // restart the provider if needed Loading @@ -135,7 +134,6 @@ final class TvRemoteProviderWatcher { if (targetIndex < mProviderProxies.size()) { for (int i = mProviderProxies.size() - 1; i >= targetIndex; i--) { TvRemoteProviderProxy providerProxy = mProviderProxies.get(i); mProvider.removeProvider(providerProxy); mProviderProxies.remove(providerProxy); providerProxy.stop(); } Loading Loading @@ -212,10 +210,4 @@ final class TvRemoteProviderWatcher { scanPackages(); } }; public interface ProviderMethods { void addProvider(TvRemoteProviderProxy providerProxy); void removeProvider(TvRemoteProviderProxy providerProxy); } }
services/core/java/com/android/server/tv/TvRemoteService.java +18 −111 Original line number Diff line number Diff line Loading @@ -17,11 +17,8 @@ package com.android.server.tv; import android.content.Context; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.Looper; import android.os.Message; import android.util.ArrayMap; import android.util.Slog; Loading @@ -29,7 +26,6 @@ import com.android.server.SystemService; import com.android.server.Watchdog; import java.io.IOException; import java.util.ArrayList; import java.util.Map; /** Loading @@ -44,9 +40,8 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { private static final boolean DEBUG = false; private static final boolean DEBUG_KEYS = false; private final TvRemoteProviderWatcher mWatcher; private Map<IBinder, UinputBridge> mBridgeMap = new ArrayMap(); private Map<IBinder, TvRemoteProviderProxy> mProviderMap = new ArrayMap(); private ArrayList<TvRemoteProviderProxy> mProviderList = new ArrayList<>(); /** * State guarded by mLock. Loading @@ -60,11 +55,10 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { */ private final Object mLock = new Object(); public final UserHandler mHandler; public TvRemoteService(Context context) { super(context); mHandler = new UserHandler(new UserProvider(TvRemoteService.this), context); mWatcher = new TvRemoteProviderWatcher(context, new UserProvider(TvRemoteService.this)); Watchdog.getInstance().addMonitor(this); } Loading @@ -80,19 +74,15 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { @Override public void onBootPhase(int phase) { // All lifecycle methods are called from the system server's main looper thread. if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { if (DEBUG) Slog.d(TAG, "PHASE_THIRD_PARTY_APPS_CAN_START"); mHandler.sendEmptyMessage(UserHandler.MSG_START); } } //Outgoing calls. private void informInputBridgeConnected(IBinder token) { mHandler.obtainMessage(UserHandler.MSG_INPUT_BRIDGE_CONNECTED, 0, 0, token).sendToTarget(); mWatcher.start(); // Also schedules the start of all providers. } } // Incoming calls. private void openInputBridgeInternalLocked(TvRemoteProviderProxy provider, final IBinder token, private boolean openInputBridgeInternalLocked(final IBinder token, String name, int width, int height, int maxPointers) { if (DEBUG) { Loading @@ -104,15 +94,11 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { //Create a new bridge, if one does not exist already if (mBridgeMap.containsKey(token)) { if (DEBUG) Slog.d(TAG, "RemoteBridge already exists"); // Respond back with success. informInputBridgeConnected(token); return; return true; } UinputBridge inputBridge = new UinputBridge(token, name, width, height, maxPointers); mBridgeMap.put(token, inputBridge); mProviderMap.put(token, provider); try { token.linkToDeath(new IBinder.DeathRecipient() { Loading @@ -126,15 +112,13 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } catch (RemoteException e) { if (DEBUG) Slog.d(TAG, "Token is already dead"); closeInputBridgeInternalLocked(token); return; return false; } // Respond back with success. informInputBridgeConnected(token); } catch (IOException ioe) { Slog.e(TAG, "Cannot create device for " + name); return false; } return true; } private void closeInputBridgeInternalLocked(IBinder token) { Loading @@ -149,7 +133,6 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } mBridgeMap.remove(token); mProviderMap.remove(token); } private void clearInputBridgeInternalLocked(IBinder token) { Loading Loading @@ -220,47 +203,7 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } } private final class UserHandler extends Handler { public static final int MSG_START = 1; public static final int MSG_INPUT_BRIDGE_CONNECTED = 2; private final TvRemoteProviderWatcher mWatcher; private boolean mRunning; public UserHandler(UserProvider provider, Context context) { super(Looper.getMainLooper(), null, true); mWatcher = new TvRemoteProviderWatcher(context, provider, this); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_START: { start(); break; } case MSG_INPUT_BRIDGE_CONNECTED: { IBinder token = (IBinder) msg.obj; TvRemoteProviderProxy provider = mProviderMap.get(token); if (provider != null) { provider.inputBridgeConnected(token); } break; } } } private void start() { if (!mRunning) { mRunning = true; mWatcher.start(); // also starts all providers } } } private final class UserProvider implements TvRemoteProviderWatcher.ProviderMethods, TvRemoteProviderProxy.ProviderMethods { private final class UserProvider implements TvRemoteProviderProxy.ProviderMethods { private final TvRemoteService mService; Loading @@ -269,7 +212,7 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } @Override public void openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, public boolean openInputBridge(TvRemoteProviderProxy provider, IBinder token, String name, int width, int height, int maxPointers) { if (DEBUG) { Slog.d(TAG, "openInputBridge(), token: " + token + Loading @@ -278,10 +221,8 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.openInputBridgeInternalLocked(provider, token, name, width, height, maxPointers); } return mService.openInputBridgeInternalLocked(token, name, width, height, maxPointers); } } Loading @@ -289,21 +230,17 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { public void closeInputBridge(TvRemoteProviderProxy provider, IBinder token) { if (DEBUG) Slog.d(TAG, "closeInputBridge(), token: " + token); synchronized (mLock) { if (mProviderList.contains(provider)) { mService.closeInputBridgeInternalLocked(token); } } } @Override public void clearInputBridge(TvRemoteProviderProxy provider, IBinder token) { if (DEBUG) Slog.d(TAG, "clearInputBridge(), token: " + token); synchronized (mLock) { if (mProviderList.contains(provider)) { mService.clearInputBridgeInternalLocked(token); } } } @Override public void sendKeyDown(TvRemoteProviderProxy provider, IBinder token, int keyCode) { Loading @@ -311,11 +248,9 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendKeyDown(), token: " + token + ", keyCode: " + keyCode); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendKeyDownInternalLocked(token, keyCode); } } } @Override public void sendKeyUp(TvRemoteProviderProxy provider, IBinder token, int keyCode) { Loading @@ -323,11 +258,9 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendKeyUp(), token: " + token + ", keyCode: " + keyCode); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendKeyUpInternalLocked(token, keyCode); } } } @Override public void sendPointerDown(TvRemoteProviderProxy provider, IBinder token, int pointerId, Loading @@ -336,11 +269,9 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendPointerDown(), token: " + token + ", pointerId: " + pointerId); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendPointerDownInternalLocked(token, pointerId, x, y); } } } @Override public void sendPointerUp(TvRemoteProviderProxy provider, IBinder token, int pointerId) { Loading @@ -348,40 +279,16 @@ public class TvRemoteService extends SystemService implements Watchdog.Monitor { Slog.d(TAG, "sendPointerUp(), token: " + token + ", pointerId: " + pointerId); } synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendPointerUpInternalLocked(token, pointerId); } } } @Override public void sendPointerSync(TvRemoteProviderProxy provider, IBinder token) { if (DEBUG_KEYS) Slog.d(TAG, "sendPointerSync(), token: " + token); synchronized (mLock) { if (mProviderList.contains(provider)) { mService.sendPointerSyncInternalLocked(token); } } } @Override public void addProvider(TvRemoteProviderProxy provider) { if (DEBUG) Slog.d(TAG, "addProvider " + provider); synchronized (mLock) { provider.setProviderSink(this); mProviderList.add(provider); Slog.d(TAG, "provider: " + provider.toString()); } } @Override public void removeProvider(TvRemoteProviderProxy provider) { if (DEBUG) Slog.d(TAG, "removeProvider " + provider); synchronized (mLock) { if (mProviderList.remove(provider) == false) { Slog.e(TAG, "Unknown provider " + provider); } } } } }