diff options
7 files changed, 71 insertions, 10 deletions
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java index d0c2870bfefb..81d750682c78 100644 --- a/core/java/android/os/WorkSource.java +++ b/core/java/android/os/WorkSource.java @@ -1,7 +1,10 @@ package android.os; import android.annotation.Nullable; +import android.content.Context; import android.os.WorkSourceProto; +import android.provider.Settings; +import android.provider.Settings.Global; import android.util.Log; import android.util.proto.ProtoOutputStream; @@ -109,6 +112,17 @@ public class WorkSource implements Parcelable { } } + /** + * Whether system services should create {@code WorkChains} (wherever possible) in the place + * of flat UID lists. + * + * @hide + */ + public static boolean isChainedBatteryAttributionEnabled(Context context) { + return Settings.Global.getInt(context.getContentResolver(), + Global.CHAINED_BATTERY_ATTRIBUTION_ENABLED, 0) == 1; + } + /** @hide */ public int size() { return mNum; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1ea486187935..cadca24f12e7 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11248,6 +11248,16 @@ public final class Settings { */ public static final String OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION = "override_settings_provider_restore_any_version"; + /** + * Flag to toggle whether system services report attribution chains when they attribute + * battery use via a {@code WorkSource}. + * + * Type: int (0 to disable, 1 to enable) + * + * @hide + */ + public static final String CHAINED_BATTERY_ATTRIBUTION_ENABLED = + "chained_battery_attribution_enabled"; /** * Settings to backup. This is here so that it's in the same place as the settings diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto index fd2832276922..27fbb24566f0 100644 --- a/core/proto/android/providers/settings.proto +++ b/core/proto/android/providers/settings.proto @@ -394,8 +394,9 @@ message GlobalSettingsProto { optional SettingProto wifi_connected_mac_randomization_enabled = 350; optional SettingProto show_restart_in_crash_dialog = 351; optional SettingProto show_mute_in_crash_dialog = 352; + optional SettingProto chained_battery_attribution_enabled = 353; - // Next tag = 353; + // Next tag = 354; } message SecureSettingsProto { diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 225b685b92a5..1520fb684e23 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -444,7 +444,8 @@ public class SettingsBackupTest { Settings.Global.ZEN_MODE_CONFIG_ETAG, Settings.Global.ZEN_MODE_RINGER_LEVEL, Settings.Global.ZRAM_ENABLED, - Settings.Global.OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION); + Settings.Global.OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION, + Settings.Global.CHAINED_BATTERY_ATTRIBUTION_ENABLED); private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS = newHashSet( diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index d556db47939d..6970c86aa5d7 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -19,6 +19,7 @@ package com.android.providers.settings; import android.annotation.NonNull; import android.os.UserHandle; import android.provider.Settings; +import android.provider.Settings.Global; import android.providers.settings.GlobalSettingsProto; import android.providers.settings.SecureSettingsProto; import android.providers.settings.SettingProto; @@ -1137,6 +1138,12 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG, GlobalSettingsProto.SHOW_MUTE_IN_CRASH_DIALOG); + dumpSetting(s, p, + Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, + GlobalSettingsProto.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED); + dumpSetting(s, p, + Global.CHAINED_BATTERY_ATTRIBUTION_ENABLED, + GlobalSettingsProto.CHAINED_BATTERY_ATTRIBUTION_ENABLED); } /** Dump a single {@link SettingsState.Setting} to a proto buf */ diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java index 83a3c1993d4b..f23147b445c2 100644 --- a/services/core/java/com/android/server/job/JobServiceContext.java +++ b/services/core/java/com/android/server/job/JobServiceContext.java @@ -400,7 +400,7 @@ public final class JobServiceContext implements ServiceConnection { (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, runningJob.getTag()); - wl.setWorkSource(new WorkSource(runningJob.getSourceUid())); + wl.setWorkSource(deriveWorkSource(runningJob)); wl.setReferenceCounted(false); wl.acquire(); @@ -419,6 +419,19 @@ public final class JobServiceContext implements ServiceConnection { } } + private WorkSource deriveWorkSource(JobStatus runningJob) { + final int jobUid = runningJob.getSourceUid(); + if (WorkSource.isChainedBatteryAttributionEnabled(mContext)) { + WorkSource workSource = new WorkSource(); + workSource.createWorkChain() + .addNode(jobUid, null) + .addNode(android.os.Process.SYSTEM_UID, "JobScheduler"); + return workSource; + } else { + return new WorkSource(jobUid); + } + } + /** If the client service crashes we reschedule this job and clean up. */ @Override public void onServiceDisconnected(ComponentName name) { diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java index bbee0ebd281b..a91f5a46409c 100644 --- a/services/core/java/com/android/server/job/controllers/TimeController.java +++ b/services/core/java/com/android/server/job/controllers/TimeController.java @@ -18,9 +18,11 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; +import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AlarmManager.OnAlarmListener; import android.content.Context; +import android.os.Process; import android.os.UserHandle; import android.os.WorkSource; import android.util.Slog; @@ -52,6 +54,8 @@ public final class TimeController extends StateController { private long mNextJobExpiredElapsedMillis; private long mNextDelayExpiredElapsedMillis; + private final boolean mChainedAttributionEnabled; + private AlarmManager mAlarmService = null; /** List of tracked jobs, sorted asc. by deadline */ private final List<JobStatus> mTrackedJobs = new LinkedList<>(); @@ -71,6 +75,7 @@ public final class TimeController extends StateController { mNextJobExpiredElapsedMillis = Long.MAX_VALUE; mNextDelayExpiredElapsedMillis = Long.MAX_VALUE; + mChainedAttributionEnabled = WorkSource.isChainedBatteryAttributionEnabled(context); } /** @@ -113,7 +118,7 @@ public final class TimeController extends StateController { maybeUpdateAlarmsLocked( job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE, job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE, - new WorkSource(job.getSourceUid(), job.getSourcePackageName())); + deriveWorkSource(job.getSourceUid(), job.getSourcePackageName())); } } @@ -179,9 +184,8 @@ public final class TimeController extends StateController { break; } } - setDeadlineExpiredAlarmLocked(nextExpiryTime, nextExpiryPackageName != null - ? new WorkSource(nextExpiryUid, nextExpiryPackageName) - : new WorkSource(nextExpiryUid)); + setDeadlineExpiredAlarmLocked(nextExpiryTime, + deriveWorkSource(nextExpiryUid, nextExpiryPackageName)); } } @@ -236,9 +240,20 @@ public final class TimeController extends StateController { if (ready) { mStateChangedListener.onControllerStateChanged(); } - setDelayExpiredAlarmLocked(nextDelayTime, nextDelayPackageName != null - ? new WorkSource(nextDelayUid, nextDelayPackageName) - : new WorkSource(nextDelayUid)); + setDelayExpiredAlarmLocked(nextDelayTime, + deriveWorkSource(nextDelayUid, nextDelayPackageName)); + } + } + + private WorkSource deriveWorkSource(int uid, @Nullable String packageName) { + if (mChainedAttributionEnabled) { + WorkSource ws = new WorkSource(); + ws.createWorkChain() + .addNode(uid, packageName) + .addNode(Process.SYSTEM_UID, "JobScheduler"); + return ws; + } else { + return packageName == null ? new WorkSource(uid) : new WorkSource(uid, packageName); } } |