Use taskRootPackageName instead of packageName to load uid when usage

resource is USAGE_SOURCE_TASK_ROOT_ACTIVITY and taskRootPackageName is
not empty.

This logic is consistent with digital wellbeing: assign the screen-on
time onto task root activity when usage resource is
USAGE_SOURCE_TASK_ROOT_ACTIVITY.

Bug: 260964679
Test: make RunSettingsRoboTests + manual
Change-Id: I4c7ed342d8c00951879f5826bf79575f330ce86e
This commit is contained in:
Kuan Wang
2022-12-19 14:54:50 +08:00
parent a1a7cba6a6
commit 2c7f06e9b3
3 changed files with 122 additions and 13 deletions

View File

@@ -17,7 +17,9 @@ package com.android.settings.fuelgauge.batteryusage;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStatsManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -25,7 +27,9 @@ import android.database.Cursor;
import android.os.BatteryUsageStats;
import android.os.Build;
import android.os.LocaleList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Base64;
import android.util.Log;
@@ -167,8 +171,10 @@ public final class ConvertUtils {
/** Converts to {@link AppUsageEvent} from {@link Event} */
@Nullable
public static AppUsageEvent convertToAppUsageEvent(
Context context, final Event event, final long userId) {
if (event.getPackageName() == null) {
Context context, final IUsageStatsManager usageStatsManager, final Event event,
final long userId) {
final String packageName = event.getPackageName();
if (packageName == null) {
// See b/190609174: Event package names should never be null, but sometimes they are.
// Note that system events like device shutting down should still come with the android
// package name.
@@ -182,13 +188,20 @@ public final class ConvertUtils {
appUsageEventBuilder
.setTimestamp(event.getTimeStamp())
.setType(getAppUsageEventType(event.getEventType()))
.setPackageName(event.getPackageName())
.setPackageName(packageName)
.setUserId(userId);
final String taskRootPackageName = getTaskRootPackageName(event);
if (taskRootPackageName != null) {
appUsageEventBuilder.setTaskRootPackageName(taskRootPackageName);
}
final String effectivePackageName =
getEffectivePackageName(usageStatsManager, packageName, taskRootPackageName);
try {
final long uid = context
.getPackageManager()
.getPackageUidAsUser(event.getPackageName(), (int) userId);
.getPackageUidAsUser(effectivePackageName, (int) userId);
appUsageEventBuilder.setUid(uid);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, String.format(
@@ -201,10 +214,6 @@ public final class ConvertUtils {
} catch (NoClassDefFoundError | NoSuchMethodError e) {
Log.w(TAG, "UsageEvent instance ID API error");
}
String taskRootPackageName = getTaskRootPackageName(event);
if (taskRootPackageName != null) {
appUsageEventBuilder.setTaskRootPackageName(taskRootPackageName);
}
return appUsageEventBuilder.build();
}
@@ -267,6 +276,35 @@ public final class ConvertUtils {
: Locale.getDefault();
}
/**
* Returns the package name the app usage should be attributed to.
*
* <ul>
* <li>If {@link UsageStatsManager#getUsageSource()} returns {@link
* UsageStatsManager#USAGE_SOURCE_CURRENT_ACTIVITY}, this method will return packageName.
* <li>If {@link UsageStatsManager#getUsageSource()} returns {@link
* UsageStatsManager#USAGE_SOURCE_TASK_ROOT_ACTIVITY}, this method will return
* taskRootPackageName if it exists, or packageName otherwise.
* </ul>
*/
@VisibleForTesting
static String getEffectivePackageName(
final IUsageStatsManager usageStatsManager, final String packageName,
final String taskRootPackageName) {
int usageSource = getUsageSource(usageStatsManager);
switch (usageSource) {
case UsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY:
return !TextUtils.isEmpty(taskRootPackageName)
? taskRootPackageName
: packageName;
case UsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY:
return packageName;
default:
Log.e(TAG, "Unexpected usage source: " + usageSource);
return packageName;
}
}
/**
* Returns the package name of the task root when this event was reported when {@code event} is
* one of:
@@ -298,6 +336,20 @@ public final class ConvertUtils {
}
}
/**
* Returns what App Usage Observers will consider the source of usage for an activity.
*
* @see UsageStatsManager#getUsageSource()
*/
private static int getUsageSource(final IUsageStatsManager usageStatsManager) {
try {
return usageStatsManager.getUsageSource();
} catch (RemoteException e) {
Log.e(TAG, "Failed to getUsageSource", e);
return UsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY;
}
}
private static AppUsageEventType getAppUsageEventType(final int eventType) {
switch (eventType) {
case Event.ACTIVITY_RESUMED:

View File

@@ -256,7 +256,8 @@ public final class DataProcessor {
break;
}
final AppUsageEvent appUsageEvent =
ConvertUtils.convertToAppUsageEvent(context, event, userId);
ConvertUtils.convertToAppUsageEvent(
context, sUsageStatsManager, event, userId);
if (appUsageEvent != null) {
numEventsFetched++;
appUsageEventList.add(appUsageEvent);