Add cache strategy for getUsageSource().
Cache usage source into SharedPreferences when phone is booting to avoid calling it too frequently. It should be safe because the usage source can only change on reboot. Bug: 293366011 Test: make RunSettingsRoboTests Change-Id: I35c07539d294737c5764b03b746cfb39f4ce008d
This commit is contained in:
@@ -83,6 +83,10 @@ public final class BootBroadcastReceiver extends BroadcastReceiver {
|
||||
recheckIntent.setClass(context, BootBroadcastReceiver.class);
|
||||
final long delayedTime = getRescheduleTimeForBootAction(context);
|
||||
mHandler.postDelayed(() -> context.sendBroadcast(recheckIntent), delayedTime);
|
||||
|
||||
// Refreshes the usage source from UsageStatsManager when booting.
|
||||
DatabaseUtils.removeUsageSource(context);
|
||||
|
||||
BatteryUsageLogUtils.writeLog(context, Action.RECHECK_JOB, "delay:" + delayedTime);
|
||||
} else if (ACTION_SETUP_WIZARD_FINISHED.equals(action)) {
|
||||
ElapsedTimeUtils.storeSuwFinishedTimestamp(context, System.currentTimeMillis());
|
||||
|
||||
@@ -17,7 +17,6 @@ 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;
|
||||
@@ -27,7 +26,6 @@ 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;
|
||||
@@ -67,6 +65,12 @@ public final class ConvertUtils {
|
||||
public static final int CONSUMER_TYPE_USER_BATTERY = 2;
|
||||
public static final int CONSUMER_TYPE_SYSTEM_BATTERY = 3;
|
||||
|
||||
public static final int DEFAULT_USAGE_SOURCE = UsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY;
|
||||
public static final int EMPTY_USAGE_SOURCE = -1;
|
||||
|
||||
@VisibleForTesting
|
||||
static int sUsageSource = EMPTY_USAGE_SOURCE;
|
||||
|
||||
private ConvertUtils() {
|
||||
}
|
||||
|
||||
@@ -181,8 +185,7 @@ public final class ConvertUtils {
|
||||
/** Converts to {@link AppUsageEvent} from {@link Event} */
|
||||
@Nullable
|
||||
public static AppUsageEvent convertToAppUsageEvent(
|
||||
Context context, final IUsageStatsManager usageStatsManager, final Event event,
|
||||
final long userId) {
|
||||
Context context, 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.
|
||||
@@ -207,7 +210,7 @@ public final class ConvertUtils {
|
||||
}
|
||||
|
||||
final String effectivePackageName =
|
||||
getEffectivePackageName(usageStatsManager, packageName, taskRootPackageName);
|
||||
getEffectivePackageName(context, packageName, taskRootPackageName);
|
||||
try {
|
||||
final long uid = context
|
||||
.getPackageManager()
|
||||
@@ -323,9 +326,8 @@ public final class ConvertUtils {
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static String getEffectivePackageName(
|
||||
final IUsageStatsManager usageStatsManager, final String packageName,
|
||||
final String taskRootPackageName) {
|
||||
int usageSource = getUsageSource(usageStatsManager);
|
||||
Context context, final String packageName, final String taskRootPackageName) {
|
||||
final int usageSource = getUsageSource(context);
|
||||
switch (usageSource) {
|
||||
case UsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY:
|
||||
return !TextUtils.isEmpty(taskRootPackageName)
|
||||
@@ -370,18 +372,11 @@ 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 int getUsageSource(Context context) {
|
||||
if (sUsageSource == EMPTY_USAGE_SOURCE) {
|
||||
sUsageSource = DatabaseUtils.getUsageSource(context);
|
||||
}
|
||||
return sUsageSource;
|
||||
}
|
||||
|
||||
private static AppUsageEventType getAppUsageEventType(final int eventType) {
|
||||
|
||||
@@ -397,8 +397,8 @@ public class DataProcessManager {
|
||||
}
|
||||
// Generates the indexed AppUsagePeriod list data for each corresponding time slot for
|
||||
// further use.
|
||||
mAppUsagePeriodMap = DataProcessor.generateAppUsagePeriodMap(mRawStartTimestamp,
|
||||
mHourlyBatteryLevelsPerDay, mAppUsageEventList, mBatteryEventList);
|
||||
mAppUsagePeriodMap = DataProcessor.generateAppUsagePeriodMap(
|
||||
mContext, mHourlyBatteryLevelsPerDay, mAppUsageEventList, mBatteryEventList);
|
||||
}
|
||||
|
||||
private void tryToGenerateFinalDataAndApplyCallback() {
|
||||
|
||||
@@ -32,7 +32,6 @@ import android.os.BatteryUsageStats;
|
||||
import android.os.BatteryUsageStatsQuery;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
@@ -78,8 +77,6 @@ public final class DataProcessor {
|
||||
private static final int MIN_DAILY_DATA_SIZE = 2;
|
||||
private static final int MIN_TIMESTAMP_DATA_SIZE = 2;
|
||||
private static final int MAX_DIFF_SECONDS_OF_UPPER_TIMESTAMP = 5;
|
||||
// Maximum total time value for each hourly slot cumulative data at most 2 hours.
|
||||
private static final float TOTAL_HOURLY_TIME_THRESHOLD = DateUtils.HOUR_IN_MILLIS * 2;
|
||||
private static final long MIN_TIME_SLOT = DateUtils.HOUR_IN_MILLIS * 2;
|
||||
private static final String MEDIASERVER_PACKAGE_NAME = "mediaserver";
|
||||
private static final String ANDROID_CORE_APPS_SHARED_USER_ID = "android.uid.shared";
|
||||
@@ -111,11 +108,6 @@ public final class DataProcessor {
|
||||
@VisibleForTesting
|
||||
static Set<String> sTestSystemAppsPackageNames;
|
||||
|
||||
@VisibleForTesting
|
||||
static IUsageStatsManager sUsageStatsManager =
|
||||
IUsageStatsManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.USAGE_STATS_SERVICE));
|
||||
|
||||
public static final String CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER =
|
||||
"CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER";
|
||||
|
||||
@@ -271,7 +263,7 @@ public final class DataProcessor {
|
||||
@Nullable
|
||||
public static Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>>
|
||||
generateAppUsagePeriodMap(
|
||||
final long rawStartTimestamp,
|
||||
Context context,
|
||||
final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
|
||||
final List<AppUsageEvent> appUsageEventList,
|
||||
final List<BatteryEvent> batteryEventList) {
|
||||
@@ -305,7 +297,7 @@ public final class DataProcessor {
|
||||
// The value could be null when there is no data in the hourly slot.
|
||||
dailyMap.put(
|
||||
hourlyIndex,
|
||||
buildAppUsagePeriodList(hourlyAppUsageEventList, batteryEventList,
|
||||
buildAppUsagePeriodList(context, hourlyAppUsageEventList, batteryEventList,
|
||||
startTimestamp, endTimestamp));
|
||||
}
|
||||
}
|
||||
@@ -346,8 +338,7 @@ public final class DataProcessor {
|
||||
break;
|
||||
}
|
||||
final AppUsageEvent appUsageEvent =
|
||||
ConvertUtils.convertToAppUsageEvent(
|
||||
context, sUsageStatsManager, event, userId);
|
||||
ConvertUtils.convertToAppUsageEvent(context, event, userId);
|
||||
if (appUsageEvent != null) {
|
||||
numEventsFetched++;
|
||||
appUsageEventList.add(appUsageEvent);
|
||||
@@ -661,8 +652,8 @@ public final class DataProcessor {
|
||||
@VisibleForTesting
|
||||
@Nullable
|
||||
static Map<Long, Map<String, List<AppUsagePeriod>>> buildAppUsagePeriodList(
|
||||
final List<AppUsageEvent> appUsageEvents, final List<BatteryEvent> batteryEventList,
|
||||
final long startTime, final long endTime) {
|
||||
Context context, final List<AppUsageEvent> appUsageEvents,
|
||||
final List<BatteryEvent> batteryEventList, final long startTime, final long endTime) {
|
||||
if (appUsageEvents.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
@@ -702,7 +693,7 @@ public final class DataProcessor {
|
||||
final AppUsageEvent firstEvent = usageEvents.get(0);
|
||||
final long eventUserId = firstEvent.getUserId();
|
||||
final String packageName = getEffectivePackageName(
|
||||
sUsageStatsManager,
|
||||
context,
|
||||
firstEvent.getPackageName(),
|
||||
firstEvent.getTaskRootPackageName());
|
||||
usageEvents.addAll(deviceEvents);
|
||||
@@ -975,7 +966,7 @@ public final class DataProcessor {
|
||||
final long startTime = DatabaseUtils.getAppUsageStartTimestampOfUser(
|
||||
context, userID, earliestTimestamp);
|
||||
return loadAppUsageEventsForUserFromService(
|
||||
sUsageStatsManager, startTime, now, userID, callingPackage);
|
||||
DatabaseUtils.sUsageStatsManager, startTime, now, userID, callingPackage);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.batteryusage;
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
@@ -28,6 +30,8 @@ import android.os.BatteryManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
@@ -63,6 +67,7 @@ public final class DatabaseUtils {
|
||||
static final int DATA_RETENTION_INTERVAL_DAY = 9;
|
||||
static final String KEY_LAST_LOAD_FULL_CHARGE_TIME = "last_load_full_charge_time";
|
||||
static final String KEY_LAST_UPLOAD_FULL_CHARGE_TIME = "last_upload_full_charge_time";
|
||||
static final String KEY_LAST_USAGE_SOURCE = "last_usage_source";
|
||||
|
||||
/** An authority name of the battery content provider. */
|
||||
public static final String AUTHORITY = "com.android.settings.battery.usage.provider";
|
||||
@@ -74,8 +79,6 @@ public final class DatabaseUtils {
|
||||
public static final String BATTERY_STATE_TABLE = "BatteryState";
|
||||
/** A path name for app usage latest timestamp query. */
|
||||
public static final String APP_USAGE_LATEST_TIMESTAMP_PATH = "appUsageLatestTimestamp";
|
||||
/** A class name for battery usage data provider. */
|
||||
public static final String SETTINGS_PACKAGE_PATH = "com.android.settings";
|
||||
/** Key for query parameter timestamp used in BATTERY_CONTENT_URI **/
|
||||
public static final String QUERY_KEY_TIMESTAMP = "timestamp";
|
||||
/** Key for query parameter userid used in APP_USAGE_EVENT_URI **/
|
||||
@@ -114,6 +117,11 @@ public final class DatabaseUtils {
|
||||
@VisibleForTesting
|
||||
static Supplier<Cursor> sFakeSupplier;
|
||||
|
||||
@VisibleForTesting
|
||||
static IUsageStatsManager sUsageStatsManager =
|
||||
IUsageStatsManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.USAGE_STATS_SERVICE));
|
||||
|
||||
private DatabaseUtils() {
|
||||
}
|
||||
|
||||
@@ -468,6 +476,37 @@ public final class DatabaseUtils {
|
||||
SHARED_PREFS_FILE, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
static void removeUsageSource(Context context) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
if (sharedPreferences != null && sharedPreferences.contains(KEY_LAST_USAGE_SOURCE)) {
|
||||
sharedPreferences.edit().remove(KEY_LAST_USAGE_SOURCE).apply();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns what App Usage Observers will consider the source of usage for an activity.
|
||||
*
|
||||
* @see UsageStatsManager#getUsageSource()
|
||||
*/
|
||||
static int getUsageSource(Context context) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
if (sharedPreferences != null && sharedPreferences.contains(KEY_LAST_USAGE_SOURCE)) {
|
||||
return sharedPreferences
|
||||
.getInt(KEY_LAST_USAGE_SOURCE, ConvertUtils.DEFAULT_USAGE_SOURCE);
|
||||
}
|
||||
int usageSource = ConvertUtils.DEFAULT_USAGE_SOURCE;
|
||||
|
||||
try {
|
||||
usageSource = sUsageStatsManager.getUsageSource();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to getUsageSource", e);
|
||||
}
|
||||
if (sharedPreferences != null) {
|
||||
sharedPreferences.edit().putInt(KEY_LAST_USAGE_SOURCE, usageSource).apply();
|
||||
}
|
||||
return usageSource;
|
||||
}
|
||||
|
||||
static void recordDateTime(Context context, String preferenceKey) {
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
if (sharedPreferences != null) {
|
||||
@@ -564,7 +603,7 @@ public final class DatabaseUtils {
|
||||
|
||||
private static Map<Long, Map<String, BatteryHistEntry>> loadHistoryMapFromContentProvider(
|
||||
Context context, Uri batteryStateUri) {
|
||||
context = DatabaseUtils.getParentContext(context);
|
||||
context = getParentContext(context);
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user