Merge "Treat IME processes as hosting activities"
This commit is contained in:
committed by
Android (Google) Code Review
commit
e9ebd60fc4
@@ -241,6 +241,16 @@ public abstract class Context {
|
|||||||
*/
|
*/
|
||||||
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
|
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.
|
* @hide An idea that is not yet implemented.
|
||||||
* Flag for {@link #bindService}: If binding from an activity, consider
|
* Flag for {@link #bindService}: If binding from an activity, consider
|
||||||
|
|||||||
@@ -1225,7 +1225,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
|||||||
mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
|
mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
|
||||||
mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
|
mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
|
||||||
if (bindCurrentInputMethodService(mCurIntent, this, Context.BIND_AUTO_CREATE
|
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();
|
mLastBindTime = SystemClock.uptimeMillis();
|
||||||
mHaveConnection = true;
|
mHaveConnection = true;
|
||||||
mCurId = info.getId();
|
mCurId = info.getId();
|
||||||
@@ -1783,7 +1784,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
|||||||
mInputShown = true;
|
mInputShown = true;
|
||||||
if (mHaveConnection && !mVisibleBound) {
|
if (mHaveConnection && !mVisibleBound) {
|
||||||
bindCurrentInputMethodService(
|
bindCurrentInputMethodService(
|
||||||
mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE);
|
mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE
|
||||||
|
| Context.BIND_TREAT_LIKE_ACTIVITY);
|
||||||
mVisibleBound = true;
|
mVisibleBound = true;
|
||||||
}
|
}
|
||||||
res = true;
|
res = true;
|
||||||
|
|||||||
@@ -667,8 +667,7 @@ public final class ActiveServices {
|
|||||||
// what they are, so we can report this elsewhere for
|
// what they are, so we can report this elsewhere for
|
||||||
// others to know why certain services are running.
|
// others to know why certain services are running.
|
||||||
try {
|
try {
|
||||||
clientIntent = (PendingIntent)service.getParcelableExtra(
|
clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
|
||||||
Intent.EXTRA_CLIENT_INTENT);
|
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
}
|
}
|
||||||
if (clientIntent != null) {
|
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;
|
final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
|
||||||
|
|
||||||
ServiceLookupResult res =
|
ServiceLookupResult res =
|
||||||
@@ -755,8 +759,12 @@ public final class ActiveServices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (s.app != null) {
|
if (s.app != null) {
|
||||||
|
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
|
||||||
|
s.app.treatLikeActivity = true;
|
||||||
|
}
|
||||||
// This could have made the service more important.
|
// 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);
|
mAm.updateOomAdjLocked(s.app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,6 +866,12 @@ public final class ActiveServices {
|
|||||||
|
|
||||||
if (r.binding.service.app != null) {
|
if (r.binding.service.app != null) {
|
||||||
// This could have made the service less important.
|
// 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);
|
mAm.updateOomAdjLocked(r.binding.service.app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2314,11 +2314,12 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
|
|
||||||
final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
|
final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
|
||||||
ProcessRecord client) {
|
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;
|
final boolean hasService = false; // not impl yet. app.services.size() > 0;
|
||||||
if (!activityChange && hasActivity) {
|
if (!activityChange && hasActivity) {
|
||||||
// The process has activties, so we are only going to allow activity-based
|
// The process has activities, so we are only allowing activity-based adjustments
|
||||||
// adjustments move it. It should be kept in the front of the list with other
|
// 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
|
// processes that have activities, and we don't want those to change their
|
||||||
// order except due to activity operations.
|
// order except due to activity operations.
|
||||||
return;
|
return;
|
||||||
@@ -12571,6 +12572,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
updateProcessForegroundLocked(app, false, false);
|
updateProcessForegroundLocked(app, false, false);
|
||||||
app.foregroundActivities = false;
|
app.foregroundActivities = false;
|
||||||
app.hasShownUi = false;
|
app.hasShownUi = false;
|
||||||
|
app.treatLikeActivity = false;
|
||||||
app.hasAboveClient = false;
|
app.hasAboveClient = false;
|
||||||
|
|
||||||
mServices.killServicesLocked(app, allowRestart);
|
mServices.killServicesLocked(app, allowRestart);
|
||||||
@@ -14862,6 +14864,9 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
app.adjTarget = s.name;
|
app.adjTarget = s.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
|
||||||
|
app.treatLikeActivity = true;
|
||||||
|
}
|
||||||
final ActivityRecord a = cr.activity;
|
final ActivityRecord a = cr.activity;
|
||||||
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
|
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
|
||||||
if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
|
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) {
|
if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
|
||||||
// This is a cached process, but with client activities. Mark it so.
|
if (app.hasClientActivities) {
|
||||||
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
|
// This is a cached process, but with client activities. Mark it so.
|
||||||
app.adjType = "cch-client-act";
|
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) {
|
if (adj == ProcessList.SERVICE_ADJ) {
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ final class ProcessRecord {
|
|||||||
boolean hasShownUi; // Has UI been shown in this process since it was started?
|
boolean hasShownUi; // Has UI been shown in this process since it was started?
|
||||||
boolean pendingUiClean; // Want to clean up resources from showing UI?
|
boolean pendingUiClean; // Want to clean up resources from showing UI?
|
||||||
boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower
|
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 bad; // True if disabled in the bad process list
|
||||||
boolean killedByAm; // True when proc has been killed by activity manager, not for RAM
|
boolean killedByAm; // True when proc has been killed by activity manager, not for RAM
|
||||||
boolean procStateChanged; // Keep track of whether we changed 'setAdj'.
|
boolean procStateChanged; // Keep track of whether we changed 'setAdj'.
|
||||||
@@ -251,10 +252,11 @@ final class ProcessRecord {
|
|||||||
pw.print(" lastStateTime=");
|
pw.print(" lastStateTime=");
|
||||||
TimeUtils.formatDuration(lastStateTime, now, pw);
|
TimeUtils.formatDuration(lastStateTime, now, pw);
|
||||||
pw.println();
|
pw.println();
|
||||||
if (hasShownUi || pendingUiClean || hasAboveClient) {
|
if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
|
||||||
pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
|
pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
|
||||||
pw.print(" pendingUiClean="); pw.print(pendingUiClean);
|
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) {
|
if (setIsForeground || foregroundServices || forcingToForeground != null) {
|
||||||
pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
|
pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
|
||||||
|
|||||||
Reference in New Issue
Block a user