summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/Keyguard/res/values-hi/strings.xml2
-rw-r--r--packages/Keyguard/res/values-nl/strings.xml4
-rw-r--r--packages/Keyguard/res/values-zu/strings.xml4
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java25
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java11
-rw-r--r--services/java/com/android/server/am/ActivityStack.java483
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java346
-rw-r--r--services/java/com/android/server/am/CompatModePackages.java10
8 files changed, 452 insertions, 433 deletions
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index 57bad8c83fc9..09092f40226f 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -101,7 +101,7 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम PIN डालें"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"PIN डालें"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड डालें"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम अब अक्षम हो गई है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए वाहक से संपर्क करें."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम अब अक्षम हो गई है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए कैरियर से संपर्क करें."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित पिन कोड डालें"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित पिन कोड की पुष्टि करें"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलॉक कर रहा है…"</string>
diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
index ad4e84115101..33a99c802a83 100644
--- a/packages/Keyguard/res/values-nl/strings.xml
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -29,7 +29,7 @@
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Typ pincode om te ontgrendelen"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Onjuiste pincode."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"Druk op \'Menu\' en vervolgens op 0 om te ontgrendelen."</string>
- <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximaal aantal pogingen voor Face Unlock overschreden"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximaal aantal pogingen voor Ontgrendelen via gezichtsherkenning overschreden"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Opgeladen"</string>
<string name="keyguard_plugged_in" msgid="8117572000639998388">"Opladen, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Sluit de oplader aan."</string>
@@ -61,7 +61,7 @@
<string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ontgrendelingsgebied uitvouwen."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ontgrendeling via schuiven."</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ontgrendeling via patroon."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ontgrendeling via gezichtsherkenning."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ontgrendelen via gezichtsherkenning"</string>
<string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ontgrendeling via pincode."</string>
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ontgrendeling via wachtwoord."</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Tekengebied voor patroon."</string>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
index 4424faf91f39..350feb0c440d 100644
--- a/packages/Keyguard/res/values-zu/strings.xml
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -125,8 +125,8 @@
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ithebhulethi manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-<xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> amasekhondi."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Susa"</string>
<string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Inkinombo yethrekhi yangaphambilini"</string>
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f3be0ea10fcd..5ad554452bdd 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -900,7 +900,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static ActivityManagerService mSelf;
static ActivityThread mSystemThread;
- private int mCurrentUserId = 0;
+ int mCurrentUserId = 0;
private UserManagerService mUserManager;
private final class AppDeathRecipient implements IBinder.DeathRecipient {
@@ -962,6 +962,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
static final int FIRST_COMPAT_MODE_MSG = 300;
+ static final int FIRST_SUPERVISOR_STACK_MSG = 100;
AlertDialog mUidAlert;
CompatModeDialog mCompatModeDialog;
@@ -1488,6 +1489,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public void setWindowManager(WindowManagerService wm) {
mWindowManager = wm;
+ mStackSupervisor.setWindowManager(wm);
wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
}
@@ -1520,7 +1522,6 @@ public final class ActivityManagerService extends ActivityManagerNative
m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
- m.mStackSupervisor.init(m.mCurrentUserId);
m.mBatteryStatsService.publish(context);
m.mUsageStatsService.publish(context);
@@ -2659,7 +2660,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
// If this is coming from the currently resumed activity, it is
// effectively saying that app switches are allowed at this point.
- final ActivityStack stack = getTopStack();
+ final ActivityStack stack = getFocusedStack();
if (stack.mResumedActivity != null &&
stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
mAppSwitchesAllowedTime = 0;
@@ -7243,7 +7244,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
try {
- getTopStack().unhandledBackLocked();
+ getFocusedStack().unhandledBackLocked();
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -7649,7 +7650,7 @@ public final class ActivityManagerService extends ActivityManagerNative
PendingActivityExtras pae;
Bundle extras = new Bundle();
synchronized (this) {
- ActivityRecord activity = getTopStack().mResumedActivity;
+ ActivityRecord activity = getFocusedStack().mResumedActivity;
if (activity == null) {
Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
return null;
@@ -7745,7 +7746,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public boolean isTopActivityImmersive() {
enforceNotIsolatedCaller("startActivity");
synchronized (this) {
- ActivityRecord r = getTopStack().topRunningActivityLocked(null);
+ ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
return (r != null) ? r.immersive : false;
}
}
@@ -9651,7 +9652,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
pw.println(" mConfiguration: " + mConfiguration);
if (dumpAll) {
- pw.println(" mConfigWillChange: " + getTopStack().mConfigWillChange);
+ pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
if (mCompatModePackages.getPackages().size() > 0) {
boolean printed = false;
for (Map.Entry<String, Integer> entry
@@ -9711,8 +9712,8 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" mLastPowerCheckUptime=");
TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
pw.println("");
- pw.println(" mGoingToSleep=" + getTopStack().mGoingToSleep);
- pw.println(" mLaunchingActivity=" + getTopStack().mLaunchingActivity);
+ pw.println(" mGoingToSleep=" + getFocusedStack().mGoingToSleep);
+ pw.println(" mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
+ " mNumHiddenProcs=" + mNumHiddenProcs
@@ -12451,8 +12452,8 @@ public final class ActivityManagerService extends ActivityManagerNative
return config;
}
- ActivityStack getTopStack() {
- return mStackSupervisor.getTopStack();
+ ActivityStack getFocusedStack() {
+ return mStackSupervisor.getFocusedStack();
}
public Configuration getConfiguration() {
@@ -12596,7 +12597,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
boolean kept = true;
- final ActivityStack mainStack = mStackSupervisor.getTopStack();
+ final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
if (changes != 0 && starting == null) {
// If the configuration changed, and the caller is not already
// in the process of starting an activity, then find the top
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 351d329f936e..88bcdab4cfaa 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -803,7 +803,7 @@ final class ActivityRecord {
}
Log.i(ActivityManagerService.TAG, sb.toString());
}
- stack.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
+ mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
if (totalTime > 0) {
service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
}
@@ -818,7 +818,7 @@ final class ActivityRecord {
public void windowsVisible() {
synchronized(service) {
final ActivityStack stack = task.stack;
- stack.reportActivityVisibleLocked(this);
+ mStackSupervisor.reportActivityVisibleLocked(this);
if (ActivityManagerService.DEBUG_SWITCH) Log.v(
ActivityManagerService.TAG, "windowsVisible(): " + this);
if (!nowVisible) {
@@ -845,9 +845,7 @@ final class ActivityRecord {
"Was waiting for visible: " + r);
}
mStackSupervisor.mWaitingVisibleActivities.clear();
- Message msg = Message.obtain();
- msg.what = ActivityStack.IDLE_NOW_MSG;
- stack.mHandler.sendMessage(msg);
+ mStackSupervisor.scheduleIdleLocked();
}
}
service.scheduleAppGcsLocked();
@@ -960,7 +958,8 @@ final class ActivityRecord {
@Override
public String toString() {
if (stringName != null) {
- return stringName + " t" + task.taskId + (finishing ? " f}" : "}");
+ return stringName + " t" + (task == null ? -1 : task.taskId) +
+ (finishing ? " f}" : "}");
}
StringBuilder sb = new StringBuilder(128);
sb.append("ActivityRecord{");
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index e02fcacfee42..9f3198287395 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -23,19 +23,18 @@ import com.android.internal.util.Objects;
import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.wm.AppTransition;
import com.android.server.wm.TaskGroup;
+import com.android.server.wm.WindowManagerService;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityController;
-import android.app.IActivityManager;
import android.app.IThumbnailReceiver;
import android.app.IThumbnailRetriever;
import android.app.IApplicationThread;
import android.app.ResultInfo;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.IActivityManager.WaitResult;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -91,10 +90,6 @@ final class ActivityStack {
static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS;
- // How long we wait until giving up on the last activity telling us it
- // is idle.
- static final int IDLE_TIMEOUT = 10*1000;
-
// Ticks during which we check progress while waiting for an app to launch.
static final int LAUNCH_TICK = 500;
@@ -143,6 +138,7 @@ final class ActivityStack {
}
final ActivityManagerService mService;
+ final WindowManagerService mWindowManager;
final Context mContext;
@@ -167,38 +163,13 @@ final class ActivityStack {
/**
* List of activities that are in the process of going to sleep.
*/
- final ArrayList<ActivityRecord> mGoingToSleepActivities
- = new ArrayList<ActivityRecord>();
+ final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
/**
* Animations that for the current transition have requested not to
* be considered for the transition animation.
*/
- final ArrayList<ActivityRecord> mNoAnimActivities
- = new ArrayList<ActivityRecord>();
-
- /**
- * List of activities that are ready to be finished, but waiting
- * for the previous activity to settle down before doing so. It contains
- * HistoryRecord objects.
- */
- final ArrayList<ActivityRecord> mFinishingActivities
- = new ArrayList<ActivityRecord>();
-
- /**
- * List of people waiting to find out about the next launched activity.
- */
- final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched
- = new ArrayList<IActivityManager.WaitResult>();
-
- /**
- * List of people waiting to find out about the next visible activity.
- */
- final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible
- = new ArrayList<IActivityManager.WaitResult>();
-
- final ArrayList<UserStartedState> mStartingUsers
- = new ArrayList<UserStartedState>();
+ final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();
/**
* Set when the system is going to sleep, until we have
@@ -260,12 +231,6 @@ final class ActivityStack {
private ActivityRecord mLastScreenshotActivity = null;
private Bitmap mLastScreenshotBitmap = null;
- /**
- * List of ActivityRecord objects that have been finished and must
- * still report back to a pending thumbnail receiver.
- */
- private final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
-
int mThumbnailWidth = -1;
int mThumbnailHeight = -1;
@@ -278,14 +243,12 @@ final class ActivityStack {
static final int SLEEP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG;
static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
- static final int IDLE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
- static final int IDLE_NOW_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
- static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
- static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
- static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
- static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
- static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 8;
- static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 9;
+ static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
+ static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
+ static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
+ static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
+ static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
+ static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
static class ScheduleDestroyArgs {
final ProcessRecord mOwner;
@@ -334,22 +297,6 @@ final class ActivityStack {
activityPausedLocked(r != null ? r.appToken : null, true);
}
} break;
- case IDLE_TIMEOUT_MSG: {
- if (mService.mDidDexOpt) {
- mService.mDidDexOpt = false;
- Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
- nmsg.obj = msg.obj;
- mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
- return;
- }
- // We don't at this point know if the activity is fullscreen,
- // so we need to be conservative and assume it isn't.
- ActivityRecord r = (ActivityRecord)msg.obj;
- Slog.w(TAG, "Activity idle timeout for " + r);
- synchronized (mService) {
- activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
- }
- } break;
case LAUNCH_TICK_MSG: {
ActivityRecord r = (ActivityRecord)msg.obj;
synchronized (mService) {
@@ -368,12 +315,6 @@ final class ActivityStack {
activityDestroyedLocked(r != null ? r.appToken : null);
}
} break;
- case IDLE_NOW_MSG: {
- ActivityRecord r = (ActivityRecord)msg.obj;
- synchronized (mService) {
- activityIdleInternalLocked(r != null ? r.appToken : null, false, null);
- }
- } break;
case LAUNCH_TIMEOUT_MSG: {
if (mService.mDidDexOpt) {
mService.mDidDexOpt = false;
@@ -390,7 +331,7 @@ final class ActivityStack {
} break;
case RESUME_TOP_ACTIVITY_MSG: {
synchronized (mService) {
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
}
} break;
case STOP_TIMEOUT_MSG: {
@@ -422,19 +363,20 @@ final class ActivityStack {
return count;
}
- ActivityStack(ActivityManagerService service, Context context, Looper looper, int stackId,
- ActivityStackSupervisor supervisor, int userId) {
+ ActivityStack(ActivityManagerService service, Context context, Looper looper, int stackId) {
mHandler = new ActivityStackHandler(looper);
mService = service;
+ mWindowManager = service.mWindowManager;
+ mStackSupervisor = service.mStackSupervisor;
mContext = context;
PowerManager pm =
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
- mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
+ mLaunchingActivity =
+ pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
mLaunchingActivity.setReferenceCounted(false);
mStackId = stackId;
- mStackSupervisor = supervisor;
- mCurrentUser = userId;
+ mCurrentUser = service.mCurrentUserId;
}
private boolean okToShow(ActivityRecord r) {
@@ -641,7 +583,6 @@ final class ActivityStack {
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
- mStartingUsers.add(uss);
if (mCurrentUser == userId) {
return true;
}
@@ -717,6 +658,7 @@ final class ActivityStack {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+ // TODO: Skip if finishing?
activities.get(activityNdx).setSleeping(false);
}
}
@@ -753,7 +695,7 @@ final class ActivityStack {
// Still need to tell some activities to stop; can't sleep yet.
if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
+ mStackSupervisor.mStoppingActivities.size() + " activities");
- scheduleIdleLocked();
+ mStackSupervisor.scheduleIdleLocked();
return;
}
@@ -809,7 +751,7 @@ final class ActivityStack {
|| mLastScreenshotBitmap.getWidth() != w
|| mLastScreenshotBitmap.getHeight() != h) {
mLastScreenshotActivity = who;
- mLastScreenshotBitmap = mService.mWindowManager.screenshotApplications(
+ mLastScreenshotBitmap = mWindowManager.screenshotApplications(
who.appToken, Display.DEFAULT_DISPLAY, w, h);
}
if (mLastScreenshotBitmap != null) {
@@ -828,7 +770,7 @@ final class ActivityStack {
if (prev == null) {
Slog.e(TAG, "Trying to pause when nothing is resumed",
new RuntimeException("here").fillInStackTrace());
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
return;
}
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
@@ -896,7 +838,7 @@ final class ActivityStack {
// This activity failed to schedule the
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
}
}
@@ -954,7 +896,7 @@ final class ActivityStack {
} else {
if (r.configDestroy) {
destroyActivityLocked(r, true, false, "stop-config");
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
} else {
// Now that this process has stopped, we may want to consider
// it to be the previous app to try to keep around in case
@@ -1009,7 +951,7 @@ final class ActivityStack {
// them out. Or if r is the last of activity of the last task the stack
// will be empty and must be cleared immediately.
if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
- scheduleIdleLocked();
+ mStackSupervisor.scheduleIdleLocked();
} else {
checkReadyForSleepLocked();
}
@@ -1021,7 +963,7 @@ final class ActivityStack {
mPausingActivity = null;
}
- final ActivityStack topStack = mStackSupervisor.getTopStack();
+ final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {
topStack.resumeTopActivityLocked(prev);
} else {
@@ -1075,31 +1017,12 @@ final class ActivityStack {
next.newIntents = null;
// schedule an idle timeout in case the app doesn't do it for us.
- Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
- msg.obj = next;
- mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
+ mStackSupervisor.scheduleIdleTimeoutLocked(next);
- if (false) {
- // The activity was never told to pause, so just keep
- // things going as-is. To maintain our own state,
- // we need to emulate it coming back and saying it is
- // idle.
- msg = mHandler.obtainMessage(IDLE_NOW_MSG);
- msg.obj = next;
- mHandler.sendMessage(msg);
- }
+ mStackSupervisor.reportResumedActivityLocked(next);
- if (mStackSupervisor.isFrontStack(this)) {
- // TODO: Should this be done for all stacks, not just mMainStack?
- mService.reportResumedActivityLocked(next);
- mService.setFocusedActivityLocked(next);
- }
- if (mStackSupervisor.allResumedActivitiesComplete()) {
- next.resumeKeyDispatchingLocked();
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
- mService.mWindowManager.executeAppTransition();
- mNoAnimActivities.clear();
- }
+ next.resumeKeyDispatchingLocked();
+ mNoAnimActivities.clear();
// Mark the point when the activity is resuming
// TODO: To be more accurate, the mark should be before the onCreate,
@@ -1166,7 +1089,7 @@ final class ActivityStack {
if (!r.visible) {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Starting and making visible: " + r);
- mService.mWindowManager.setAppVisibility(r.appToken, true);
+ mWindowManager.setAppVisibility(r.appToken, true);
}
if (r != starting) {
mStackSupervisor.startSpecificActivityLocked(r, false, false);
@@ -1189,7 +1112,7 @@ final class ActivityStack {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Making visible and scheduling visibility: " + r);
try {
- mService.mWindowManager.setAppVisibility(r.appToken, true);
+ mWindowManager.setAppVisibility(r.appToken, true);
r.sleeping = false;
r.app.pendingUiClean = true;
r.app.thread.scheduleWindowVisibility(r.appToken, true);
@@ -1223,7 +1146,7 @@ final class ActivityStack {
if (DEBUG_VISBILITY) Slog.v(TAG, "Making invisible: " + r);
r.visible = false;
try {
- mService.mWindowManager.setAppVisibility(r.appToken, false);
+ mWindowManager.setAppVisibility(r.appToken, false);
if ((r.state == ActivityState.STOPPING
|| r.state == ActivityState.STOPPED)
&& r.app != null && r.app.thread != null) {
@@ -1293,7 +1216,7 @@ final class ActivityStack {
mStackSupervisor.allResumedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
- mService.mWindowManager.executeAppTransition();
+ mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
return false;
@@ -1311,7 +1234,7 @@ final class ActivityStack {
&& mStackSupervisor.allPausedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
- mService.mWindowManager.executeAppTransition();
+ mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
return false;
@@ -1424,7 +1347,7 @@ final class ActivityStack {
// previous should actually be hidden depending on whether the
// new one is found to be full-screen or not.
if (prev.finishing) {
- mService.mWindowManager.setAppVisibility(prev.appToken, false);
+ mWindowManager.setAppVisibility(prev.appToken, false);
if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
+ prev + ", waitingVisible="
+ (prev != null ? prev.waitingVisible : null)
@@ -1458,42 +1381,37 @@ final class ActivityStack {
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare close transition: prev=" + prev);
if (mNoAnimActivities.contains(prev)) {
- mService.mWindowManager.prepareAppTransition(
- AppTransition.TRANSIT_NONE, false);
+ noAnim = true;
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
- mService.mWindowManager.prepareAppTransition(prev.task == next.task
+ mWindowManager.prepareAppTransition(prev.task == next.task
? AppTransition.TRANSIT_ACTIVITY_CLOSE
: AppTransition.TRANSIT_TASK_CLOSE, false);
}
- mService.mWindowManager.setAppWillBeHidden(prev.appToken);
- mService.mWindowManager.setAppVisibility(prev.appToken, false);
+ mWindowManager.setAppWillBeHidden(prev.appToken);
+ mWindowManager.setAppVisibility(prev.appToken, false);
} else {
- if (DEBUG_TRANSITION) Slog.v(TAG,
- "Prepare open transition: prev=" + prev);
+ if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev);
if (mNoAnimActivities.contains(next)) {
noAnim = true;
- mService.mWindowManager.prepareAppTransition(
- AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
- mService.mWindowManager.prepareAppTransition(prev.task == next.task
+ mWindowManager.prepareAppTransition(prev.task == next.task
? AppTransition.TRANSIT_ACTIVITY_OPEN
: AppTransition.TRANSIT_TASK_OPEN, false);
}
}
if (false) {
- mService.mWindowManager.setAppWillBeHidden(prev.appToken);
- mService.mWindowManager.setAppVisibility(prev.appToken, false);
+ mWindowManager.setAppWillBeHidden(prev.appToken);
+ mWindowManager.setAppVisibility(prev.appToken, false);
}
} else {
- if (DEBUG_TRANSITION) Slog.v(TAG,
- "Prepare open transition: no previous");
+ if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous");
if (mNoAnimActivities.contains(next)) {
noAnim = true;
- mService.mWindowManager.prepareAppTransition(
- AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
- mService.mWindowManager.prepareAppTransition(
- AppTransition.TRANSIT_ACTIVITY_OPEN, false);
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
}
}
if (!noAnim) {
@@ -1506,7 +1424,7 @@ final class ActivityStack {
if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
// This activity is now becoming visible.
- mService.mWindowManager.setAppVisibility(next.appToken, true);
+ mWindowManager.setAppVisibility(next.appToken, true);
// schedule launch ticks to collect information about slow apps.
next.startLaunchTickingLocked();
@@ -1529,7 +1447,7 @@ final class ActivityStack {
// the screen based on the new activity order.
boolean updated = false;
if (mStackSupervisor.isFrontStack(this)) {
- Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
+ Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
if (config != null) {
@@ -1552,12 +1470,7 @@ final class ActivityStack {
// Do over!
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
}
- if (mStackSupervisor.isFrontStack(this)) {
- mService.setFocusedActivityLocked(next);
- }
- if (mStackSupervisor.allResumedActivitiesComplete()) {
- ensureActivitiesVisibleLocked(null, 0);
- mService.mWindowManager.executeAppTransition();
+ if (mStackSupervisor.reportResumedActivityLocked(next)) {
mNoAnimActivities.clear();
return true;
}
@@ -1606,7 +1519,7 @@ final class ActivityStack {
next.hasBeenLaunched = true;
} else if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
mStackSupervisor.isFrontStack(lastStack)) {
- mService.mWindowManager.setAppStartingWindow(
+ mWindowManager.setAppStartingWindow(
next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
next.nonLocalizedLabel, next.labelRes, next.icon, next.windowFlags,
@@ -1637,7 +1550,7 @@ final class ActivityStack {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
- mService.mWindowManager.setAppStartingWindow(
+ mWindowManager.setAppStartingWindow(
next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(
next.info.applicationInfo),
@@ -1666,7 +1579,7 @@ final class ActivityStack {
mTaskHistory.remove(rTask);
// Now put task at top.
mTaskHistory.add(rTask);
- mService.mWindowManager.moveTaskToTop(taskId);
+ mWindowManager.moveTaskToTop(taskId);
}
if (!newTask) {
// If starting in an existing task, find where that is...
@@ -1682,9 +1595,8 @@ final class ActivityStack {
+ task, new RuntimeException("here").fillInStackTrace());
task.addActivityToTop(r);
r.putInHistory();
- mService.mWindowManager.addAppToken(task.mActivities.indexOf(r),
- r.appToken, r.task.taskId, mStackId, r.info.screenOrientation,
- r.fullscreen,
+ mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
+ r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
@@ -1735,17 +1647,16 @@ final class ActivityStack {
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare open transition: starting " + r);
if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
- mService.mWindowManager.prepareAppTransition(
- AppTransition.TRANSIT_NONE, keepCurTransition);
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
mNoAnimActivities.add(r);
} else {
- mService.mWindowManager.prepareAppTransition(newTask
+ mWindowManager.prepareAppTransition(newTask
? AppTransition.TRANSIT_TASK_OPEN
: AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
r.updateOptionsLocked(options);
- mService.mWindowManager.addAppToken(task.mActivities.indexOf(r),
+ mWindowManager.addAppToken(task.mActivities.indexOf(r),
r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
boolean doShow = true;
@@ -1778,7 +1689,7 @@ final class ActivityStack {
prev = null;
}
}
- mService.mWindowManager.setAppStartingWindow(
+ mWindowManager.setAppStartingWindow(
r.appToken, r.packageName, r.theme,
mService.compatibilityInfoForPackageLocked(
r.info.applicationInfo), r.nonLocalizedLabel,
@@ -1788,7 +1699,7 @@ final class ActivityStack {
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
- mService.mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
+ mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
ActivityOptions.abort(options);
@@ -1821,7 +1732,7 @@ final class ActivityStack {
group.tokens.add(r.appToken);
}
}
- mService.mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
+ mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
}
/**
@@ -1836,8 +1747,7 @@ final class ActivityStack {
* @param forceReset
* @return An ActivityOptions that needs to be processed.
*/
- final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task,
- boolean forceReset) {
+ final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
ActivityOptions topOptions = null;
int replyChainEnd = -1;
@@ -1901,7 +1811,7 @@ final class ActivityStack {
final TaskRecord targetTask = target.task;
final int targetTaskId = targetTask.taskId;
- mService.mWindowManager.setAppGroupId(target.appToken, targetTaskId);
+ mWindowManager.setAppGroupId(target.appToken, targetTaskId);
ThumbnailHolder curThumbHolder = target.thumbHolder;
boolean gotOptions = !canMoveOptions;
@@ -1929,10 +1839,10 @@ final class ActivityStack {
p.setTask(targetTask, curThumbHolder, false);
targetTask.addActivityAtBottom(p);
- mService.mWindowManager.setAppGroupId(p.appToken, targetTaskId);
+ mWindowManager.setAppGroupId(p.appToken, targetTaskId);
}
- mService.mWindowManager.moveTaskToBottom(targetTaskId);
+ mWindowManager.moveTaskToBottom(targetTaskId);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -2064,9 +1974,9 @@ final class ActivityStack {
new RuntimeException("here").fillInStackTrace());
if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p + " from " + srcPos
+ " in to resetting task " + task);
- mService.mWindowManager.setAppGroupId(p.appToken, taskId);
+ mWindowManager.setAppGroupId(p.appToken, taskId);
}
- mService.mWindowManager.moveTaskToTop(taskId);
+ mWindowManager.moveTaskToTop(taskId);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -2167,34 +2077,6 @@ final class ActivityStack {
return null;
}
- 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();
- }
-
- 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();
- mStackSupervisor.dismissKeyguard();
- }
-
void sendActivityResultLocked(int callingUid, ActivityRecord r,
String resultWho, int requestCode, int resultCode, Intent data) {
@@ -2221,7 +2103,7 @@ final class ActivityStack {
r.addResultLocked(null, resultWho, requestCode, resultCode, data);
}
- private final void stopActivityLocked(ActivityRecord r) {
+ final void stopActivityLocked(ActivityRecord r) {
if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
@@ -2254,7 +2136,7 @@ final class ActivityStack {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Stopping visible=" + r.visible + " for " + r);
if (!r.visible) {
- mService.mWindowManager.setAppVisibility(r.appToken, false);
+ mWindowManager.setAppVisibility(r.appToken, false);
}
r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
if (mService.isSleepingOrShuttingDown()) {
@@ -2279,12 +2161,6 @@ final class ActivityStack {
}
}
- final void scheduleIdleLocked() {
- Message msg = Message.obtain();
- msg.what = IDLE_NOW_MSG;
- mHandler.sendMessage(msg);
- }
-
// Checked.
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
@@ -2302,145 +2178,18 @@ final class ActivityStack {
boolean enableScreen = false;
boolean activityRemoved = false;
- ActivityRecord r = ActivityRecord.forToken(token);
- if (r != null) {
- mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
- r.finishLaunchTickingLocked();
- }
-
// Get the activity record.
- if (isInStackLocked(token) != null) {
- res = r;
-
- if (fromTimeout) {
- reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
- }
-
- // This is a hack to semi-deal with a race condition
- // in the client where it can be constructed with a
- // newer configuration from when we asked it to launch.
- // We'll update with whatever configuration it now says
- // it used to launch.
- if (config != null) {
- r.configuration = config;
- }
-
+ res = isInStackLocked(token);
+ if (res != null) {
// No longer need to keep the device awake.
- if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
+ if (mResumedActivity == res && mLaunchingActivity.isHeld()) {
mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
mLaunchingActivity.release();
}
- // We are now idle. If someone is waiting for a thumbnail from
- // us, we can now deliver.
- r.idle = true;
- if (mStackSupervisor.allResumedActivitiesIdle()) {
- mService.scheduleAppGcsLocked();
- }
- if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
- sendThumbnail = r.app.thread;
- r.thumbnailNeeded = false;
- }
-
// If this activity is fullscreen, set up to hide those under it.
-
- if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + r);
+ if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + res);
ensureActivitiesVisibleLocked(null, 0);
-
- //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
- if (!mService.mBooted && mStackSupervisor.isFrontStack(this)) {
- mService.mBooted = true;
- enableScreen = true;
- }
- } else if (fromTimeout) {
- reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
- }
-
- // Atomically retrieve all of the other things to do.
- stops = mStackSupervisor.processStoppingActivitiesLocked(true);
- NS = stops != null ? stops.size() : 0;
- if ((NF=mFinishingActivities.size()) > 0) {
- finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
- mFinishingActivities.clear();
- }
-
- final ArrayList<ActivityRecord> thumbnails;
- final int NT = mCancelledThumbnails.size();
- if (NT > 0) {
- thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
- mCancelledThumbnails.clear();
- } else {
- thumbnails = null;
- }
-
- if (mStackSupervisor.isFrontStack(this)) {
- booting = mService.mBooting;
- mService.mBooting = false;
- }
-
- if (mStartingUsers.size() > 0) {
- startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
- mStartingUsers.clear();
- }
-
- // Perform the following actions from unsynchronized state.
- final IApplicationThread thumbnailThread = sendThumbnail;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (thumbnailThread != null) {
- try {
- thumbnailThread.requestThumbnail(token);
- } catch (Exception e) {
- Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
- mService.sendPendingThumbnail(null, token, null, null, true);
- }
- }
-
- // Report back to any thumbnail receivers.
- for (int i = 0; i < NT; i++) {
- ActivityRecord r = thumbnails.get(i);
- mService.sendPendingThumbnail(r, null, null, null, true);
- }
- }
- });
-
- // Stop any activities that are scheduled to do so but have been
- // waiting for the next one to start.
- for (int i = 0; i < NS; i++) {
- r = stops.get(i);
- if (r.finishing) {
- finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
- } else {
- r.task.stack.stopActivityLocked(r);
- }
- }
-
- // Finish any activities that are scheduled to do so but have been
- // waiting for the next one to start.
- for (int i = 0; i < NF; i++) {
- r = finishes.get(i);
- activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
- }
-
- if (booting) {
- mService.finishBooting();
- } else if (startingUsers != null) {
- for (int i = 0; i < startingUsers.size(); i++) {
- mService.finishUserSwitch(startingUsers.get(i));
- }
- }
-
- mService.trimApplications();
- //dump();
- //mWindowManager.dump();
-
- if (enableScreen) {
- mService.enableScreenAfterBoot();
- }
-
- if (activityRemoved) {
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
}
return res;
@@ -2563,8 +2312,8 @@ final class ActivityStack {
* @return Returns true if this activity has been removed from the history
* list, or false if it is still in the list and will be removed later.
*/
- final boolean finishActivityLocked(ActivityRecord r, int resultCode,
- Intent resultData, String reason, boolean oomAdj) {
+ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
+ String reason, boolean oomAdj) {
if (r.finishing) {
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
@@ -2603,19 +2352,19 @@ final class ActivityStack {
// There are clients waiting to receive thumbnails so, in case
// this is an activity that someone is waiting for, add it
// to the pending list so we can correctly update the clients.
- mCancelledThumbnails.add(r);
+ mStackSupervisor.mCancelledThumbnails.add(r);
}
if (mResumedActivity == r) {
boolean endTask = index <= 0;
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare close transition: finishing " + r);
- mService.mWindowManager.prepareAppTransition(endTask
+ mWindowManager.prepareAppTransition(endTask
? AppTransition.TRANSIT_TASK_CLOSE
: AppTransition.TRANSIT_ACTIVITY_CLOSE, false);
// Tell window manager to prepare for this one to be removed.
- mService.mWindowManager.setAppVisibility(r.appToken, false);
+ mWindowManager.setAppVisibility(r.appToken, false);
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
@@ -2635,12 +2384,11 @@ final class ActivityStack {
return false;
}
- private static final int FINISH_IMMEDIATELY = 0;
- private static final int FINISH_AFTER_PAUSE = 1;
- private static final int FINISH_AFTER_VISIBLE = 2;
+ static final int FINISH_IMMEDIATELY = 0;
+ static final int FINISH_AFTER_PAUSE = 1;
+ static final int FINISH_AFTER_VISIBLE = 2;
- private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
- int mode, boolean oomAdj) {
+ final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
// First things first: if this activity is currently visible,
// and the resumed activity is not yet visible, then hold off on
// finishing until the resumed one becomes visible.
@@ -2653,7 +2401,7 @@ final class ActivityStack {
// then give up on things going idle and start clearing
// them out. Or if r is the last of activity of the last task the stack
// will be empty and must be cleared immediately.
- scheduleIdleLocked();
+ mStackSupervisor.scheduleIdleLocked();
} else {
checkReadyForSleepLocked();
}
@@ -2686,7 +2434,7 @@ final class ActivityStack {
boolean activityRemoved = destroyActivityLocked(r, true,
oomAdj, "finish-imm");
if (activityRemoved) {
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
}
return activityRemoved ? null : r;
}
@@ -2694,8 +2442,8 @@ final class ActivityStack {
// Need to go through the full pause cycle to get this
// activity into the stopped state and then finish it.
if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
- mFinishingActivities.add(r);
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.mFinishingActivities.add(r);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
return r;
}
@@ -2807,7 +2555,7 @@ final class ActivityStack {
// Make sure this record is no longer in the pending finishes list.
// This could happen, for example, if we are trimming activities
// down to the max limit while they are still waiting to finish.
- mFinishingActivities.remove(r);
+ mStackSupervisor.mFinishingActivities.remove(r);
mStackSupervisor.mWaitingVisibleActivities.remove(r);
// Remove any pending results.
@@ -2829,7 +2577,7 @@ final class ActivityStack {
// There are clients waiting to receive thumbnails so, in case
// this is an activity that someone is waiting for, add it
// to the pending list so we can correctly update the clients.
- mCancelledThumbnails.add(r);
+ mStackSupervisor.mCancelledThumbnails.add(r);
}
// Get rid of any pending idle timeouts.
@@ -2837,9 +2585,9 @@ final class ActivityStack {
}
private void removeTimeoutsForActivityLocked(ActivityRecord r) {
+ mStackSupervisor.removeTimeoutsForActivityLocked(r);
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
- mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
r.finishLaunchTickingLocked();
}
@@ -2864,7 +2612,7 @@ final class ActivityStack {
r.state = ActivityState.DESTROYED;
if (DEBUG_APP) Slog.v(TAG, "Clearing app during remove for activity " + r);
r.app = null;
- mService.mWindowManager.removeAppToken(r.appToken);
+ mWindowManager.removeAppToken(r.appToken);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -2928,7 +2676,7 @@ final class ActivityStack {
}
}
if (activityRemoved) {
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
}
}
@@ -3045,7 +2793,7 @@ final class ActivityStack {
removeActivityFromHistoryLocked(r);
}
}
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -3076,7 +2824,8 @@ final class ActivityStack {
removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app, "mGoingToSleepActivities");
removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
"mWaitingVisibleActivities");
- removeHistoryRecordsForAppLocked(mFinishingActivities, app, "mFinishingActivities");
+ removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
+ "mFinishingActivities");
boolean hasVisibleActivities = false;
@@ -3161,7 +2910,7 @@ final class ActivityStack {
ActivityOptions.abort(options);
}
}
- mService.mWindowManager.prepareAppTransition(transit, false);
+ mWindowManager.prepareAppTransition(transit, false);
}
final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
@@ -3205,7 +2954,7 @@ final class ActivityStack {
if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
if (reason != null &&
(reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
- mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
ActivityRecord r = topRunningActivityLocked(null);
if (r != null) {
mNoAnimActivities.add(r);
@@ -3215,9 +2964,9 @@ final class ActivityStack {
updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
}
- mService.mWindowManager.moveTaskToTop(tr.taskId);
+ mWindowManager.moveTaskToTop(tr.taskId);
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
if (VALIDATE_TOKENS) {
@@ -3226,13 +2975,13 @@ final class ActivityStack {
}
/**
- * Worker method for rearranging history stack. Implements the function of moving all
- * activities for a specific task (gathering them if disjoint) into a single group at the
+ * Worker method for rearranging history stack. Implements the function of moving all
+ * activities for a specific task (gathering them if disjoint) into a single group at the
* bottom of the stack.
- *
+ *
* If a watcher is installed, the action is preflighted and the watcher has an opportunity
* to premeptively cancel the move.
- *
+ *
* @param task The taskId to collect and move to the bottom.
* @return Returns true if the move completed, false if not.
*/
@@ -3272,17 +3021,17 @@ final class ActivityStack {
mTaskHistory.add(0, tr);
if (reason != null &&
- (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
- mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+ (reason.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+ mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
ActivityRecord r = topRunningActivityLocked(null);
if (r != null) {
mNoAnimActivities.add(r);
}
} else {
- mService.mWindowManager.prepareAppTransition(
+ mWindowManager.prepareAppTransition(
AppTransition.TRANSIT_TASK_TO_BACK, false);
}
- mService.mWindowManager.moveTaskToBottom(task);
+ mWindowManager.moveTaskToBottom(task);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
@@ -3294,7 +3043,7 @@ final class ActivityStack {
return mStackSupervisor.resumeHomeActivity(null);
}
- mStackSupervisor.getTopStack().resumeTopActivityLocked(null);
+ mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
return true;
}
@@ -3444,7 +3193,7 @@ final class ActivityStack {
"Skipping config check (will change): " + r);
return true;
}
-
+
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
"Ensuring correct configuration: " + r);
@@ -3456,7 +3205,7 @@ final class ActivityStack {
"Configuration unchanged in " + r);
return true;
}
-
+
// We don't worry about activities that are finishing.
if (r.finishing) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
@@ -3464,7 +3213,7 @@ final class ActivityStack {
r.stopFreezingScreenLocked(false);
return true;
}
-
+
// Okay we now are going to make this activity have the new config.
// But then we need to figure out how it needs to deal with that.
Configuration oldConfig = r.configuration;
@@ -3490,7 +3239,7 @@ final class ActivityStack {
r.forceNewConfig = false;
return true;
}
-
+
// Figure out how to handle the changes between the configurations.
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
@@ -3530,12 +3279,12 @@ final class ActivityStack {
relaunchActivityLocked(r, r.configChangeFlags, false);
r.configChangeFlags = 0;
}
-
+
// All done... tell the caller we weren't able to keep this
// activity around.
return false;
}
-
+
// Default case: the activity can handle this new configuration, so
// hand it over. Note that we don't need to give it the new
// configuration, since we always send configuration changes to all
@@ -3550,7 +3299,7 @@ final class ActivityStack {
}
}
r.stopFreezingScreenLocked(false);
-
+
return true;
}
@@ -3758,7 +3507,7 @@ final class ActivityStack {
boolean hasVisibleActivities = removeHistoryRecordsForAppLocked(app);
if (!restarting) {
- ActivityStack stack = mStackSupervisor.getTopStack();
+ ActivityStack stack = mStackSupervisor.getFocusedStack();
if (stack == null) {
mStackSupervisor.resumeHomeActivity(null);
} else if (!stack.resumeTopActivityLocked(null)) {
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 05d721b742db..af358c2abeca 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.Activity;
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.pm.ResolveInfo;
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.internal.app.HeavyWeightSwitcherActivity;
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;
@@ -82,10 +85,21 @@ public class ActivityStackSupervisor {
public static final int HOME_STACK_ID = 0;
+ /** How long we wait until giving up on the last activity telling us it is idle. */
+ static final int IDLE_TIMEOUT = 10*1000;
+
+ static final int IDLE_TIMEOUT_MSG = ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+ static final int IDLE_NOW_MSG = ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG + 1;
+
final ActivityManagerService mService;
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,10 +133,29 @@ public class ActivityStackSupervisor {
* 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>();
+ /** List of activities that are ready to be finished, but waiting for the previous activity to
+ * settle down before doing so. It contains ActivityRecord objects. */
+ final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
+
+ /** List of ActivityRecord objects that have been finished and must still report back to a
+ * pending thumbnail receiver. */
+ final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
+
+ /** Used on user changes */
+ final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
+
/** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
* is being brought in front of us. */
boolean mUserLeaving = false;
@@ -132,21 +165,23 @@ public class ActivityStackSupervisor {
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 +208,12 @@ public class ActivityStackSupervisor {
}
}
+ 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 +295,7 @@ public class ActivityStackSupervisor {
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 +304,10 @@ public class ActivityStackSupervisor {
}
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 +403,34 @@ public class ActivityStackSupervisor {
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 +548,7 @@ public class ActivityStackSupervisor {
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 +648,7 @@ public class ActivityStackSupervisor {
if (outResult != null) {
outResult.result = res;
if (res == ActivityManager.START_SUCCESS) {
- stack.mWaitingActivityLaunched.add(outResult);
+ mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait();
@@ -594,7 +664,7 @@ public class ActivityStackSupervisor {
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
- stack.mWaitingActivityVisible.add(outResult);
+ mWaitingActivityVisible.add(outResult);
do {
try {
mService.wait();
@@ -694,7 +764,7 @@ public class ActivityStackSupervisor {
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 +776,7 @@ public class ActivityStackSupervisor {
// 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 +1098,7 @@ public class ActivityStackSupervisor {
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 +1193,7 @@ public class ActivityStackSupervisor {
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 +1433,7 @@ public class ActivityStackSupervisor {
// 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) {
@@ -1519,6 +1589,154 @@ public class ActivityStackSupervisor {
return ActivityManager.START_SUCCESS;
}
+ // Checked.
+ final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
+ Configuration config) {
+ if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
+
+ ActivityRecord res = null;
+
+ ArrayList<ActivityRecord> stops = null;
+ ArrayList<ActivityRecord> finishes = null;
+ ArrayList<UserStartedState> startingUsers = null;
+ int NS = 0;
+ int NF = 0;
+ IApplicationThread sendThumbnail = null;
+ boolean booting = false;
+ boolean enableScreen = false;
+ boolean activityRemoved = false;
+
+ ActivityRecord r = ActivityRecord.forToken(token);
+ if (r != null) {
+ mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
+ r.finishLaunchTickingLocked();
+ res = r.task.stack.activityIdleInternalLocked(token, fromTimeout, config);
+ if (res != null) {
+ if (fromTimeout) {
+ reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
+ }
+
+ // This is a hack to semi-deal with a race condition
+ // in the client where it can be constructed with a
+ // newer configuration from when we asked it to launch.
+ // We'll update with whatever configuration it now says
+ // it used to launch.
+ if (config != null) {
+ r.configuration = config;
+ }
+
+ // We are now idle. If someone is waiting for a thumbnail from
+ // us, we can now deliver.
+ r.idle = true;
+ if (allResumedActivitiesIdle()) {
+ mService.scheduleAppGcsLocked();
+ }
+ if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
+ sendThumbnail = r.app.thread;
+ r.thumbnailNeeded = false;
+ }
+
+ //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
+ if (!mService.mBooted && isFrontStack(r.task.stack)) {
+ mService.mBooted = true;
+ enableScreen = true;
+ }
+ } else if (fromTimeout) {
+ reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
+ }
+ }
+
+ // Atomically retrieve all of the other things to do.
+ stops = processStoppingActivitiesLocked(true);
+ NS = stops != null ? stops.size() : 0;
+ if ((NF=mFinishingActivities.size()) > 0) {
+ finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
+ mFinishingActivities.clear();
+ }
+
+ final ArrayList<ActivityRecord> thumbnails;
+ final int NT = mCancelledThumbnails.size();
+ if (NT > 0) {
+ thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
+ mCancelledThumbnails.clear();
+ } else {
+ thumbnails = null;
+ }
+
+ if (isFrontStack(mHomeStack)) {
+ booting = mService.mBooting;
+ mService.mBooting = false;
+ }
+
+ if (mStartingUsers.size() > 0) {
+ startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
+ mStartingUsers.clear();
+ }
+
+ // Perform the following actions from unsynchronized state.
+ final IApplicationThread thumbnailThread = sendThumbnail;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (thumbnailThread != null) {
+ try {
+ thumbnailThread.requestThumbnail(token);
+ } catch (Exception e) {
+ Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
+ mService.sendPendingThumbnail(null, token, null, null, true);
+ }
+ }
+
+ // Report back to any thumbnail receivers.
+ for (int i = 0; i < NT; i++) {
+ ActivityRecord r = thumbnails.get(i);
+ mService.sendPendingThumbnail(r, null, null, null, true);
+ }
+ }
+ });
+
+ // Stop any activities that are scheduled to do so but have been
+ // waiting for the next one to start.
+ for (int i = 0; i < NS; i++) {
+ r = stops.get(i);
+ final ActivityStack stack = r.task.stack;
+ if (r.finishing) {
+ stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
+ } else {
+ stack.stopActivityLocked(r);
+ }
+ }
+
+ // Finish any activities that are scheduled to do so but have been
+ // waiting for the next one to start.
+ for (int i = 0; i < NF; i++) {
+ r = finishes.get(i);
+ activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
+ }
+
+ if (booting) {
+ mService.finishBooting();
+ } else if (startingUsers != null) {
+ for (int i = 0; i < startingUsers.size(); i++) {
+ mService.finishUserSwitch(startingUsers.get(i));
+ }
+ }
+
+ mService.trimApplications();
+ //dump();
+ //mWindowManager.dump();
+
+ if (enableScreen) {
+ mService.enableScreenAfterBoot();
+ }
+
+ if (activityRemoved) {
+ getFocusedStack().resumeTopActivityLocked(null);
+ }
+
+ return res;
+ }
+
void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
// Just in case.
final int numStacks = mStacks.size();
@@ -1567,12 +1785,6 @@ public class ActivityStackSupervisor {
}
}
- void scheduleIdleLocked() {
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).scheduleIdleLocked();
- }
- }
-
void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
@@ -1605,8 +1817,7 @@ public class ActivityStackSupervisor {
break;
}
}
- mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId, this,
- mCurrentUser));
+ mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
return mLastStackId;
}
}
@@ -1673,17 +1884,29 @@ public class ActivityStackSupervisor {
}
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) {
@@ -1708,12 +1931,12 @@ public class ActivityStackSupervisor {
boolean switchUserLocked(int userId, UserStartedState uss) {
mCurrentUser = userId;
- boolean homeInBack = !homeIsInFront();
+ mStartingUsers.add(uss);
boolean haveActivities = false;
final int numStacks = mStacks.size();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
- if (stack.isHomeStack() ^ homeInBack) {
+ if (isFrontStack(stack)) {
haveActivities |= stack.switchUserLocked(userId, uss);
}
}
@@ -1742,7 +1965,7 @@ public class ActivityStackSupervisor {
// 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 +1989,7 @@ public class ActivityStackSupervisor {
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
- return getTopStack().getDumpActivitiesLocked(name);
+ return getFocusedStack().getDumpActivitiesLocked(name);
}
boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
@@ -1786,12 +2009,6 @@ public class ActivityStackSupervisor {
dumpHistoryList(fd, pw, stack.mGoingToSleepActivities, " ", "Sleep", false,
!dumpAll, false, dumpPackage);
}
- if (stack.mFinishingActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting to finish:");
- dumpHistoryList(fd, pw, stack.mFinishingActivities, " ", "Fin", false,
- !dumpAll, false, dumpPackage);
- }
pw.print(" Stack #"); pw.println(mStacks.indexOf(stack));
if (stack.mPausingActivity != null) {
@@ -1804,6 +2021,13 @@ public class ActivityStackSupervisor {
}
}
+ if (mFinishingActivities.size() > 0) {
+ pw.println(" ");
+ pw.println(" Activities waiting to finish:");
+ dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, false,
+ dumpPackage);
+ }
+
if (mStoppingActivities.size() > 0) {
pw.println(" ");
pw.println(" Activities waiting to stop:");
@@ -1893,4 +2117,50 @@ public class ActivityStackSupervisor {
}
}
}
+
+ void scheduleIdleTimeoutLocked(ActivityRecord next) {
+ mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next).sendToTarget();
+ }
+
+ final void scheduleIdleLocked() {
+ mHandler.obtainMessage(IDLE_NOW_MSG).sendToTarget();
+ }
+
+ void removeTimeoutsForActivityLocked(ActivityRecord r) {
+ mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
+ }
+
+ private final class ActivityStackSupervisorHandler extends Handler {
+
+ public ActivityStackSupervisorHandler(Looper looper) {
+ super(looper);
+ }
+
+ void activityIdleInternal(ActivityRecord r) {
+ synchronized (mService) {
+ activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
+ }
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case IDLE_TIMEOUT_MSG: {
+ if (mService.mDidDexOpt) {
+ mService.mDidDexOpt = false;
+ Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
+ nmsg.obj = msg.obj;
+ mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
+ return;
+ }
+ // We don't at this point know if the activity is fullscreen,
+ // so we need to be conservative and assume it isn't.
+ activityIdleInternal((ActivityRecord)msg.obj);
+ } break;
+ case IDLE_NOW_MSG: {
+ activityIdleInternal((ActivityRecord)msg.obj);
+ } break;
+ }
+ }
+ }
}
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index 64b9572d4c73..e697f88f8729 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -165,7 +165,7 @@ public class CompatModePackages {
}
public boolean getFrontActivityAskCompatModeLocked() {
- ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null);
+ ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
if (r == null) {
return false;
}
@@ -177,7 +177,7 @@ public class CompatModePackages {
}
public void setFrontActivityAskCompatModeLocked(boolean ask) {
- ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null);
+ ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
if (r != null) {
setPackageAskCompatModeLocked(r.packageName, ask);
}
@@ -199,7 +199,7 @@ public class CompatModePackages {
}
public int getFrontActivityScreenCompatModeLocked() {
- ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null);
+ ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
if (r == null) {
return ActivityManager.COMPAT_MODE_UNKNOWN;
}
@@ -207,7 +207,7 @@ public class CompatModePackages {
}
public void setFrontActivityScreenCompatModeLocked(int mode) {
- ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null);
+ ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
if (r == null) {
Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
return;
@@ -294,7 +294,7 @@ public class CompatModePackages {
Message msg = mHandler.obtainMessage(MSG_WRITE);
mHandler.sendMessageDelayed(msg, 10000);
- final ActivityStack stack = mService.getTopStack();
+ final ActivityStack stack = mService.getFocusedStack();
ActivityRecord starting = stack.restartPackage(packageName);
// Tell all processes that loaded this package about the change.