Report user interaction into UsageStatsManager when user engages & disengages with media
Bug: 297052684
Test: Manual playback
Change-Id: I09f6302bda83cf14c3d5f1d1f849ff15a6628ce1
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 2cd3ab1..b06a7b9 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -34,6 +34,8 @@
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.usage.UsageStatsManager;
+import android.app.usage.UsageStatsManagerInternal;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -68,6 +70,7 @@
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.PowerExemptionManager;
import android.os.PowerManager;
import android.os.Process;
@@ -100,7 +103,9 @@
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* System implementation of MediaSessionManager
@@ -145,6 +150,8 @@
private AudioManager mAudioManager;
private boolean mHasFeatureLeanback;
private ActivityManagerInternal mActivityManagerInternal;
+ private UsageStatsManagerInternal mUsageStatsManagerInternal;
+ private final Set<Integer> mUserEngagingSessions = new HashSet<>();
// The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile)
// It's always not null after the MediaSessionService is started.
@@ -230,6 +237,7 @@
mContext.registerReceiver(mNotificationListenerEnabledChangedReceiver, filter);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
}
@Override
@@ -574,12 +582,43 @@
if (allowRunningInForeground) {
mActivityManagerInternal.startForegroundServiceDelegate(
foregroundServiceDelegationOptions, /* connection= */ null);
+ reportMediaInteractionEvent(record, /* userEngaged= */ true);
} else {
mActivityManagerInternal.stopForegroundServiceDelegate(
foregroundServiceDelegationOptions);
+ reportMediaInteractionEvent(record, /* userEngaged= */ false);
}
}
+ private void reportMediaInteractionEvent(MediaSessionRecordImpl record, boolean userEngaged) {
+ if (!android.app.usage.Flags.userInteractionTypeApi()) {
+ return;
+ }
+
+ String packageName = record.getPackageName();
+ int sessionUid = record.getUid();
+ String actionToLog = null;
+ if (userEngaged) {
+ if (!mUserEngagingSessions.contains(sessionUid)) {
+ actionToLog = "start";
+ }
+ mUserEngagingSessions.add(sessionUid);
+ } else {
+ if (mUserEngagingSessions.contains(sessionUid)) {
+ actionToLog = "stop";
+ }
+ mUserEngagingSessions.remove(sessionUid);
+ }
+
+ if (actionToLog != null) {
+ PersistableBundle extras = new PersistableBundle();
+ extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media");
+ extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, actionToLog);
+ mUsageStatsManagerInternal.reportUserInteractionEvent(
+ packageName, record.getUserId(), extras);
+ }
+ }
+
void tempAllowlistTargetPkgIfPossible(int targetUid, String targetPackage,
int callingPid, int callingUid, String callingPackage, String reason) {
final long token = Binder.clearCallingIdentity();