Merge "Treat IME processes as hosting activities"

This commit is contained in:
Dianne Hackborn
2014-03-18 16:50:24 +00:00
committed by Android (Google) Code Review
5 changed files with 54 additions and 14 deletions

View File

@@ -241,6 +241,16 @@ public abstract class Context {
*/
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
/**
* @hide Flag for {@link #bindService}: Treat the binding as hosting
* an activity, an unbinding as the activity going in the background.
* That is, when unbinding, the process when empty will go on the activity
* LRU list instead of the regular one, keeping it around more aggressively
* than it otherwise would be. This is intended for use with IMEs to try
* to keep IME processes around for faster keyboard switching.
*/
public static final int BIND_TREAT_LIKE_ACTIVITY = 0x08000000;
/**
* @hide An idea that is not yet implemented.
* Flag for {@link #bindService}: If binding from an activity, consider

View File

@@ -1225,7 +1225,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
if (bindCurrentInputMethodService(mCurIntent, this, Context.BIND_AUTO_CREATE
| Context.BIND_NOT_VISIBLE | Context.BIND_SHOWING_UI)) {
| Context.BIND_NOT_VISIBLE | Context.BIND_NOT_FOREGROUND
| Context.BIND_SHOWING_UI)) {
mLastBindTime = SystemClock.uptimeMillis();
mHaveConnection = true;
mCurId = info.getId();
@@ -1783,7 +1784,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mInputShown = true;
if (mHaveConnection && !mVisibleBound) {
bindCurrentInputMethodService(
mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE);
mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE
| Context.BIND_TREAT_LIKE_ACTIVITY);
mVisibleBound = true;
}
res = true;

View File

@@ -667,8 +667,7 @@ public final class ActiveServices {
// what they are, so we can report this elsewhere for
// others to know why certain services are running.
try {
clientIntent = (PendingIntent)service.getParcelableExtra(
Intent.EXTRA_CLIENT_INTENT);
clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
} catch (RuntimeException e) {
}
if (clientIntent != null) {
@@ -682,6 +681,11 @@ public final class ActiveServices {
}
}
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
"BIND_TREAT_LIKE_ACTIVITY");
}
final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
ServiceLookupResult res =
@@ -755,8 +759,12 @@ public final class ActiveServices {
}
if (s.app != null) {
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
s.app.treatLikeActivity = true;
}
// This could have made the service more important.
mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
|| s.app.treatLikeActivity, b.client);
mAm.updateOomAdjLocked(s.app);
}
@@ -858,6 +866,12 @@ public final class ActiveServices {
if (r.binding.service.app != null) {
// This could have made the service less important.
if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
r.binding.service.app.treatLikeActivity = true;
mAm.updateLruProcessLocked(r.binding.service.app,
r.binding.service.app.hasClientActivities
|| r.binding.service.app.treatLikeActivity, null);
}
mAm.updateOomAdjLocked(r.binding.service.app);
}
}

View File

@@ -2314,11 +2314,12 @@ public final class ActivityManagerService extends ActivityManagerNative
final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
ProcessRecord client) {
final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
|| app.treatLikeActivity;
final boolean hasService = false; // not impl yet. app.services.size() > 0;
if (!activityChange && hasActivity) {
// The process has activties, so we are only going to allow activity-based
// adjustments move it. It should be kept in the front of the list with other
// The process has activities, so we are only allowing activity-based adjustments
// to move it. It should be kept in the front of the list with other
// processes that have activities, and we don't want those to change their
// order except due to activity operations.
return;
@@ -12571,6 +12572,7 @@ public final class ActivityManagerService extends ActivityManagerNative
updateProcessForegroundLocked(app, false, false);
app.foregroundActivities = false;
app.hasShownUi = false;
app.treatLikeActivity = false;
app.hasAboveClient = false;
mServices.killServicesLocked(app, allowRestart);
@@ -14862,6 +14864,9 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjTarget = s.name;
}
}
if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
app.treatLikeActivity = true;
}
final ActivityRecord a = cr.activity;
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
@@ -14994,10 +14999,17 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
// This is a cached process, but with client activities. Mark it so.
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
app.adjType = "cch-client-act";
if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
if (app.hasClientActivities) {
// This is a cached process, but with client activities. Mark it so.
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
app.adjType = "cch-client-act";
} else if (app.treatLikeActivity) {
// This is a cached process, but somebody wants us to treat it like it has
// an activity, okay!
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
app.adjType = "cch-as-act";
}
}
if (adj == ProcessList.SERVICE_ADJ) {

View File

@@ -95,6 +95,7 @@ final class ProcessRecord {
boolean hasShownUi; // Has UI been shown in this process since it was started?
boolean pendingUiClean; // Want to clean up resources from showing UI?
boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower
boolean treatLikeActivity; // Bound using BIND_TREAT_LIKE_ACTIVITY
boolean bad; // True if disabled in the bad process list
boolean killedByAm; // True when proc has been killed by activity manager, not for RAM
boolean procStateChanged; // Keep track of whether we changed 'setAdj'.
@@ -251,10 +252,11 @@ final class ProcessRecord {
pw.print(" lastStateTime=");
TimeUtils.formatDuration(lastStateTime, now, pw);
pw.println();
if (hasShownUi || pendingUiClean || hasAboveClient) {
if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
pw.print(" pendingUiClean="); pw.print(pendingUiClean);
pw.print(" hasAboveClient="); pw.println(hasAboveClient);
pw.print(" hasAboveClient="); pw.print(hasAboveClient);
pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
}
if (setIsForeground || foregroundServices || forcingToForeground != null) {
pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);