Loading apex/jobscheduler/service/java/com/android/server/tare/Agent.java +28 −3 Original line number Original line Diff line number Diff line Loading @@ -196,7 +196,6 @@ class Agent { final int eventId, @Nullable String tag) { final int eventId, @Nullable String tag) { final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis(); final Ledger ledger = getLedgerLocked(userId, pkgName); final Ledger ledger = getLedgerLocked(userId, pkgName); final boolean wasSolvent = getBalanceLocked(userId, pkgName) > 0; final int eventType = getEventType(eventId); final int eventType = getEventType(eventId); switch (eventType) { switch (eventType) { Loading Loading @@ -400,12 +399,16 @@ class Agent { SparseArrayMap<String, OngoingEvent> ongoingEvents = SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents == null) { if (ongoingEvents == null) { Slog.wtf(TAG, "No ongoing transactions :/"); // This may occur if TARE goes from disabled to enabled while an event is already // occurring. Slog.w(TAG, "No ongoing transactions for <" + userId + ">" + pkgName); return; return; } } final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag); final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag); if (ongoingEvent == null) { if (ongoingEvent == null) { Slog.wtf(TAG, "Nonexistent ongoing transaction " // This may occur if TARE goes from disabled to enabled while an event is already // occurring. Slog.w(TAG, "Nonexistent ongoing transaction " + eventToString(eventId) + (tag == null ? "" : ":" + tag) + eventToString(eventId) + (tag == null ? "" : ":" + tag) + " for <" + userId + ">" + pkgName + " ended"); + " for <" + userId + ">" + pkgName + " ended"); return; return; Loading Loading @@ -768,6 +771,15 @@ class Agent { SystemClock.elapsedRealtime() + timeToThresholdMs); SystemClock.elapsedRealtime() + timeToThresholdMs); } } @GuardedBy("mLock") void tearDownLocked() { mLedgers.clear(); mCurrentNarcsInCirculation = 0; mCurrentOngoingEvents.clear(); mBalanceThresholdAlarmListener.dropAllAlarmsLocked(); mLedgerCleanupAlarmListener.dropAllAlarmsLocked(); } @VisibleForTesting @VisibleForTesting static class OngoingEvent { static class OngoingEvent { public final long startTimeElapsed; public final long startTimeElapsed; Loading Loading @@ -986,6 +998,12 @@ class Agent { } } } } @GuardedBy("mLock") void dropAllAlarmsLocked() { mAlarmQueue.clear(); setNextAlarmLocked(0); } @GuardedBy("mLock") @GuardedBy("mLock") protected abstract void processExpiredAlarmLocked(int userId, @NonNull String packageName); protected abstract void processExpiredAlarmLocked(int userId, @NonNull String packageName); Loading Loading @@ -1069,6 +1087,13 @@ class Agent { final ActionAffordabilityNote note = final ActionAffordabilityNote note = new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy); new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy); if (actionAffordabilityNotes.add(note)) { if (actionAffordabilityNotes.add(note)) { if (!mIrs.isEnabled()) { // When TARE isn't enabled, we always say something is affordable. We also don't // want to silently drop affordability change listeners in case TARE becomes enabled // because then clients will be in an ambiguous state. note.setNewAffordability(true); return; } note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName); note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName); note.setNewAffordability( note.setNewAffordability( getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice()); getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice()); Loading apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java +14 −1 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,16 @@ class ChargingModifier extends Modifier { super(); super(); mIrs = irs; mIrs = irs; mChargingTracker = new ChargingTracker(); mChargingTracker = new ChargingTracker(); mChargingTracker.startTracking(irs.getContext()); } @Override public void setup() { mChargingTracker.startTracking(mIrs.getContext()); } @Override public void tearDown() { mChargingTracker.stopTracking(mIrs.getContext()); } } @Override @Override Loading Loading @@ -84,6 +93,10 @@ class ChargingModifier extends Modifier { mCharging = batteryManager.isCharging(); mCharging = batteryManager.isCharging(); } } public void stopTracking(@NonNull Context context) { context.unregisterReceiver(this); } @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final String action = intent.getAction(); Loading apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java +14 −1 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,16 @@ class DeviceIdleModifier extends Modifier { mIrs = irs; mIrs = irs; mPowerManager = irs.getContext().getSystemService(PowerManager.class); mPowerManager = irs.getContext().getSystemService(PowerManager.class); mDeviceIdleTracker = new DeviceIdleTracker(); mDeviceIdleTracker = new DeviceIdleTracker(); mDeviceIdleTracker.startTracking(irs.getContext()); } @Override public void setup() { mDeviceIdleTracker.startTracking(mIrs.getContext()); } @Override public void tearDown() { mDeviceIdleTracker.stopTracking(mIrs.getContext()); } } @Override @Override Loading Loading @@ -81,6 +90,10 @@ class DeviceIdleModifier extends Modifier { mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode(); mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode(); } } void stopTracking(@NonNull Context context) { context.unregisterReceiver(this); } @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final String action = intent.getAction(); Loading apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java +12 −2 Original line number Original line Diff line number Diff line Loading @@ -157,11 +157,21 @@ public abstract class EconomicPolicy { } } @CallSuper @CallSuper void onSystemServicesReady() { void setup() { for (int i = 0; i < NUM_COST_MODIFIERS; ++i) { for (int i = 0; i < NUM_COST_MODIFIERS; ++i) { final Modifier modifier = COST_MODIFIER_BY_INDEX[i]; final Modifier modifier = COST_MODIFIER_BY_INDEX[i]; if (modifier != null) { if (modifier != null) { modifier.onSystemServicesReady(); modifier.setup(); } } } @CallSuper void tearDown() { for (int i = 0; i < NUM_COST_MODIFIERS; ++i) { final Modifier modifier = COST_MODIFIER_BY_INDEX[i]; if (modifier != null) { modifier.tearDown(); } } } } } } Loading apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +119 −29 Original line number Original line Diff line number Diff line Loading @@ -24,11 +24,13 @@ import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AlarmManager; import android.app.tare.IEconomyManager; import android.app.tare.IEconomyManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.net.Uri; import android.os.BatteryManagerInternal; import android.os.BatteryManagerInternal; import android.os.Binder; import android.os.Binder; Loading @@ -38,6 +40,7 @@ import android.os.Looper; import android.os.Message; import android.os.Message; import android.os.SystemClock; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Log; Loading Loading @@ -81,6 +84,7 @@ public class InternalResourceService extends SystemService { private final Agent mAgent; private final Agent mAgent; private final CompleteEconomicPolicy mCompleteEconomicPolicy; private final CompleteEconomicPolicy mCompleteEconomicPolicy; private final ConfigObserver mConfigObserver; private final EconomyManagerStub mEconomyManagerStub; private final EconomyManagerStub mEconomyManagerStub; @NonNull @NonNull Loading @@ -91,8 +95,8 @@ public class InternalResourceService extends SystemService { @GuardedBy("mLock") @GuardedBy("mLock") private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>(); private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>(); @GuardedBy("mLock") private volatile boolean mIsEnabled; private boolean mIsSetup; private volatile int mBootPhase; // In the range [0,100] to represent 0% to 100% battery. // In the range [0,100] to represent 0% to 100% battery. @GuardedBy("mLock") @GuardedBy("mLock") private int mCurrentBatteryLevel; private int mCurrentBatteryLevel; Loading Loading @@ -185,18 +189,7 @@ public class InternalResourceService extends SystemService { mCompleteEconomicPolicy = new CompleteEconomicPolicy(this); mCompleteEconomicPolicy = new CompleteEconomicPolicy(this); mAgent = new Agent(this, mCompleteEconomicPolicy); mAgent = new Agent(this, mCompleteEconomicPolicy); final IntentFilter filter = new IntentFilter(); mConfigObserver = new ConfigObserver(mHandler, context); filter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); final IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); pkgFilter.addDataScheme("package"); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, pkgFilter, null, null); final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED); userFilter.addAction(Intent.ACTION_USER_ADDED); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, userFilter, null, null); publishLocalService(EconomyManagerInternal.class, new LocalService()); publishLocalService(EconomyManagerInternal.class, new LocalService()); } } Loading @@ -208,19 +201,11 @@ public class InternalResourceService extends SystemService { @Override @Override public void onBootPhase(int phase) { public void onBootPhase(int phase) { mBootPhase = phase; if (PHASE_SYSTEM_SERVICES_READY == phase) { if (PHASE_SYSTEM_SERVICES_READY == phase) { synchronized (mLock) { mConfigObserver.start(); mCurrentBatteryLevel = getCurrentBatteryLevel(); setupEverything(); // TODO: base on if we have anything persisted final boolean isFirstSetup = true; if (isFirstSetup) { mHandler.post(this::setupEconomy); } else { mIsSetup = true; } scheduleUnusedWealthReclamationLocked(); mCompleteEconomicPolicy.onSystemServicesReady(); } } } } } Loading @@ -247,6 +232,10 @@ public class InternalResourceService extends SystemService { / 100; / 100; } } boolean isEnabled() { return mIsEnabled; } void onBatteryLevelChanged() { void onBatteryLevelChanged() { synchronized (mLock) { synchronized (mLock) { final int newBatteryLevel = getCurrentBatteryLevel(); final int newBatteryLevel = getCurrentBatteryLevel(); Loading Loading @@ -396,11 +385,67 @@ public class InternalResourceService extends SystemService { mPkgCache = mPackageManager.getInstalledPackages(0); mPkgCache = mPackageManager.getInstalledPackages(0); } } private void setupEconomy() { private void registerReceivers() { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED); getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); final IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); pkgFilter.addDataScheme("package"); getContext() .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, pkgFilter, null, null); final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED); userFilter.addAction(Intent.ACTION_USER_ADDED); getContext() .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, userFilter, null, null); } /** Perform long-running and/or heavy setup work. This should be called off the main thread. */ private void setupHeavyWork() { synchronized (mLock) { synchronized (mLock) { loadInstalledPackageListLocked(); loadInstalledPackageListLocked(); // TODO: base on if we have anything persisted final boolean isFirstSetup = true; if (isFirstSetup) { mAgent.grantBirthrightsLocked(); mAgent.grantBirthrightsLocked(); mIsSetup = true; } } } private void setupEverything() { if (mBootPhase < PHASE_SYSTEM_SERVICES_READY || !mIsEnabled) { return; } synchronized (mLock) { registerReceivers(); mCurrentBatteryLevel = getCurrentBatteryLevel(); mHandler.post(this::setupHeavyWork); scheduleUnusedWealthReclamationLocked(); mCompleteEconomicPolicy.setup(); } } private void tearDownEverything() { if (mIsEnabled) { return; } synchronized (mLock) { mAgent.tearDownLocked(); mCompleteEconomicPolicy.tearDown(); mHandler.post(() -> { // Never call out to AlarmManager with the lock held. This sits below AM. AlarmManager alarmManager = getContext().getSystemService(AlarmManager.class); if (alarmManager != null) { alarmManager.cancel(mUnusedWealthReclamationListener); } }); mPkgCache.clear(); mUidToPackageCache.clear(); getContext().unregisterReceiver(mBroadcastReceiver); } } } } Loading Loading @@ -487,6 +532,9 @@ public class InternalResourceService extends SystemService { @Override @Override public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) { public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) { if (!mIsEnabled) { return true; } // TODO: take temp-allowlist into consideration // TODO: take temp-allowlist into consideration long requiredBalance = 0; long requiredBalance = 0; final List<EconomyManagerInternal.AnticipatedAction> projectedActions = final List<EconomyManagerInternal.AnticipatedAction> projectedActions = Loading @@ -506,6 +554,9 @@ public class InternalResourceService extends SystemService { @Override @Override public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @Nullable String tag) { if (!mIsEnabled) { return; } synchronized (mLock) { synchronized (mLock) { mAgent.noteInstantaneousEventLocked(userId, pkgName, eventId, tag); mAgent.noteInstantaneousEventLocked(userId, pkgName, eventId, tag); } } Loading @@ -514,6 +565,9 @@ public class InternalResourceService extends SystemService { @Override @Override public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @Nullable String tag) { if (!mIsEnabled) { return; } synchronized (mLock) { synchronized (mLock) { final long nowElapsed = SystemClock.elapsedRealtime(); final long nowElapsed = SystemClock.elapsedRealtime(); mAgent.noteOngoingEventLocked(userId, pkgName, eventId, tag, nowElapsed); mAgent.noteOngoingEventLocked(userId, pkgName, eventId, tag, nowElapsed); Loading @@ -523,6 +577,9 @@ public class InternalResourceService extends SystemService { @Override @Override public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @Nullable String tag) { if (!mIsEnabled) { return; } final long nowElapsed = SystemClock.elapsedRealtime(); final long nowElapsed = SystemClock.elapsedRealtime(); final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis(); synchronized (mLock) { synchronized (mLock) { Loading @@ -531,6 +588,39 @@ public class InternalResourceService extends SystemService { } } } } private class ConfigObserver extends ContentObserver { private final ContentResolver mContentResolver; ConfigObserver(Handler handler, Context context) { super(handler); mContentResolver = context.getContentResolver(); } public void start() { mContentResolver.registerContentObserver( Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this); updateConfig(); } @Override public void onChange(boolean selfChange) { updateConfig(); } private void updateConfig() { final boolean isTareEnabled = Settings.Global.getInt(mContentResolver, Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1; if (mIsEnabled != isTareEnabled) { mIsEnabled = isTareEnabled; if (mIsEnabled) { setupEverything(); } else { tearDownEverything(); } } } } private static void dumpHelp(PrintWriter pw) { private static void dumpHelp(PrintWriter pw) { pw.println("Resource Economy (economy) dump options:"); pw.println("Resource Economy (economy) dump options:"); pw.println(" [-h|--help] [package] ..."); pw.println(" [-h|--help] [package] ..."); Loading Loading
apex/jobscheduler/service/java/com/android/server/tare/Agent.java +28 −3 Original line number Original line Diff line number Diff line Loading @@ -196,7 +196,6 @@ class Agent { final int eventId, @Nullable String tag) { final int eventId, @Nullable String tag) { final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis(); final Ledger ledger = getLedgerLocked(userId, pkgName); final Ledger ledger = getLedgerLocked(userId, pkgName); final boolean wasSolvent = getBalanceLocked(userId, pkgName) > 0; final int eventType = getEventType(eventId); final int eventType = getEventType(eventId); switch (eventType) { switch (eventType) { Loading Loading @@ -400,12 +399,16 @@ class Agent { SparseArrayMap<String, OngoingEvent> ongoingEvents = SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents == null) { if (ongoingEvents == null) { Slog.wtf(TAG, "No ongoing transactions :/"); // This may occur if TARE goes from disabled to enabled while an event is already // occurring. Slog.w(TAG, "No ongoing transactions for <" + userId + ">" + pkgName); return; return; } } final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag); final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag); if (ongoingEvent == null) { if (ongoingEvent == null) { Slog.wtf(TAG, "Nonexistent ongoing transaction " // This may occur if TARE goes from disabled to enabled while an event is already // occurring. Slog.w(TAG, "Nonexistent ongoing transaction " + eventToString(eventId) + (tag == null ? "" : ":" + tag) + eventToString(eventId) + (tag == null ? "" : ":" + tag) + " for <" + userId + ">" + pkgName + " ended"); + " for <" + userId + ">" + pkgName + " ended"); return; return; Loading Loading @@ -768,6 +771,15 @@ class Agent { SystemClock.elapsedRealtime() + timeToThresholdMs); SystemClock.elapsedRealtime() + timeToThresholdMs); } } @GuardedBy("mLock") void tearDownLocked() { mLedgers.clear(); mCurrentNarcsInCirculation = 0; mCurrentOngoingEvents.clear(); mBalanceThresholdAlarmListener.dropAllAlarmsLocked(); mLedgerCleanupAlarmListener.dropAllAlarmsLocked(); } @VisibleForTesting @VisibleForTesting static class OngoingEvent { static class OngoingEvent { public final long startTimeElapsed; public final long startTimeElapsed; Loading Loading @@ -986,6 +998,12 @@ class Agent { } } } } @GuardedBy("mLock") void dropAllAlarmsLocked() { mAlarmQueue.clear(); setNextAlarmLocked(0); } @GuardedBy("mLock") @GuardedBy("mLock") protected abstract void processExpiredAlarmLocked(int userId, @NonNull String packageName); protected abstract void processExpiredAlarmLocked(int userId, @NonNull String packageName); Loading Loading @@ -1069,6 +1087,13 @@ class Agent { final ActionAffordabilityNote note = final ActionAffordabilityNote note = new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy); new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy); if (actionAffordabilityNotes.add(note)) { if (actionAffordabilityNotes.add(note)) { if (!mIrs.isEnabled()) { // When TARE isn't enabled, we always say something is affordable. We also don't // want to silently drop affordability change listeners in case TARE becomes enabled // because then clients will be in an ambiguous state. note.setNewAffordability(true); return; } note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName); note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName); note.setNewAffordability( note.setNewAffordability( getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice()); getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice()); Loading
apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java +14 −1 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,16 @@ class ChargingModifier extends Modifier { super(); super(); mIrs = irs; mIrs = irs; mChargingTracker = new ChargingTracker(); mChargingTracker = new ChargingTracker(); mChargingTracker.startTracking(irs.getContext()); } @Override public void setup() { mChargingTracker.startTracking(mIrs.getContext()); } @Override public void tearDown() { mChargingTracker.stopTracking(mIrs.getContext()); } } @Override @Override Loading Loading @@ -84,6 +93,10 @@ class ChargingModifier extends Modifier { mCharging = batteryManager.isCharging(); mCharging = batteryManager.isCharging(); } } public void stopTracking(@NonNull Context context) { context.unregisterReceiver(this); } @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final String action = intent.getAction(); Loading
apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java +14 −1 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,16 @@ class DeviceIdleModifier extends Modifier { mIrs = irs; mIrs = irs; mPowerManager = irs.getContext().getSystemService(PowerManager.class); mPowerManager = irs.getContext().getSystemService(PowerManager.class); mDeviceIdleTracker = new DeviceIdleTracker(); mDeviceIdleTracker = new DeviceIdleTracker(); mDeviceIdleTracker.startTracking(irs.getContext()); } @Override public void setup() { mDeviceIdleTracker.startTracking(mIrs.getContext()); } @Override public void tearDown() { mDeviceIdleTracker.stopTracking(mIrs.getContext()); } } @Override @Override Loading Loading @@ -81,6 +90,10 @@ class DeviceIdleModifier extends Modifier { mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode(); mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode(); } } void stopTracking(@NonNull Context context) { context.unregisterReceiver(this); } @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final String action = intent.getAction(); Loading
apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java +12 −2 Original line number Original line Diff line number Diff line Loading @@ -157,11 +157,21 @@ public abstract class EconomicPolicy { } } @CallSuper @CallSuper void onSystemServicesReady() { void setup() { for (int i = 0; i < NUM_COST_MODIFIERS; ++i) { for (int i = 0; i < NUM_COST_MODIFIERS; ++i) { final Modifier modifier = COST_MODIFIER_BY_INDEX[i]; final Modifier modifier = COST_MODIFIER_BY_INDEX[i]; if (modifier != null) { if (modifier != null) { modifier.onSystemServicesReady(); modifier.setup(); } } } @CallSuper void tearDown() { for (int i = 0; i < NUM_COST_MODIFIERS; ++i) { final Modifier modifier = COST_MODIFIER_BY_INDEX[i]; if (modifier != null) { modifier.tearDown(); } } } } } } Loading
apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +119 −29 Original line number Original line Diff line number Diff line Loading @@ -24,11 +24,13 @@ import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AlarmManager; import android.app.tare.IEconomyManager; import android.app.tare.IEconomyManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.net.Uri; import android.os.BatteryManagerInternal; import android.os.BatteryManagerInternal; import android.os.Binder; import android.os.Binder; Loading @@ -38,6 +40,7 @@ import android.os.Looper; import android.os.Message; import android.os.Message; import android.os.SystemClock; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Log; Loading Loading @@ -81,6 +84,7 @@ public class InternalResourceService extends SystemService { private final Agent mAgent; private final Agent mAgent; private final CompleteEconomicPolicy mCompleteEconomicPolicy; private final CompleteEconomicPolicy mCompleteEconomicPolicy; private final ConfigObserver mConfigObserver; private final EconomyManagerStub mEconomyManagerStub; private final EconomyManagerStub mEconomyManagerStub; @NonNull @NonNull Loading @@ -91,8 +95,8 @@ public class InternalResourceService extends SystemService { @GuardedBy("mLock") @GuardedBy("mLock") private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>(); private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>(); @GuardedBy("mLock") private volatile boolean mIsEnabled; private boolean mIsSetup; private volatile int mBootPhase; // In the range [0,100] to represent 0% to 100% battery. // In the range [0,100] to represent 0% to 100% battery. @GuardedBy("mLock") @GuardedBy("mLock") private int mCurrentBatteryLevel; private int mCurrentBatteryLevel; Loading Loading @@ -185,18 +189,7 @@ public class InternalResourceService extends SystemService { mCompleteEconomicPolicy = new CompleteEconomicPolicy(this); mCompleteEconomicPolicy = new CompleteEconomicPolicy(this); mAgent = new Agent(this, mCompleteEconomicPolicy); mAgent = new Agent(this, mCompleteEconomicPolicy); final IntentFilter filter = new IntentFilter(); mConfigObserver = new ConfigObserver(mHandler, context); filter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); final IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); pkgFilter.addDataScheme("package"); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, pkgFilter, null, null); final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED); userFilter.addAction(Intent.ACTION_USER_ADDED); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, userFilter, null, null); publishLocalService(EconomyManagerInternal.class, new LocalService()); publishLocalService(EconomyManagerInternal.class, new LocalService()); } } Loading @@ -208,19 +201,11 @@ public class InternalResourceService extends SystemService { @Override @Override public void onBootPhase(int phase) { public void onBootPhase(int phase) { mBootPhase = phase; if (PHASE_SYSTEM_SERVICES_READY == phase) { if (PHASE_SYSTEM_SERVICES_READY == phase) { synchronized (mLock) { mConfigObserver.start(); mCurrentBatteryLevel = getCurrentBatteryLevel(); setupEverything(); // TODO: base on if we have anything persisted final boolean isFirstSetup = true; if (isFirstSetup) { mHandler.post(this::setupEconomy); } else { mIsSetup = true; } scheduleUnusedWealthReclamationLocked(); mCompleteEconomicPolicy.onSystemServicesReady(); } } } } } Loading @@ -247,6 +232,10 @@ public class InternalResourceService extends SystemService { / 100; / 100; } } boolean isEnabled() { return mIsEnabled; } void onBatteryLevelChanged() { void onBatteryLevelChanged() { synchronized (mLock) { synchronized (mLock) { final int newBatteryLevel = getCurrentBatteryLevel(); final int newBatteryLevel = getCurrentBatteryLevel(); Loading Loading @@ -396,11 +385,67 @@ public class InternalResourceService extends SystemService { mPkgCache = mPackageManager.getInstalledPackages(0); mPkgCache = mPackageManager.getInstalledPackages(0); } } private void setupEconomy() { private void registerReceivers() { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED); getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); final IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); pkgFilter.addDataScheme("package"); getContext() .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, pkgFilter, null, null); final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED); userFilter.addAction(Intent.ACTION_USER_ADDED); getContext() .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, userFilter, null, null); } /** Perform long-running and/or heavy setup work. This should be called off the main thread. */ private void setupHeavyWork() { synchronized (mLock) { synchronized (mLock) { loadInstalledPackageListLocked(); loadInstalledPackageListLocked(); // TODO: base on if we have anything persisted final boolean isFirstSetup = true; if (isFirstSetup) { mAgent.grantBirthrightsLocked(); mAgent.grantBirthrightsLocked(); mIsSetup = true; } } } private void setupEverything() { if (mBootPhase < PHASE_SYSTEM_SERVICES_READY || !mIsEnabled) { return; } synchronized (mLock) { registerReceivers(); mCurrentBatteryLevel = getCurrentBatteryLevel(); mHandler.post(this::setupHeavyWork); scheduleUnusedWealthReclamationLocked(); mCompleteEconomicPolicy.setup(); } } private void tearDownEverything() { if (mIsEnabled) { return; } synchronized (mLock) { mAgent.tearDownLocked(); mCompleteEconomicPolicy.tearDown(); mHandler.post(() -> { // Never call out to AlarmManager with the lock held. This sits below AM. AlarmManager alarmManager = getContext().getSystemService(AlarmManager.class); if (alarmManager != null) { alarmManager.cancel(mUnusedWealthReclamationListener); } }); mPkgCache.clear(); mUidToPackageCache.clear(); getContext().unregisterReceiver(mBroadcastReceiver); } } } } Loading Loading @@ -487,6 +532,9 @@ public class InternalResourceService extends SystemService { @Override @Override public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) { public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) { if (!mIsEnabled) { return true; } // TODO: take temp-allowlist into consideration // TODO: take temp-allowlist into consideration long requiredBalance = 0; long requiredBalance = 0; final List<EconomyManagerInternal.AnticipatedAction> projectedActions = final List<EconomyManagerInternal.AnticipatedAction> projectedActions = Loading @@ -506,6 +554,9 @@ public class InternalResourceService extends SystemService { @Override @Override public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @Nullable String tag) { if (!mIsEnabled) { return; } synchronized (mLock) { synchronized (mLock) { mAgent.noteInstantaneousEventLocked(userId, pkgName, eventId, tag); mAgent.noteInstantaneousEventLocked(userId, pkgName, eventId, tag); } } Loading @@ -514,6 +565,9 @@ public class InternalResourceService extends SystemService { @Override @Override public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @Nullable String tag) { if (!mIsEnabled) { return; } synchronized (mLock) { synchronized (mLock) { final long nowElapsed = SystemClock.elapsedRealtime(); final long nowElapsed = SystemClock.elapsedRealtime(); mAgent.noteOngoingEventLocked(userId, pkgName, eventId, tag, nowElapsed); mAgent.noteOngoingEventLocked(userId, pkgName, eventId, tag, nowElapsed); Loading @@ -523,6 +577,9 @@ public class InternalResourceService extends SystemService { @Override @Override public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @Nullable String tag) { if (!mIsEnabled) { return; } final long nowElapsed = SystemClock.elapsedRealtime(); final long nowElapsed = SystemClock.elapsedRealtime(); final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis(); synchronized (mLock) { synchronized (mLock) { Loading @@ -531,6 +588,39 @@ public class InternalResourceService extends SystemService { } } } } private class ConfigObserver extends ContentObserver { private final ContentResolver mContentResolver; ConfigObserver(Handler handler, Context context) { super(handler); mContentResolver = context.getContentResolver(); } public void start() { mContentResolver.registerContentObserver( Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this); updateConfig(); } @Override public void onChange(boolean selfChange) { updateConfig(); } private void updateConfig() { final boolean isTareEnabled = Settings.Global.getInt(mContentResolver, Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1; if (mIsEnabled != isTareEnabled) { mIsEnabled = isTareEnabled; if (mIsEnabled) { setupEverything(); } else { tearDownEverything(); } } } } private static void dumpHelp(PrintWriter pw) { private static void dumpHelp(PrintWriter pw) { pw.println("Resource Economy (economy) dump options:"); pw.println("Resource Economy (economy) dump options:"); pw.println(" [-h|--help] [package] ..."); pw.println(" [-h|--help] [package] ..."); Loading