Refactoring Activity Manager.
Mid-course corrections.
- Simplify ActivityStackSupervisor and ActivityStack constructors to
get passed parameters from ActivityManagerService.
- Store WindowManagerService referecne locally in
ActivityStackSupervisor and ActivityStack.
- Rename getTopStack to getFocusedStack in ActivityStackSupervisor
and ActivityManagerService.
- Move mWaitingActivityLaunched/reportActivityLaunchedLocked and
mWaitingActivityVisible/reportActivityVisibleLocked from ActivityStack
to ActivityStackSupervisor.
- Moved reportResumedActivity to ActivityStackSupervisor.
- Added a Handler to ActivityStackSupervisor. Will populate it on next
CL.
Change-Id: I1bbe5eb737c5cac6b896bc9748f329891e94d00f
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 05d721b..be3e260 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -32,6 +32,7 @@
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppGlobals;
+import android.app.IActivityManager;
import android.app.IApplicationThread;
import android.app.IThumbnailReceiver;
import android.app.PendingIntent;
@@ -50,6 +51,7 @@
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -64,6 +66,7 @@
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.StackBox;
+import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -86,6 +89,11 @@
final Context mContext;
final Looper mLooper;
+ final ActivityStackSupervisorHandler mHandler;
+
+ /** Short cut */
+ WindowManagerService mWindowManager;
+
/** Dismiss the keyguard after the next activity is displayed? */
private boolean mDismissKeyguardOnNextActivity = false;
@@ -119,6 +127,14 @@
* whatever operation they are supposed to do. */
final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
+ /** List of processes waiting to find out about the next visible activity. */
+ final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
+ new ArrayList<IActivityManager.WaitResult>();
+
+ /** List of processes waiting to find out about the next launched activity. */
+ final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
+ new ArrayList<IActivityManager.WaitResult>();
+
/** List of activities that are ready to be stopped, but waiting for the next activity to
* settle down before doing so. */
final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
@@ -132,21 +148,23 @@
mService = service;
mContext = context;
mLooper = looper;
+ mHandler = new ActivityStackSupervisorHandler(looper);
}
- void init(int userId) {
- mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID, this, userId);
+ void setWindowManager(WindowManagerService wm) {
+ mWindowManager = wm;
+ mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
mStacks.add(mHomeStack);
}
void dismissKeyguard() {
if (mDismissKeyguardOnNextActivity) {
mDismissKeyguardOnNextActivity = false;
- mService.mWindowManager.dismissKeyguard();
+ mWindowManager.dismissKeyguard();
}
}
- ActivityStack getTopStack() {
+ ActivityStack getFocusedStack() {
if (mFocusedStack == null) {
return mHomeStack;
}
@@ -173,8 +191,12 @@
}
}
+ boolean isFocusedStack(ActivityStack stack) {
+ return getFocusedStack() == stack;
+ }
+
boolean isFrontStack(ActivityStack stack) {
- return !(stack.isHomeStack() ^ getTopStack().isHomeStack());
+ return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
}
boolean homeIsInFront() {
@@ -256,7 +278,7 @@
if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
mStacks.remove(stack);
final int stackId = stack.mStackId;
- final int nextStackId = mService.mWindowManager.removeStack(stackId);
+ final int nextStackId = mWindowManager.removeStack(stackId);
// TODO: Perhaps we need to let the ActivityManager determine the next focus...
if (mFocusedStack.mStackId == stackId) {
mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
@@ -265,7 +287,10 @@
}
ActivityRecord resumedAppLocked() {
- ActivityStack stack = getTopStack();
+ ActivityStack stack = getFocusedStack();
+ if (stack == null) {
+ return null;
+ }
ActivityRecord resumedActivity = stack.mResumedActivity;
if (resumedActivity == null || resumedActivity.app == null) {
resumedActivity = stack.mPausingActivity;
@@ -361,6 +386,34 @@
return true;
}
+ void reportActivityVisibleLocked(ActivityRecord r) {
+ for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) {
+ WaitResult w = mWaitingActivityVisible.get(i);
+ w.timeout = false;
+ if (r != null) {
+ w.who = new ComponentName(r.info.packageName, r.info.name);
+ }
+ w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
+ w.thisTime = w.totalTime;
+ }
+ mService.notifyAll();
+ dismissKeyguard();
+ }
+
+ void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
+ long thisTime, long totalTime) {
+ for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
+ WaitResult w = mWaitingActivityLaunched.get(i);
+ w.timeout = timeout;
+ if (r != null) {
+ w.who = new ComponentName(r.info.packageName, r.info.name);
+ }
+ w.thisTime = thisTime;
+ w.totalTime = totalTime;
+ }
+ mService.notifyAll();
+ }
+
ActivityRecord topRunningActivityLocked() {
ActivityRecord r = null;
if (mFocusedStack != null) {
@@ -478,7 +531,7 @@
callingPid = callingUid = -1;
}
- final ActivityStack stack = getTopStack();
+ final ActivityStack stack = getFocusedStack();
stack.mConfigWillChange = config != null
&& mService.mConfiguration.diff(config) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG,
@@ -578,7 +631,7 @@
if (outResult != null) {
outResult.result = res;
if (res == ActivityManager.START_SUCCESS) {
- stack.mWaitingActivityLaunched.add(outResult);
+ mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait();
@@ -594,7 +647,7 @@
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
- stack.mWaitingActivityVisible.add(outResult);
+ mWaitingActivityVisible.add(outResult);
do {
try {
mService.wait();
@@ -694,7 +747,7 @@
throws RemoteException {
r.startFreezingScreenLocked(app, 0);
- mService.mWindowManager.setAppVisibility(r.appToken, true);
+ mWindowManager.setAppVisibility(r.appToken, true);
// schedule launch ticks to collect information about slow apps.
r.startLaunchTickingLocked();
@@ -706,7 +759,7 @@
// because the activity is not currently running so we are
// just restarting it anyway.
if (checkConfig) {
- Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
+ Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false, false);
@@ -1028,7 +1081,7 @@
outActivity[0] = r;
}
- final ActivityStack stack = getTopStack();
+ final ActivityStack stack = getFocusedStack();
if (stack.mResumedActivity == null
|| stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
@@ -1123,7 +1176,7 @@
if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
ActivityRecord checkedCaller = sourceRecord;
if (checkedCaller == null) {
- checkedCaller = getTopStack().topRunningNonDelayedActivityLocked(notTop);
+ checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
}
if (!checkedCaller.realActivity.equals(r.realActivity)) {
// Caller is not the same as launcher, so always needed.
@@ -1363,7 +1416,7 @@
// If the activity being launched is the same as the one currently
// at the top, then we need to check if it should only be launched
// once.
- ActivityStack topStack = getTopStack();
+ ActivityStack topStack = getFocusedStack();
ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
if (top != null && r.resultTo == null) {
if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
@@ -1605,8 +1658,7 @@
break;
}
}
- mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId, this,
- mCurrentUser));
+ mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
return mLastStackId;
}
}
@@ -1673,17 +1725,29 @@
}
void comeOutOfSleepIfNeededLocked() {
- final boolean homeIsBack = !homeIsInFront();
- final int numStacks = mStacks.size();
- for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
- if (stack.isHomeStack() ^ homeIsBack) {
- stack.awakeFromSleepingLocked();
+ stack.awakeFromSleepingLocked();
+ if (isFrontStack(stack)) {
stack.resumeTopActivityLocked(null);
}
}
}
+ boolean reportResumedActivityLocked(ActivityRecord r) {
+ final ActivityStack stack = r.task.stack;
+ if (isFrontStack(stack)) {
+ mService.reportResumedActivityLocked(r);
+ mService.setFocusedActivityLocked(r);
+ }
+ if (allResumedActivitiesComplete()) {
+ ensureActivitiesVisibleLocked(null, 0);
+ mWindowManager.executeAppTransition();
+ return true;
+ }
+ return false;
+ }
+
void handleAppCrashLocked(ProcessRecord app) {
final int numStacks = mStacks.size();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
@@ -1742,7 +1806,7 @@
// normal flow and hide it once we determine that it is
// hidden by the activities in front of it.
if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
- mService.mWindowManager.setAppVisibility(s.appToken, false);
+ mWindowManager.setAppVisibility(s.appToken, false);
}
}
if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
@@ -1766,7 +1830,7 @@
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
- return getTopStack().getDumpActivitiesLocked(name);
+ return getFocusedStack().getDumpActivitiesLocked(name);
}
boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
@@ -1893,4 +1957,17 @@
}
}
}
+
+ private final class ActivityStackSupervisorHandler extends Handler {
+ public ActivityStackSupervisorHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+
+ }
+ }
+ }
}