summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java30
-rw-r--r--services/core/jni/com_android_server_am_CachedAppOptimizer.cpp10
2 files changed, 40 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index c5047e5eed03..966038986791 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -479,6 +479,21 @@ public final class CachedAppOptimizer {
private static native void enableFreezerInternal(boolean enable);
/**
+ * Informs binder that a process is about to be frozen. If freezer is enabled on a process via
+ * this method, this method will synchronously dispatch all pending transactions to the
+ * specified pid. This method will not add significant latencies when unfreezing.
+ * After freezing binder calls, binder will block all transaction to the frozen pid, and return
+ * an error to the sending process.
+ *
+ * @param pid the target pid for which binder transactions are to be frozen
+ * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze
+ * binder for the specificed pid.
+ *
+ * @throws RuntimeException in case a flush/freeze operation could not complete successfully.
+ */
+ private static native void freezeBinder(int pid, boolean freeze);
+
+ /**
* Determines whether the freezer is supported by this system
*/
public static boolean isFreezerSupported() {
@@ -727,6 +742,13 @@ public final class CachedAppOptimizer {
}
if (!app.frozen) {
+ 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);
+ }
+
if (DEBUG_FREEZER) {
Slog.d(TAG_AM, "sync unfroze " + app.pid + " " + app.processName);
}
@@ -1039,6 +1061,14 @@ public final class CachedAppOptimizer {
return;
}
+ try {
+ freezeBinder(pid, true);
+ } catch (RuntimeException e) {
+ // TODO: it might be preferable to kill the target pid in this case
+ Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
+ return;
+ }
+
if (pid == 0 || proc.frozen) {
// Already frozen or not a real process, either one being
// launched or one being killed
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 7e9e11d209a6..95d4ba7c199a 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -29,6 +29,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <binder/IPCThreadState.h>
#include <jni.h>
#include <processgroup/processgroup.h>
@@ -90,11 +91,20 @@ static void com_android_server_am_CachedAppOptimizer_enableFreezerInternal(
}
}
+static void com_android_server_am_CachedAppOptimizer_freezeBinder(
+ JNIEnv *env, jobject clazz, jint pid, jboolean freeze) {
+
+ if (IPCThreadState::freeze(pid, freeze, 100 /* timeout [ms] */) != 0) {
+ jniThrowException(env, "java/lang/RuntimeException", "Unable to freeze/unfreeze binder");
+ }
+}
+
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}
};
int register_android_server_am_CachedAppOptimizer(JNIEnv* env)