CachedAppOptimizer: ensure binder is never frozen with app unfrozen
Unfreezing a binder interface after the app, as well as freezing it before the app, opens a time window during wich the process is active and yet synchrnous binder transactions would fail. Unfreeze binder before the app, and similarly freeze it after freezing, to ensure consistent states. Bug: b/171239744 Test: verified correct working of the sequence by manually sending synchronous messages during the critical intervals. Change-Id: I5fad4cdf497a567aceb15b1fc3025b049c54983e
This commit is contained in:
@@ -776,6 +776,17 @@ public final class CachedAppOptimizer {
|
||||
|
||||
long freezeTime = app.freezeUnfreezeTime;
|
||||
|
||||
try {
|
||||
freezeBinder(app.pid, false);
|
||||
} catch (RuntimeException e) {
|
||||
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;
|
||||
}
|
||||
|
||||
try {
|
||||
Process.setProcessFrozen(app.pid, app.uid, false);
|
||||
|
||||
@@ -783,21 +794,10 @@ public final class CachedAppOptimizer {
|
||||
app.frozen = false;
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG_AM, "Unable to unfreeze " + app.pid + " " + app.processName
|
||||
+ ". Any related user experience might be hanged.");
|
||||
+ ". This might cause inconsistency or UI hangs.");
|
||||
}
|
||||
|
||||
if (!app.frozen) {
|
||||
try {
|
||||
freezeBinder(app.pid, false);
|
||||
} catch (RuntimeException e) {
|
||||
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) {
|
||||
Slog.d(TAG_AM, "sync unfroze " + app.pid + " " + app.processName);
|
||||
}
|
||||
@@ -1110,14 +1110,6 @@ 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
|
||||
@@ -1146,6 +1138,15 @@ public final class CachedAppOptimizer {
|
||||
|
||||
EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);
|
||||
|
||||
try {
|
||||
freezeBinder(pid, true);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
|
||||
proc.kill("Unable to freeze binder interface",
|
||||
ApplicationExitInfo.REASON_OTHER,
|
||||
ApplicationExitInfo.SUBREASON_INVALID_STATE, true);
|
||||
}
|
||||
|
||||
// See above for why we're not taking mPhenotypeFlagLock here
|
||||
if (mRandom.nextFloat() < mFreezerStatsdSampleRate) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.APP_FREEZE_CHANGED,
|
||||
|
||||
Reference in New Issue
Block a user