Merge "Allow enabling TARE via DeviceConfig."
This commit is contained in:
committed by
Android (Google) Code Review
commit
d52a578ac6
@@ -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 -> {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user