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();
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();
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:
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
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();
}
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.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
-
+
// Tell the activity manager we have paused.
try {
ActivityManagerNative.getDefault().activityPaused(token);
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;
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;
}
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);
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);
}
}
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(
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);
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;
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),
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);
// 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;
}
"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 {
mDismissKeyguardOnNextActivity = false;
mService.mWindowManager.dismissKeyguard();
}
- Slog.i(TAG, "DONE STARTING!");
return err;
}