Merge changes from topic "cgroup v2 freezer frameworks" into rvc-qpr-dev am: 7176835583

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12392113

Change-Id: I2f87b8c3fb60848bf8e9266116ddccbf0eb68f30
This commit is contained in:
Marco Ballesio
2020-08-28 18:16:01 +00:00
committed by Automerger Merge Worker
7 changed files with 124 additions and 47 deletions

View File

@@ -684,4 +684,14 @@ interface IActivityManager {
* Kills uid with the reason of permission change.
*/
void killUidForPermissionChange(int appId, int userId, String reason);
/**
* Control the app freezer state. Returns true in case of success, false if the operation
* didn't succeed (for example, when the app freezer isn't supported).
* Handling the freezer state via this method is reentrant, that is it can be
* disabled and re-enabled multiple times in parallel. As long as there's a 1:1 disable to
* enable match, the freezer is re-enabled at last enable only.
* @param enable set it to true to enable the app freezer, false to disable it.
*/
boolean enableAppFreezer(in boolean enable);
}

View File

@@ -18,6 +18,7 @@ package android.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.util.Log;
import android.util.SparseIntArray;
@@ -255,7 +256,12 @@ public final class BinderProxy implements IBinder {
// out of system_server to all processes hosting binder objects it holds a reference to;
// since some of those processes might be frozen, we don't want to block here
// forever. Disable the freezer.
Process.enableFreezer(false);
try {
ActivityManager.getService().enableAppFreezer(false);
} catch (RemoteException e) {
Log.e(Binder.TAG, "RemoteException while disabling app freezer");
}
for (WeakReference<BinderProxy> weakRef : proxiesToQuery) {
BinderProxy bp = weakRef.get();
String key;
@@ -278,7 +284,11 @@ public final class BinderProxy implements IBinder {
counts.put(key, i + 1);
}
}
Process.enableFreezer(true);
try {
ActivityManager.getService().enableAppFreezer(true);
} catch (RemoteException e) {
Log.e(Binder.TAG, "RemoteException while re-enabling app freezer");
}
Map.Entry<String, Integer>[] sorted = counts.entrySet().toArray(
new Map.Entry[counts.size()]);

View File

@@ -346,22 +346,6 @@ void android_os_Process_setProcessFrozen(
}
}
void android_os_Process_enableFreezer(
JNIEnv *env, jobject clazz, jboolean enable)
{
bool success = true;
if (enable) {
success = SetTaskProfiles(0, {"FreezerEnabled"}, true);
} else {
success = SetTaskProfiles(0, {"FreezerDisabled"}, true);
}
if (!success) {
jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
}
}
jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid)
{
SchedPolicy sp;
@@ -1360,7 +1344,6 @@ static const JNINativeMethod methods[] = {
{"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
{"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},
{"setProcessFrozen", "(IIZ)V", (void*)android_os_Process_setProcessFrozen},
{"enableFreezer", "(Z)V", (void*)android_os_Process_enableFreezer},
{"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
{"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory},
{"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V",

View File

@@ -2218,17 +2218,13 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"meminfo", pw)) return;
PriorityDump.dump(mPriorityDumper, fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2242,17 +2238,13 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"gfxinfo", pw)) return;
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2266,17 +2258,13 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"dbinfo", pw)) return;
mActivityManagerService.dumpDbInfo(fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -2322,9 +2310,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"cacheinfo", pw)) {
@@ -2333,9 +2319,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mActivityManagerService.dumpBinderCacheContents(fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}
}
@@ -18630,14 +18614,14 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
Process.enableFreezer(false);
mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
final RemoteCallback intermediateCallback = new RemoteCallback(
new RemoteCallback.OnResultListener() {
@Override
public void onResult(Bundle result) {
finishCallback.sendResult(result);
Process.enableFreezer(true);
mOomAdjuster.mCachedAppOptimizer.enableFreezer(true);
}
}, null);
@@ -20399,4 +20383,16 @@ public class ActivityManagerService extends IActivityManager.Stub
Binder.restoreCallingIdentity(token);
}
}
@Override
public boolean enableAppFreezer(boolean enable) {
int callerUid = Binder.getCallingUid();
// Only system can toggle the freezer state
if (callerUid == SYSTEM_UID) {
return mOomAdjuster.mCachedAppOptimizer.enableFreezer(enable);
} else {
throw new SecurityException("Caller uid " + callerUid + " cannot set freezer state ");
}
}
}

View File

@@ -208,6 +208,8 @@ public final class CachedAppOptimizer {
@GuardedBy("mPhenotypeFlagLock")
private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION;
private volatile boolean mUseFreezer = DEFAULT_USE_FREEZER;
@GuardedBy("this")
private int mFreezerDisableCount = 1; // Freezer is initially disabled, until enabled
private final Random mRandom = new Random();
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting volatile float mCompactStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE;
@@ -419,6 +421,63 @@ public final class CachedAppOptimizer {
}
}
/**
* Enables or disabled the app freezer.
* @param enable Enables the freezer if true, disables it if false.
* @return true if the operation completed successfully, false otherwise.
*/
public synchronized boolean enableFreezer(boolean enable) {
if (!mUseFreezer) {
return false;
}
if (enable) {
mFreezerDisableCount--;
if (mFreezerDisableCount > 0) {
return true;
} else if (mFreezerDisableCount < 0) {
Slog.e(TAG_AM, "unbalanced call to enableFreezer, ignoring");
mFreezerDisableCount = 0;
return false;
}
} else {
mFreezerDisableCount++;
if (mFreezerDisableCount > 1) {
return true;
}
}
try {
enableFreezerInternal(enable);
return true;
} catch (java.lang.RuntimeException e) {
if (enable) {
mFreezerDisableCount = 0;
} else {
mFreezerDisableCount = 1;
}
Slog.e(TAG_AM, "Exception handling freezer state (enable: " + enable + "): "
+ e.toString());
}
return false;
}
/**
* Enable or disable the freezer. When enable == false all frozen processes are unfrozen,
* but aren't removed from the freezer. While in this state, processes can be added or removed
* by using Process.setProcessFrozen(), but they wouldn't be actually frozen until the freezer
* is enabled. If enable == true all processes in the freezer are frozen.
*
* @param enable Specify whether to enable (true) or disable (false) the freezer.
*
* @hide
*/
private static native void enableFreezerInternal(boolean enable);
/**
* Determines whether the freezer is supported by this system
*/
@@ -471,7 +530,7 @@ public final class CachedAppOptimizer {
if (mUseFreezer && mFreezeHandler == null) {
Slog.d(TAG_AM, "Freezer enabled");
Process.enableFreezer(true);
enableFreezer(true);
if (!mCachedAppOptimizerThread.isAlive()) {
mCachedAppOptimizerThread.start();
@@ -482,7 +541,7 @@ public final class CachedAppOptimizer {
Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
Process.THREAD_GROUP_SYSTEM);
} else {
Process.enableFreezer(false);
enableFreezer(false);
}
}

View File

@@ -105,6 +105,7 @@ cc_defaults {
"libkeystore_binder",
"libmtp",
"libnativehelper",
"libprocessgroup",
"libutils",
"libui",
"libinput",

View File

@@ -30,6 +30,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <jni.h>
#include <processgroup/processgroup.h>
using android::base::StringPrintf;
using android::base::WriteStringToFile;
@@ -74,9 +75,26 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job
}
}
static void com_android_server_am_CachedAppOptimizer_enableFreezerInternal(
JNIEnv *env, jobject clazz, jboolean enable) {
bool success = true;
if (enable) {
success = SetTaskProfiles(0, {"FreezerEnabled"}, true);
} else {
success = SetTaskProfiles(0, {"FreezerDisabled"}, true);
}
if (!success) {
jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
}
}
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
{"enableFreezerInternal", "(Z)V",
(void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal},
};
int register_android_server_am_CachedAppOptimizer(JNIEnv* env)