Add some new experiment constants for activity and power manager.
Activity manager now has constants, starting with two: bg check
and process limit.
Power manager now has constants, starting with one: controlling
disabling of wake locks from cached processes.
Test: manual
Change-Id: I05db42e2104e9d31584f85251412df2d5efb34b6
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 71b9482..9360778 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -58,6 +58,7 @@
import android.os.LocaleList;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.speech.tts.TextToSpeech;
@@ -162,13 +163,13 @@
* In some cases, a matching Activity may not exist, so ensure you
* safeguard against this.
* <p>
- * Input: {@link ConnectivityManager.EXTRA_TETHER_TYPE} should be included to specify which type
- * of tethering should be checked. {@link ConnectivityManager.EXTRA_PROVISION_CALLBACK} should
+ * Input: {@link ConnectivityManager#EXTRA_TETHER_TYPE} should be included to specify which type
+ * of tethering should be checked. {@link ConnectivityManager#EXTRA_PROVISION_CALLBACK} should
* contain a {@link ResultReceiver} which will be called back with a tether result code.
* <p>
* Output: The result of the provisioning check.
- * {@link ConnectivityManager.TETHER_ERROR_NO_ERROR} if successful,
- * {@link ConnectivityManager.TETHER_ERROR_PROVISION_FAILED} for failure.
+ * {@link ConnectivityManager#TETHER_ERROR_NO_ERROR} if successful,
+ * {@link ConnectivityManager#TETHER_ERROR_PROVISION_FAILED} for failure.
*
* @hide
*/
@@ -8742,6 +8743,26 @@
BLUETOOTH_PAN_PRIORITY_PREFIX = "bluetooth_pan_priority_";
/**
+ * Activity manager specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "enforce_bg_check=true,max_cached_processes=24"
+ *
+ * The following keys are supported:
+ *
+ * <pre>
+ * enforce_bg_check (boolean)
+ * max_cached_processes (int)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * @hide
+ * @see com.android.server.am.ActivityManagerConstants
+ */
+ public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants";
+
+ /**
* Device Idle (Doze) specific settings.
* This is encoded as a key=value list, separated by commas. Ex:
*
@@ -8807,6 +8828,25 @@
public static final String APP_IDLE_CONSTANTS = "app_idle_constants";
/**
+ * Power manager specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "no_cached_wake_locks=1"
+ *
+ * The following keys are supported:
+ *
+ * <pre>
+ * no_cached_wake_locks (boolean)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * @hide
+ * @see com.android.server.power.PowerManagerConstants
+ */
+ public static final String POWER_MANAGER_CONSTANTS = "power_manager_constants";
+
+ /**
* Alarm manager specific settings.
* This is encoded as a key=value list, separated by commas. Ex:
*
@@ -9355,7 +9395,7 @@
/**
* WFC mode on roaming network.
* <p>
- * Type: int - see {@link WFC_IMS_MODE} for values
+ * Type: int - see {@link #WFC_IMS_MODE} for values
*
* @hide
*/
diff --git a/core/java/android/util/KeyValueListParser.java b/core/java/android/util/KeyValueListParser.java
index e4c025d..be531ff 100644
--- a/core/java/android/util/KeyValueListParser.java
+++ b/core/java/android/util/KeyValueListParser.java
@@ -129,4 +129,22 @@
}
return def;
}
+
+ /**
+ * Get the value for key as a boolean.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found.
+ * @return the string value associated with the key.
+ */
+ public boolean getBoolean(String key, boolean def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ return Boolean.parseBoolean(value);
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 0e07ec0..b1560e6 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -275,7 +275,7 @@
} catch (IllegalArgumentException e) {
// Failed to parse the settings string, log this and move on
// with defaults.
- Slog.e(TAG, "Bad device idle settings", e);
+ Slog.e(TAG, "Bad alarm manager settings", e);
}
MIN_FUTURITY = mParser.getLong(KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY);
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
new file mode 100644
index 0000000..3c90f93
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.KeyValueListParser;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+
+/**
+ * Settings constants that can modify the activity manager's behavior.
+ */
+final class ActivityManagerConstants extends ContentObserver {
+ // Key names stored in the settings value.
+ private static final String KEY_ENFORCE_BG_CHECK = "enforce_bg_check";
+ private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes";
+
+ private static final boolean DEFAULT_ENFORCE_BG_CHECK = SystemProperties.getBoolean(
+ "debug.bgcheck", false);
+ private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
+
+ // Enforce background check on apps targeting O?
+ public boolean ENFORCE_BG_CHECK = DEFAULT_ENFORCE_BG_CHECK;
+
+ // Maximum number of cached processes we will allow.
+ public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
+
+ private final ActivityManagerService mService;
+ private ContentResolver mResolver;
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+
+ private int mOverrideMaxCachedProcesses = -1;
+
+ // The maximum number of cached processes we will keep around before killing them.
+ // NOTE: this constant is *only* a control to not let us go too crazy with
+ // keeping around processes on devices with large amounts of RAM. For devices that
+ // are tighter on RAM, the out of memory killer is responsible for killing background
+ // processes as RAM is needed, and we should *never* be relying on this limit to
+ // kill them. Also note that this limit only applies to cached background processes;
+ // we have no limit on the number of service, visible, foreground, or other such
+ // processes and the number of those processes does not count against the cached
+ // process limit.
+ public int CUR_MAX_CACHED_PROCESSES;
+
+ // The maximum number of empty app processes we will let sit around.
+ public int CUR_MAX_EMPTY_PROCESSES;
+
+ // The number of empty apps at which we don't consider it necessary to do
+ // memory trimming.
+ public int CUR_TRIM_EMPTY_PROCESSES;
+
+ // The number of cached at which we don't consider it necessary to do
+ // memory trimming.
+ public int CUR_TRIM_CACHED_PROCESSES;
+
+ public ActivityManagerConstants(ActivityManagerService service, Handler handler) {
+ super(handler);
+ mService = service;
+ updateMaxCachedProcesses();
+ }
+
+ public void start(ContentResolver resolver) {
+ mResolver = resolver;
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS), false, this);
+ updateConstants();
+ }
+
+ public void setOverrideMaxCachedProcesses(int value) {
+ mOverrideMaxCachedProcesses = value;
+ updateMaxCachedProcesses();
+ }
+
+ public int getOverrideMaxCachedProcesses() {
+ return mOverrideMaxCachedProcesses;
+ }
+
+ public static int computeEmptyProcessLimit(int totalProcessLimit) {
+ return totalProcessLimit/2;
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updateConstants();
+ }
+
+ private void updateConstants() {
+ synchronized (mService) {
+ try {
+ mParser.setString(Settings.Global.getString(mResolver,
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS));
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on
+ // with defaults.
+ Slog.e("ActivityManagerConstants", "Bad activity manager config settings", e);
+ }
+
+ ENFORCE_BG_CHECK = mParser.getBoolean(KEY_ENFORCE_BG_CHECK, DEFAULT_ENFORCE_BG_CHECK);
+ MAX_CACHED_PROCESSES = mParser.getInt(KEY_MAX_CACHED_PROCESSES,
+ DEFAULT_MAX_CACHED_PROCESSES);
+ updateMaxCachedProcesses();
+ }
+ }
+
+ private void updateMaxCachedProcesses() {
+ CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0
+ ? MAX_CACHED_PROCESSES : mOverrideMaxCachedProcesses;
+ CUR_MAX_EMPTY_PROCESSES = computeEmptyProcessLimit(CUR_MAX_CACHED_PROCESSES);
+
+ // Note the trim levels do NOT depend on the override process limit, we want
+ // to consider the same level the point where we do trimming regardless of any
+ // additional enforced limit.
+ final int rawMaxEmptyProcesses = computeEmptyProcessLimit(MAX_CACHED_PROCESSES);
+ CUR_TRIM_EMPTY_PROCESSES = rawMaxEmptyProcesses/2;
+ CUR_TRIM_CACHED_PROCESSES = (MAX_CACHED_PROCESSES-rawMaxEmptyProcesses)/3;
+ }
+
+ void dump(PrintWriter pw) {
+ pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
+ + Settings.Global.ACTIVITY_MANAGER_CONSTANTS + ":");
+
+ pw.print(" "); pw.print(KEY_ENFORCE_BG_CHECK); pw.print("=");
+ pw.println(ENFORCE_BG_CHECK);
+
+ pw.print(" "); pw.print(KEY_MAX_CACHED_PROCESSES); pw.print("=");
+ pw.println(MAX_CACHED_PROCESSES);
+
+ pw.println();
+ if (mOverrideMaxCachedProcesses >= 0) {
+ pw.print(" mOverrideMaxCachedProcesses="); pw.println(mOverrideMaxCachedProcesses);
+ }
+ pw.print(" CUR_MAX_CACHED_PROCESSES="); pw.println(CUR_MAX_CACHED_PROCESSES);
+ pw.print(" CUR_MAX_EMPTY_PROCESSES="); pw.println(CUR_MAX_EMPTY_PROCESSES);
+ pw.print(" CUR_TRIM_EMPTY_PROCESSES="); pw.println(CUR_TRIM_EMPTY_PROCESSES);
+ pw.print(" CUR_TRIM_CACHED_PROCESSES="); pw.println(CUR_TRIM_CACHED_PROCESSES);
+ }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e9fc0bb..34ebaa2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -761,11 +761,6 @@
ProcessRecord mHeavyWeightProcess = null;
/**
- * Are we enforcing background restrictions?
- */
- final boolean mEnforceBackgroundCheck;
-
- /**
* Non-persistent app uid whitelist for background restrictions
*/
int[] mBackgroundUidWhitelist = new int[] {
@@ -1515,9 +1510,6 @@
*/
boolean mBooted = false;
- int mProcessLimit = ProcessList.MAX_CACHED_APPS;
- int mProcessLimitOverride = -1;
-
WindowManagerService mWindowManager;
final ActivityThread mSystemThread;
@@ -1639,6 +1631,8 @@
final MainHandler mHandler;
final UiHandler mUiHandler;
+ final ActivityManagerConstants mConstants;
+
PackageManagerInternal mPackageManagerInt;
// VoiceInteraction session ID that changes for each new request except when
@@ -2620,10 +2614,9 @@
mPermissionReviewRequired = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_permissionReviewRequired);
- mEnforceBackgroundCheck = SystemProperties.getBoolean("debug.bgcheck", false);
mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
if (DEBUG_BACKGROUND_CHECK) {
- Slog.d(TAG, "Enforcing O+ bg restrictions: " + mEnforceBackgroundCheck);
+ Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK);
StringBuilder sb = new StringBuilder(200);
sb.append(" ");
for (String a : mBackgroundLaunchBroadcasts) {
@@ -2639,6 +2632,8 @@
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = new UiHandler();
+ mConstants = new ActivityManagerConstants(this, mHandler);
+
/* static; one-time init here */
if (sKillHandler == null) {
sKillThread = new ServiceThread(TAG + ":kill",
@@ -7276,9 +7271,6 @@
/**
* Whitelists {@code targetUid} to temporarily bypass Power Save mode.
- *
- * <p>{@code callerUid} must be allowed to request such whitelist by calling
- * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
*/
void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
if (DEBUG_WHITELISTS) {
@@ -7470,8 +7462,7 @@
enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
"setProcessLimit()");
synchronized (this) {
- mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
- mProcessLimitOverride = max;
+ mConstants.setOverrideMaxCachedProcesses(max);
}
trimApplications();
}
@@ -7479,7 +7470,7 @@
@Override
public int getProcessLimit() {
synchronized (this) {
- return mProcessLimitOverride;
+ return mConstants.getOverrideMaxCachedProcesses();
}
}
@@ -8036,7 +8027,7 @@
// Unified app-op and target sdk check
int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
// Apps that target O+ are always subject to background check
- if (mEnforceBackgroundCheck && packageTargetSdk >= Build.VERSION_CODES.O) {
+ if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) {
if (DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
}
@@ -11559,6 +11550,7 @@
mSystemThread.installSystemProviders(providers);
}
+ mConstants.start(mContext.getContentResolver());
mCoreSettingsObserver = new CoreSettingsObserver(this);
mFontScaleSettingObserver = new FontScaleSettingObserver();
@@ -14496,6 +14488,10 @@
synchronized (this) {
dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
}
+ } else if ("settings".equals(cmd)) {
+ synchronized (this) {
+ mConstants.dump(pw);
+ }
} else if ("services".equals(cmd) || "s".equals(cmd)) {
if (dumpClient) {
ActiveServices.ServiceDumper dumper;
@@ -14536,6 +14532,11 @@
} else if (dumpClient) {
ActiveServices.ServiceDumper sdumper;
synchronized (this) {
+ mConstants.dump(pw);
+ pw.println();
+ if (dumpAll) {
+ pw.println("-------------------------------------------------------------------------------");
+ }
dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
pw.println();
if (dumpAll) {
@@ -14594,6 +14595,11 @@
} else {
synchronized (this) {
+ mConstants.dump(pw);
+ pw.println();
+ if (dumpAll) {
+ pw.println("-------------------------------------------------------------------------------");
+ }
dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
pw.println();
if (dumpAll) {
@@ -21393,17 +21399,8 @@
mNewNumServiceProcs = 0;
mNewNumAServiceProcs = 0;
- final int emptyProcessLimit;
- final int cachedProcessLimit;
- if (mProcessLimit <= 0) {
- emptyProcessLimit = cachedProcessLimit = 0;
- } else if (mProcessLimit == 1) {
- emptyProcessLimit = 1;
- cachedProcessLimit = 0;
- } else {
- emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
- cachedProcessLimit = mProcessLimit - emptyProcessLimit;
- }
+ final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
+ final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
// Let's determine how many processes we have running vs.
// how many slots we have for background processes; we may want
@@ -21511,7 +21508,7 @@
}
break;
case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
- if (numEmpty > ProcessList.TRIM_EMPTY_APPS
+ if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
&& app.lastActivityTime < oldTime) {
app.kill("empty for "
+ ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
@@ -21564,8 +21561,8 @@
// memory they want.
final int numCachedAndEmpty = numCached + numEmpty;
int memFactor;
- if (numCached <= ProcessList.TRIM_CACHED_APPS
- && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
+ if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
+ && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
} else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 202868a..24eb267 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2378,6 +2378,7 @@
pw.println(" provider [COMP_SPEC]: provider client-side state");
pw.println(" s[ervices] [COMP_SPEC ...]: service state");
pw.println(" as[sociations]: tracked app associations");
+ pw.println(" settings: currently applied config settings");
pw.println(" service [COMP_SPEC]: service client-side state");
pw.println(" package [PACKAGE_NAME]: all state related to given package");
pw.println(" all: dump all activities");
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 1322ecf..40effff 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -138,31 +138,9 @@
// without empty apps being able to push them out of memory.
static final int MIN_CACHED_APPS = 2;
- // The maximum number of cached processes we will keep around before killing them.
- // NOTE: this constant is *only* a control to not let us go too crazy with
- // keeping around processes on devices with large amounts of RAM. For devices that
- // are tighter on RAM, the out of memory killer is responsible for killing background
- // processes as RAM is needed, and we should *never* be relying on this limit to
- // kill them. Also note that this limit only applies to cached background processes;
- // we have no limit on the number of service, visible, foreground, or other such
- // processes and the number of those processes does not count against the cached
- // process limit.
- static final int MAX_CACHED_APPS = 32;
-
// We allow empty processes to stick around for at most 30 minutes.
static final long MAX_EMPTY_TIME = 30*60*1000;
- // The maximum number of empty app processes we will let sit around.
- private static final int MAX_EMPTY_APPS = computeEmptyProcessLimit(MAX_CACHED_APPS);
-
- // The number of empty apps at which we don't consider it necessary to do
- // memory trimming.
- static final int TRIM_EMPTY_APPS = MAX_EMPTY_APPS/2;
-
- // The number of cached at which we don't consider it necessary to do
- // memory trimming.
- static final int TRIM_CACHED_APPS = (MAX_CACHED_APPS-MAX_EMPTY_APPS)/3;
-
// Threshold of number of cached+empty where we consider memory critical.
static final int TRIM_CRITICAL_THRESHOLD = 3;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index e1b6c87..238866a 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -57,6 +57,7 @@
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.EventLog;
+import android.util.KeyValueListParser;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Slog;
@@ -522,6 +523,65 @@
// True if we are currently in VR Mode.
private boolean mIsVrModeEnabled;
+ /**
+ * All times are in milliseconds. These constants are kept synchronized with the system
+ * global Settings. Any access to this class or its fields should be done while
+ * holding the PowerManagerService.mLock lock.
+ */
+ private final class Constants extends ContentObserver {
+ // Key names stored in the settings value.
+ private static final String KEY_NO_CACHED_WAKE_LOCKS = "no_cached_wake_locks";
+
+ private static final boolean DEFAULT_NO_CACHED_WAKE_LOCKS = true;
+
+ // Prevent processes that are cached from holding wake locks?
+ public boolean NO_CACHED_WAKE_LOCKS = DEFAULT_NO_CACHED_WAKE_LOCKS;
+
+ private ContentResolver mResolver;
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+
+ public Constants(Handler handler) {
+ super(handler);
+ }
+
+ public void start(ContentResolver resolver) {
+ mResolver = resolver;
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.POWER_MANAGER_CONSTANTS), false, this);
+ updateConstants();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updateConstants();
+ }
+
+ private void updateConstants() {
+ synchronized (mLock) {
+ try {
+ mParser.setString(Settings.Global.getString(mResolver,
+ Settings.Global.POWER_MANAGER_CONSTANTS));
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on
+ // with defaults.
+ Slog.e(TAG, "Bad alarm manager settings", e);
+ }
+
+ NO_CACHED_WAKE_LOCKS = mParser.getBoolean(KEY_NO_CACHED_WAKE_LOCKS,
+ DEFAULT_NO_CACHED_WAKE_LOCKS);
+ }
+ }
+
+ void dump(PrintWriter pw) {
+ pw.println(" Settings " + Settings.Global.POWER_MANAGER_CONSTANTS + ":");
+
+ pw.print(" "); pw.print(KEY_NO_CACHED_WAKE_LOCKS); pw.print("=");
+ pw.println(NO_CACHED_WAKE_LOCKS);
+ }
+ }
+
+ final Constants mConstants;
+
private native void nativeInit();
private static native void nativeAcquireSuspendBlocker(String name);
@@ -538,6 +598,7 @@
Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
+ mConstants = new Constants(mHandler);
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
@@ -616,6 +677,9 @@
mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
mPolicy);
+ final ContentResolver resolver = mContext.getContentResolver();
+ mConstants.start(resolver);
+
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
mHandler);
@@ -629,7 +693,6 @@
mDisplayPowerCallbacks, mHandler, sensorManager);
// Register for settings changes.
- final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
false, mSettingsObserver, UserHandle.USER_ALL);
@@ -2795,7 +2858,7 @@
state.mProcState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
disabled = true;
}
- } else {
+ } else if (mConstants.NO_CACHED_WAKE_LOCKS) {
disabled = !wakeLock.mUidState.mActive &&
wakeLock.mUidState.mProcState
!= ActivityManager.PROCESS_STATE_NONEXISTENT &&
@@ -3005,6 +3068,7 @@
final WirelessChargerDetector wcd;
synchronized (mLock) {
pw.println("Power Manager State:");
+ mConstants.dump(pw);
pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
pw.println(" mWakefulness=" + PowerManagerInternal.wakefulnessToString(mWakefulness));
pw.println(" mWakefulnessChanging=" + mWakefulnessChanging);