From 1fd8b5675e090a180406be8f6f3e48c310a2ef3f Mon Sep 17 00:00:00 2001 From: Nick Chalko Date: Wed, 12 Aug 2020 09:40:13 -0700 Subject: [PATCH] Add TifTuneStateChanged atom. This is the base atom for all TIF metrics Test: ./out/host/linux-x86/bin/statsd_testdrive Bug: 165369586 Change-Id: I2e5c3e7f51abd2700611fcc0eaef91ec029513c8 --- cmds/statsd/src/atoms.proto | 35 +++++++ core/proto/android/stats/tv/tif_enums.proto | 56 +++++++++++ .../server/tv/TvInputManagerService.java | 95 ++++++++++++++++++- 3 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 core/proto/android/stats/tv/tif_enums.proto diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 0f60eaebd59f6..d616d3d5f663c 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -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"; @@ -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. @@ -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. diff --git a/core/proto/android/stats/tv/tif_enums.proto b/core/proto/android/stats/tv/tif_enums.proto new file mode 100644 index 0000000000000..a9028e5291860 --- /dev/null +++ b/core/proto/android/stats/tv/tif_enums.proto @@ -0,0 +1,56 @@ +/* + * 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; +} diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index afbe5527a5cbc..4e35e577ccfea 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -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; @@ -715,7 +716,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); @@ -738,6 +740,7 @@ public final class TvInputManagerService extends SystemService { } } removeSessionStateLocked(sessionToken, userId); + return sessionState; } @GuardedBy("mLock") @@ -1248,7 +1251,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. + * + *

This field contains no user or device reference and is large enough to be + * effectively globally unique. + * + *

WARNING Any changes to this field should be carefully reviewed for privacy. + * Inspect the code at: + * + *

+ */ String uniqueSessionId = UUID.randomUUID().toString(); try { synchronized (mLock) { @@ -1301,6 +1319,8 @@ public final class TvInputManagerService extends SystemService { } else { updateServiceConnectionLocked(info.getComponent(), resolvedUserId); } + logTuneStateChanged(FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__CREATED, + sessionState); } } finally { Binder.restoreCallingIdentity(identity); @@ -1317,8 +1337,13 @@ public final class TvInputManagerService extends SystemService { userId, "releaseSession"); final long identity = Binder.clearCallingIdentity(); try { + SessionState sessionState = null; synchronized (mLock) { - releaseSessionLocked(sessionToken, callingUid, resolvedUserId); + sessionState = releaseSessionLocked(sessionToken, callingUid, resolvedUserId); + } + if (sessionState != null) { + logTuneStateChanged(FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__RELEASED, + sessionState); } } finally { Binder.restoreCallingIdentity(identity); @@ -1372,10 +1397,11 @@ public final class TvInputManagerService extends SystemService { final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, userId, "setSurface"); final long identity = Binder.clearCallingIdentity(); + SessionState sessionState = null; try { synchronized (mLock) { try { - SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, + sessionState = getSessionStateLocked(sessionToken, callingUid, resolvedUserId); if (sessionState.hardwareSessionToken == null) { getSessionLocked(sessionState).setSurface(surface); @@ -1392,6 +1418,13 @@ 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); + } Binder.restoreCallingIdentity(identity); } } @@ -1479,6 +1512,9 @@ public final class TvInputManagerService extends SystemService { return; } + logTuneStateChanged( + FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__TUNE_STARTED, + sessionState); // Log the start of watch. SomeArgs args = SomeArgs.obtain(); args.arg1 = sessionState.componentName.getPackageName(); @@ -2367,6 +2403,27 @@ public final class TvInputManagerService extends SystemService { } } + /** + * Log Tune state changes to {@link FrameworkStatsLog}. + * + *

WARNING Any changes to this field should be carefully reviewed for privacy. + * Inspect the code at: + * + *

+ */ + private void logTuneStateChanged(int state, SessionState sessionState) { + // TODO(b/165372105): log the tis uid. + // TODO(b/173536904): log input type and id + FrameworkStatsLog.write(FrameworkStatsLog.TIF_TUNE_CHANGED, + new int[]{sessionState.callingUid}, + new String[]{"tif_player"}, state, sessionState.sessionId); + } + private static final class UserState { // A mapping from the TV input id to its TvInputState. private Map inputMap = new HashMap<>(); @@ -2478,6 +2535,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. + * + *

This field contains no user or device reference and is large enough to be + * effectively globally unique. + * + *

WARNING Any changes to this field should be carefully reviewed for privacy. + * Inspect the code at: + * + *

+ */ private final String sessionId; private final ComponentName componentName; private final boolean isRecordingSession; @@ -2817,6 +2891,9 @@ public final class TvInputManagerService extends SystemService { } try { mSessionState.client.onVideoAvailable(mSessionState.seq); + logTuneStateChanged( + FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_AVAILABLE, + mSessionState); } catch (RemoteException e) { Slog.e(TAG, "error in onVideoAvailable", e); } @@ -2834,6 +2911,16 @@ public final class TvInputManagerService extends SystemService { } 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); } catch (RemoteException e) { Slog.e(TAG, "error in onVideoUnavailable", e); }