summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2020-09-26 01:41:46 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-09-26 01:41:46 +0000
commita76f514974fce3d476e11000bfefdf7e8996963d (patch)
tree2aab7b29e5de43258a98239eabeb6614cd824d0c
parent1134c5adae8a27a0cf13a13ae96900668cb93915 (diff)
parent990957db49a401a8da80cd4a85540bd8860aca76 (diff)
Merge "Implement callback for current channel infos"
-rw-r--r--media/java/android/media/tv/ITvInputManager.aidl2
-rw-r--r--media/java/android/media/tv/ITvInputManagerCallback.aidl2
-rw-r--r--media/java/android/media/tv/TvInputManager.java29
-rwxr-xr-xservices/core/java/com/android/server/tv/TvInputManagerService.java153
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