Merge "Add TARE enable constant."
This commit is contained in:
@@ -196,7 +196,6 @@ class Agent {
|
||||
final int eventId, @Nullable String tag) {
|
||||
final long now = System.currentTimeMillis();
|
||||
final Ledger ledger = getLedgerLocked(userId, pkgName);
|
||||
final boolean wasSolvent = getBalanceLocked(userId, pkgName) > 0;
|
||||
|
||||
final int eventType = getEventType(eventId);
|
||||
switch (eventType) {
|
||||
@@ -400,12 +399,16 @@ class Agent {
|
||||
SparseArrayMap<String, OngoingEvent> ongoingEvents =
|
||||
mCurrentOngoingEvents.get(userId, pkgName);
|
||||
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;
|
||||
}
|
||||
final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag);
|
||||
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)
|
||||
+ " for <" + userId + ">" + pkgName + " ended");
|
||||
return;
|
||||
@@ -768,6 +771,15 @@ class Agent {
|
||||
SystemClock.elapsedRealtime() + timeToThresholdMs);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
void tearDownLocked() {
|
||||
mLedgers.clear();
|
||||
mCurrentNarcsInCirculation = 0;
|
||||
mCurrentOngoingEvents.clear();
|
||||
mBalanceThresholdAlarmListener.dropAllAlarmsLocked();
|
||||
mLedgerCleanupAlarmListener.dropAllAlarmsLocked();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class OngoingEvent {
|
||||
public final long startTimeElapsed;
|
||||
@@ -986,6 +998,12 @@ class Agent {
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
void dropAllAlarmsLocked() {
|
||||
mAlarmQueue.clear();
|
||||
setNextAlarmLocked(0);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
protected abstract void processExpiredAlarmLocked(int userId, @NonNull String packageName);
|
||||
|
||||
@@ -1069,6 +1087,13 @@ class Agent {
|
||||
final ActionAffordabilityNote note =
|
||||
new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy);
|
||||
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.setNewAffordability(
|
||||
getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice());
|
||||
|
||||
@@ -40,7 +40,16 @@ class ChargingModifier extends Modifier {
|
||||
super();
|
||||
mIrs = irs;
|
||||
mChargingTracker = new ChargingTracker();
|
||||
mChargingTracker.startTracking(irs.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
mChargingTracker.startTracking(mIrs.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() {
|
||||
mChargingTracker.stopTracking(mIrs.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,6 +93,10 @@ class ChargingModifier extends Modifier {
|
||||
mCharging = batteryManager.isCharging();
|
||||
}
|
||||
|
||||
public void stopTracking(@NonNull Context context) {
|
||||
context.unregisterReceiver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
|
||||
@@ -40,7 +40,16 @@ class DeviceIdleModifier extends Modifier {
|
||||
mIrs = irs;
|
||||
mPowerManager = irs.getContext().getSystemService(PowerManager.class);
|
||||
mDeviceIdleTracker = new DeviceIdleTracker();
|
||||
mDeviceIdleTracker.startTracking(irs.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
mDeviceIdleTracker.startTracking(mIrs.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() {
|
||||
mDeviceIdleTracker.stopTracking(mIrs.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,6 +90,10 @@ class DeviceIdleModifier extends Modifier {
|
||||
mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode();
|
||||
}
|
||||
|
||||
void stopTracking(@NonNull Context context) {
|
||||
context.unregisterReceiver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
|
||||
@@ -157,11 +157,21 @@ public abstract class EconomicPolicy {
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
void onSystemServicesReady() {
|
||||
void setup() {
|
||||
for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
|
||||
final Modifier modifier = COST_MODIFIER_BY_INDEX[i];
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,13 @@ import android.annotation.Nullable;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.tare.IEconomyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManagerInternal;
|
||||
import android.os.Binder;
|
||||
@@ -38,6 +40,7 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
@@ -81,6 +84,7 @@ public class InternalResourceService extends SystemService {
|
||||
|
||||
private final Agent mAgent;
|
||||
private final CompleteEconomicPolicy mCompleteEconomicPolicy;
|
||||
private final ConfigObserver mConfigObserver;
|
||||
private final EconomyManagerStub mEconomyManagerStub;
|
||||
|
||||
@NonNull
|
||||
@@ -91,8 +95,8 @@ public class InternalResourceService extends SystemService {
|
||||
@GuardedBy("mLock")
|
||||
private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mIsSetup;
|
||||
private volatile boolean mIsEnabled;
|
||||
private volatile int mBootPhase;
|
||||
// In the range [0,100] to represent 0% to 100% battery.
|
||||
@GuardedBy("mLock")
|
||||
private int mCurrentBatteryLevel;
|
||||
@@ -185,18 +189,7 @@ public class InternalResourceService extends SystemService {
|
||||
mCompleteEconomicPolicy = new CompleteEconomicPolicy(this);
|
||||
mAgent = new Agent(this, mCompleteEconomicPolicy);
|
||||
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
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);
|
||||
mConfigObserver = new ConfigObserver(mHandler, context);
|
||||
|
||||
publishLocalService(EconomyManagerInternal.class, new LocalService());
|
||||
}
|
||||
@@ -208,19 +201,11 @@ public class InternalResourceService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
mBootPhase = phase;
|
||||
|
||||
if (PHASE_SYSTEM_SERVICES_READY == phase) {
|
||||
synchronized (mLock) {
|
||||
mCurrentBatteryLevel = getCurrentBatteryLevel();
|
||||
// TODO: base on if we have anything persisted
|
||||
final boolean isFirstSetup = true;
|
||||
if (isFirstSetup) {
|
||||
mHandler.post(this::setupEconomy);
|
||||
} else {
|
||||
mIsSetup = true;
|
||||
}
|
||||
scheduleUnusedWealthReclamationLocked();
|
||||
mCompleteEconomicPolicy.onSystemServicesReady();
|
||||
}
|
||||
mConfigObserver.start();
|
||||
setupEverything();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,6 +232,10 @@ public class InternalResourceService extends SystemService {
|
||||
/ 100;
|
||||
}
|
||||
|
||||
boolean isEnabled() {
|
||||
return mIsEnabled;
|
||||
}
|
||||
|
||||
void onBatteryLevelChanged() {
|
||||
synchronized (mLock) {
|
||||
final int newBatteryLevel = getCurrentBatteryLevel();
|
||||
@@ -396,11 +385,67 @@ public class InternalResourceService extends SystemService {
|
||||
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) {
|
||||
loadInstalledPackageListLocked();
|
||||
mAgent.grantBirthrightsLocked();
|
||||
mIsSetup = true;
|
||||
// TODO: base on if we have anything persisted
|
||||
final boolean isFirstSetup = true;
|
||||
if (isFirstSetup) {
|
||||
mAgent.grantBirthrightsLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,6 +532,9 @@ public class InternalResourceService extends SystemService {
|
||||
|
||||
@Override
|
||||
public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) {
|
||||
if (!mIsEnabled) {
|
||||
return true;
|
||||
}
|
||||
// TODO: take temp-allowlist into consideration
|
||||
long requiredBalance = 0;
|
||||
final List<EconomyManagerInternal.AnticipatedAction> projectedActions =
|
||||
@@ -506,6 +554,9 @@ public class InternalResourceService extends SystemService {
|
||||
@Override
|
||||
public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
|
||||
@Nullable String tag) {
|
||||
if (!mIsEnabled) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mAgent.noteInstantaneousEventLocked(userId, pkgName, eventId, tag);
|
||||
}
|
||||
@@ -514,6 +565,9 @@ public class InternalResourceService extends SystemService {
|
||||
@Override
|
||||
public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId,
|
||||
@Nullable String tag) {
|
||||
if (!mIsEnabled) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
final long nowElapsed = SystemClock.elapsedRealtime();
|
||||
mAgent.noteOngoingEventLocked(userId, pkgName, eventId, tag, nowElapsed);
|
||||
@@ -523,6 +577,9 @@ public class InternalResourceService extends SystemService {
|
||||
@Override
|
||||
public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId,
|
||||
@Nullable String tag) {
|
||||
if (!mIsEnabled) {
|
||||
return;
|
||||
}
|
||||
final long nowElapsed = SystemClock.elapsedRealtime();
|
||||
final long now = System.currentTimeMillis();
|
||||
synchronized (mLock) {
|
||||
@@ -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) {
|
||||
pw.println("Resource Economy (economy) dump options:");
|
||||
pw.println(" [-h|--help] [package] ...");
|
||||
|
||||
@@ -60,7 +60,10 @@ abstract class Modifier {
|
||||
return price;
|
||||
}
|
||||
|
||||
void onSystemServicesReady() {
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void tearDown() {
|
||||
}
|
||||
|
||||
abstract void dump(IndentingPrintWriter pw);
|
||||
|
||||
@@ -110,7 +110,7 @@ class ProcessStateModifier extends Modifier {
|
||||
|
||||
@Override
|
||||
@GuardedBy("mLock")
|
||||
void onSystemServicesReady() {
|
||||
void setup() {
|
||||
try {
|
||||
ActivityManager.getService().registerUidObserver(mUidObserver,
|
||||
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
|
||||
@@ -120,6 +120,18 @@ class ProcessStateModifier extends Modifier {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@GuardedBy("mLock")
|
||||
void tearDown() {
|
||||
try {
|
||||
ActivityManager.getService().unregisterUidObserver(mUidObserver);
|
||||
} catch (RemoteException e) {
|
||||
// ignored; both services live in system_server
|
||||
}
|
||||
mPackageToUidCache.clear();
|
||||
mUidProcStateBucketCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the final modified price based on an app's process state.
|
||||
*
|
||||
|
||||
@@ -13495,6 +13495,21 @@ public final class Settings {
|
||||
public static final String FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED
|
||||
= "forced_app_standby_for_small_battery_enabled";
|
||||
|
||||
/**
|
||||
* Whether to enable the TARE subsystem as a whole or not.
|
||||
* 1 means enable, 0 means disable.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ENABLE_TARE = "enable_tare";
|
||||
|
||||
/**
|
||||
* Default value for {@link #ENABLE_TARE}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int DEFAULT_ENABLE_TARE = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to enable the User Absent, Radios Off feature on small battery devices.
|
||||
* Type: int (0 for false, 1 for true)
|
||||
|
||||
@@ -117,6 +117,7 @@ public class GlobalSettingsValidators {
|
||||
VALIDATORS.put(Global.CLOCKWORK_SYSUI_MAIN_ACTIVITY_NAME, ANY_STRING_VALIDATOR);
|
||||
VALIDATORS.put(Global.CLOCKWORK_SYSUI_PACKAGE_NAME, ANY_STRING_VALIDATOR);
|
||||
VALIDATORS.put(Global.CLOCKWORK_HOME_READY, ANY_STRING_VALIDATOR);
|
||||
VALIDATORS.put(Global.ENABLE_TARE, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Global.PRIVATE_DNS_MODE, ANY_STRING_VALIDATOR);
|
||||
VALIDATORS.put(Global.PRIVATE_DNS_SPECIFIER, ANY_STRING_VALIDATOR);
|
||||
VALIDATORS.put(Global.SOFT_AP_TIMEOUT_ENABLED, BOOLEAN_VALIDATOR);
|
||||
|
||||
@@ -265,6 +265,7 @@ public class SettingsBackupTest {
|
||||
Settings.Global.ENABLE_DISKSTATS_LOGGING,
|
||||
Settings.Global.ENABLE_EPHEMERAL_FEATURE,
|
||||
Settings.Global.ENABLE_RESTRICTED_BUCKET,
|
||||
Settings.Global.ENABLE_TARE,
|
||||
Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
|
||||
Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
|
||||
Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
|
||||
|
||||
Reference in New Issue
Block a user