Loading cmds/statsd/src/atoms.proto +35 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto"; import "frameworks/base/core/proto/android/stats/style/style_enums.proto"; import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto"; import "frameworks/base/core/proto/android/stats/tls/enums.proto"; import "frameworks/base/core/proto/android/stats/tv/tif_enums.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/view/enums.proto"; Loading Loading @@ -510,6 +511,7 @@ message Atom { MediaPlaybackTrackChanged media_playback_track_changed = 324; WifiScanReported wifi_scan_reported = 325 [(module) = "wifi"]; WifiPnoScanReported wifi_pno_scan_reported = 326 [(module) = "wifi"]; TifTuneStateChanged tif_tune_changed = 327 [(module) = "framework"]; // StatsdStats tracks platform atoms with ids upto 500. // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. Loading Loading @@ -10351,6 +10353,39 @@ message CellBroadcastMessageError { optional string exception_message = 2; } /** * Logs when a TV Input Service Session changes tune state * This is atom ID 327. * * Logged from: * frameworks/base/services/core/java/com/android/server/tv/TvInputManagerService.java */ message TifTuneStateChanged { // Tv Input Service uid, TV Player uid repeated AttributionNode attribution_node = 1 [ (state_field_option).primary_field_first_uid = true ]; optional android.stats.tv.TifTuneState state = 2 [ (state_field_option).exclusive_state = true, (state_field_option).default_state_value = 0, (state_field_option).nested = false ]; // This a globally unique 128 bit random number created by TvInputManagerService when // android.media.tv.TvInputManager#createSession is called. // It is has no device or user association. // See android.media.tv.TvInputService.onCreateSession(java.lang.String, java.lang.String) // WARNING: Any changes to this field should be carefully reviewed for privacy. // Inspect the code at // framework/base/cmds/statsd/src/atoms.proto // TifTuneState // frameworks/base/services/core/java/com/android/server/tv/TvInputManagerService.java // logTuneStateChanged // BinderService.createSession // SessionState.sessionId optional string tif_session_id = 3 [(state_field_option).primary_field = true]; } /** * Logs when a tune occurs through device's Frontend. * This is atom ID 276. Loading core/proto/android/stats/tv/tif_enums.proto 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto2"; package android.stats.tv; option java_multiple_files = true; // Enums for TV Input Framework option java_outer_classname = "TifStatsEnums"; // Tune State of a TV Input Service Framework enum TifTuneState { TIF_TUNE_STATE_UNKNOWN = 0; CREATED = 1; SURFACE_ATTACHED = 2; SURFACE_DETACHED = 3; RELEASED = 4; TUNE_STARTED = 5; VIDEO_AVAILABLE = 6; // Keep in sync with TvInputManager // Use the TvInputManager value + 100 VIDEO_UNAVAILABLE_REASON_UNKNOWN = 100; VIDEO_UNAVAILABLE_REASON_TUNING = 101; VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 102; VIDEO_UNAVAILABLE_REASON_BUFFERING = 103; VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 104; VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 105; VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 106; VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION=107; VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED=108; VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE=109; VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED=110; VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION=111; VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING=112; VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD=113; VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE=114; VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID=115; VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT=116; VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING=117; VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN=118; } services/core/java/com/android/server/tv/TvInputManagerService.java +153 −10 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; import com.android.internal.os.SomeArgs; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; import com.android.server.SystemService; Loading Loading @@ -337,6 +338,7 @@ public final class TvInputManagerService extends SystemService { inputState = new TvInputState(); } inputState.info = info; inputState.uid = getInputUid(info); inputMap.put(info.getId(), inputState); } Loading Loading @@ -371,6 +373,16 @@ public final class TvInputManagerService extends SystemService { userState.inputMap = inputMap; } private int getInputUid(TvInputInfo info) { try { return getContext().getPackageManager().getApplicationInfo( info.getServiceInfo().packageName, 0).uid; } catch (NameNotFoundException e) { Slog.w(TAG, "Unable to get UID for " + info, e); return Process.INVALID_UID; } } @GuardedBy("mLock") private void buildTvContentRatingSystemListLocked(int userId) { UserState userState = getOrCreateUserStateLocked(userId); Loading Loading @@ -405,7 +417,7 @@ public final class TvInputManagerService extends SystemService { return; } if (mUserStates.contains(mCurrentUserId)) { UserState userState = mUserStates.get(mCurrentUserId); UserState userState = getUserStateLocked(mCurrentUserId); List<SessionState> sessionStatesToRelease = new ArrayList<>(); for (SessionState sessionState : userState.sessionStateMap.values()) { if (sessionState.session != null && !sessionState.isRecordingSession) { Loading Loading @@ -474,7 +486,7 @@ public final class TvInputManagerService extends SystemService { private void removeUser(int userId) { synchronized (mLock) { UserState userState = mUserStates.get(userId); UserState userState = getUserStateLocked(userId); if (userState == null) { return; } Loading Loading @@ -535,7 +547,7 @@ public final class TvInputManagerService extends SystemService { @GuardedBy("mLock") private UserState getOrCreateUserStateLocked(int userId) { UserState userState = mUserStates.get(userId); UserState userState = getUserStateLocked(userId); if (userState == null) { userState = new UserState(mContext, userId); mUserStates.put(userId, userState); Loading Loading @@ -715,7 +727,8 @@ public final class TvInputManagerService extends SystemService { } @GuardedBy("mLock") private void releaseSessionLocked(IBinder sessionToken, int callingUid, int userId) { @Nullable private SessionState releaseSessionLocked(IBinder sessionToken, int callingUid, int userId) { SessionState sessionState = null; try { sessionState = getSessionStateLocked(sessionToken, callingUid, userId); Loading @@ -738,6 +751,7 @@ public final class TvInputManagerService extends SystemService { } } removeSessionStateLocked(sessionToken, userId); return sessionState; } @GuardedBy("mLock") Loading Loading @@ -908,6 +922,7 @@ public final class TvInputManagerService extends SystemService { return; } inputState.info = inputInfo; inputState.uid = getInputUid(inputInfo); int n = userState.mCallbacks.beginBroadcast(); for (int i = 0; i < n; ++i) { Loading Loading @@ -1248,7 +1263,22 @@ public final class TvInputManagerService extends SystemService { final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, "createSession"); final long identity = Binder.clearCallingIdentity(); // Generate a unique session id with a random UUID. /** * A randomly generated id for this this session. * * <p>This field contains no user or device reference and is large enough to be * effectively globally unique. * * <p><b>WARNING</b> Any changes to this field should be carefully reviewed for privacy. * Inspect the code at: * * <ul> * <li>framework/base/cmds/statsd/src/atoms.proto#TifTuneState * <li>{@link #logTuneStateChanged} * <li>{@link TvInputManagerService.BinderService#createSession} * <li>{@link SessionState#sessionId} * </ul> */ String uniqueSessionId = UUID.randomUUID().toString(); try { synchronized (mLock) { Loading @@ -1269,6 +1299,8 @@ public final class TvInputManagerService extends SystemService { TvInputInfo info = inputState.info; ServiceState serviceState = userState.serviceStateMap.get(info.getComponent()); if (serviceState == null) { int tisUid = PackageManager.getApplicationInfoAsUserCached( info.getComponent().getPackageName(), 0, resolvedUserId).uid; serviceState = new ServiceState(info.getComponent(), resolvedUserId); userState.serviceStateMap.put(info.getComponent(), serviceState); } Loading Loading @@ -1301,6 +1333,8 @@ public final class TvInputManagerService extends SystemService { } else { updateServiceConnectionLocked(info.getComponent(), resolvedUserId); } logTuneStateChanged(FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__CREATED, sessionState, inputState); } } finally { Binder.restoreCallingIdentity(identity); Loading @@ -1317,8 +1351,17 @@ public final class TvInputManagerService extends SystemService { userId, "releaseSession"); final long identity = Binder.clearCallingIdentity(); try { SessionState sessionState = null; UserState userState = null; synchronized (mLock) { releaseSessionLocked(sessionToken, callingUid, resolvedUserId); sessionState = releaseSessionLocked(sessionToken, callingUid, resolvedUserId); userState = getUserStateLocked(userId); } if (sessionState != null) { TvInputState tvInputState = TvInputManagerService.getTvInputState(sessionState, userState); logTuneStateChanged(FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__RELEASED, sessionState, tvInputState); } } finally { Binder.restoreCallingIdentity(identity); Loading Loading @@ -1372,10 +1415,13 @@ public final class TvInputManagerService extends SystemService { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, userId, "setSurface"); final long identity = Binder.clearCallingIdentity(); SessionState sessionState = null; UserState userState = null; try { synchronized (mLock) { try { SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, userState = getUserStateLocked(userId); sessionState = getSessionStateLocked(sessionToken, callingUid, resolvedUserId); if (sessionState.hardwareSessionToken == null) { getSessionLocked(sessionState).setSurface(surface); Loading @@ -1392,6 +1438,14 @@ public final class TvInputManagerService extends SystemService { // surface is not used in TvInputManagerService. surface.release(); } if (sessionState != null) { int state = surface == null ? FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_ATTACHED : FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_DETACHED; logTuneStateChanged(state, sessionState, TvInputManagerService.getTvInputState(sessionState, userState)); } Binder.restoreCallingIdentity(identity); } } Loading Loading @@ -1479,6 +1533,10 @@ public final class TvInputManagerService extends SystemService { return; } logTuneStateChanged( FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__TUNE_STARTED, sessionState, TvInputManagerService.getTvInputState(sessionState, userState)); // Log the start of watch. SomeArgs args = SomeArgs.obtain(); args.arg1 = sessionState.componentName.getPackageName(); Loading Loading @@ -2302,6 +2360,16 @@ public final class TvInputManagerService extends SystemService { } } @Nullable private static TvInputState getTvInputState( SessionState sessionState, @Nullable UserState userState) { if (userState != null) { return userState.inputMap.get(sessionState.inputId); } return null; } @GuardedBy("mLock") private List<TunedInfo> getCurrentTunedInfosInternalLocked( UserState userState, int callingPid, int callingUid) { Loading Loading @@ -2367,6 +2435,28 @@ public final class TvInputManagerService extends SystemService { } } /** * Log Tune state changes to {@link FrameworkStatsLog}. * * <p><b>WARNING</b> Any changes to this field should be carefully reviewed for privacy. * Inspect the code at: * * <ul> * <li>framework/base/cmds/statsd/src/atoms.proto#TifTuneState * <li>{@link #logTuneStateChanged} * <li>{@link TvInputManagerService.BinderService#createSession} * <li>{@link SessionState#sessionId} * </ul> */ private void logTuneStateChanged(int state, SessionState sessionState, @Nullable TvInputState inputState) { // TODO(b/173536904): log input type and id FrameworkStatsLog.write(FrameworkStatsLog.TIF_TUNE_CHANGED, new int[]{sessionState.callingUid, inputState == null ? Process.INVALID_UID : inputState.uid}, new String[]{"tif_player", "tv_input_service"}, state, sessionState.sessionId); } private static final class UserState { // A mapping from the TV input id to its TvInputState. private Map<String, TvInputState> inputMap = new HashMap<>(); Loading Loading @@ -2464,10 +2554,25 @@ public final class TvInputManagerService extends SystemService { } private static final class TvInputState { // A TvInputInfo object which represents the TV input. /** A TvInputInfo object which represents the TV input. */ private TvInputInfo info; // The state of TV input. Connected by default. /** * The kernel user-ID that has been assigned to the application the TvInput is a part of. * * <p> * Currently this is not a unique ID (multiple applications can have * the same uid). */ private int uid; /** * The state of TV input. * * <p> * Connected by default */ private int state = INPUT_STATE_CONNECTED; @Override Loading @@ -2478,6 +2583,23 @@ public final class TvInputManagerService extends SystemService { private final class SessionState implements IBinder.DeathRecipient { private final String inputId; /** * A randomly generated id for this this session. * * <p>This field contains no user or device reference and is large enough to be * effectively globally unique. * * <p><b>WARNING</b> Any changes to this field should be carefully reviewed for privacy. * Inspect the code at: * * <ul> * <li>framework/base/cmds/statsd/src/atoms.proto#TifTuneState * <li>{@link #logTuneStateChanged} * <li>{@link TvInputManagerService.BinderService#createSession} * <li>{@link SessionState#sessionId} * </ul> */ private final String sessionId; private final ComponentName componentName; private final boolean isRecordingSession; Loading Loading @@ -2545,7 +2667,7 @@ public final class TvInputManagerService extends SystemService { Slog.d(TAG, "onServiceConnected(component=" + component + ")"); } synchronized (mLock) { UserState userState = mUserStates.get(mUserId); UserState userState = getUserStateLocked(mUserId); if (userState == null) { // The user was removed while connecting. mContext.unbindService(this); Loading Loading @@ -2815,8 +2937,13 @@ public final class TvInputManagerService extends SystemService { if (mSessionState.session == null || mSessionState.client == null) { return; } TvInputState tvInputState = getTvInputState(mSessionState, getUserStateLocked(mCurrentUserId)); try { mSessionState.client.onVideoAvailable(mSessionState.seq); logTuneStateChanged( FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_AVAILABLE, mSessionState, tvInputState); } catch (RemoteException e) { Slog.e(TAG, "error in onVideoAvailable", e); } Loading @@ -2832,8 +2959,20 @@ public final class TvInputManagerService extends SystemService { if (mSessionState.session == null || mSessionState.client == null) { return; } TvInputState tvInputState = getTvInputState(mSessionState, getUserStateLocked(mCurrentUserId)); try { mSessionState.client.onVideoUnavailable(reason, mSessionState.seq); int loggedReason = reason + FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN; if (loggedReason < FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN || loggedReason > FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN) { loggedReason = FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN; } logTuneStateChanged(loggedReason, mSessionState, tvInputState); } catch (RemoteException e) { Slog.e(TAG, "error in onVideoUnavailable", e); } Loading Loading @@ -3019,6 +3158,10 @@ public final class TvInputManagerService extends SystemService { } } private UserState getUserStateLocked(int userId) { return mUserStates.get(userId); } private static final class WatchLogHandler extends Handler { // There are only two kinds of watch events that can happen on the system: // 1. The current TV input session is tuned to a new channel. Loading Loading
cmds/statsd/src/atoms.proto +35 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto"; import "frameworks/base/core/proto/android/stats/style/style_enums.proto"; import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto"; import "frameworks/base/core/proto/android/stats/tls/enums.proto"; import "frameworks/base/core/proto/android/stats/tv/tif_enums.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/view/enums.proto"; Loading Loading @@ -510,6 +511,7 @@ message Atom { MediaPlaybackTrackChanged media_playback_track_changed = 324; WifiScanReported wifi_scan_reported = 325 [(module) = "wifi"]; WifiPnoScanReported wifi_pno_scan_reported = 326 [(module) = "wifi"]; TifTuneStateChanged tif_tune_changed = 327 [(module) = "framework"]; // StatsdStats tracks platform atoms with ids upto 500. // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. Loading Loading @@ -10351,6 +10353,39 @@ message CellBroadcastMessageError { optional string exception_message = 2; } /** * Logs when a TV Input Service Session changes tune state * This is atom ID 327. * * Logged from: * frameworks/base/services/core/java/com/android/server/tv/TvInputManagerService.java */ message TifTuneStateChanged { // Tv Input Service uid, TV Player uid repeated AttributionNode attribution_node = 1 [ (state_field_option).primary_field_first_uid = true ]; optional android.stats.tv.TifTuneState state = 2 [ (state_field_option).exclusive_state = true, (state_field_option).default_state_value = 0, (state_field_option).nested = false ]; // This a globally unique 128 bit random number created by TvInputManagerService when // android.media.tv.TvInputManager#createSession is called. // It is has no device or user association. // See android.media.tv.TvInputService.onCreateSession(java.lang.String, java.lang.String) // WARNING: Any changes to this field should be carefully reviewed for privacy. // Inspect the code at // framework/base/cmds/statsd/src/atoms.proto // TifTuneState // frameworks/base/services/core/java/com/android/server/tv/TvInputManagerService.java // logTuneStateChanged // BinderService.createSession // SessionState.sessionId optional string tif_session_id = 3 [(state_field_option).primary_field = true]; } /** * Logs when a tune occurs through device's Frontend. * This is atom ID 276. Loading
core/proto/android/stats/tv/tif_enums.proto 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto2"; package android.stats.tv; option java_multiple_files = true; // Enums for TV Input Framework option java_outer_classname = "TifStatsEnums"; // Tune State of a TV Input Service Framework enum TifTuneState { TIF_TUNE_STATE_UNKNOWN = 0; CREATED = 1; SURFACE_ATTACHED = 2; SURFACE_DETACHED = 3; RELEASED = 4; TUNE_STARTED = 5; VIDEO_AVAILABLE = 6; // Keep in sync with TvInputManager // Use the TvInputManager value + 100 VIDEO_UNAVAILABLE_REASON_UNKNOWN = 100; VIDEO_UNAVAILABLE_REASON_TUNING = 101; VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 102; VIDEO_UNAVAILABLE_REASON_BUFFERING = 103; VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 104; VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 105; VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 106; VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION=107; VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED=108; VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE=109; VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED=110; VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION=111; VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING=112; VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD=113; VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE=114; VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID=115; VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT=116; VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING=117; VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN=118; }
services/core/java/com/android/server/tv/TvInputManagerService.java +153 −10 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; import com.android.internal.os.SomeArgs; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; import com.android.server.SystemService; Loading Loading @@ -337,6 +338,7 @@ public final class TvInputManagerService extends SystemService { inputState = new TvInputState(); } inputState.info = info; inputState.uid = getInputUid(info); inputMap.put(info.getId(), inputState); } Loading Loading @@ -371,6 +373,16 @@ public final class TvInputManagerService extends SystemService { userState.inputMap = inputMap; } private int getInputUid(TvInputInfo info) { try { return getContext().getPackageManager().getApplicationInfo( info.getServiceInfo().packageName, 0).uid; } catch (NameNotFoundException e) { Slog.w(TAG, "Unable to get UID for " + info, e); return Process.INVALID_UID; } } @GuardedBy("mLock") private void buildTvContentRatingSystemListLocked(int userId) { UserState userState = getOrCreateUserStateLocked(userId); Loading Loading @@ -405,7 +417,7 @@ public final class TvInputManagerService extends SystemService { return; } if (mUserStates.contains(mCurrentUserId)) { UserState userState = mUserStates.get(mCurrentUserId); UserState userState = getUserStateLocked(mCurrentUserId); List<SessionState> sessionStatesToRelease = new ArrayList<>(); for (SessionState sessionState : userState.sessionStateMap.values()) { if (sessionState.session != null && !sessionState.isRecordingSession) { Loading Loading @@ -474,7 +486,7 @@ public final class TvInputManagerService extends SystemService { private void removeUser(int userId) { synchronized (mLock) { UserState userState = mUserStates.get(userId); UserState userState = getUserStateLocked(userId); if (userState == null) { return; } Loading Loading @@ -535,7 +547,7 @@ public final class TvInputManagerService extends SystemService { @GuardedBy("mLock") private UserState getOrCreateUserStateLocked(int userId) { UserState userState = mUserStates.get(userId); UserState userState = getUserStateLocked(userId); if (userState == null) { userState = new UserState(mContext, userId); mUserStates.put(userId, userState); Loading Loading @@ -715,7 +727,8 @@ public final class TvInputManagerService extends SystemService { } @GuardedBy("mLock") private void releaseSessionLocked(IBinder sessionToken, int callingUid, int userId) { @Nullable private SessionState releaseSessionLocked(IBinder sessionToken, int callingUid, int userId) { SessionState sessionState = null; try { sessionState = getSessionStateLocked(sessionToken, callingUid, userId); Loading @@ -738,6 +751,7 @@ public final class TvInputManagerService extends SystemService { } } removeSessionStateLocked(sessionToken, userId); return sessionState; } @GuardedBy("mLock") Loading Loading @@ -908,6 +922,7 @@ public final class TvInputManagerService extends SystemService { return; } inputState.info = inputInfo; inputState.uid = getInputUid(inputInfo); int n = userState.mCallbacks.beginBroadcast(); for (int i = 0; i < n; ++i) { Loading Loading @@ -1248,7 +1263,22 @@ public final class TvInputManagerService extends SystemService { final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, "createSession"); final long identity = Binder.clearCallingIdentity(); // Generate a unique session id with a random UUID. /** * A randomly generated id for this this session. * * <p>This field contains no user or device reference and is large enough to be * effectively globally unique. * * <p><b>WARNING</b> Any changes to this field should be carefully reviewed for privacy. * Inspect the code at: * * <ul> * <li>framework/base/cmds/statsd/src/atoms.proto#TifTuneState * <li>{@link #logTuneStateChanged} * <li>{@link TvInputManagerService.BinderService#createSession} * <li>{@link SessionState#sessionId} * </ul> */ String uniqueSessionId = UUID.randomUUID().toString(); try { synchronized (mLock) { Loading @@ -1269,6 +1299,8 @@ public final class TvInputManagerService extends SystemService { TvInputInfo info = inputState.info; ServiceState serviceState = userState.serviceStateMap.get(info.getComponent()); if (serviceState == null) { int tisUid = PackageManager.getApplicationInfoAsUserCached( info.getComponent().getPackageName(), 0, resolvedUserId).uid; serviceState = new ServiceState(info.getComponent(), resolvedUserId); userState.serviceStateMap.put(info.getComponent(), serviceState); } Loading Loading @@ -1301,6 +1333,8 @@ public final class TvInputManagerService extends SystemService { } else { updateServiceConnectionLocked(info.getComponent(), resolvedUserId); } logTuneStateChanged(FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__CREATED, sessionState, inputState); } } finally { Binder.restoreCallingIdentity(identity); Loading @@ -1317,8 +1351,17 @@ public final class TvInputManagerService extends SystemService { userId, "releaseSession"); final long identity = Binder.clearCallingIdentity(); try { SessionState sessionState = null; UserState userState = null; synchronized (mLock) { releaseSessionLocked(sessionToken, callingUid, resolvedUserId); sessionState = releaseSessionLocked(sessionToken, callingUid, resolvedUserId); userState = getUserStateLocked(userId); } if (sessionState != null) { TvInputState tvInputState = TvInputManagerService.getTvInputState(sessionState, userState); logTuneStateChanged(FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__RELEASED, sessionState, tvInputState); } } finally { Binder.restoreCallingIdentity(identity); Loading Loading @@ -1372,10 +1415,13 @@ public final class TvInputManagerService extends SystemService { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, userId, "setSurface"); final long identity = Binder.clearCallingIdentity(); SessionState sessionState = null; UserState userState = null; try { synchronized (mLock) { try { SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, userState = getUserStateLocked(userId); sessionState = getSessionStateLocked(sessionToken, callingUid, resolvedUserId); if (sessionState.hardwareSessionToken == null) { getSessionLocked(sessionState).setSurface(surface); Loading @@ -1392,6 +1438,14 @@ public final class TvInputManagerService extends SystemService { // surface is not used in TvInputManagerService. surface.release(); } if (sessionState != null) { int state = surface == null ? FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_ATTACHED : FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_DETACHED; logTuneStateChanged(state, sessionState, TvInputManagerService.getTvInputState(sessionState, userState)); } Binder.restoreCallingIdentity(identity); } } Loading Loading @@ -1479,6 +1533,10 @@ public final class TvInputManagerService extends SystemService { return; } logTuneStateChanged( FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__TUNE_STARTED, sessionState, TvInputManagerService.getTvInputState(sessionState, userState)); // Log the start of watch. SomeArgs args = SomeArgs.obtain(); args.arg1 = sessionState.componentName.getPackageName(); Loading Loading @@ -2302,6 +2360,16 @@ public final class TvInputManagerService extends SystemService { } } @Nullable private static TvInputState getTvInputState( SessionState sessionState, @Nullable UserState userState) { if (userState != null) { return userState.inputMap.get(sessionState.inputId); } return null; } @GuardedBy("mLock") private List<TunedInfo> getCurrentTunedInfosInternalLocked( UserState userState, int callingPid, int callingUid) { Loading Loading @@ -2367,6 +2435,28 @@ public final class TvInputManagerService extends SystemService { } } /** * Log Tune state changes to {@link FrameworkStatsLog}. * * <p><b>WARNING</b> Any changes to this field should be carefully reviewed for privacy. * Inspect the code at: * * <ul> * <li>framework/base/cmds/statsd/src/atoms.proto#TifTuneState * <li>{@link #logTuneStateChanged} * <li>{@link TvInputManagerService.BinderService#createSession} * <li>{@link SessionState#sessionId} * </ul> */ private void logTuneStateChanged(int state, SessionState sessionState, @Nullable TvInputState inputState) { // TODO(b/173536904): log input type and id FrameworkStatsLog.write(FrameworkStatsLog.TIF_TUNE_CHANGED, new int[]{sessionState.callingUid, inputState == null ? Process.INVALID_UID : inputState.uid}, new String[]{"tif_player", "tv_input_service"}, state, sessionState.sessionId); } private static final class UserState { // A mapping from the TV input id to its TvInputState. private Map<String, TvInputState> inputMap = new HashMap<>(); Loading Loading @@ -2464,10 +2554,25 @@ public final class TvInputManagerService extends SystemService { } private static final class TvInputState { // A TvInputInfo object which represents the TV input. /** A TvInputInfo object which represents the TV input. */ private TvInputInfo info; // The state of TV input. Connected by default. /** * The kernel user-ID that has been assigned to the application the TvInput is a part of. * * <p> * Currently this is not a unique ID (multiple applications can have * the same uid). */ private int uid; /** * The state of TV input. * * <p> * Connected by default */ private int state = INPUT_STATE_CONNECTED; @Override Loading @@ -2478,6 +2583,23 @@ public final class TvInputManagerService extends SystemService { private final class SessionState implements IBinder.DeathRecipient { private final String inputId; /** * A randomly generated id for this this session. * * <p>This field contains no user or device reference and is large enough to be * effectively globally unique. * * <p><b>WARNING</b> Any changes to this field should be carefully reviewed for privacy. * Inspect the code at: * * <ul> * <li>framework/base/cmds/statsd/src/atoms.proto#TifTuneState * <li>{@link #logTuneStateChanged} * <li>{@link TvInputManagerService.BinderService#createSession} * <li>{@link SessionState#sessionId} * </ul> */ private final String sessionId; private final ComponentName componentName; private final boolean isRecordingSession; Loading Loading @@ -2545,7 +2667,7 @@ public final class TvInputManagerService extends SystemService { Slog.d(TAG, "onServiceConnected(component=" + component + ")"); } synchronized (mLock) { UserState userState = mUserStates.get(mUserId); UserState userState = getUserStateLocked(mUserId); if (userState == null) { // The user was removed while connecting. mContext.unbindService(this); Loading Loading @@ -2815,8 +2937,13 @@ public final class TvInputManagerService extends SystemService { if (mSessionState.session == null || mSessionState.client == null) { return; } TvInputState tvInputState = getTvInputState(mSessionState, getUserStateLocked(mCurrentUserId)); try { mSessionState.client.onVideoAvailable(mSessionState.seq); logTuneStateChanged( FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_AVAILABLE, mSessionState, tvInputState); } catch (RemoteException e) { Slog.e(TAG, "error in onVideoAvailable", e); } Loading @@ -2832,8 +2959,20 @@ public final class TvInputManagerService extends SystemService { if (mSessionState.session == null || mSessionState.client == null) { return; } TvInputState tvInputState = getTvInputState(mSessionState, getUserStateLocked(mCurrentUserId)); try { mSessionState.client.onVideoUnavailable(reason, mSessionState.seq); int loggedReason = reason + FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN; if (loggedReason < FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN || loggedReason > FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN) { loggedReason = FrameworkStatsLog .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN; } logTuneStateChanged(loggedReason, mSessionState, tvInputState); } catch (RemoteException e) { Slog.e(TAG, "error in onVideoUnavailable", e); } Loading Loading @@ -3019,6 +3158,10 @@ public final class TvInputManagerService extends SystemService { } } private UserState getUserStateLocked(int userId) { return mUserStates.get(userId); } private static final class WatchLogHandler extends Handler { // There are only two kinds of watch events that can happen on the system: // 1. The current TV input session is tuned to a new channel. Loading