Loading services/core/java/com/android/server/am/CachedAppOptimizer.java +52 −3 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ApplicationExitInfo; import android.os.Debug; import android.os.Handler; import android.os.Message; Loading Loading @@ -132,11 +133,15 @@ public final class CachedAppOptimizer { static final int REPORT_UNFREEZE_MSG = 4; //TODO:change this static definition into a configurable flag. static final int FREEZE_TIMEOUT_MS = 500; static final int FREEZE_TIMEOUT_MS = 10000; static final int DO_FREEZE = 1; static final int REPORT_UNFREEZE = 2; // Bitfield values for sync/async transactions reveived by frozen processes static final int SYNC_RECEIVED_WHILE_FROZEN = 1; static final int ASYNC_RECEIVED_WHILE_FROZEN = 2; /** * This thread must be moved to the system background cpuset. * If that doesn't happen, it's probably going to draw a lot of power. Loading Loading @@ -493,6 +498,15 @@ public final class CachedAppOptimizer { */ private static native void freezeBinder(int pid, boolean freeze); /** * Retrieves binder freeze info about a process. * @param pid the pid for which binder freeze info is to be retrieved. * * @throws RuntimeException if the operation could not complete successfully. * @return a bit field reporting the binder freeze info for the process. */ private static native int getBinderFreezeInfo(int pid); /** * Determines whether the freezer is supported by this system */ Loading Loading @@ -729,6 +743,37 @@ public final class CachedAppOptimizer { return; } boolean processKilled = false; try { int freezeInfo = getBinderFreezeInfo(app.pid); if ((freezeInfo & SYNC_RECEIVED_WHILE_FROZEN) != 0) { Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + " received sync transactions while frozen, killing"); app.kill("Sync transaction while in frozen state", ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_INVALID_STATE, true); processKilled = true; } if ((freezeInfo & ASYNC_RECEIVED_WHILE_FROZEN) != 0) { Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + " received async transactions while frozen"); } } catch (Exception e) { Slog.d(TAG_AM, "Unable to query binder frozen info for pid " + app.pid + " " + app.processName + ". Killing it. Exception: " + e); app.kill("Unable to query binder frozen stats", ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_INVALID_STATE, true); processKilled = true; } if (processKilled) { return; } long freezeTime = app.freezeUnfreezeTime; try { Loading @@ -745,8 +790,12 @@ public final class CachedAppOptimizer { try { freezeBinder(app.pid, false); } catch (RuntimeException e) { // TODO: it might be preferable to kill the target pid in this case Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName); Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName + ". Killing it"); app.kill("Unable to unfreeze", ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_INVALID_STATE, true); return; } if (DEBUG_FREEZER) { Loading services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ using android::base::StringPrintf; using android::base::WriteStringToFile; #define SYNC_RECEIVED_WHILE_FROZEN (1) #define ASYNC_RECEIVED_WHILE_FROZEN (2) namespace android { // This performs per-process reclaim on all processes belonging to non-app UIDs. Loading Loading @@ -99,12 +102,37 @@ static void com_android_server_am_CachedAppOptimizer_freezeBinder( } } static jint com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo(JNIEnv *env, jobject clazz, jint pid) { bool syncReceived = false, asyncReceived = false; int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived); if (error < 0) { jniThrowException(env, "java/lang/RuntimeException", strerror(error)); } jint retVal = 0; if(syncReceived) { retVal |= SYNC_RECEIVED_WHILE_FROZEN;; } if(asyncReceived) { retVal |= ASYNC_RECEIVED_WHILE_FROZEN; } return retVal; } 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}, {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder} {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder}, {"getBinderFreezeInfo", "(I)I", (void*)com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo} }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) Loading Loading
services/core/java/com/android/server/am/CachedAppOptimizer.java +52 −3 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ApplicationExitInfo; import android.os.Debug; import android.os.Handler; import android.os.Message; Loading Loading @@ -132,11 +133,15 @@ public final class CachedAppOptimizer { static final int REPORT_UNFREEZE_MSG = 4; //TODO:change this static definition into a configurable flag. static final int FREEZE_TIMEOUT_MS = 500; static final int FREEZE_TIMEOUT_MS = 10000; static final int DO_FREEZE = 1; static final int REPORT_UNFREEZE = 2; // Bitfield values for sync/async transactions reveived by frozen processes static final int SYNC_RECEIVED_WHILE_FROZEN = 1; static final int ASYNC_RECEIVED_WHILE_FROZEN = 2; /** * This thread must be moved to the system background cpuset. * If that doesn't happen, it's probably going to draw a lot of power. Loading Loading @@ -493,6 +498,15 @@ public final class CachedAppOptimizer { */ private static native void freezeBinder(int pid, boolean freeze); /** * Retrieves binder freeze info about a process. * @param pid the pid for which binder freeze info is to be retrieved. * * @throws RuntimeException if the operation could not complete successfully. * @return a bit field reporting the binder freeze info for the process. */ private static native int getBinderFreezeInfo(int pid); /** * Determines whether the freezer is supported by this system */ Loading Loading @@ -729,6 +743,37 @@ public final class CachedAppOptimizer { return; } boolean processKilled = false; try { int freezeInfo = getBinderFreezeInfo(app.pid); if ((freezeInfo & SYNC_RECEIVED_WHILE_FROZEN) != 0) { Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + " received sync transactions while frozen, killing"); app.kill("Sync transaction while in frozen state", ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_INVALID_STATE, true); processKilled = true; } if ((freezeInfo & ASYNC_RECEIVED_WHILE_FROZEN) != 0) { Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + " received async transactions while frozen"); } } catch (Exception e) { Slog.d(TAG_AM, "Unable to query binder frozen info for pid " + app.pid + " " + app.processName + ". Killing it. Exception: " + e); app.kill("Unable to query binder frozen stats", ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_INVALID_STATE, true); processKilled = true; } if (processKilled) { return; } long freezeTime = app.freezeUnfreezeTime; try { Loading @@ -745,8 +790,12 @@ public final class CachedAppOptimizer { try { freezeBinder(app.pid, false); } catch (RuntimeException e) { // TODO: it might be preferable to kill the target pid in this case Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName); Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName + ". Killing it"); app.kill("Unable to unfreeze", ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_INVALID_STATE, true); return; } if (DEBUG_FREEZER) { Loading
services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ using android::base::StringPrintf; using android::base::WriteStringToFile; #define SYNC_RECEIVED_WHILE_FROZEN (1) #define ASYNC_RECEIVED_WHILE_FROZEN (2) namespace android { // This performs per-process reclaim on all processes belonging to non-app UIDs. Loading Loading @@ -99,12 +102,37 @@ static void com_android_server_am_CachedAppOptimizer_freezeBinder( } } static jint com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo(JNIEnv *env, jobject clazz, jint pid) { bool syncReceived = false, asyncReceived = false; int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived); if (error < 0) { jniThrowException(env, "java/lang/RuntimeException", strerror(error)); } jint retVal = 0; if(syncReceived) { retVal |= SYNC_RECEIVED_WHILE_FROZEN;; } if(asyncReceived) { retVal |= ASYNC_RECEIVED_WHILE_FROZEN; } return retVal; } 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}, {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder} {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder}, {"getBinderFreezeInfo", "(I)I", (void*)com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo} }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) Loading