Loading core/java/android/content/Context.java +10 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/InputMethodManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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; Loading services/core/java/com/android/server/am/ActiveServices.java +17 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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 = Loading Loading @@ -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); } Loading Loading @@ -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); } } Loading services/core/java/com/android/server/am/ActivityManagerService.java +19 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 && Loading Loading @@ -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) { 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) { services/core/java/com/android/server/am/ProcessRecord.java +4 −2 Original line number Diff line number Diff line Loading @@ -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'. Loading Loading @@ -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); Loading Loading
core/java/android/content/Context.java +10 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/InputMethodManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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; Loading
services/core/java/com/android/server/am/ActiveServices.java +17 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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 = Loading Loading @@ -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); } Loading Loading @@ -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); } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +19 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 && Loading Loading @@ -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) { 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) {
services/core/java/com/android/server/am/ProcessRecord.java +4 −2 Original line number Diff line number Diff line Loading @@ -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'. Loading Loading @@ -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); Loading