diff options
| author | 2020-09-26 01:41:46 +0000 | |
|---|---|---|
| committer | 2020-09-26 01:41:46 +0000 | |
| commit | a76f514974fce3d476e11000bfefdf7e8996963d (patch) | |
| tree | 2aab7b29e5de43258a98239eabeb6614cd824d0c | |
| parent | 1134c5adae8a27a0cf13a13ae96900668cb93915 (diff) | |
| parent | 990957db49a401a8da80cd4a85540bd8860aca76 (diff) | |
Merge "Implement callback for current channel infos"
4 files changed, 119 insertions, 67 deletions
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl index cf82ba001632..4380c134b82b 100644 --- a/media/java/android/media/tv/ITvInputManager.aidl +++ b/media/java/android/media/tv/ITvInputManager.aidl @@ -89,7 +89,7 @@ interface ITvInputManager { void timeShiftSetPlaybackParams(in IBinder sessionToken, in PlaybackParams params, int userId); void timeShiftEnablePositionTracking(in IBinder sessionToken, boolean enable, int userId); - List<TvChannelInfo> getTvCurrentChannelInfos(int userId); + List<TvChannelInfo> getCurrentTvChannelInfos(int userId); // For the recording session void startRecording(in IBinder sessionToken, in Uri programUri, in Bundle params, int userId); diff --git a/media/java/android/media/tv/ITvInputManagerCallback.aidl b/media/java/android/media/tv/ITvInputManagerCallback.aidl index 0f8bf2fb3a1d..9f80bf52123a 100644 --- a/media/java/android/media/tv/ITvInputManagerCallback.aidl +++ b/media/java/android/media/tv/ITvInputManagerCallback.aidl @@ -16,6 +16,7 @@ package android.media.tv; +import android.media.tv.TvChannelInfo; import android.media.tv.TvInputInfo; /** @@ -28,4 +29,5 @@ oneway interface ITvInputManagerCallback { void onInputUpdated(in String inputId); void onInputStateChanged(in String inputId, int state); void onTvInputInfoUpdated(in TvInputInfo TvInputInfo); + void onCurrentTvChannelInfosUpdated(in List<TvChannelInfo> currentTvChannelInfos); } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 71694392a9db..d38369fea2b8 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -899,6 +899,10 @@ public final class TvInputManager { */ public void onTvInputInfoUpdated(TvInputInfo inputInfo) { } + + /** @hide */ + public void onCurrentTvChannelInfosUpdated(List<TvChannelInfo> tvChannelInfos) { + } } private static final class TvInputCallbackRecord { @@ -958,6 +962,16 @@ public final class TvInputManager { } }); } + + public void postCurrentTvChannelInfosUpdated( + final List<TvChannelInfo> currentTvChannelInfos) { + mHandler.post(new Runnable() { + @Override + public void run() { + mCallback.onCurrentTvChannelInfosUpdated(currentTvChannelInfos); + } + }); + } } /** @@ -1262,6 +1276,15 @@ public final class TvInputManager { } } } + + @Override + public void onCurrentTvChannelInfosUpdated(List<TvChannelInfo> currentTvChannelInfos) { + synchronized (mLock) { + for (TvInputCallbackRecord record : mCallbackRecords) { + record.postCurrentTvChannelInfosUpdated(currentTvChannelInfos); + } + } + } }; try { if (mService != null) { @@ -1955,11 +1978,9 @@ public final class TvInputManager { /** * @hide */ - public List<TvChannelInfo> getTvCurrentChannelInfos() { - // TODO: handle retuned() cases and add a method to TvInputCallback - // TODO: unhide + public List<TvChannelInfo> getCurrentTvChannelInfos() { try { - return mService.getTvCurrentChannelInfos(mUserId); + return mService.getCurrentTvChannelInfos(mUserId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 4cb7c5c95867..cfceaabfc229 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -699,8 +699,8 @@ public final class TvInputManagerService extends SystemService { SessionState sessionState = null; try { sessionState = getSessionStateLocked(sessionToken, callingUid, userId); + UserState userState = getOrCreateUserStateLocked(userId); if (sessionState.session != null) { - UserState userState = getOrCreateUserStateLocked(userId); if (sessionToken == userState.mainSessionToken) { setMainLocked(sessionToken, false, callingUid, userId); } @@ -709,6 +709,8 @@ public final class TvInputManagerService extends SystemService { } sessionState.isCurrent = false; sessionState.currentChannel = null; + notifyCurrentChannelInfosUpdatedLocked( + userState, getCurrentTvChannelInfosInternalLocked(userState)); } catch (RemoteException | SessionNotFoundException e) { Slog.e(TAG, "error in releaseSession", e); } finally { @@ -849,6 +851,22 @@ public final class TvInputManagerService extends SystemService { } } + private void notifyCurrentChannelInfosUpdatedLocked( + UserState userState, List<TvChannelInfo> infos) { + if (DEBUG) { + Slog.d(TAG, "notifyCurrentChannelInfosUpdatedLocked"); + } + int n = userState.mCallbacks.beginBroadcast(); + for (int i = 0; i < n; ++i) { + try { + userState.mCallbacks.getBroadcastItem(i).onCurrentTvChannelInfosUpdated(infos); + } catch (RemoteException e) { + Slog.e(TAG, "failed to report updated current channel infos to callback", e); + } + } + userState.mCallbacks.finishBroadcast(); + } + private void updateTvInputInfoLocked(UserState userState, TvInputInfo inputInfo) { if (DEBUG) { Slog.d(TAG, "updateTvInputInfoLocked(inputInfo=" + inputInfo + ")"); @@ -1414,6 +1432,8 @@ public final class TvInputManagerService extends SystemService { if (sessionState != null) { sessionState.isCurrent = true; sessionState.currentChannel = channelUri; + notifyCurrentChannelInfosUpdatedLocked( + userState, getCurrentTvChannelInfosInternalLocked(userState)); } if (TvContract.isChannelUriForPassthroughInput(channelUri)) { // Do not log the watch history for passthrough inputs. @@ -2069,79 +2089,20 @@ public final class TvInputManagerService extends SystemService { } @Override - public List<TvChannelInfo> getTvCurrentChannelInfos(@UserIdInt int userId) { + public List<TvChannelInfo> getCurrentTvChannelInfos(@UserIdInt int userId) { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), Binder.getCallingUid(), userId, "getTvCurrentChannelInfos"); final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { UserState userState = getOrCreateUserStateLocked(resolvedUserId); - List<TvChannelInfo> channelInfos = new ArrayList<>(); - boolean watchedProgramsAccess = hasAccessWatchedProgramsPermission(); - for (SessionState state : userState.sessionStateMap.values()) { - if (state.isCurrent) { - Integer appTag; - int appType; - if (state.callingUid == Binder.getCallingUid()) { - appTag = APP_TAG_SELF; - appType = TvChannelInfo.APP_TYPE_SELF; - } else { - appTag = userState.mAppTagMap.get(state.callingUid); - if (appTag == null) { - appTag = userState.mNextAppTag++; - userState.mAppTagMap.put(state.callingUid, appTag); - } - appType = isSystemApp(state.componentName.getPackageName()) - ? TvChannelInfo.APP_TYPE_SYSTEM - : TvChannelInfo.APP_TYPE_NON_SYSTEM; - } - channelInfos.add(new TvChannelInfo( - state.inputId, - watchedProgramsAccess ? state.currentChannel : null, - state.isRecordingSession, - isForeground(state.callingPid), - appType, - appTag)); - } - } - return channelInfos; + return getCurrentTvChannelInfosInternalLocked(userState); } } finally { Binder.restoreCallingIdentity(identity); } } - protected boolean isForeground(int pid) { - if (mActivityManager == null) { - return false; - } - List<RunningAppProcessInfo> appProcesses = mActivityManager.getRunningAppProcesses(); - if (appProcesses == null) { - return false; - } - for (RunningAppProcessInfo appProcess : appProcesses) { - if (appProcess.pid == pid - && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { - return true; - } - } - return false; - } - - private boolean hasAccessWatchedProgramsPermission() { - return mContext.checkCallingPermission(PERMISSION_ACCESS_WATCHED_PROGRAMS) - == PackageManager.PERMISSION_GRANTED; - } - - private boolean isSystemApp(String pkg) { - try { - return (mContext.getPackageManager().getApplicationInfo(pkg, 0).flags - & ApplicationInfo.FLAG_SYSTEM) != 0; - } catch (NameNotFoundException e) { - return false; - } - } - /** * Add a hardware device in the TvInputHardwareManager for CTS testing * purpose. @@ -2312,6 +2273,69 @@ public final class TvInputManagerService extends SystemService { } } + private List<TvChannelInfo> getCurrentTvChannelInfosInternalLocked(UserState userState) { + List<TvChannelInfo> channelInfos = new ArrayList<>(); + boolean watchedProgramsAccess = hasAccessWatchedProgramsPermission(); + for (SessionState state : userState.sessionStateMap.values()) { + if (state.isCurrent) { + Integer appTag; + int appType; + if (state.callingUid == Binder.getCallingUid()) { + appTag = APP_TAG_SELF; + appType = TvChannelInfo.APP_TYPE_SELF; + } else { + appTag = userState.mAppTagMap.get(state.callingUid); + if (appTag == null) { + appTag = userState.mNextAppTag++; + userState.mAppTagMap.put(state.callingUid, appTag); + } + appType = isSystemApp(state.componentName.getPackageName()) + ? TvChannelInfo.APP_TYPE_SYSTEM + : TvChannelInfo.APP_TYPE_NON_SYSTEM; + } + channelInfos.add(new TvChannelInfo( + state.inputId, + watchedProgramsAccess ? state.currentChannel : null, + state.isRecordingSession, + isForeground(state.callingPid), + appType, + appTag)); + } + } + return channelInfos; + } + + private boolean isForeground(int pid) { + if (mActivityManager == null) { + return false; + } + List<RunningAppProcessInfo> appProcesses = mActivityManager.getRunningAppProcesses(); + if (appProcesses == null) { + return false; + } + for (RunningAppProcessInfo appProcess : appProcesses) { + if (appProcess.pid == pid + && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { + return true; + } + } + return false; + } + + private boolean hasAccessWatchedProgramsPermission() { + return mContext.checkCallingPermission(PERMISSION_ACCESS_WATCHED_PROGRAMS) + == PackageManager.PERMISSION_GRANTED; + } + + private boolean isSystemApp(String pkg) { + try { + return (mContext.getPackageManager().getApplicationInfo(pkg, 0).flags + & ApplicationInfo.FLAG_SYSTEM) != 0; + } catch (NameNotFoundException e) { + return false; + } + } + private static final class UserState { // A mapping from the TV input id to its TvInputState. private Map<String, TvInputState> inputMap = new HashMap<>(); @@ -2685,6 +2709,11 @@ public final class TvInputManagerService extends SystemService { if (mSessionState.session == null || mSessionState.client == null) { return; } + mSessionState.isCurrent = true; + mSessionState.currentChannel = channelUri; + UserState userState = getOrCreateUserStateLocked(mSessionState.userId); + notifyCurrentChannelInfosUpdatedLocked( + userState, getCurrentTvChannelInfosInternalLocked(userState)); try { // TODO: Consider adding this channel change in the watch log. When we do // that, how we can protect the watch log from malicious tv inputs should |