diff options
| author | 2012-09-17 15:35:01 -0700 | |
|---|---|---|
| committer | 2012-09-17 16:03:22 -0700 | |
| commit | ad9b32115bf8c84a93ab30e6f30f8c46e86d7244 (patch) | |
| tree | 2a6931f6e9fe8faa72e7d7a4cc828ede29b25aa2 | |
| parent | c71a57d6fa45edf67e79e948b4656fa25a11f1b8 (diff) | |
Try again to fix issue #6912004:tap on gmail notification sends me to home screen
Add a new call to the activity manager to tell it when the activity
is resumed, so it can mark its state as dirty then instead of when
it first tries to create it.
Also tweak things to update the LRU list for the upcoming activity
at the point we start pausing the current activity, to avoid an
inefficiency where we may decide to kill the process of the upcoming
activity if it is at the end of the LRU list.
Change-Id: Ia6dc8c34dc6d4b085a1efbe3a5d5f47721d55078
| -rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 19 | ||||
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 18 | ||||
| -rw-r--r-- | core/java/android/app/IActivityManager.java | 8 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 26 | ||||
| -rwxr-xr-x | services/java/com/android/server/am/ActivityStack.java | 34 |
5 files changed, 75 insertions, 30 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index eae3b1f9bb17..773f73cbd1de 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -404,6 +404,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case ACTIVITY_RESUMED_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + activityResumed(token); + reply.writeNoException(); + return true; + } + case ACTIVITY_PAUSED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); @@ -2152,6 +2160,17 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } + public void activityResumed(IBinder token) throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + mRemote.transact(ACTIVITY_RESUMED_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } public void activityPaused(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index cb4d4a116956..9b82f2a38519 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1245,7 +1245,7 @@ public final class ActivityThread { case RESUME_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); handleResumeActivity((IBinder)msg.obj, true, - msg.arg1 != 0); + msg.arg1 != 0, true); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case SEND_RESULT: @@ -2175,7 +2175,8 @@ public final class ActivityThread { if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; - handleResumeActivity(r.token, false, r.isForward); + handleResumeActivity(r.token, false, r.isForward, + !r.activity.mFinished && !r.startsNotResumed); if (!r.activity.mFinished && r.startsNotResumed) { // The activity manager actually wants this one to start out @@ -2684,7 +2685,8 @@ public final class ActivityThread { r.mPendingRemoveWindowManager = null; } - final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) { + final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, + boolean reallyResume) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); @@ -2781,6 +2783,14 @@ public final class ActivityThread { } r.onlyLocalRequest = false; + // Tell the activity manager we have resumed. + if (reallyResume) { + try { + ActivityManagerNative.getDefault().activityResumed(token); + } catch (RemoteException ex) { + } + } + } else { // If an exception was thrown when trying to resume, then // just end this activity. @@ -2865,7 +2875,7 @@ public final class ActivityThread { if (r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } - + // Tell the activity manager we have paused. try { ActivityManagerNative.getDefault().activityPaused(token); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 9ef375ac256d..2fb17b64e673 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -87,19 +87,15 @@ public interface IActivityManager extends IInterface { String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky, int userId) throws RemoteException; public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException; - /* oneway */ public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; - /* oneway */ + public void activityResumed(IBinder token) throws RemoteException; public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) throws RemoteException; public void activityPaused(IBinder token) throws RemoteException; - /* oneway */ public void activityStopped(IBinder token, Bundle state, Bitmap thumbnail, CharSequence description) throws RemoteException; - /* oneway */ public void activitySlept(IBinder token) throws RemoteException; - /* oneway */ public void activityDestroyed(IBinder token) throws RemoteException; public String getCallingPackage(IBinder token) throws RemoteException; public ComponentName getCallingActivity(IBinder token) throws RemoteException; @@ -496,7 +492,7 @@ public interface IActivityManager extends IInterface { int BIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+35; int UNBIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+36; int PUBLISH_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+37; - + int ACTIVITY_RESUMED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+38; int GOING_TO_SLEEP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+39; int WAKING_UP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+40; int SET_DEBUG_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+41; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 989477f54420..db042b514c7c 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1794,7 +1794,7 @@ public final class ActivityManagerService extends ActivityManagerNative } private final void updateLruProcessInternalLocked(ProcessRecord app, - boolean oomAdj, boolean updateActivityTime, int bestPos) { + boolean updateActivityTime, int bestPos) { // put it on the LRU to keep track of when it should be exited. int lrui = mLruProcesses.indexOf(app); if (lrui >= 0) mLruProcesses.remove(lrui); @@ -1851,7 +1851,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (cr.binding != null && cr.binding.service != null && cr.binding.service.app != null && cr.binding.service.app.lruSeq != mLruSeq) { - updateLruProcessInternalLocked(cr.binding.service.app, false, + updateLruProcessInternalLocked(cr.binding.service.app, updateActivityTime, i+1); } } @@ -1859,21 +1859,21 @@ public final class ActivityManagerService extends ActivityManagerNative for (int j=app.conProviders.size()-1; j>=0; j--) { ContentProviderRecord cpr = app.conProviders.get(j).provider; if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { - updateLruProcessInternalLocked(cpr.proc, false, + updateLruProcessInternalLocked(cpr.proc, updateActivityTime, i+1); } } - - //Slog.i(TAG, "Putting proc to front: " + app.processName); - if (oomAdj) { - updateOomAdjLocked(); - } } final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime) { mLruSeq++; - updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); + updateLruProcessInternalLocked(app, updateActivityTime, 0); + + //Slog.i(TAG, "Putting proc to front: " + app.processName); + if (oomAdj) { + updateOomAdjLocked(); + } } final ProcessRecord getProcessRecordLocked( @@ -4455,7 +4455,13 @@ public final class ActivityManagerService extends ActivityManagerNative enableScreenAfterBoot(); } } - + + public final void activityResumed(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + mMainStack.activityResumed(token); + Binder.restoreCallingIdentity(origId); + } + public final void activityPaused(IBinder token) { final long origId = Binder.clearCallingIdentity(); mMainStack.activityPaused(token, false); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index f72d31806bf3..29ee0bcfe5a9 100755 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -52,7 +52,6 @@ import android.os.IBinder; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.PowerManager; -import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -755,8 +754,6 @@ final class ActivityStack { completeResumeLocked(r); checkReadyForSleepLocked(); if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle); - r.icicle = null; - r.haveState = false; } else { // This activity is not starting in the resumed state... which // should look like we asked it to pause+stop (but remain visible), @@ -1010,7 +1007,21 @@ final class ActivityStack { resumeTopActivityLocked(null); } } - + + final void activityResumed(IBinder token) { + ActivityRecord r = null; + + synchronized (mService) { + int index = indexOfTokenLocked(token); + if (index >= 0) { + r = mHistory.get(index); + if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r); + r.icicle = null; + r.haveState = false; + } + } + } + final void activityPaused(IBinder token, boolean timeout) { if (DEBUG_PAUSE) Slog.v( TAG, "Activity paused: token=" + token + ", timeout=" + timeout); @@ -1488,6 +1499,15 @@ final class ActivityStack { // can be resumed... if (mResumedActivity != null) { if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing"); + // At this point we want to put the upcoming activity's process + // at the top of the LRU list, since we know we will be needing it + // very soon and it would be a waste to let it get killed if it + // happens to be sitting towards the end. + if (next.app != null && next.app.thread != null) { + // No reason to do full oom adj update here; we'll let that + // happen whenever it needs to later. + mService.updateLruProcessLocked(next.app, false, true); + } startPausingLocked(userLeaving, false); return true; } @@ -1728,11 +1748,6 @@ final class ActivityStack { "resume-exception", true); return true; } - - // Didn't need to use the icicle, and it is now out of date. - if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; didn't need icicle of: " + next); - next.icicle = null; - next.haveState = false; next.stopped = false; } else { @@ -2578,7 +2593,6 @@ final class ActivityStack { mDismissKeyguardOnNextActivity = false; mService.mWindowManager.dismissKeyguard(); } - Slog.i(TAG, "DONE STARTING!"); return err; } |