diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-03-18 16:50:24 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-03-18 16:50:25 +0000 |
commit | e9ebd60fc4dd32a57784e8d9c7dcb8b599d25f75 (patch) | |
tree | 2e7be6d794504e71cb13f288e231a47b1bcfb2a1 | |
parent | 3ebdf0021796d94e82392f0308cd81a4887080c5 (diff) | |
parent | f0f94d129b6eb3c48624e915898d86d4f2de59ff (diff) | |
download | frameworks_base-e9ebd60fc4dd32a57784e8d9c7dcb8b599d25f75.zip frameworks_base-e9ebd60fc4dd32a57784e8d9c7dcb8b599d25f75.tar.gz frameworks_base-e9ebd60fc4dd32a57784e8d9c7dcb8b599d25f75.tar.bz2 |
Merge "Treat IME processes as hosting activities"
5 files changed, 54 insertions, 14 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 81a886a..134ffa9 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -242,6 +242,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 * this service to be visible like the binding activity is. That is, diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 6827b3f..af8a6e7 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -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; diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index a845127..1345cfd 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -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); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b8ec3ab..5eaa3a1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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) { diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 10574ed..d04a6b2 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -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); |