diff options
-rw-r--r-- | api/current.txt | 12 | ||||
-rw-r--r-- | core/java/android/tv/ITvInputClient.aidl | 4 | ||||
-rw-r--r-- | core/java/android/tv/ITvInputManager.aidl | 8 | ||||
-rw-r--r-- | core/java/android/tv/ITvInputServiceCallback.aidl | 2 | ||||
-rw-r--r-- | core/java/android/tv/TvInputInfo.java | 15 | ||||
-rw-r--r-- | core/java/android/tv/TvInputManager.java | 78 | ||||
-rw-r--r-- | core/java/android/tv/TvInputService.java | 10 | ||||
-rw-r--r-- | core/java/android/tv/TvView.java | 12 | ||||
-rw-r--r-- | services/core/java/com/android/server/tv/TvInputManagerService.java | 249 |
9 files changed, 200 insertions, 190 deletions
diff --git a/api/current.txt b/api/current.txt index 380d641..92e3fb1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29130,11 +29130,11 @@ package android.tv { } public final class TvInputManager { - method public void createSession(android.content.ComponentName, android.tv.TvInputManager.SessionCreateCallback, android.os.Handler); - method public boolean getAvailability(android.content.ComponentName); + method public void createSession(java.lang.String, android.tv.TvInputManager.SessionCreateCallback, android.os.Handler); + method public boolean getAvailability(java.lang.String); method public java.util.List<android.tv.TvInputInfo> getTvInputList(); - method public void registerListener(android.content.ComponentName, android.tv.TvInputManager.TvInputListener, android.os.Handler); - method public void unregisterListener(android.content.ComponentName, android.tv.TvInputManager.TvInputListener); + method public void registerListener(java.lang.String, android.tv.TvInputManager.TvInputListener, android.os.Handler); + method public void unregisterListener(java.lang.String, android.tv.TvInputManager.TvInputListener); } public static final class TvInputManager.Session { @@ -29149,7 +29149,7 @@ package android.tv { public static abstract class TvInputManager.TvInputListener { ctor public TvInputManager.TvInputListener(); - method public void onAvailabilityChanged(android.content.ComponentName, boolean); + method public void onAvailabilityChanged(java.lang.String, boolean); } public abstract class TvInputService extends android.app.Service { @@ -29181,7 +29181,7 @@ package android.tv { ctor public TvView(android.content.Context); ctor public TvView(android.content.Context, android.util.AttributeSet); ctor public TvView(android.content.Context, android.util.AttributeSet, int); - method public void bindTvInput(android.content.ComponentName, android.tv.TvInputManager.SessionCreateCallback); + method public void bindTvInput(java.lang.String, android.tv.TvInputManager.SessionCreateCallback); method public boolean dispatchUnhandledInputEvent(android.view.InputEvent); method public boolean onUnhandledInputEvent(android.view.InputEvent); method public void setOnUnhandledInputEventListener(android.tv.TvView.OnUnhandledInputEventListener); diff --git a/core/java/android/tv/ITvInputClient.aidl b/core/java/android/tv/ITvInputClient.aidl index 538f8a1..2adcaf1 100644 --- a/core/java/android/tv/ITvInputClient.aidl +++ b/core/java/android/tv/ITvInputClient.aidl @@ -26,6 +26,6 @@ import android.view.InputChannel; * @hide */ oneway interface ITvInputClient { - void onSessionCreated(in ComponentName name, IBinder token, in InputChannel channel, int seq); - void onAvailabilityChanged(in ComponentName name, boolean isAvailable); + void onSessionCreated(in String inputId, IBinder token, in InputChannel channel, int seq); + void onAvailabilityChanged(in String inputId, boolean isAvailable); } diff --git a/core/java/android/tv/ITvInputManager.aidl b/core/java/android/tv/ITvInputManager.aidl index a4c99e4..b756aba 100644 --- a/core/java/android/tv/ITvInputManager.aidl +++ b/core/java/android/tv/ITvInputManager.aidl @@ -30,12 +30,12 @@ import android.view.Surface; interface ITvInputManager { List<TvInputInfo> getTvInputList(int userId); - boolean getAvailability(in ITvInputClient client, in ComponentName name, int userId); + boolean getAvailability(in ITvInputClient client, in String inputId, int userId); - void registerCallback(in ITvInputClient client, in ComponentName name, int userId); - void unregisterCallback(in ITvInputClient client, in ComponentName name, int userId); + void registerCallback(in ITvInputClient client, in String inputId, int userId); + void unregisterCallback(in ITvInputClient client, in String inputId, int userId); - void createSession(in ITvInputClient client, in ComponentName name, int seq, int userId); + void createSession(in ITvInputClient client, in String inputId, int seq, int userId); void releaseSession(in IBinder sessionToken, int userId); void setSurface(in IBinder sessionToken, in Surface surface, int userId); diff --git a/core/java/android/tv/ITvInputServiceCallback.aidl b/core/java/android/tv/ITvInputServiceCallback.aidl index e535c81..71fc780 100644 --- a/core/java/android/tv/ITvInputServiceCallback.aidl +++ b/core/java/android/tv/ITvInputServiceCallback.aidl @@ -24,5 +24,5 @@ import android.content.ComponentName; * @hide */ oneway interface ITvInputServiceCallback { - void onAvailabilityChanged(in ComponentName name, boolean isAvailable); + void onAvailabilityChanged(in String inputId, boolean isAvailable); } diff --git a/core/java/android/tv/TvInputInfo.java b/core/java/android/tv/TvInputInfo.java index 90e4177..50462cc 100644 --- a/core/java/android/tv/TvInputInfo.java +++ b/core/java/android/tv/TvInputInfo.java @@ -39,7 +39,7 @@ public final class TvInputInfo implements Parcelable { public TvInputInfo(ResolveInfo service) { mService = service; ServiceInfo si = service.serviceInfo; - mId = new ComponentName(si.packageName, si.name).flattenToShortString(); + mId = generateInputIdForComponenetName(new ComponentName(si.packageName, si.name)); } /** @@ -75,7 +75,7 @@ public final class TvInputInfo implements Parcelable { * Loads the user-displayed label for this TV input service. * * @param pm Supplies a PackageManager used to load the TV input's resources. - * @return Returns a CharSequence containing the TV input's label. If the TV input does not have + * @return a CharSequence containing the TV input's label. If the TV input does not have * a label, its name is returned. */ public CharSequence loadLabel(PackageManager pm) { @@ -128,6 +128,17 @@ public final class TvInputInfo implements Parcelable { } /** + * Used to generate an input id from a ComponentName. + * + * @param name the component name for generating an input id. + * @return the generated input id for the given {@code name}. + * @hide + */ + public static final String generateInputIdForComponenetName(ComponentName name) { + return name.flattenToShortString(); + } + + /** * Used to make this class parcelable. * * @hide diff --git a/core/java/android/tv/TvInputManager.java b/core/java/android/tv/TvInputManager.java index 7b9b1fb..e246fcf 100644 --- a/core/java/android/tv/TvInputManager.java +++ b/core/java/android/tv/TvInputManager.java @@ -16,7 +16,6 @@ package android.tv; -import android.content.ComponentName; import android.graphics.Rect; import android.net.Uri; import android.os.Handler; @@ -50,8 +49,8 @@ public final class TvInputManager { private final ITvInputManager mService; // A mapping from an input to the list of its TvInputListenerRecords. - private final Map<ComponentName, List<TvInputListenerRecord>> mTvInputListenerRecordsMap = - new HashMap<ComponentName, List<TvInputListenerRecord>>(); + private final Map<String, List<TvInputListenerRecord>> mTvInputListenerRecordsMap = + new HashMap<String, List<TvInputListenerRecord>>(); // A mapping from the sequence number of a session to its SessionCreateCallbackRecord. private final SparseArray<SessionCreateCallbackRecord> mSessionCreateCallbackRecordMap = @@ -105,12 +104,11 @@ public final class TvInputManager { /** * This is called when the availability status of a given TV input is changed. * - * @param name {@link ComponentName} of {@link android.app.Service} that implements the - * given TV input. + * @param inputId the id of the TV input. * @param isAvailable {@code true} if the given TV input is available to show TV programs. * {@code false} otherwise. */ - public void onAvailabilityChanged(ComponentName name, boolean isAvailable) { + public void onAvailabilityChanged(String inputId, boolean isAvailable) { } } @@ -127,11 +125,11 @@ public final class TvInputManager { return mListener; } - public void postAvailabilityChanged(final ComponentName name, final boolean isAvailable) { + public void postAvailabilityChanged(final String inputId, final boolean isAvailable) { mHandler.post(new Runnable() { @Override public void run() { - mListener.onAvailabilityChanged(name, isAvailable); + mListener.onAvailabilityChanged(inputId, isAvailable); } }); } @@ -145,7 +143,7 @@ public final class TvInputManager { mUserId = userId; mClient = new ITvInputClient.Stub() { @Override - public void onSessionCreated(ComponentName name, IBinder token, InputChannel channel, + public void onSessionCreated(String inputId, IBinder token, InputChannel channel, int seq) { synchronized (mSessionCreateCallbackRecordMap) { SessionCreateCallbackRecord record = mSessionCreateCallbackRecordMap.get(seq); @@ -163,16 +161,16 @@ public final class TvInputManager { } @Override - public void onAvailabilityChanged(ComponentName name, boolean isAvailable) { + public void onAvailabilityChanged(String inputId, boolean isAvailable) { synchronized (mTvInputListenerRecordsMap) { - List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(name); + List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId); if (records == null) { // Silently ignore - no listener is registered yet. return; } int recordsCount = records.size(); for (int i = 0; i < recordsCount; i++) { - records.get(i).postAvailabilityChanged(name, isAvailable); + records.get(i).postAvailabilityChanged(inputId, isAvailable); } } } @@ -195,24 +193,23 @@ public final class TvInputManager { /** * Returns the availability of a given TV input. * - * @param name {@link ComponentName} of {@link android.app.Service} that implements the given TV - * input. + * @param inputId the id of the TV input. * @throws IllegalArgumentException if the argument is {@code null}. * @throws IllegalStateException If there is no {@link TvInputListener} registered on the given * TV input. */ - public boolean getAvailability(ComponentName name) { - if (name == null) { - throw new IllegalArgumentException("name cannot be null"); + public boolean getAvailability(String inputId) { + if (inputId == null) { + throw new IllegalArgumentException("id cannot be null"); } synchronized (mTvInputListenerRecordsMap) { - List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(name); + List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId); if (records == null || records.size() == 0) { throw new IllegalStateException("At least one listener should be registered."); } } try { - return mService.getAvailability(mClient, name, mUserId); + return mService.getAvailability(mClient, inputId, mUserId); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -221,15 +218,14 @@ public final class TvInputManager { /** * Registers a {@link TvInputListener} for a given TV input. * - * @param name {@link ComponentName} of {@link android.app.Service} that implements the given TV - * input. + * @param inputId the id of the TV input. * @param listener a listener used to monitor status of the given TV input. * @param handler a {@link Handler} that the status change will be delivered to. * @throws IllegalArgumentException if any of the arguments is {@code null}. */ - public void registerListener(ComponentName name, TvInputListener listener, Handler handler) { - if (name == null) { - throw new IllegalArgumentException("name cannot be null"); + public void registerListener(String inputId, TvInputListener listener, Handler handler) { + if (inputId == null) { + throw new IllegalArgumentException("id cannot be null"); } if (listener == null) { throw new IllegalArgumentException("listener cannot be null"); @@ -238,12 +234,12 @@ public final class TvInputManager { throw new IllegalArgumentException("handler cannot be null"); } synchronized (mTvInputListenerRecordsMap) { - List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(name); + List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId); if (records == null) { records = new ArrayList<TvInputListenerRecord>(); - mTvInputListenerRecordsMap.put(name, records); + mTvInputListenerRecordsMap.put(inputId, records); try { - mService.registerCallback(mClient, name, mUserId); + mService.registerCallback(mClient, inputId, mUserId); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -255,22 +251,21 @@ public final class TvInputManager { /** * Unregisters the existing {@link TvInputListener} for a given TV input. * - * @param name {@link ComponentName} of {@link android.app.Service} that implements the given TV - * input. + * @param inputId the id of the TV input. * @param listener the existing listener to remove for the given TV input. * @throws IllegalArgumentException if any of the arguments is {@code null}. */ - public void unregisterListener(ComponentName name, final TvInputListener listener) { - if (name == null) { - throw new IllegalArgumentException("name cannot be null"); + public void unregisterListener(String inputId, final TvInputListener listener) { + if (inputId == null) { + throw new IllegalArgumentException("id cannot be null"); } if (listener == null) { throw new IllegalArgumentException("listener cannot be null"); } synchronized (mTvInputListenerRecordsMap) { - List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(name); + List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId); if (records == null) { - Log.e(TAG, "No listener found for " + name.getClassName()); + Log.e(TAG, "No listener found for " + inputId); return; } for (Iterator<TvInputListenerRecord> it = records.iterator(); it.hasNext();) { @@ -281,11 +276,11 @@ public final class TvInputManager { } if (records.isEmpty()) { try { - mService.unregisterCallback(mClient, name, mUserId); + mService.unregisterCallback(mClient, inputId, mUserId); } catch (RemoteException e) { throw new RuntimeException(e); } finally { - mTvInputListenerRecordsMap.remove(name); + mTvInputListenerRecordsMap.remove(inputId); } } } @@ -298,16 +293,15 @@ public final class TvInputManager { * the given TV input. * </p> * - * @param name {@link ComponentName} of {@link android.app.Service} that implements the given TV - * input. + * @param inputId the id of the TV input. * @param callback a callback used to receive the created session. * @param handler a {@link Handler} that the session creation will be delivered to. * @throws IllegalArgumentException if any of the arguments is {@code null}. */ - public void createSession(ComponentName name, final SessionCreateCallback callback, + public void createSession(String inputId, final SessionCreateCallback callback, Handler handler) { - if (name == null) { - throw new IllegalArgumentException("name cannot be null"); + if (inputId == null) { + throw new IllegalArgumentException("id cannot be null"); } if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); @@ -320,7 +314,7 @@ public final class TvInputManager { int seq = mNextSeq++; mSessionCreateCallbackRecordMap.put(seq, record); try { - mService.createSession(mClient, name, seq, mUserId); + mService.createSession(mClient, inputId, seq, mUserId); } catch (RemoteException e) { throw new RuntimeException(e); } diff --git a/core/java/android/tv/TvInputService.java b/core/java/android/tv/TvInputService.java index 70e7f95..1d6298d 100644 --- a/core/java/android/tv/TvInputService.java +++ b/core/java/android/tv/TvInputService.java @@ -60,7 +60,7 @@ public abstract class TvInputService extends Service { */ public static final String SERVICE_INTERFACE = "android.tv.TvInputService"; - private ComponentName mComponentName; + private String mId; private final Handler mHandler = new ServiceHandler(); private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks = new RemoteCallbackList<ITvInputServiceCallback>(); @@ -69,7 +69,8 @@ public abstract class TvInputService extends Service { @Override public void onCreate() { super.onCreate(); - mComponentName = new ComponentName(getPackageName(), getClass().getName()); + mId = TvInputInfo.generateInputIdForComponenetName( + new ComponentName(getPackageName(), getClass().getName())); } @Override @@ -82,7 +83,7 @@ public abstract class TvInputService extends Service { // The first time a callback is registered, the service needs to report its // availability status so that the system can know its initial value. try { - cb.onAvailabilityChanged(mComponentName, mAvailable); + cb.onAvailabilityChanged(mId, mAvailable); } catch (RemoteException e) { Log.e(TAG, "error in onAvailabilityChanged", e); } @@ -531,8 +532,7 @@ public abstract class TvInputService extends Service { int n = mCallbacks.beginBroadcast(); try { for (int i = 0; i < n; i++) { - mCallbacks.getBroadcastItem(i).onAvailabilityChanged(mComponentName, - isAvailable); + mCallbacks.getBroadcastItem(i).onAvailabilityChanged(mId, isAvailable); } } catch (RemoteException e) { Log.e(TAG, "Unexpected exception", e); diff --git a/core/java/android/tv/TvView.java b/core/java/android/tv/TvView.java index 289823b..0186220 100644 --- a/core/java/android/tv/TvView.java +++ b/core/java/android/tv/TvView.java @@ -16,10 +16,10 @@ package android.tv; -import android.content.ComponentName; import android.content.Context; import android.graphics.Rect; import android.os.Handler; +import android.text.TextUtils; import android.tv.TvInputManager.Session; import android.tv.TvInputManager.Session.FinishedInputEventCallback; import android.tv.TvInputManager.SessionCreateCallback; @@ -113,14 +113,14 @@ public class TvView extends SurfaceView { * If a TV input is already bound, the input will be unbound from this view and its session * will be released. * - * @param name TV input name will be bound to this view. + * @param inputId the id of TV input which will be bound to this view. * @param callback called when TV input is bound. The callback sends * {@link TvInputManager.Session} * @throws IllegalArgumentException if any of the arguments is {@code null}. */ - public void bindTvInput(ComponentName name, SessionCreateCallback callback) { - if (name == null) { - throw new IllegalArgumentException("name cannot be null"); + public void bindTvInput(String inputId, SessionCreateCallback callback) { + if (TextUtils.isEmpty(inputId)) { + throw new IllegalArgumentException("inputId cannot be null or an empty string"); } if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); @@ -134,7 +134,7 @@ public class TvView extends SurfaceView { // is newly assigned for every bindTvInput call and compared with // MySessionCreateCallback.this. mSessionCreateCallback = new MySessionCreateCallback(callback); - mTvInputManager.createSession(name, mSessionCreateCallback, mHandler); + mTvInputManager.createSession(inputId, mSessionCreateCallback, mHandler); } /** diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 50dd27d..5524bca 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -134,7 +134,7 @@ public final class TvInputManagerService extends SystemService { private void buildTvInputListLocked(int userId) { UserState userState = getUserStateLocked(userId); - userState.inputList.clear(); + userState.inputMap.clear(); if (DEBUG) Slog.d(TAG, "buildTvInputList"); PackageManager pm = mContext.getPackageManager(); @@ -149,7 +149,7 @@ public final class TvInputManagerService extends SystemService { } TvInputInfo info = new TvInputInfo(ri); if (DEBUG) Slog.d(TAG, "add " + info.getId()); - userState.inputList.add(info); + userState.inputMap.put(info.getId(), info); } } @@ -179,9 +179,9 @@ public final class TvInputManagerService extends SystemService { } // Release created sessions. for (SessionState state : userState.sessionStateMap.values()) { - if (state.session != null) { + if (state.mSession != null) { try { - state.session.release(); + state.mSession.release(); } catch (RemoteException e) { Slog.e(TAG, "error in release", e); } @@ -191,15 +191,15 @@ public final class TvInputManagerService extends SystemService { // Unregister all callbacks and unbind all services. for (ServiceState serviceState : userState.serviceStateMap.values()) { - if (serviceState.callback != null) { + if (serviceState.mCallback != null) { try { - serviceState.service.unregisterCallback(serviceState.callback); + serviceState.mService.unregisterCallback(serviceState.mCallback); } catch (RemoteException e) { Slog.e(TAG, "error in unregisterCallback", e); } } - serviceState.clients.clear(); - mContext.unbindService(serviceState.connection); + serviceState.mClients.clear(); + mContext.unbindService(serviceState.mConnection); } userState.serviceStateMap.clear(); @@ -215,11 +215,11 @@ public final class TvInputManagerService extends SystemService { return userState; } - private ServiceState getServiceStateLocked(ComponentName name, int userId) { + private ServiceState getServiceStateLocked(String inputId, int userId) { UserState userState = getUserStateLocked(userId); - ServiceState serviceState = userState.serviceStateMap.get(name); + ServiceState serviceState = userState.serviceStateMap.get(inputId); if (serviceState == null) { - throw new IllegalStateException("Service state not found for " + name + " (userId=" + throw new IllegalStateException("Service state not found for " + inputId + " (userId=" + userId + ")"); } return serviceState; @@ -232,11 +232,11 @@ public final class TvInputManagerService extends SystemService { throw new IllegalArgumentException("Session state not found for token " + sessionToken); } // Only the application that requested this session or the system can access it. - if (callingUid != Process.SYSTEM_UID && callingUid != sessionState.callingUid) { + if (callingUid != Process.SYSTEM_UID && callingUid != sessionState.mCallingUid) { throw new SecurityException("Illegal access to the session with token " + sessionToken + " from uid " + callingUid); } - ITvInputSession session = sessionState.session; + ITvInputSession session = sessionState.mSession; if (session == null) { throw new IllegalStateException("Session not yet created for token " + sessionToken); } @@ -249,38 +249,40 @@ public final class TvInputManagerService extends SystemService { false, methodName, null); } - private void updateServiceConnectionLocked(ComponentName name, int userId) { + private void updateServiceConnectionLocked(String inputId, int userId) { UserState userState = getUserStateLocked(userId); - ServiceState serviceState = userState.serviceStateMap.get(name); + ServiceState serviceState = userState.serviceStateMap.get(inputId); if (serviceState == null) { return; } - boolean isStateEmpty = serviceState.clients.isEmpty() - && serviceState.sessionTokens.isEmpty(); - if (serviceState.service == null && !isStateEmpty && userId == mCurrentUserId) { + boolean isStateEmpty = serviceState.mClients.isEmpty() + && serviceState.mSessionTokens.isEmpty(); + if (serviceState.mService == null && !isStateEmpty && userId == mCurrentUserId) { // This means that the service is not yet connected but its state indicates that we // have pending requests. Then, connect the service. - if (serviceState.bound) { + if (serviceState.mBound) { // We have already bound to the service so we don't try to bind again until after we // unbind later on. return; } if (DEBUG) { - Slog.d(TAG, "bindServiceAsUser(name=" + name.getClassName() + ", userId=" + userId + Slog.d(TAG, "bindServiceAsUser(inputId=" + inputId + ", userId=" + userId + ")"); } - Intent i = new Intent(TvInputService.SERVICE_INTERFACE).setComponent(name); - mContext.bindServiceAsUser(i, serviceState.connection, Context.BIND_AUTO_CREATE, + + Intent i = new Intent(TvInputService.SERVICE_INTERFACE).setComponent( + userState.inputMap.get(inputId).getComponent()); + mContext.bindServiceAsUser(i, serviceState.mConnection, Context.BIND_AUTO_CREATE, new UserHandle(userId)); - serviceState.bound = true; - } else if (serviceState.service != null && isStateEmpty) { + serviceState.mBound = true; + } else if (serviceState.mService != null && isStateEmpty) { // This means that the service is already connected but its state indicates that we have // nothing to do with it. Then, disconnect the service. if (DEBUG) { - Slog.d(TAG, "unbindService(name=" + name.getClassName() + ")"); + Slog.d(TAG, "unbindService(inputId=" + inputId + ")"); } - mContext.unbindService(serviceState.connection); - userState.serviceStateMap.remove(name); + mContext.unbindService(serviceState.mConnection); + userState.serviceStateMap.remove(inputId); } } @@ -289,8 +291,7 @@ public final class TvInputManagerService extends SystemService { final SessionState sessionState = getUserStateLocked(userId).sessionStateMap.get(sessionToken); if (DEBUG) { - Slog.d(TAG, "createSessionInternalLocked(name=" + sessionState.name.getClassName() - + ")"); + Slog.d(TAG, "createSessionInternalLocked(inputId=" + sessionState.mInputId + ")"); } final InputChannel[] channels = InputChannel.openInputChannelPair(sessionToken.toString()); @@ -300,17 +301,17 @@ public final class TvInputManagerService extends SystemService { @Override public void onSessionCreated(ITvInputSession session) { if (DEBUG) { - Slog.d(TAG, "onSessionCreated(name=" + sessionState.name.getClassName() + ")"); + Slog.d(TAG, "onSessionCreated(inputId=" + sessionState.mInputId + ")"); } synchronized (mLock) { - sessionState.session = session; + sessionState.mSession = session; if (session == null) { removeSessionStateLocked(sessionToken, userId); - sendSessionTokenToClientLocked(sessionState.client, sessionState.name, null, - null, sessionState.seq, userId); + sendSessionTokenToClientLocked(sessionState.mClient, sessionState.mInputId, null, + null, sessionState.mSeq, userId); } else { - sendSessionTokenToClientLocked(sessionState.client, sessionState.name, - sessionToken, channels[0], sessionState.seq, userId); + sendSessionTokenToClientLocked(sessionState.mClient, sessionState.mInputId, + sessionToken, channels[0], sessionState.mSeq, userId); } channels[0].dispose(); } @@ -323,23 +324,23 @@ public final class TvInputManagerService extends SystemService { } catch (RemoteException e) { Slog.e(TAG, "error in createSession", e); removeSessionStateLocked(sessionToken, userId); - sendSessionTokenToClientLocked(sessionState.client, sessionState.name, null, null, - sessionState.seq, userId); + sendSessionTokenToClientLocked(sessionState.mClient, sessionState.mInputId, null, null, + sessionState.mSeq, userId); } channels[1].dispose(); } - private void sendSessionTokenToClientLocked(ITvInputClient client, ComponentName name, + private void sendSessionTokenToClientLocked(ITvInputClient client, String inputId, IBinder sessionToken, InputChannel channel, int seq, int userId) { try { - client.onSessionCreated(name, sessionToken, channel, seq); + client.onSessionCreated(inputId, sessionToken, channel, seq); } catch (RemoteException exception) { Slog.e(TAG, "error in onSessionCreated", exception); } if (sessionToken == null) { // This means that the session creation failed. We might want to disconnect the service. - updateServiceConnectionLocked(name, userId); + updateServiceConnectionLocked(inputId, userId); } } @@ -349,19 +350,19 @@ public final class TvInputManagerService extends SystemService { SessionState sessionState = userState.sessionStateMap.remove(sessionToken); // Close the open log entry, if any. - if (sessionState.logUri != null) { + if (sessionState.mLogUri != null) { SomeArgs args = SomeArgs.obtain(); - args.arg1 = sessionState.logUri; + args.arg1 = sessionState.mLogUri; args.arg2 = System.currentTimeMillis(); mLogHandler.obtainMessage(LogHandler.MSG_CLOSE_ENTRY, args).sendToTarget(); } // Also remove the session token from the session token list of the current service. - ServiceState serviceState = userState.serviceStateMap.get(sessionState.name); + ServiceState serviceState = userState.serviceStateMap.get(sessionState.mInputId); if (serviceState != null) { - serviceState.sessionTokens.remove(sessionToken); + serviceState.mSessionTokens.remove(sessionToken); } - updateServiceConnectionLocked(sessionState.name, userId); + updateServiceConnectionLocked(sessionState.mInputId, userId); } private final class BinderService extends ITvInputManager.Stub { @@ -373,7 +374,7 @@ public final class TvInputManagerService extends SystemService { try { synchronized (mLock) { UserState userState = getUserStateLocked(resolvedUserId); - return new ArrayList<TvInputInfo>(userState.inputList); + return new ArrayList<TvInputInfo>(userState.inputMap.values()); } } finally { Binder.restoreCallingIdentity(identity); @@ -381,7 +382,7 @@ public final class TvInputManagerService extends SystemService { } @Override - public boolean getAvailability(final ITvInputClient client, final ComponentName name, + public boolean getAvailability(final ITvInputClient client, final String inputId, int userId) { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), Binder.getCallingUid(), userId, "getAvailability"); @@ -389,11 +390,11 @@ public final class TvInputManagerService extends SystemService { try { synchronized (mLock) { UserState userState = getUserStateLocked(resolvedUserId); - ServiceState serviceState = userState.serviceStateMap.get(name); + ServiceState serviceState = userState.serviceStateMap.get(inputId); if (serviceState != null) { // We already know the status of this input service. Return the cached // status. - return serviceState.available; + return serviceState.mAvailable; } } } finally { @@ -403,7 +404,7 @@ public final class TvInputManagerService extends SystemService { } @Override - public void registerCallback(final ITvInputClient client, final ComponentName name, + public void registerCallback(final ITvInputClient client, final String inputId, int userId) { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), Binder.getCallingUid(), userId, "registerCallback"); @@ -413,28 +414,29 @@ public final class TvInputManagerService extends SystemService { // Create a new service callback and add it to the callback map of the current // service. UserState userState = getUserStateLocked(resolvedUserId); - ServiceState serviceState = userState.serviceStateMap.get(name); + ServiceState serviceState = userState.serviceStateMap.get(inputId); if (serviceState == null) { - serviceState = new ServiceState(resolvedUserId); - userState.serviceStateMap.put(name, serviceState); + serviceState = new ServiceState( + userState.inputMap.get(inputId), resolvedUserId); + userState.serviceStateMap.put(inputId, serviceState); } IBinder iBinder = client.asBinder(); - if (!serviceState.clients.contains(iBinder)) { - serviceState.clients.add(iBinder); + if (!serviceState.mClients.contains(iBinder)) { + serviceState.mClients.add(iBinder); } - if (serviceState.service != null) { - if (serviceState.callback != null) { + if (serviceState.mService != null) { + if (serviceState.mCallback != null) { // We already handled. return; } - serviceState.callback = new ServiceCallback(resolvedUserId); + serviceState.mCallback = new ServiceCallback(resolvedUserId); try { - serviceState.service.registerCallback(serviceState.callback); + serviceState.mService.registerCallback(serviceState.mCallback); } catch (RemoteException e) { Slog.e(TAG, "error in registerCallback", e); } } else { - updateServiceConnectionLocked(name, resolvedUserId); + updateServiceConnectionLocked(inputId, resolvedUserId); } } } finally { @@ -443,34 +445,34 @@ public final class TvInputManagerService extends SystemService { } @Override - public void unregisterCallback(ITvInputClient client, ComponentName name, int userId) { + public void unregisterCallback(ITvInputClient client, String inputId, int userId) { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), Binder.getCallingUid(), userId, "unregisterCallback"); final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { UserState userState = getUserStateLocked(resolvedUserId); - ServiceState serviceState = userState.serviceStateMap.get(name); + ServiceState serviceState = userState.serviceStateMap.get(inputId); if (serviceState == null) { return; } // Remove this client from the client list and unregister the callback. - serviceState.clients.remove(client.asBinder()); - if (!serviceState.clients.isEmpty()) { + serviceState.mClients.remove(client.asBinder()); + if (!serviceState.mClients.isEmpty()) { // We have other clients who want to keep the callback. Do this later. return; } - if (serviceState.service == null || serviceState.callback == null) { + if (serviceState.mService == null || serviceState.mCallback == null) { return; } try { - serviceState.service.unregisterCallback(serviceState.callback); + serviceState.mService.unregisterCallback(serviceState.mCallback); } catch (RemoteException e) { Slog.e(TAG, "error in unregisterCallback", e); } finally { - serviceState.callback = null; - updateServiceConnectionLocked(name, resolvedUserId); + serviceState.mCallback = null; + updateServiceConnectionLocked(inputId, resolvedUserId); } } } finally { @@ -479,7 +481,7 @@ public final class TvInputManagerService extends SystemService { } @Override - public void createSession(final ITvInputClient client, final ComponentName name, + public void createSession(final ITvInputClient client, final String inputId, int seq, int userId) { final int callingUid = Binder.getCallingUid(); final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, @@ -489,26 +491,27 @@ public final class TvInputManagerService extends SystemService { synchronized (mLock) { // Create a new session token and a session state. IBinder sessionToken = new Binder(); - SessionState sessionState = new SessionState(name, client, seq, callingUid); - sessionState.session = null; + SessionState sessionState = new SessionState(inputId, client, seq, callingUid); + sessionState.mSession = null; // Add them to the global session state map of the current user. UserState userState = getUserStateLocked(resolvedUserId); userState.sessionStateMap.put(sessionToken, sessionState); // Also, add them to the session state map of the current service. - ServiceState serviceState = userState.serviceStateMap.get(name); + ServiceState serviceState = userState.serviceStateMap.get(inputId); if (serviceState == null) { - serviceState = new ServiceState(resolvedUserId); - userState.serviceStateMap.put(name, serviceState); + serviceState = new ServiceState( + userState.inputMap.get(inputId), resolvedUserId); + userState.serviceStateMap.put(inputId, serviceState); } - serviceState.sessionTokens.add(sessionToken); + serviceState.mSessionTokens.add(sessionToken); - if (serviceState.service != null) { - createSessionInternalLocked(serviceState.service, sessionToken, + if (serviceState.mService != null) { + createSessionInternalLocked(serviceState.mService, sessionToken, resolvedUserId); } else { - updateServiceConnectionLocked(name, resolvedUserId); + updateServiceConnectionLocked(inputId, resolvedUserId); } } } finally { @@ -599,9 +602,9 @@ public final class TvInputManagerService extends SystemService { // Close the open log entry first, if any. UserState userState = getUserStateLocked(resolvedUserId); SessionState sessionState = userState.sessionStateMap.get(sessionToken); - if (sessionState.logUri != null) { + if (sessionState.mLogUri != null) { SomeArgs args = SomeArgs.obtain(); - args.arg1 = sessionState.logUri; + args.arg1 = sessionState.mLogUri; args.arg2 = currentTime; mLogHandler.obtainMessage(LogHandler.MSG_CLOSE_ENTRY, args) .sendToTarget(); @@ -614,10 +617,10 @@ public final class TvInputManagerService extends SystemService { values.put(TvContract.WatchedPrograms.WATCH_END_TIME_UTC_MILLIS, 0); values.put(TvContract.WatchedPrograms.CHANNEL_ID, channelId); - sessionState.logUri = mContentResolver.insert( + sessionState.mLogUri = mContentResolver.insert( TvContract.WatchedPrograms.CONTENT_URI, values); SomeArgs args = SomeArgs.obtain(); - args.arg1 = sessionState.logUri; + args.arg1 = sessionState.mLogUri; args.arg2 = ContentUris.parseId(channelUri); args.arg3 = currentTime; mLogHandler.obtainMessage(LogHandler.MSG_OPEN_ENTRY, args).sendToTarget(); @@ -694,12 +697,12 @@ public final class TvInputManagerService extends SystemService { } private static final class UserState { - // A list of all known TV inputs on the system. - private final List<TvInputInfo> inputList = new ArrayList<TvInputInfo>(); + // A mapping from the TV input id to its TvInputInfo. + private final Map<String, TvInputInfo> inputMap = new HashMap<String,TvInputInfo>(); // A mapping from the name of a TV input service to its state. - private final Map<ComponentName, ServiceState> serviceStateMap = - new HashMap<ComponentName, ServiceState>(); + private final Map<String, ServiceState> serviceStateMap = + new HashMap<String, ServiceState>(); // A mapping from the token of a TV input session to its state. private final Map<IBinder, SessionState> sessionStateMap = @@ -707,66 +710,68 @@ public final class TvInputManagerService extends SystemService { } private final class ServiceState { - private final List<IBinder> clients = new ArrayList<IBinder>(); - private final List<IBinder> sessionTokens = new ArrayList<IBinder>(); - private final ServiceConnection connection; + private final List<IBinder> mClients = new ArrayList<IBinder>(); + private final List<IBinder> mSessionTokens = new ArrayList<IBinder>(); + private final ServiceConnection mConnection; - private ITvInputService service; - private ServiceCallback callback; - private boolean bound; - private boolean available; + private ITvInputService mService; + private ServiceCallback mCallback; + private boolean mBound; + private boolean mAvailable; - private ServiceState(int userId) { - this.connection = new InputServiceConnection(userId); + private ServiceState(TvInputInfo inputInfo, int userId) { + this.mConnection = new InputServiceConnection(inputInfo, userId); } } private static final class SessionState { - private final ComponentName name; - private final ITvInputClient client; - private final int seq; - private final int callingUid; + private final String mInputId; + private final ITvInputClient mClient; + private final int mSeq; + private final int mCallingUid; - private ITvInputSession session; - private Uri logUri; + private ITvInputSession mSession; + private Uri mLogUri; - private SessionState(ComponentName name, ITvInputClient client, int seq, int callingUid) { - this.name = name; - this.client = client; - this.seq = seq; - this.callingUid = callingUid; + private SessionState(String inputId, ITvInputClient client, int seq, int callingUid) { + this.mInputId = inputId; + this.mClient = client; + this.mSeq = seq; + this.mCallingUid = callingUid; } } private final class InputServiceConnection implements ServiceConnection { + private final TvInputInfo mTvInputInfo; private final int mUserId; - private InputServiceConnection(int userId) { + private InputServiceConnection(TvInputInfo inputInfo, int userId) { mUserId = userId; + mTvInputInfo = inputInfo; } @Override public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG) { - Slog.d(TAG, "onServiceConnected(name=" + name.getClassName() + ")"); + Slog.d(TAG, "onServiceConnected(inputId=" + mTvInputInfo.getId() + ")"); } synchronized (mLock) { - ServiceState serviceState = getServiceStateLocked(name, mUserId); - serviceState.service = ITvInputService.Stub.asInterface(service); + ServiceState serviceState = getServiceStateLocked(mTvInputInfo.getId(), mUserId); + serviceState.mService = ITvInputService.Stub.asInterface(service); // Register a callback, if we need to. - if (!serviceState.clients.isEmpty() && serviceState.callback == null) { - serviceState.callback = new ServiceCallback(mUserId); + if (!serviceState.mClients.isEmpty() && serviceState.mCallback == null) { + serviceState.mCallback = new ServiceCallback(mUserId); try { - serviceState.service.registerCallback(serviceState.callback); + serviceState.mService.registerCallback(serviceState.mCallback); } catch (RemoteException e) { Slog.e(TAG, "error in registerCallback", e); } } // And create sessions, if any. - for (IBinder sessionToken : serviceState.sessionTokens) { - createSessionInternalLocked(serviceState.service, sessionToken, mUserId); + for (IBinder sessionToken : serviceState.mSessionTokens) { + createSessionInternalLocked(serviceState.mService, sessionToken, mUserId); } } } @@ -774,7 +779,7 @@ public final class TvInputManagerService extends SystemService { @Override public void onServiceDisconnected(ComponentName name) { if (DEBUG) { - Slog.d(TAG, "onServiceDisconnected(name=" + name.getClassName() + ")"); + Slog.d(TAG, "onServiceDisconnected(inputId=" + mTvInputInfo.getId() + ")"); } } } @@ -787,18 +792,18 @@ public final class TvInputManagerService extends SystemService { } @Override - public void onAvailabilityChanged(ComponentName name, boolean isAvailable) + public void onAvailabilityChanged(String inputId, boolean isAvailable) throws RemoteException { if (DEBUG) { - Slog.d(TAG, "onAvailabilityChanged(name=" + name.getClassName() + ", isAvailable=" + Slog.d(TAG, "onAvailabilityChanged(inputId=" + inputId + ", isAvailable=" + isAvailable + ")"); } synchronized (mLock) { - ServiceState serviceState = getServiceStateLocked(name, mUserId); - serviceState.available = isAvailable; - for (IBinder iBinder : serviceState.clients) { + ServiceState serviceState = getServiceStateLocked(inputId, mUserId); + serviceState.mAvailable = isAvailable; + for (IBinder iBinder : serviceState.mClients) { ITvInputClient client = ITvInputClient.Stub.asInterface(iBinder); - client.onAvailabilityChanged(name, isAvailable); + client.onAvailabilityChanged(inputId, isAvailable); } } } |