Allow enabling TARE via DeviceConfig.

Bug: 158300259
Bug: 205624100
Test: Run adb commands and verify TARE is toggled when user hasn't set a value
Change-Id: I931c354cc2c972be566ac798853f57335d3b50aa
This commit is contained in:
Kweku Adams
2021-11-09 08:53:48 -08:00
parent d980b9e776
commit 6358d44202
6 changed files with 122 additions and 51 deletions

View File

@@ -490,8 +490,8 @@ public class AlarmManagerService extends SystemService {
* holding the AlarmManagerService.mLock lock.
*/
@VisibleForTesting
final class Constants extends ContentObserver
implements DeviceConfig.OnPropertiesChangedListener {
final class Constants implements DeviceConfig.OnPropertiesChangedListener,
EconomyManagerInternal.TareStateChangeListener {
@VisibleForTesting
static final int MAX_EXACT_ALARM_DENY_LIST_SIZE = 250;
@@ -695,7 +695,6 @@ public class AlarmManagerService extends SystemService {
private int mVersion = 0;
Constants(Handler handler) {
super(handler);
updateAllowWhileIdleWhitelistDurationLocked();
for (int i = 0; i < APP_STANDBY_QUOTAS.length; i++) {
APP_STANDBY_QUOTAS[i] = DEFAULT_APP_STANDBY_QUOTAS[i];
@@ -709,11 +708,12 @@ public class AlarmManagerService extends SystemService {
}
public void start() {
mInjector.registerContentObserver(this,
Settings.Global.getUriFor(Settings.Global.ENABLE_TARE));
mInjector.registerDeviceConfigListener(this);
final EconomyManagerInternal economyManagerInternal =
LocalServices.getService(EconomyManagerInternal.class);
economyManagerInternal.registerTareStateChangeListener(this);
onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER));
updateTareSettings();
updateTareSettings(economyManagerInternal.isEnabled());
}
public void updateAllowWhileIdleWhitelistDurationLocked() {
@@ -886,15 +886,12 @@ public class AlarmManagerService extends SystemService {
}
@Override
public void onChange(boolean selfChange) {
updateTareSettings();
public void onTareEnabledStateChanged(boolean isTareEnabled) {
updateTareSettings(isTareEnabled);
}
private void updateTareSettings() {
private void updateTareSettings(boolean isTareEnabled) {
synchronized (mLock) {
final boolean isTareEnabled = Settings.Global.getInt(
getContext().getContentResolver(),
Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1;
if (USE_TARE_POLICY != isTareEnabled) {
USE_TARE_POLICY = isTareEnabled;
final boolean changed = mAlarmStore.updateAlarmDeliveries(alarm -> {

View File

@@ -43,7 +43,6 @@ import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -54,7 +53,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
@@ -118,6 +116,7 @@ import com.android.server.job.controllers.TimeController;
import com.android.server.job.restrictions.JobRestriction;
import com.android.server.job.restrictions.ThermalStatusRestriction;
import com.android.server.pm.UserManagerInternal;
import com.android.server.tare.EconomyManagerInternal;
import com.android.server.usage.AppStandbyInternal;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import com.android.server.utils.quota.Categorizer;
@@ -356,40 +355,21 @@ public class JobSchedulerService extends com.android.server.SystemService
// (ScheduledJobStateChanged and JobStatusDumpProto).
public static final int RESTRICTED_INDEX = 5;
private class ConstantsObserver extends ContentObserver
implements DeviceConfig.OnPropertiesChangedListener {
private final ContentResolver mContentResolver;
ConstantsObserver(Handler handler, Context context) {
super(handler);
mContentResolver = context.getContentResolver();
}
private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener,
EconomyManagerInternal.TareStateChangeListener {
public void start() {
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
JobSchedulerBackgroundThread.getExecutor(), this);
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
final EconomyManagerInternal economyManagerInternal =
LocalServices.getService(EconomyManagerInternal.class);
economyManagerInternal.registerTareStateChangeListener(this);
// Load all the constants.
synchronized (mLock) {
mConstants.updateSettingsConstantsLocked(mContentResolver);
mConstants.updateTareSettingsLocked(economyManagerInternal.isEnabled());
}
onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER));
}
@Override
public void onChange(boolean selfChange) {
synchronized (mLock) {
if (mConstants.updateSettingsConstantsLocked(mContentResolver)) {
for (int controller = 0; controller < mControllers.size(); controller++) {
final StateController sc = mControllers.get(controller);
sc.onConstantsUpdatedLocked();
}
onControllerStateChanged(null);
}
}
}
@Override
public void onPropertiesChanged(DeviceConfig.Properties properties) {
boolean apiQuotaScheduleUpdated = false;
@@ -465,6 +445,17 @@ public class JobSchedulerService extends com.android.server.SystemService
}
}
}
@Override
public void onTareEnabledStateChanged(boolean isTareEnabled) {
if (mConstants.updateTareSettingsLocked(isTareEnabled)) {
for (int controller = 0; controller < mControllers.size(); controller++) {
final StateController sc = mControllers.get(controller);
sc.onConstantsUpdatedLocked();
}
onControllerStateChanged(null);
}
}
}
@VisibleForTesting
@@ -719,10 +710,8 @@ public class JobSchedulerService extends com.android.server.SystemService
DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS));
}
private boolean updateSettingsConstantsLocked(ContentResolver contentResolver) {
private boolean updateTareSettingsLocked(boolean isTareEnabled) {
boolean changed = false;
final boolean isTareEnabled = Settings.Global.getInt(contentResolver,
Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1;
if (USE_TARE_POLICY != isTareEnabled) {
USE_TARE_POLICY = isTareEnabled;
changed = true;
@@ -1673,7 +1662,7 @@ public class JobSchedulerService extends com.android.server.SystemService
mHandler = new JobHandler(context.getMainLooper());
mConstants = new Constants();
mConstantsObserver = new ConstantsObserver(mHandler, context);
mConstantsObserver = new ConstantsObserver();
mJobSchedulerStub = new JobSchedulerStub();
mConcurrencyManager = new JobConcurrencyManager(this);

View File

@@ -119,6 +119,11 @@ public interface EconomyManagerInternal {
boolean canAfford);
}
/** Listener for various TARE state changes. */
interface TareStateChangeListener {
void onTareEnabledStateChanged(boolean isTareEnabled);
}
/**
* Return {@code true} if the app is able to pay for the anticipated actions.
*/
@@ -130,6 +135,9 @@ public interface EconomyManagerInternal {
*/
long getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill);
/** Returns true if TARE is enabled. */
boolean isEnabled();
/**
* Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the
* indicated bill changes.
@@ -144,6 +152,16 @@ public interface EconomyManagerInternal {
void unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName,
@NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill);
/**
* Register a {@link TareStateChangeListener} to track when TARE's state changes.
*/
void registerTareStateChangeListener(@NonNull TareStateChangeListener listener);
/**
* Unregister a {@link TareStateChangeListener} from being notified when TARE's state changes.
*/
void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener);
/**
* Note that an instantaneous event has occurred. The event must be specified in one of the
* EconomicPolicies.

View File

@@ -53,6 +53,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
@@ -68,11 +69,13 @@ import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.tare.EconomyManagerInternal.TareStateChangeListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Responsible for handling app's ARC count based on events, ensuring ARCs are credited when
@@ -169,6 +172,9 @@ public class InternalResourceService extends SystemService {
@GuardedBy("mPackageToUidCache")
private final SparseArrayMap<String, Integer> mPackageToUidCache = new SparseArrayMap<>();
private final CopyOnWriteArraySet<TareStateChangeListener> mStateChangeListeners =
new CopyOnWriteArraySet<>();
/** List of packages that are "exempted" from battery restrictions. */
// TODO(144864180): include userID
@GuardedBy("mLock")
@@ -261,6 +267,7 @@ public class InternalResourceService extends SystemService {
private static final int MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT = 1;
private static final int MSG_PROCESS_USAGE_EVENT = 2;
private static final int MSG_MAYBE_FORCE_RECLAIM = 3;
private static final int MSG_NOTIFY_STATE_CHANGE_LISTENERS = 4;
private static final String ALARM_TAG_WEALTH_RECLAMATION = "*tare.reclamation*";
/**
@@ -802,6 +809,13 @@ public class InternalResourceService extends SystemService {
}
break;
case MSG_NOTIFY_STATE_CHANGE_LISTENERS: {
for (TareStateChangeListener listener : mStateChangeListeners) {
listener.onTareEnabledStateChanged(mIsEnabled);
}
}
break;
case MSG_PROCESS_USAGE_EVENT: {
final int userId = msg.arg1;
final UsageEvents.Event event = (UsageEvents.Event) msg.obj;
@@ -891,6 +905,16 @@ public class InternalResourceService extends SystemService {
}
}
@Override
public void registerTareStateChangeListener(@NonNull TareStateChangeListener listener) {
mStateChangeListeners.add(listener);
}
@Override
public void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener) {
mStateChangeListeners.remove(listener);
}
@Override
public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) {
if (!mIsEnabled) {
@@ -943,6 +967,11 @@ public class InternalResourceService extends SystemService {
}
}
@Override
public boolean isEnabled() {
return mIsEnabled;
}
@Override
public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
@Nullable String tag) {
@@ -980,7 +1009,10 @@ public class InternalResourceService extends SystemService {
}
}
private class ConfigObserver extends ContentObserver {
private class ConfigObserver extends ContentObserver
implements DeviceConfig.OnPropertiesChangedListener {
private static final String KEY_DC_ENABLE_TARE = "enable_tare";
private final ContentResolver mContentResolver;
ConfigObserver(Handler handler, Context context) {
@@ -989,12 +1021,15 @@ public class InternalResourceService extends SystemService {
}
public void start() {
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_TARE,
TareHandlerThread.getExecutor(), this);
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this);
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this);
onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TARE));
updateEnabledStatus();
}
@@ -1008,9 +1043,31 @@ public class InternalResourceService extends SystemService {
}
}
@Override
public void onPropertiesChanged(DeviceConfig.Properties properties) {
synchronized (mLock) {
for (String name : properties.getKeyset()) {
if (name == null) {
continue;
}
switch (name) {
case KEY_DC_ENABLE_TARE:
updateEnabledStatus();
break;
}
}
}
}
private void updateEnabledStatus() {
// User setting should override DeviceConfig setting.
// NOTE: There's currently no way for a user to reset the value (via UI), so if a user
// manually toggles TARE via UI, we'll always defer to the user's current setting
// TODO: add a "reset" value if the user toggle is an issue
final boolean isTareEnabledDC = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TARE,
KEY_DC_ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE == 1);
final boolean isTareEnabled = Settings.Global.getInt(mContentResolver,
Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1;
Settings.Global.ENABLE_TARE, isTareEnabledDC ? 1 : 0) == 1;
if (mIsEnabled != isTareEnabled) {
mIsEnabled = isTareEnabled;
if (mIsEnabled) {
@@ -1018,6 +1075,7 @@ public class InternalResourceService extends SystemService {
} else {
tearDownEverything();
}
mHandler.sendEmptyMessage(MSG_NOTIFY_STATE_CHANGE_LISTENERS);
}
}

View File

@@ -17,10 +17,13 @@
package com.android.server.tare;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Trace;
import java.util.concurrent.Executor;
/**
* Singleton thread for all of TARE.
*
@@ -29,6 +32,7 @@ import android.os.Trace;
final class TareHandlerThread extends HandlerThread {
private static TareHandlerThread sInstance;
private static Executor sHandlerExecutor;
private static Handler sHandler;
private TareHandlerThread() {
@@ -42,6 +46,7 @@ final class TareHandlerThread extends HandlerThread {
final Looper looper = sInstance.getLooper();
looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
sHandler = new Handler(sInstance.getLooper());
sHandlerExecutor = new HandlerExecutor(sHandler);
}
}
@@ -52,6 +57,14 @@ final class TareHandlerThread extends HandlerThread {
return sInstance;
}
/** Returns the singleton handler executor for TareHandlerThread */
public static Executor getExecutor() {
synchronized (TareHandlerThread.class) {
ensureThreadLocked();
return sHandlerExecutor;
}
}
/** Returns the singleton handler for TareHandlerThread. */
public static Handler getHandler() {
synchronized (TareHandlerThread.class) {

View File

@@ -621,12 +621,8 @@ public class AlarmManagerServiceTest {
}
private void setTareEnabled(boolean enabled) {
doReturn(enabled ? 1 : 0).when(
() -> Settings.Global.getInt(mContentResolver, Settings.Global.ENABLE_TARE));
doReturn(enabled ? 1 : 0).when(
() -> Settings.Global.getInt(mContentResolver,
Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE));
mService.mConstants.onChange(true);
when(mEconomyManagerInternal.isEnabled()).thenReturn(enabled);
mService.mConstants.onTareEnabledStateChanged(enabled);
}
/**