ActivityStackSupervisor.java revision e7c58b6d7d761b93e785b0a399e5b00fdb82f4ce
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.START_ANY_ACTIVITY; 20import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.server.am.ActivityManagerService.localLOGV; 24import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION; 25import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS; 26import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE; 27import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS; 28import static com.android.server.am.ActivityManagerService.DEBUG_STACK; 29import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH; 30import static com.android.server.am.ActivityManagerService.DEBUG_TASKS; 31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; 32import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 33import static com.android.server.am.ActivityManagerService.TAG; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityOptions; 38import android.app.AppGlobals; 39import android.app.IActivityManager; 40import android.app.IApplicationThread; 41import android.app.IThumbnailReceiver; 42import android.app.PendingIntent; 43import android.app.ActivityManager.RunningTaskInfo; 44import android.app.IActivityManager.WaitResult; 45import android.app.ResultInfo; 46import android.content.ComponentName; 47import android.content.Context; 48import android.content.IIntentSender; 49import android.content.Intent; 50import android.content.IntentSender; 51import android.content.pm.ActivityInfo; 52import android.content.pm.ApplicationInfo; 53import android.content.pm.PackageManager; 54import android.content.pm.ResolveInfo; 55import android.content.res.Configuration; 56import android.os.Binder; 57import android.os.Bundle; 58import android.os.Debug; 59import android.os.Handler; 60import android.os.IBinder; 61import android.os.Looper; 62import android.os.Message; 63import android.os.ParcelFileDescriptor; 64import android.os.PowerManager; 65import android.os.RemoteException; 66import android.os.SystemClock; 67import android.os.UserHandle; 68import android.util.EventLog; 69import android.util.Slog; 70import android.util.SparseArray; 71 72import com.android.internal.app.HeavyWeightSwitcherActivity; 73import com.android.internal.os.TransferPipe; 74import com.android.server.am.ActivityManagerService.PendingActivityLaunch; 75import com.android.server.am.ActivityStack.ActivityState; 76import com.android.server.wm.StackBox; 77import com.android.server.wm.WindowManagerService; 78 79import java.io.FileDescriptor; 80import java.io.IOException; 81import java.io.PrintWriter; 82import java.util.ArrayList; 83import java.util.List; 84 85public final class ActivityStackSupervisor { 86 static final boolean DEBUG = ActivityManagerService.DEBUG || false; 87 static final boolean DEBUG_ADD_REMOVE = DEBUG || false; 88 static final boolean DEBUG_APP = DEBUG || false; 89 static final boolean DEBUG_SAVED_STATE = DEBUG || false; 90 static final boolean DEBUG_STATES = DEBUG || false; 91 static final boolean DEBUG_IDLE = DEBUG || false; 92 93 public static final int HOME_STACK_ID = 0; 94 95 /** How long we wait until giving up on the last activity telling us it is idle. */ 96 static final int IDLE_TIMEOUT = 10*1000; 97 98 /** How long we can hold the sleep wake lock before giving up. */ 99 static final int SLEEP_TIMEOUT = 5*1000; 100 101 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 102 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 103 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 104 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 105 106 final ActivityManagerService mService; 107 final Context mContext; 108 final Looper mLooper; 109 110 final ActivityStackSupervisorHandler mHandler; 111 112 /** Short cut */ 113 WindowManagerService mWindowManager; 114 115 /** Dismiss the keyguard after the next activity is displayed? */ 116 private boolean mDismissKeyguardOnNextActivity = false; 117 118 /** Identifier counter for all ActivityStacks */ 119 private int mLastStackId = HOME_STACK_ID; 120 121 /** Task identifier that activities are currently being started in. Incremented each time a 122 * new task is created. */ 123 private int mCurTaskId = 0; 124 125 /** The current user */ 126 private int mCurrentUser; 127 128 /** The stack containing the launcher app */ 129 private ActivityStack mHomeStack; 130 131 /** The non-home stack currently receiving input or launching the next activity. If home is 132 * in front then mHomeStack overrides mFocusedStack. 133 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */ 134 private ActivityStack mFocusedStack; 135 136 /** All the non-launcher stacks */ 137 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 138 139 private static final int STACK_STATE_HOME_IN_FRONT = 0; 140 private static final int STACK_STATE_HOME_TO_BACK = 1; 141 private static final int STACK_STATE_HOME_IN_BACK = 2; 142 private static final int STACK_STATE_HOME_TO_FRONT = 3; 143 private int mStackState = STACK_STATE_HOME_IN_FRONT; 144 145 /** List of activities that are waiting for a new activity to become visible before completing 146 * whatever operation they are supposed to do. */ 147 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); 148 149 /** List of processes waiting to find out about the next visible activity. */ 150 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = 151 new ArrayList<IActivityManager.WaitResult>(); 152 153 /** List of processes waiting to find out about the next launched activity. */ 154 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = 155 new ArrayList<IActivityManager.WaitResult>(); 156 157 /** List of activities that are ready to be stopped, but waiting for the next activity to 158 * settle down before doing so. */ 159 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); 160 161 /** List of activities that are ready to be finished, but waiting for the previous activity to 162 * settle down before doing so. It contains ActivityRecord objects. */ 163 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>(); 164 165 /** List of activities that are in the process of going to sleep. */ 166 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>(); 167 168 /** List of ActivityRecord objects that have been finished and must still report back to a 169 * pending thumbnail receiver. */ 170 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>(); 171 172 /** Used on user changes */ 173 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>(); 174 175 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 176 * is being brought in front of us. */ 177 boolean mUserLeaving = false; 178 179 /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */ 180 final SparseArray<UserState> mUserStates = new SparseArray<UserState>(); 181 182 /** Set when we have taken too long waiting to go to sleep. */ 183 boolean mSleepTimeout = false; 184 185 /** 186 * Set when the system is going to sleep, until we have 187 * successfully paused the current activity and released our wake lock. 188 * At that point the system is allowed to actually sleep. 189 */ 190 final PowerManager.WakeLock mGoingToSleep; 191 192 public ActivityStackSupervisor(ActivityManagerService service, Context context, 193 Looper looper) { 194 mService = service; 195 mContext = context; 196 mLooper = looper; 197 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 198 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 199 mHandler = new ActivityStackSupervisorHandler(looper); 200 } 201 202 void setWindowManager(WindowManagerService wm) { 203 mWindowManager = wm; 204 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID); 205 mStacks.add(mHomeStack); 206 } 207 208 void dismissKeyguard() { 209 if (mDismissKeyguardOnNextActivity) { 210 mDismissKeyguardOnNextActivity = false; 211 mWindowManager.dismissKeyguard(); 212 } 213 } 214 215 ActivityStack getFocusedStack() { 216 if (mFocusedStack == null) { 217 return mHomeStack; 218 } 219 switch (mStackState) { 220 case STACK_STATE_HOME_IN_FRONT: 221 case STACK_STATE_HOME_TO_FRONT: 222 return mHomeStack; 223 case STACK_STATE_HOME_IN_BACK: 224 case STACK_STATE_HOME_TO_BACK: 225 default: 226 return mFocusedStack; 227 } 228 } 229 230 ActivityStack getLastStack() { 231 switch (mStackState) { 232 case STACK_STATE_HOME_IN_FRONT: 233 case STACK_STATE_HOME_TO_BACK: 234 return mHomeStack; 235 case STACK_STATE_HOME_TO_FRONT: 236 case STACK_STATE_HOME_IN_BACK: 237 default: 238 return mFocusedStack; 239 } 240 } 241 242 boolean isFrontStack(ActivityStack stack) { 243 return (stack.mCurrentUser == mCurrentUser) && 244 !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); 245 } 246 247 void moveHomeStack(boolean toFront) { 248 final boolean homeInFront = isFrontStack(mHomeStack); 249 if (homeInFront ^ toFront) { 250 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" + 251 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ? 252 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT)); 253 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT; 254 } 255 } 256 257 boolean resumeHomeActivity(ActivityRecord prev) { 258 moveHomeStack(true); 259 if (prev != null) { 260 prev.mLaunchHomeTaskNext = false; 261 } 262 if (mHomeStack.topRunningActivityLocked(null) != null) { 263 return resumeTopActivitiesLocked(mHomeStack, prev, null); 264 } 265 return mService.startHomeActivityLocked(mCurrentUser); 266 } 267 268 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r, 269 ActivityStack stack) { 270 if (stack == mHomeStack) { 271 return; 272 } 273 if ((sourceRecord == null && getLastStack() == mHomeStack) || 274 (sourceRecord != null && sourceRecord.isHomeActivity())) { 275 if (r == null) { 276 r = stack.topRunningActivityLocked(null); 277 } 278 if (r != null && !r.isHomeActivity() && r.isRootActivity()) { 279 r.mLaunchHomeTaskNext = true; 280 } 281 } 282 } 283 284 void setDismissKeyguard(boolean dismiss) { 285 mDismissKeyguardOnNextActivity = dismiss; 286 } 287 288 TaskRecord anyTaskForIdLocked(int id) { 289 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 290 ActivityStack stack = mStacks.get(stackNdx); 291 TaskRecord task = stack.taskForIdLocked(id); 292 if (task != null) { 293 return task; 294 } 295 } 296 return null; 297 } 298 299 ActivityRecord isInAnyStackLocked(IBinder token) { 300 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 301 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token); 302 if (r != null) { 303 return r; 304 } 305 } 306 return null; 307 } 308 309 int getNextTaskId() { 310 do { 311 mCurTaskId++; 312 if (mCurTaskId <= 0) { 313 mCurTaskId = 1; 314 } 315 } while (anyTaskForIdLocked(mCurTaskId) != null); 316 return mCurTaskId; 317 } 318 319 void removeTask(TaskRecord task) { 320 mWindowManager.removeTask(task.taskId); 321 final ActivityStack stack = task.stack; 322 final ActivityRecord r = stack.mResumedActivity; 323 if (r != null && r.task == task) { 324 stack.mResumedActivity = null; 325 } 326 if (stack.removeTask(task) && !stack.isHomeStack()) { 327 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); 328 mStacks.remove(stack); 329 final int stackId = stack.mStackId; 330 final int nextStackId = mWindowManager.removeStack(stackId); 331 // TODO: Perhaps we need to let the ActivityManager determine the next focus... 332 if (getFocusedStack().mStackId == stackId) { 333 // If this is the last app stack, set mFocusedStack to null. 334 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId); 335 } 336 } 337 } 338 339 ActivityRecord resumedAppLocked() { 340 ActivityStack stack = getFocusedStack(); 341 if (stack == null) { 342 return null; 343 } 344 ActivityRecord resumedActivity = stack.mResumedActivity; 345 if (resumedActivity == null || resumedActivity.app == null) { 346 resumedActivity = stack.mPausingActivity; 347 if (resumedActivity == null || resumedActivity.app == null) { 348 resumedActivity = stack.topRunningActivityLocked(null); 349 } 350 } 351 return resumedActivity; 352 } 353 354 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception { 355 boolean didSomething = false; 356 final String processName = app.processName; 357 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 358 final ActivityStack stack = mStacks.get(stackNdx); 359 if (!isFrontStack(stack)) { 360 continue; 361 } 362 ActivityRecord hr = stack.topRunningActivityLocked(null); 363 if (hr != null) { 364 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 365 && processName.equals(hr.processName)) { 366 try { 367 if (headless) { 368 Slog.e(TAG, "Starting activities not supported on headless device: " 369 + hr); 370 } else if (realStartActivityLocked(hr, app, true, true)) { 371 didSomething = true; 372 } 373 } catch (Exception e) { 374 Slog.w(TAG, "Exception in new application when starting activity " 375 + hr.intent.getComponent().flattenToShortString(), e); 376 throw e; 377 } 378 } 379 } 380 } 381 if (!didSomething) { 382 ensureActivitiesVisibleLocked(null, 0); 383 } 384 return didSomething; 385 } 386 387 boolean allResumedActivitiesIdle() { 388 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 389 final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity; 390 if (resumedActivity == null || !resumedActivity.idle) { 391 return false; 392 } 393 } 394 return true; 395 } 396 397 boolean allResumedActivitiesComplete() { 398 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 399 final ActivityStack stack = mStacks.get(stackNdx); 400 if (isFrontStack(stack)) { 401 final ActivityRecord r = stack.mResumedActivity; 402 if (r != null && r.state != ActivityState.RESUMED) { 403 return false; 404 } 405 } 406 } 407 // TODO: Not sure if this should check if all Paused are complete too. 408 switch (mStackState) { 409 case STACK_STATE_HOME_TO_BACK: 410 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + 411 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" + 412 stackStateToString(STACK_STATE_HOME_IN_BACK)); 413 mStackState = STACK_STATE_HOME_IN_BACK; 414 break; 415 case STACK_STATE_HOME_TO_FRONT: 416 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + 417 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" + 418 stackStateToString(STACK_STATE_HOME_IN_FRONT)); 419 mStackState = STACK_STATE_HOME_IN_FRONT; 420 break; 421 } 422 return true; 423 } 424 425 boolean allResumedActivitiesVisible() { 426 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 427 final ActivityStack stack = mStacks.get(stackNdx); 428 final ActivityRecord r = stack.mResumedActivity; 429 if (r != null && (!r.nowVisible || r.waitingVisible)) { 430 return false; 431 } 432 } 433 return true; 434 } 435 436 boolean pauseBackStacks(boolean userLeaving) { 437 boolean someActivityPaused = false; 438 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 439 final ActivityStack stack = mStacks.get(stackNdx); 440 if (!isFrontStack(stack) && stack.mResumedActivity != null) { 441 stack.startPausingLocked(userLeaving, false); 442 someActivityPaused = true; 443 } 444 } 445 return someActivityPaused; 446 } 447 448 boolean allPausedActivitiesComplete() { 449 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 450 final ActivityStack stack = mStacks.get(stackNdx); 451 final ActivityRecord r = stack.mPausingActivity; 452 if (r != null && r.state != ActivityState.PAUSED 453 && r.state != ActivityState.STOPPED 454 && r.state != ActivityState.STOPPING) { 455 return false; 456 } 457 } 458 return true; 459 } 460 461 void reportActivityVisibleLocked(ActivityRecord r) { 462 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 463 WaitResult w = mWaitingActivityVisible.get(i); 464 w.timeout = false; 465 if (r != null) { 466 w.who = new ComponentName(r.info.packageName, r.info.name); 467 } 468 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 469 w.thisTime = w.totalTime; 470 } 471 mService.notifyAll(); 472 dismissKeyguard(); 473 } 474 475 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 476 long thisTime, long totalTime) { 477 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 478 WaitResult w = mWaitingActivityLaunched.remove(i); 479 w.timeout = timeout; 480 if (r != null) { 481 w.who = new ComponentName(r.info.packageName, r.info.name); 482 } 483 w.thisTime = thisTime; 484 w.totalTime = totalTime; 485 } 486 mService.notifyAll(); 487 } 488 489 ActivityRecord topRunningActivityLocked() { 490 final ActivityStack focusedStack = getFocusedStack(); 491 ActivityRecord r = focusedStack.topRunningActivityLocked(null); 492 if (r != null) { 493 return r; 494 } 495 496 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 497 final ActivityStack stack = mStacks.get(stackNdx); 498 if (stack.mCurrentUser == mCurrentUser && stack != focusedStack && 499 isFrontStack(stack)) { 500 r = stack.topRunningActivityLocked(null); 501 if (r != null) { 502 return r; 503 } 504 } 505 } 506 return null; 507 } 508 509 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, 510 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) { 511 ActivityRecord r = null; 512 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 513 final ActivityStack stack = mStacks.get(stackNdx); 514 final ActivityRecord ar = 515 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list); 516 if (isFrontStack(stack)) { 517 r = ar; 518 } 519 } 520 return r; 521 } 522 523 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 524 String profileFile, ParcelFileDescriptor profileFd, int userId) { 525 // Collect information about the target of the Intent. 526 ActivityInfo aInfo; 527 try { 528 ResolveInfo rInfo = 529 AppGlobals.getPackageManager().resolveIntent( 530 intent, resolvedType, 531 PackageManager.MATCH_DEFAULT_ONLY 532 | ActivityManagerService.STOCK_PM_FLAGS, userId); 533 aInfo = rInfo != null ? rInfo.activityInfo : null; 534 } catch (RemoteException e) { 535 aInfo = null; 536 } 537 538 if (aInfo != null) { 539 // Store the found target back into the intent, because now that 540 // we have it we never want to do this again. For example, if the 541 // user navigates back to this point in the history, we should 542 // always restart the exact same activity. 543 intent.setComponent(new ComponentName( 544 aInfo.applicationInfo.packageName, aInfo.name)); 545 546 // Don't debug things in the system process 547 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 548 if (!aInfo.processName.equals("system")) { 549 mService.setDebugApp(aInfo.processName, true, false); 550 } 551 } 552 553 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 554 if (!aInfo.processName.equals("system")) { 555 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 556 } 557 } 558 559 if (profileFile != null) { 560 if (!aInfo.processName.equals("system")) { 561 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, 562 profileFile, profileFd, 563 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0); 564 } 565 } 566 } 567 return aInfo; 568 } 569 570 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 571 moveHomeStack(true); 572 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, 573 null, false, null); 574 } 575 576 final int startActivityMayWait(IApplicationThread caller, int callingUid, 577 String callingPackage, Intent intent, String resolvedType, IBinder resultTo, 578 String resultWho, int requestCode, int startFlags, String profileFile, 579 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, 580 Bundle options, int userId) { 581 // Refuse possible leaked file descriptors 582 if (intent != null && intent.hasFileDescriptors()) { 583 throw new IllegalArgumentException("File descriptors passed in Intent"); 584 } 585 boolean componentSpecified = intent.getComponent() != null; 586 587 // Don't modify the client's object! 588 intent = new Intent(intent); 589 590 // Collect information about the target of the Intent. 591 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 592 profileFile, profileFd, userId); 593 594 synchronized (mService) { 595 int callingPid; 596 if (callingUid >= 0) { 597 callingPid = -1; 598 } else if (caller == null) { 599 callingPid = Binder.getCallingPid(); 600 callingUid = Binder.getCallingUid(); 601 } else { 602 callingPid = callingUid = -1; 603 } 604 605 final ActivityStack stack = getFocusedStack(); 606 stack.mConfigWillChange = config != null 607 && mService.mConfiguration.diff(config) != 0; 608 if (DEBUG_CONFIGURATION) Slog.v(TAG, 609 "Starting activity when config will change = " + stack.mConfigWillChange); 610 611 final long origId = Binder.clearCallingIdentity(); 612 613 if (aInfo != null && 614 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 615 // This may be a heavy-weight process! Check to see if we already 616 // have another, different heavy-weight process running. 617 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 618 if (mService.mHeavyWeightProcess != null && 619 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 620 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 621 int realCallingUid = callingUid; 622 if (caller != null) { 623 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 624 if (callerApp != null) { 625 realCallingUid = callerApp.info.uid; 626 } else { 627 Slog.w(TAG, "Unable to find app for caller " + caller 628 + " (pid=" + callingPid + ") when starting: " 629 + intent.toString()); 630 ActivityOptions.abort(options); 631 return ActivityManager.START_PERMISSION_DENIED; 632 } 633 } 634 635 IIntentSender target = mService.getIntentSenderLocked( 636 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 637 realCallingUid, userId, null, null, 0, new Intent[] { intent }, 638 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 639 | PendingIntent.FLAG_ONE_SHOT, null); 640 641 Intent newIntent = new Intent(); 642 if (requestCode >= 0) { 643 // Caller is requesting a result. 644 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 645 } 646 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 647 new IntentSender(target)); 648 if (mService.mHeavyWeightProcess.activities.size() > 0) { 649 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 650 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 651 hist.packageName); 652 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 653 hist.task.taskId); 654 } 655 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 656 aInfo.packageName); 657 newIntent.setFlags(intent.getFlags()); 658 newIntent.setClassName("android", 659 HeavyWeightSwitcherActivity.class.getName()); 660 intent = newIntent; 661 resolvedType = null; 662 caller = null; 663 callingUid = Binder.getCallingUid(); 664 callingPid = Binder.getCallingPid(); 665 componentSpecified = true; 666 try { 667 ResolveInfo rInfo = 668 AppGlobals.getPackageManager().resolveIntent( 669 intent, null, 670 PackageManager.MATCH_DEFAULT_ONLY 671 | ActivityManagerService.STOCK_PM_FLAGS, userId); 672 aInfo = rInfo != null ? rInfo.activityInfo : null; 673 aInfo = mService.getActivityInfoForUser(aInfo, userId); 674 } catch (RemoteException e) { 675 aInfo = null; 676 } 677 } 678 } 679 } 680 681 int res = startActivityLocked(caller, intent, resolvedType, 682 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, 683 callingPackage, startFlags, options, componentSpecified, null); 684 685 if (stack.mConfigWillChange) { 686 // If the caller also wants to switch to a new configuration, 687 // do so now. This allows a clean switch, as we are waiting 688 // for the current activity to pause (so we will not destroy 689 // it), and have not yet started the next activity. 690 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 691 "updateConfiguration()"); 692 stack.mConfigWillChange = false; 693 if (DEBUG_CONFIGURATION) Slog.v(TAG, 694 "Updating to new configuration after starting activity."); 695 mService.updateConfigurationLocked(config, null, false, false); 696 } 697 698 Binder.restoreCallingIdentity(origId); 699 700 if (outResult != null) { 701 outResult.result = res; 702 if (res == ActivityManager.START_SUCCESS) { 703 mWaitingActivityLaunched.add(outResult); 704 do { 705 try { 706 mService.wait(); 707 } catch (InterruptedException e) { 708 } 709 } while (!outResult.timeout && outResult.who == null); 710 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 711 ActivityRecord r = stack.topRunningActivityLocked(null); 712 if (r.nowVisible) { 713 outResult.timeout = false; 714 outResult.who = new ComponentName(r.info.packageName, r.info.name); 715 outResult.totalTime = 0; 716 outResult.thisTime = 0; 717 } else { 718 outResult.thisTime = SystemClock.uptimeMillis(); 719 mWaitingActivityVisible.add(outResult); 720 do { 721 try { 722 mService.wait(); 723 } catch (InterruptedException e) { 724 } 725 } while (!outResult.timeout && outResult.who == null); 726 } 727 } 728 } 729 730 return res; 731 } 732 } 733 734 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 735 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 736 Bundle options, int userId) { 737 if (intents == null) { 738 throw new NullPointerException("intents is null"); 739 } 740 if (resolvedTypes == null) { 741 throw new NullPointerException("resolvedTypes is null"); 742 } 743 if (intents.length != resolvedTypes.length) { 744 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 745 } 746 747 748 int callingPid; 749 if (callingUid >= 0) { 750 callingPid = -1; 751 } else if (caller == null) { 752 callingPid = Binder.getCallingPid(); 753 callingUid = Binder.getCallingUid(); 754 } else { 755 callingPid = callingUid = -1; 756 } 757 final long origId = Binder.clearCallingIdentity(); 758 try { 759 synchronized (mService) { 760 ActivityRecord[] outActivity = new ActivityRecord[1]; 761 for (int i=0; i<intents.length; i++) { 762 Intent intent = intents[i]; 763 if (intent == null) { 764 continue; 765 } 766 767 // Refuse possible leaked file descriptors 768 if (intent != null && intent.hasFileDescriptors()) { 769 throw new IllegalArgumentException("File descriptors passed in Intent"); 770 } 771 772 boolean componentSpecified = intent.getComponent() != null; 773 774 // Don't modify the client's object! 775 intent = new Intent(intent); 776 777 // Collect information about the target of the Intent. 778 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 779 0, null, null, userId); 780 // TODO: New, check if this is correct 781 aInfo = mService.getActivityInfoForUser(aInfo, userId); 782 783 if (aInfo != null && 784 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 785 != 0) { 786 throw new IllegalArgumentException( 787 "FLAG_CANT_SAVE_STATE not supported here"); 788 } 789 790 Bundle theseOptions; 791 if (options != null && i == intents.length-1) { 792 theseOptions = options; 793 } else { 794 theseOptions = null; 795 } 796 int res = startActivityLocked(caller, intent, resolvedTypes[i], 797 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, 798 0, theseOptions, componentSpecified, outActivity); 799 if (res < 0) { 800 return res; 801 } 802 803 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 804 } 805 } 806 } finally { 807 Binder.restoreCallingIdentity(origId); 808 } 809 810 return ActivityManager.START_SUCCESS; 811 } 812 813 final boolean realStartActivityLocked(ActivityRecord r, 814 ProcessRecord app, boolean andResume, boolean checkConfig) 815 throws RemoteException { 816 817 r.startFreezingScreenLocked(app, 0); 818 mWindowManager.setAppVisibility(r.appToken, true); 819 820 // schedule launch ticks to collect information about slow apps. 821 r.startLaunchTickingLocked(); 822 823 // Have the window manager re-evaluate the orientation of 824 // the screen based on the new activity order. Note that 825 // as a result of this, it can call back into the activity 826 // manager with a new orientation. We don't care about that, 827 // because the activity is not currently running so we are 828 // just restarting it anyway. 829 if (checkConfig) { 830 Configuration config = mWindowManager.updateOrientationFromAppTokens( 831 mService.mConfiguration, 832 r.mayFreezeScreenLocked(app) ? r.appToken : null); 833 mService.updateConfigurationLocked(config, r, false, false); 834 } 835 836 r.app = app; 837 app.waitingToKill = null; 838 r.launchCount++; 839 r.lastLaunchTime = SystemClock.uptimeMillis(); 840 841 if (localLOGV) Slog.v(TAG, "Launching: " + r); 842 843 int idx = app.activities.indexOf(r); 844 if (idx < 0) { 845 app.activities.add(r); 846 } 847 mService.updateLruProcessLocked(app, true); 848 849 final ActivityStack stack = r.task.stack; 850 try { 851 if (app.thread == null) { 852 throw new RemoteException(); 853 } 854 List<ResultInfo> results = null; 855 List<Intent> newIntents = null; 856 if (andResume) { 857 results = r.results; 858 newIntents = r.newIntents; 859 } 860 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 861 + " icicle=" + r.icicle 862 + " with results=" + results + " newIntents=" + newIntents 863 + " andResume=" + andResume); 864 if (andResume) { 865 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 866 r.userId, System.identityHashCode(r), 867 r.task.taskId, r.shortComponentName); 868 } 869 if (r.isHomeActivity()) { 870 mService.mHomeProcess = app; 871 } 872 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 873 r.sleeping = false; 874 r.forceNewConfig = false; 875 mService.showAskCompatModeDialogLocked(r); 876 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 877 String profileFile = null; 878 ParcelFileDescriptor profileFd = null; 879 boolean profileAutoStop = false; 880 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 881 if (mService.mProfileProc == null || mService.mProfileProc == app) { 882 mService.mProfileProc = app; 883 profileFile = mService.mProfileFile; 884 profileFd = mService.mProfileFd; 885 profileAutoStop = mService.mAutoStopProfiler; 886 } 887 } 888 app.hasShownUi = true; 889 app.pendingUiClean = true; 890 if (profileFd != null) { 891 try { 892 profileFd = profileFd.dup(); 893 } catch (IOException e) { 894 if (profileFd != null) { 895 try { 896 profileFd.close(); 897 } catch (IOException o) { 898 } 899 profileFd = null; 900 } 901 } 902 } 903 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 904 System.identityHashCode(r), r.info, 905 new Configuration(mService.mConfiguration), 906 r.compat, r.icicle, results, newIntents, !andResume, 907 mService.isNextTransitionForward(), profileFile, profileFd, 908 profileAutoStop); 909 910 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 911 // This may be a heavy-weight process! Note that the package 912 // manager will ensure that only activity can run in the main 913 // process of the .apk, which is the only thing that will be 914 // considered heavy-weight. 915 if (app.processName.equals(app.info.packageName)) { 916 if (mService.mHeavyWeightProcess != null 917 && mService.mHeavyWeightProcess != app) { 918 Slog.w(TAG, "Starting new heavy weight process " + app 919 + " when already running " 920 + mService.mHeavyWeightProcess); 921 } 922 mService.mHeavyWeightProcess = app; 923 Message msg = mService.mHandler.obtainMessage( 924 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 925 msg.obj = r; 926 mService.mHandler.sendMessage(msg); 927 } 928 } 929 930 } catch (RemoteException e) { 931 if (r.launchFailed) { 932 // This is the second time we failed -- finish activity 933 // and give up. 934 Slog.e(TAG, "Second failure launching " 935 + r.intent.getComponent().flattenToShortString() 936 + ", giving up", e); 937 mService.appDiedLocked(app, app.pid, app.thread); 938 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 939 "2nd-crash", false); 940 return false; 941 } 942 943 // This is the first time we failed -- restart process and 944 // retry. 945 app.activities.remove(r); 946 throw e; 947 } 948 949 r.launchFailed = false; 950 if (stack.updateLRUListLocked(r)) { 951 Slog.w(TAG, "Activity " + r 952 + " being launched, but already in LRU list"); 953 } 954 955 if (andResume) { 956 // As part of the process of launching, ActivityThread also performs 957 // a resume. 958 stack.minimalResumeActivityLocked(r); 959 } else { 960 // This activity is not starting in the resumed state... which 961 // should look like we asked it to pause+stop (but remain visible), 962 // and it has done so and reported back the current icicle and 963 // other state. 964 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 965 + " (starting in stopped state)"); 966 r.state = ActivityState.STOPPED; 967 r.stopped = true; 968 } 969 970 // Launch the new version setup screen if needed. We do this -after- 971 // launching the initial activity (that is, home), so that it can have 972 // a chance to initialize itself while in the background, making the 973 // switch back to it faster and look better. 974 if (isFrontStack(stack)) { 975 mService.startSetupActivityLocked(); 976 } 977 978 return true; 979 } 980 981 void startSpecificActivityLocked(ActivityRecord r, 982 boolean andResume, boolean checkConfig) { 983 // Is this activity's application already running? 984 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 985 r.info.applicationInfo.uid); 986 987 r.task.stack.setLaunchTime(r); 988 989 if (app != null && app.thread != null) { 990 try { 991 app.addPackage(r.info.packageName, mService.mProcessTracker); 992 realStartActivityLocked(r, app, andResume, checkConfig); 993 return; 994 } catch (RemoteException e) { 995 Slog.w(TAG, "Exception when starting activity " 996 + r.intent.getComponent().flattenToShortString(), e); 997 } 998 999 // If a dead object exception was thrown -- fall through to 1000 // restart the application. 1001 } 1002 1003 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1004 "activity", r.intent.getComponent(), false, false); 1005 } 1006 1007 final int startActivityLocked(IApplicationThread caller, 1008 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, 1009 String resultWho, int requestCode, 1010 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1011 boolean componentSpecified, ActivityRecord[] outActivity) { 1012 int err = ActivityManager.START_SUCCESS; 1013 1014 ProcessRecord callerApp = null; 1015 if (caller != null) { 1016 callerApp = mService.getRecordForAppLocked(caller); 1017 if (callerApp != null) { 1018 callingPid = callerApp.pid; 1019 callingUid = callerApp.info.uid; 1020 } else { 1021 Slog.w(TAG, "Unable to find app for caller " + caller 1022 + " (pid=" + callingPid + ") when starting: " 1023 + intent.toString()); 1024 err = ActivityManager.START_PERMISSION_DENIED; 1025 } 1026 } 1027 1028 if (err == ActivityManager.START_SUCCESS) { 1029 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1030 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1031 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); 1032 } 1033 1034 ActivityRecord sourceRecord = null; 1035 ActivityRecord resultRecord = null; 1036 if (resultTo != null) { 1037 sourceRecord = isInAnyStackLocked(resultTo); 1038 if (DEBUG_RESULTS) Slog.v( 1039 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1040 if (sourceRecord != null) { 1041 if (requestCode >= 0 && !sourceRecord.finishing) { 1042 resultRecord = sourceRecord; 1043 } 1044 } 1045 } 1046 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1047 1048 int launchFlags = intent.getFlags(); 1049 1050 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1051 && sourceRecord != null) { 1052 // Transfer the result target from the source activity to the new 1053 // one being started, including any failures. 1054 if (requestCode >= 0) { 1055 ActivityOptions.abort(options); 1056 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1057 } 1058 resultRecord = sourceRecord.resultTo; 1059 resultWho = sourceRecord.resultWho; 1060 requestCode = sourceRecord.requestCode; 1061 sourceRecord.resultTo = null; 1062 if (resultRecord != null) { 1063 resultRecord.removeResultsLocked( 1064 sourceRecord, resultWho, requestCode); 1065 } 1066 } 1067 1068 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1069 // We couldn't find a class that can handle the given Intent. 1070 // That's the end of that! 1071 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1072 } 1073 1074 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1075 // We couldn't find the specific class specified in the Intent. 1076 // Also the end of the line. 1077 err = ActivityManager.START_CLASS_NOT_FOUND; 1078 } 1079 1080 if (err != ActivityManager.START_SUCCESS) { 1081 if (resultRecord != null) { 1082 resultStack.sendActivityResultLocked(-1, 1083 resultRecord, resultWho, requestCode, 1084 Activity.RESULT_CANCELED, null); 1085 } 1086 setDismissKeyguard(false); 1087 ActivityOptions.abort(options); 1088 return err; 1089 } 1090 1091 final int startAnyPerm = mService.checkPermission( 1092 START_ANY_ACTIVITY, callingPid, callingUid); 1093 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1094 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1095 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1096 if (resultRecord != null) { 1097 resultStack.sendActivityResultLocked(-1, 1098 resultRecord, resultWho, requestCode, 1099 Activity.RESULT_CANCELED, null); 1100 } 1101 setDismissKeyguard(false); 1102 String msg; 1103 if (!aInfo.exported) { 1104 msg = "Permission Denial: starting " + intent.toString() 1105 + " from " + callerApp + " (pid=" + callingPid 1106 + ", uid=" + callingUid + ")" 1107 + " not exported from uid " + aInfo.applicationInfo.uid; 1108 } else { 1109 msg = "Permission Denial: starting " + intent.toString() 1110 + " from " + callerApp + " (pid=" + callingPid 1111 + ", uid=" + callingUid + ")" 1112 + " requires " + aInfo.permission; 1113 } 1114 Slog.w(TAG, msg); 1115 throw new SecurityException(msg); 1116 } 1117 1118 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, 1119 callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo); 1120 1121 if (mService.mController != null) { 1122 try { 1123 // The Intent we give to the watcher has the extra data 1124 // stripped off, since it can contain private information. 1125 Intent watchIntent = intent.cloneFilter(); 1126 abort |= !mService.mController.activityStarting(watchIntent, 1127 aInfo.applicationInfo.packageName); 1128 } catch (RemoteException e) { 1129 mService.mController = null; 1130 } 1131 } 1132 1133 if (abort) { 1134 if (resultRecord != null) { 1135 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1136 Activity.RESULT_CANCELED, null); 1137 } 1138 // We pretend to the caller that it was really started, but 1139 // they will just get a cancel result. 1140 setDismissKeyguard(false); 1141 ActivityOptions.abort(options); 1142 return ActivityManager.START_SUCCESS; 1143 } 1144 1145 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1146 intent, resolvedType, aInfo, mService.mConfiguration, 1147 resultRecord, resultWho, requestCode, componentSpecified, this); 1148 if (outActivity != null) { 1149 outActivity[0] = r; 1150 } 1151 1152 final ActivityStack stack = getFocusedStack(); 1153 if (stack.mResumedActivity == null 1154 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { 1155 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1156 PendingActivityLaunch pal = 1157 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1158 mService.mPendingActivityLaunches.add(pal); 1159 setDismissKeyguard(false); 1160 ActivityOptions.abort(options); 1161 return ActivityManager.START_SWITCHES_CANCELED; 1162 } 1163 } 1164 1165 if (mService.mDidAppSwitch) { 1166 // This is the second allowed switch since we stopped switches, 1167 // so now just generally allow switches. Use case: user presses 1168 // home (switches disabled, switch to home, mDidAppSwitch now true); 1169 // user taps a home icon (coming from home so allowed, we hit here 1170 // and now allow anyone to switch again). 1171 mService.mAppSwitchesAllowedTime = 0; 1172 } else { 1173 mService.mDidAppSwitch = true; 1174 } 1175 1176 mService.doPendingActivityLaunchesLocked(false); 1177 1178 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); 1179 if (stack.mPausingActivity == null) { 1180 // Someone asked to have the keyguard dismissed on the next 1181 // activity start, but we are not actually doing an activity 1182 // switch... just dismiss the keyguard now, because we 1183 // probably want to see whatever is behind it. 1184 dismissKeyguard(); 1185 } 1186 return err; 1187 } 1188 1189 ActivityStack getCorrectStack(ActivityRecord r) { 1190 final TaskRecord task = r.task; 1191 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1192 int stackNdx; 1193 for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) { 1194 if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) { 1195 break; 1196 } 1197 } 1198 if (stackNdx == 0) { 1199 // Time to create the first app stack for this user. 1200 int stackId = mService.createStack(-1, HOME_STACK_ID, 1201 StackBox.TASK_STACK_GOES_OVER, 1.0f); 1202 if (DEBUG_FOCUS) Slog.d(TAG, "getCorrectStack: New stack r=" + r + " stackId=" 1203 + stackId); 1204 mFocusedStack = getStack(stackId); 1205 } 1206 if (task != null) { 1207 if (DEBUG_FOCUS) Slog.d(TAG, "getCorrectStack: Setting focused stack to r=" + 1208 r + " task=" + task); 1209 mFocusedStack = task.stack; 1210 } 1211 return mFocusedStack; 1212 } 1213 return mHomeStack; 1214 } 1215 1216 void setFocusedStack(ActivityRecord r) { 1217 if (r == null) { 1218 return; 1219 } 1220 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) { 1221 if (mStackState != STACK_STATE_HOME_IN_FRONT) { 1222 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" + 1223 stackStateToString(mStackState) + " new=" + 1224 stackStateToString(STACK_STATE_HOME_TO_FRONT) + 1225 " Callers=" + Debug.getCallers(3)); 1226 mStackState = STACK_STATE_HOME_TO_FRONT; 1227 } 1228 } else { 1229 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: Setting focused stack to r=" + 1230 r + " task=" + r.task + " Callers=" + Debug.getCallers(3)); 1231 mFocusedStack = r.task.stack; 1232 if (mStackState != STACK_STATE_HOME_IN_BACK) { 1233 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" + 1234 stackStateToString(mStackState) + " new=" + 1235 stackStateToString(STACK_STATE_HOME_TO_BACK) + 1236 " Callers=" + Debug.getCallers(3)); 1237 mStackState = STACK_STATE_HOME_TO_BACK; 1238 } 1239 } 1240 } 1241 1242 final int startActivityUncheckedLocked(ActivityRecord r, 1243 ActivityRecord sourceRecord, int startFlags, boolean doResume, 1244 Bundle options) { 1245 final Intent intent = r.intent; 1246 final int callingUid = r.launchedFromUid; 1247 1248 int launchFlags = intent.getFlags(); 1249 1250 // We'll invoke onUserLeaving before onPause only if the launching 1251 // activity did not explicitly state that this is an automated launch. 1252 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1253 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1254 1255 // If the caller has asked not to resume at this point, we make note 1256 // of this in the record so that we can skip it when trying to find 1257 // the top running activity. 1258 if (!doResume) { 1259 r.delayedResume = true; 1260 } 1261 1262 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1263 1264 // If the onlyIfNeeded flag is set, then we can do this if the activity 1265 // being launched is the same as the one making the call... or, as 1266 // a special case, if we do not know the caller then we count the 1267 // current top activity as the caller. 1268 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1269 ActivityRecord checkedCaller = sourceRecord; 1270 if (checkedCaller == null) { 1271 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1272 } 1273 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1274 // Caller is not the same as launcher, so always needed. 1275 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1276 } 1277 } 1278 1279 if (sourceRecord == null) { 1280 // This activity is not being started from another... in this 1281 // case we -always- start a new task. 1282 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1283 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1284 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1285 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1286 } 1287 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1288 // The original activity who is starting us is running as a single 1289 // instance... this new activity it is starting must go on its 1290 // own task. 1291 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1292 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1293 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1294 // The activity being started is a single instance... it always 1295 // gets launched into its own task. 1296 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1297 } 1298 1299 final ActivityStack sourceStack; 1300 TaskRecord sourceTask; 1301 if (sourceRecord != null) { 1302 sourceTask = sourceRecord.task; 1303 sourceStack = sourceTask.stack; 1304 } else { 1305 sourceTask = null; 1306 sourceStack = null; 1307 } 1308 1309 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1310 // For whatever reason this activity is being launched into a new 1311 // task... yet the caller has requested a result back. Well, that 1312 // is pretty messed up, so instead immediately send back a cancel 1313 // and let the new task continue launched as normal without a 1314 // dependency on its originator. 1315 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1316 r.resultTo.task.stack.sendActivityResultLocked(-1, 1317 r.resultTo, r.resultWho, r.requestCode, 1318 Activity.RESULT_CANCELED, null); 1319 r.resultTo = null; 1320 } 1321 1322 boolean addingToTask = false; 1323 boolean movedHome = false; 1324 TaskRecord reuseTask = null; 1325 ActivityStack targetStack; 1326 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1327 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1328 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1329 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1330 // If bring to front is requested, and no result is requested, and 1331 // we can find a task that was started with this same 1332 // component, then instead of launching bring that one to the front. 1333 if (r.resultTo == null) { 1334 // See if there is a task to bring to the front. If this is 1335 // a SINGLE_INSTANCE activity, there can be one and only one 1336 // instance of it in the history, and it is always in its own 1337 // unique task, so we do a special search. 1338 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1339 ? findTaskLocked(intent, r.info) 1340 : findActivityLocked(intent, r.info); 1341 if (intentActivity != null) { 1342 if (r.task == null) { 1343 r.task = intentActivity.task; 1344 } 1345 targetStack = intentActivity.task.stack; 1346 moveHomeStack(targetStack.isHomeStack()); 1347 if (intentActivity.task.intent == null) { 1348 // This task was started because of movement of 1349 // the activity based on affinity... now that we 1350 // are actually launching it, we can assign the 1351 // base intent. 1352 intentActivity.task.setIntent(intent, r.info); 1353 } 1354 // If the target task is not in the front, then we need 1355 // to bring it to the front... except... well, with 1356 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1357 // to have the same behavior as if a new instance was 1358 // being started, which means not bringing it to the front 1359 // if the caller is not itself in the front. 1360 final ActivityStack lastStack = getLastStack(); 1361 ActivityRecord curTop = lastStack == null? 1362 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1363 if (curTop != null && curTop.task != intentActivity.task) { 1364 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1365 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) { 1366 // We really do want to push this one into the 1367 // user's face, right now. 1368 movedHome = true; 1369 if ((launchFlags & 1370 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1371 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1372 // Caller wants to appear on home activity, so before starting 1373 // their own activity we will bring home to the front. 1374 r.mLaunchHomeTaskNext = true; 1375 } 1376 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1377 options = null; 1378 } 1379 } 1380 // If the caller has requested that the target task be 1381 // reset, then do so. 1382 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1383 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1384 } 1385 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1386 // We don't need to start a new activity, and 1387 // the client said not to do anything if that 1388 // is the case, so this is it! And for paranoia, make 1389 // sure we have correctly resumed the top activity. 1390 if (doResume) { 1391 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1392 resumeTopActivitiesLocked(targetStack, null, options); 1393 } else { 1394 ActivityOptions.abort(options); 1395 } 1396 if (r.task == null) Slog.v(TAG, 1397 "startActivityUncheckedLocked: task left null", 1398 new RuntimeException("here").fillInStackTrace()); 1399 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1400 } 1401 if ((launchFlags & 1402 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1403 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1404 // The caller has requested to completely replace any 1405 // existing task with its new activity. Well that should 1406 // not be too hard... 1407 reuseTask = intentActivity.task; 1408 reuseTask.performClearTaskLocked(); 1409 reuseTask.setIntent(r.intent, r.info); 1410 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1411 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1412 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1413 // In this situation we want to remove all activities 1414 // from the task up to the one being started. In most 1415 // cases this means we are resetting the task to its 1416 // initial state. 1417 ActivityRecord top = 1418 intentActivity.task.performClearTaskLocked(r, launchFlags); 1419 if (top != null) { 1420 if (top.frontOfTask) { 1421 // Activity aliases may mean we use different 1422 // intents for the top activity, so make sure 1423 // the task now has the identity of the new 1424 // intent. 1425 top.task.setIntent(r.intent, r.info); 1426 } 1427 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1428 r, top.task); 1429 top.deliverNewIntentLocked(callingUid, r.intent); 1430 } else { 1431 // A special case: we need to 1432 // start the activity because it is not currently 1433 // running, and the caller has asked to clear the 1434 // current task to have this activity at the top. 1435 addingToTask = true; 1436 // Now pretend like this activity is being started 1437 // by the top of its task, so it is put in the 1438 // right place. 1439 sourceRecord = intentActivity; 1440 } 1441 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1442 // In this case the top activity on the task is the 1443 // same as the one being launched, so we take that 1444 // as a request to bring the task to the foreground. 1445 // If the top activity in the task is the root 1446 // activity, deliver this new intent to it if it 1447 // desires. 1448 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1449 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1450 && intentActivity.realActivity.equals(r.realActivity)) { 1451 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1452 intentActivity.task); 1453 if (intentActivity.frontOfTask) { 1454 intentActivity.task.setIntent(r.intent, r.info); 1455 } 1456 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1457 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1458 // In this case we are launching the root activity 1459 // of the task, but with a different intent. We 1460 // should start a new instance on top. 1461 addingToTask = true; 1462 sourceRecord = intentActivity; 1463 } 1464 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1465 // In this case an activity is being launched in to an 1466 // existing task, without resetting that task. This 1467 // is typically the situation of launching an activity 1468 // from a notification or shortcut. We want to place 1469 // the new activity on top of the current task. 1470 addingToTask = true; 1471 sourceRecord = intentActivity; 1472 } else if (!intentActivity.task.rootWasReset) { 1473 // In this case we are launching in to an existing task 1474 // that has not yet been started from its front door. 1475 // The current task has been brought to the front. 1476 // Ideally, we'd probably like to place this new task 1477 // at the bottom of its stack, but that's a little hard 1478 // to do with the current organization of the code so 1479 // for now we'll just drop it. 1480 intentActivity.task.setIntent(r.intent, r.info); 1481 } 1482 if (!addingToTask && reuseTask == null) { 1483 // We didn't do anything... but it was needed (a.k.a., client 1484 // don't use that intent!) And for paranoia, make 1485 // sure we have correctly resumed the top activity. 1486 if (doResume) { 1487 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack); 1488 targetStack.resumeTopActivityLocked(null, options); 1489 } else { 1490 ActivityOptions.abort(options); 1491 } 1492 if (r.task == null) Slog.v(TAG, 1493 "startActivityUncheckedLocked: task left null", 1494 new RuntimeException("here").fillInStackTrace()); 1495 return ActivityManager.START_TASK_TO_FRONT; 1496 } 1497 } 1498 } 1499 } 1500 1501 //String uri = r.intent.toURI(); 1502 //Intent intent2 = new Intent(uri); 1503 //Slog.i(TAG, "Given intent: " + r.intent); 1504 //Slog.i(TAG, "URI is: " + uri); 1505 //Slog.i(TAG, "To intent: " + intent2); 1506 1507 if (r.packageName != null) { 1508 // If the activity being launched is the same as the one currently 1509 // at the top, then we need to check if it should only be launched 1510 // once. 1511 ActivityStack topStack = getFocusedStack(); 1512 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1513 if (top != null && r.resultTo == null) { 1514 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1515 if (top.app != null && top.app.thread != null) { 1516 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1517 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1518 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1519 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1520 top.task); 1521 // For paranoia, make sure we have correctly 1522 // resumed the top activity. 1523 if (doResume) { 1524 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack); 1525 resumeTopActivitiesLocked(); 1526 } 1527 ActivityOptions.abort(options); 1528 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1529 // We don't need to start a new activity, and 1530 // the client said not to do anything if that 1531 // is the case, so this is it! 1532 if (r.task == null) Slog.v(TAG, 1533 "startActivityUncheckedLocked: task left null", 1534 new RuntimeException("here").fillInStackTrace()); 1535 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1536 } 1537 top.deliverNewIntentLocked(callingUid, r.intent); 1538 if (r.task == null) Slog.v(TAG, 1539 "startActivityUncheckedLocked: task left null", 1540 new RuntimeException("here").fillInStackTrace()); 1541 return ActivityManager.START_DELIVERED_TO_TOP; 1542 } 1543 } 1544 } 1545 } 1546 1547 } else { 1548 if (r.resultTo != null) { 1549 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1550 r.requestCode, Activity.RESULT_CANCELED, null); 1551 } 1552 ActivityOptions.abort(options); 1553 if (r.task == null) Slog.v(TAG, 1554 "startActivityUncheckedLocked: task left null", 1555 new RuntimeException("here").fillInStackTrace()); 1556 return ActivityManager.START_CLASS_NOT_FOUND; 1557 } 1558 1559 boolean newTask = false; 1560 boolean keepCurTransition = false; 1561 1562 // Should this be considered a new task? 1563 if (r.resultTo == null && !addingToTask 1564 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1565 targetStack = getCorrectStack(r); 1566 moveHomeStack(targetStack.isHomeStack()); 1567 if (reuseTask == null) { 1568 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1569 null, true); 1570 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1571 r.task); 1572 } else { 1573 r.setTask(reuseTask, reuseTask, true); 1574 } 1575 newTask = true; 1576 if (!movedHome) { 1577 if ((launchFlags & 1578 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1579 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1580 // Caller wants to appear on home activity, so before starting 1581 // their own activity we will bring home to the front. 1582 r.mLaunchHomeTaskNext = true; 1583 } 1584 } 1585 } else if (sourceRecord != null) { 1586 sourceTask = sourceRecord.task; 1587 targetStack = sourceTask.stack; 1588 moveHomeStack(targetStack.isHomeStack()); 1589 if (!addingToTask && 1590 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1591 // In this case, we are adding the activity to an existing 1592 // task, but the caller has asked to clear that task if the 1593 // activity is already running. 1594 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1595 keepCurTransition = true; 1596 if (top != null) { 1597 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1598 top.deliverNewIntentLocked(callingUid, r.intent); 1599 // For paranoia, make sure we have correctly 1600 // resumed the top activity. 1601 if (doResume) { 1602 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1603 targetStack.resumeTopActivityLocked(null); 1604 } 1605 ActivityOptions.abort(options); 1606 if (r.task == null) Slog.v(TAG, 1607 "startActivityUncheckedLocked: task left null", 1608 new RuntimeException("here").fillInStackTrace()); 1609 return ActivityManager.START_DELIVERED_TO_TOP; 1610 } 1611 } else if (!addingToTask && 1612 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1613 // In this case, we are launching an activity in our own task 1614 // that may already be running somewhere in the history, and 1615 // we want to shuffle it to the front of the stack if so. 1616 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1617 if (top != null) { 1618 final TaskRecord task = top.task; 1619 task.moveActivityToFrontLocked(top); 1620 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1621 top.updateOptionsLocked(options); 1622 top.deliverNewIntentLocked(callingUid, r.intent); 1623 if (doResume) { 1624 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1625 targetStack.resumeTopActivityLocked(null); 1626 } 1627 if (r.task == null) Slog.v(TAG, 1628 "startActivityUncheckedLocked: task left null", 1629 new RuntimeException("here").fillInStackTrace()); 1630 return ActivityManager.START_DELIVERED_TO_TOP; 1631 } 1632 } 1633 // An existing activity is starting this new activity, so we want 1634 // to keep the new one in the same task as the one that is starting 1635 // it. 1636 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1637 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1638 + " in existing task " + r.task); 1639 1640 } else { 1641 // This not being started from an existing activity, and not part 1642 // of a new task... just put it in the top task, though these days 1643 // this case should never happen. 1644 targetStack = getCorrectStack(r); 1645 moveHomeStack(targetStack.isHomeStack()); 1646 ActivityRecord prev = targetStack.topActivity(); 1647 r.setTask(prev != null ? prev.task 1648 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1649 null, true); 1650 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1651 + " in new guessed " + r.task); 1652 } 1653 1654 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1655 intent, r.getUriPermissionsLocked()); 1656 1657 if (newTask) { 1658 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1659 } 1660 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1661 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack); 1662 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1663 mService.setFocusedActivityLocked(r); 1664 return ActivityManager.START_SUCCESS; 1665 } 1666 1667 // Checked. 1668 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1669 Configuration config) { 1670 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1671 1672 ActivityRecord res = null; 1673 1674 ArrayList<ActivityRecord> stops = null; 1675 ArrayList<ActivityRecord> finishes = null; 1676 ArrayList<UserStartedState> startingUsers = null; 1677 int NS = 0; 1678 int NF = 0; 1679 IApplicationThread sendThumbnail = null; 1680 boolean booting = false; 1681 boolean enableScreen = false; 1682 boolean activityRemoved = false; 1683 1684 ActivityRecord r = ActivityRecord.forToken(token); 1685 if (r != null) { 1686 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1687 Debug.getCallers(4)); 1688 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1689 r.finishLaunchTickingLocked(); 1690 res = r.task.stack.activityIdleInternalLocked(token); 1691 if (res != null) { 1692 if (fromTimeout) { 1693 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1694 } 1695 1696 // This is a hack to semi-deal with a race condition 1697 // in the client where it can be constructed with a 1698 // newer configuration from when we asked it to launch. 1699 // We'll update with whatever configuration it now says 1700 // it used to launch. 1701 if (config != null) { 1702 r.configuration = config; 1703 } 1704 1705 // We are now idle. If someone is waiting for a thumbnail from 1706 // us, we can now deliver. 1707 r.idle = true; 1708 if (allResumedActivitiesIdle()) { 1709 mService.scheduleAppGcsLocked(); 1710 } 1711 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 1712 sendThumbnail = r.app.thread; 1713 r.thumbnailNeeded = false; 1714 } 1715 1716 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1717 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1718 mService.mBooted = true; 1719 enableScreen = true; 1720 } 1721 } else if (fromTimeout) { 1722 reportActivityLaunchedLocked(fromTimeout, null, -1, -1); 1723 } 1724 } 1725 1726 // Atomically retrieve all of the other things to do. 1727 stops = processStoppingActivitiesLocked(true); 1728 NS = stops != null ? stops.size() : 0; 1729 if ((NF=mFinishingActivities.size()) > 0) { 1730 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1731 mFinishingActivities.clear(); 1732 } 1733 1734 final ArrayList<ActivityRecord> thumbnails; 1735 final int NT = mCancelledThumbnails.size(); 1736 if (NT > 0) { 1737 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); 1738 mCancelledThumbnails.clear(); 1739 } else { 1740 thumbnails = null; 1741 } 1742 1743 if (isFrontStack(mHomeStack)) { 1744 booting = mService.mBooting; 1745 mService.mBooting = false; 1746 } 1747 1748 if (mStartingUsers.size() > 0) { 1749 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1750 mStartingUsers.clear(); 1751 } 1752 1753 // Perform the following actions from unsynchronized state. 1754 final IApplicationThread thumbnailThread = sendThumbnail; 1755 mHandler.post(new Runnable() { 1756 @Override 1757 public void run() { 1758 if (thumbnailThread != null) { 1759 try { 1760 thumbnailThread.requestThumbnail(token); 1761 } catch (Exception e) { 1762 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 1763 mService.sendPendingThumbnail(null, token, null, null, true); 1764 } 1765 } 1766 1767 // Report back to any thumbnail receivers. 1768 for (int i = 0; i < NT; i++) { 1769 ActivityRecord r = thumbnails.get(i); 1770 mService.sendPendingThumbnail(r, null, null, null, true); 1771 } 1772 } 1773 }); 1774 1775 // Stop any activities that are scheduled to do so but have been 1776 // waiting for the next one to start. 1777 for (int i = 0; i < NS; i++) { 1778 r = stops.get(i); 1779 final ActivityStack stack = r.task.stack; 1780 if (r.finishing) { 1781 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1782 } else { 1783 stack.stopActivityLocked(r); 1784 } 1785 } 1786 1787 // Finish any activities that are scheduled to do so but have been 1788 // waiting for the next one to start. 1789 for (int i = 0; i < NF; i++) { 1790 r = finishes.get(i); 1791 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1792 } 1793 1794 if (booting) { 1795 mService.finishBooting(); 1796 } else if (startingUsers != null) { 1797 for (int i = 0; i < startingUsers.size(); i++) { 1798 mService.finishUserSwitch(startingUsers.get(i)); 1799 } 1800 } 1801 1802 mService.trimApplications(); 1803 //dump(); 1804 //mWindowManager.dump(); 1805 1806 if (enableScreen) { 1807 mService.enableScreenAfterBoot(); 1808 } 1809 1810 if (activityRemoved) { 1811 resumeTopActivitiesLocked(); 1812 } 1813 1814 return res; 1815 } 1816 1817 void handleAppDiedLocked(ProcessRecord app, boolean restarting) { 1818 // Just in case. 1819 final int numStacks = mStacks.size(); 1820 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1821 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting); 1822 } 1823 } 1824 1825 void closeSystemDialogsLocked() { 1826 final int numStacks = mStacks.size(); 1827 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1828 final ActivityStack stack = mStacks.get(stackNdx); 1829 stack.closeSystemDialogsLocked(); 1830 } 1831 } 1832 1833 /** 1834 * @return true if some activity was finished (or would have finished if doit were true). 1835 */ 1836 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 1837 boolean didSomething = false; 1838 final int numStacks = mStacks.size(); 1839 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1840 final ActivityStack stack = mStacks.get(stackNdx); 1841 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 1842 didSomething = true; 1843 } 1844 } 1845 return didSomething; 1846 } 1847 1848 boolean resumeTopActivitiesLocked() { 1849 return resumeTopActivitiesLocked(null, null, null); 1850 } 1851 1852 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 1853 Bundle targetOptions) { 1854 if (targetStack == null) { 1855 targetStack = getFocusedStack(); 1856 } 1857 boolean result = false; 1858 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1859 final ActivityStack stack = mStacks.get(stackNdx); 1860 if (isFrontStack(stack)) { 1861 if (stack == targetStack) { 1862 result = stack.resumeTopActivityLocked(target, targetOptions); 1863 } else { 1864 stack.resumeTopActivityLocked(null); 1865 } 1866 } 1867 } 1868 return result; 1869 } 1870 1871 void finishTopRunningActivityLocked(ProcessRecord app) { 1872 final int numStacks = mStacks.size(); 1873 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1874 final ActivityStack stack = mStacks.get(stackNdx); 1875 stack.finishTopRunningActivityLocked(app); 1876 } 1877 } 1878 1879 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 1880 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1881 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 1882 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + 1883 mStacks.get(stackNdx)); 1884 return; 1885 } 1886 } 1887 } 1888 1889 ActivityStack getStack(int stackId) { 1890 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1891 final ActivityStack stack = mStacks.get(stackNdx); 1892 if (stack.getStackId() == stackId) { 1893 return stack; 1894 } 1895 } 1896 return null; 1897 } 1898 1899 ArrayList<ActivityStack> getStacks() { 1900 return new ArrayList<ActivityStack>(mStacks); 1901 } 1902 1903 int createStack() { 1904 while (true) { 1905 if (++mLastStackId <= HOME_STACK_ID) { 1906 mLastStackId = HOME_STACK_ID + 1; 1907 } 1908 if (getStack(mLastStackId) == null) { 1909 break; 1910 } 1911 } 1912 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); 1913 return mLastStackId; 1914 } 1915 1916 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 1917 final TaskRecord task = anyTaskForIdLocked(taskId); 1918 if (task == null) { 1919 return; 1920 } 1921 final ActivityStack stack = getStack(stackId); 1922 if (stack == null) { 1923 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 1924 return; 1925 } 1926 removeTask(task); 1927 stack.addTask(task, toTop); 1928 mWindowManager.addTask(taskId, stackId, toTop); 1929 resumeTopActivitiesLocked(); 1930 } 1931 1932 ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) { 1933 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1934 final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info); 1935 if (ar != null) { 1936 return ar; 1937 } 1938 } 1939 return null; 1940 } 1941 1942 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 1943 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1944 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info); 1945 if (ar != null) { 1946 return ar; 1947 } 1948 } 1949 return null; 1950 } 1951 1952 void goingToSleepLocked() { 1953 scheduleSleepTimeout(); 1954 if (!mGoingToSleep.isHeld()) { 1955 mGoingToSleep.acquire(); 1956 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1957 final ActivityStack stack = mStacks.get(stackNdx); 1958 if (stack.mResumedActivity != null) { 1959 stack.stopIfSleepingLocked(); 1960 } 1961 } 1962 } 1963 } 1964 1965 boolean shutdownLocked(int timeout) { 1966 boolean timedout = false; 1967 goingToSleepLocked(); 1968 checkReadyForSleepLocked(); 1969 1970 final long endTime = System.currentTimeMillis() + timeout; 1971 while (true) { 1972 boolean cantShutdown = false; 1973 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1974 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked(); 1975 } 1976 if (cantShutdown) { 1977 long timeRemaining = endTime - System.currentTimeMillis(); 1978 if (timeRemaining > 0) { 1979 try { 1980 mService.wait(timeRemaining); 1981 } catch (InterruptedException e) { 1982 } 1983 } else { 1984 Slog.w(TAG, "Activity manager shutdown timed out"); 1985 timedout = true; 1986 break; 1987 } 1988 } else { 1989 break; 1990 } 1991 } 1992 1993 // Force checkReadyForSleep to complete. 1994 mSleepTimeout = true; 1995 checkReadyForSleepLocked(); 1996 1997 return timedout; 1998 } 1999 2000 void comeOutOfSleepIfNeededLocked() { 2001 removeSleepTimeouts(); 2002 if (mGoingToSleep.isHeld()) { 2003 mGoingToSleep.release(); 2004 } 2005 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2006 final ActivityStack stack = mStacks.get(stackNdx); 2007 stack.awakeFromSleepingLocked(); 2008 if (isFrontStack(stack)) { 2009 resumeTopActivitiesLocked(); 2010 } 2011 } 2012 mGoingToSleepActivities.clear(); 2013 } 2014 2015 void activitySleptLocked(ActivityRecord r) { 2016 mGoingToSleepActivities.remove(r); 2017 checkReadyForSleepLocked(); 2018 } 2019 2020 void checkReadyForSleepLocked() { 2021 if (!mService.isSleepingOrShuttingDown()) { 2022 // Do not care. 2023 return; 2024 } 2025 2026 if (!mSleepTimeout) { 2027 boolean dontSleep = false; 2028 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2029 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked(); 2030 } 2031 2032 if (mStoppingActivities.size() > 0) { 2033 // Still need to tell some activities to stop; can't sleep yet. 2034 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2035 + mStoppingActivities.size() + " activities"); 2036 scheduleIdleLocked(); 2037 dontSleep = true; 2038 } 2039 2040 if (mGoingToSleepActivities.size() > 0) { 2041 // Still need to tell some activities to sleep; can't sleep yet. 2042 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2043 + mGoingToSleepActivities.size() + " activities"); 2044 dontSleep = true; 2045 } 2046 2047 if (dontSleep) { 2048 return; 2049 } 2050 } 2051 2052 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2053 mStacks.get(stackNdx).goToSleep(); 2054 } 2055 2056 removeSleepTimeouts(); 2057 2058 if (mGoingToSleep.isHeld()) { 2059 mGoingToSleep.release(); 2060 } 2061 if (mService.mShuttingDown) { 2062 mService.notifyAll(); 2063 } 2064 } 2065 2066 boolean reportResumedActivityLocked(ActivityRecord r) { 2067 final ActivityStack stack = r.task.stack; 2068 if (isFrontStack(stack)) { 2069 mService.updateUsageStats(r, true); 2070 } 2071 if (allResumedActivitiesComplete()) { 2072 ensureActivitiesVisibleLocked(null, 0); 2073 mWindowManager.executeAppTransition(); 2074 return true; 2075 } 2076 return false; 2077 } 2078 2079 void handleAppCrashLocked(ProcessRecord app) { 2080 final int numStacks = mStacks.size(); 2081 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2082 final ActivityStack stack = mStacks.get(stackNdx); 2083 stack.handleAppCrashLocked(app); 2084 } 2085 } 2086 2087 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2088 // First the front stacks. In case any are not fullscreen and are in front of home. 2089 boolean showHomeBehindStack = false; 2090 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2091 final ActivityStack stack = mStacks.get(stackNdx); 2092 if (isFrontStack(stack)) { 2093 showHomeBehindStack = 2094 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2095 } 2096 } 2097 // Now do back stacks. 2098 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2099 final ActivityStack stack = mStacks.get(stackNdx); 2100 if (!isFrontStack(stack)) { 2101 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack); 2102 } 2103 } 2104 } 2105 2106 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2107 final int numStacks = mStacks.size(); 2108 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2109 final ActivityStack stack = mStacks.get(stackNdx); 2110 stack.scheduleDestroyActivities(app, false, reason); 2111 } 2112 } 2113 2114 boolean switchUserLocked(int userId, UserStartedState uss) { 2115 mUserStates.put(mCurrentUser, new UserState()); 2116 mCurrentUser = userId; 2117 UserState userState = mUserStates.get(userId); 2118 if (userState != null) { 2119 userState.restore(); 2120 mUserStates.delete(userId); 2121 } else { 2122 mFocusedStack = null; 2123 if (DEBUG_STACK) Slog.d(TAG, "switchUserLocked: mStackState=" + 2124 stackStateToString(STACK_STATE_HOME_IN_FRONT)); 2125 mStackState = STACK_STATE_HOME_IN_FRONT; 2126 } 2127 2128 mStartingUsers.add(uss); 2129 boolean haveActivities = mHomeStack.switchUserLocked(userId); 2130 2131 resumeTopActivitiesLocked(); 2132 2133 return haveActivities; 2134 } 2135 2136 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2137 int N = mStoppingActivities.size(); 2138 if (N <= 0) return null; 2139 2140 ArrayList<ActivityRecord> stops = null; 2141 2142 final boolean nowVisible = allResumedActivitiesVisible(); 2143 for (int i=0; i<N; i++) { 2144 ActivityRecord s = mStoppingActivities.get(i); 2145 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2146 + nowVisible + " waitingVisible=" + s.waitingVisible 2147 + " finishing=" + s.finishing); 2148 if (s.waitingVisible && nowVisible) { 2149 mWaitingVisibleActivities.remove(s); 2150 s.waitingVisible = false; 2151 if (s.finishing) { 2152 // If this activity is finishing, it is sitting on top of 2153 // everyone else but we now know it is no longer needed... 2154 // so get rid of it. Otherwise, we need to go through the 2155 // normal flow and hide it once we determine that it is 2156 // hidden by the activities in front of it. 2157 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2158 mWindowManager.setAppVisibility(s.appToken, false); 2159 } 2160 } 2161 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2162 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2163 if (stops == null) { 2164 stops = new ArrayList<ActivityRecord>(); 2165 } 2166 stops.add(s); 2167 mStoppingActivities.remove(i); 2168 N--; 2169 i--; 2170 } 2171 } 2172 2173 return stops; 2174 } 2175 2176 void validateTopActivitiesLocked() { 2177 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2178 final ActivityStack stack = mStacks.get(stackNdx); 2179 final ActivityRecord r = stack.topRunningActivityLocked(null); 2180 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2181 if (isFrontStack(stack)) { 2182 if (r == null) { 2183 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2184 } else { 2185 final ActivityRecord pausing = stack.mPausingActivity; 2186 if (pausing != null && pausing == r) { 2187 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2188 " state=" + state); 2189 } 2190 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2191 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2192 " state=" + state); 2193 } 2194 } 2195 } else { 2196 final ActivityRecord resumed = stack.mResumedActivity; 2197 if (resumed != null && resumed == r) { 2198 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2199 " state=" + state); 2200 } 2201 if (r != null && (state == ActivityState.INITIALIZING 2202 || state == ActivityState.RESUMED)) { 2203 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2204 " state=" + state); 2205 } 2206 } 2207 } 2208 } 2209 2210 private static String stackStateToString(int stackState) { 2211 switch (stackState) { 2212 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT"; 2213 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK"; 2214 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK"; 2215 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT"; 2216 default: return "Unknown stackState=" + stackState; 2217 } 2218 } 2219 2220 public void dump(PrintWriter pw, String prefix) { 2221 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:"); 2222 pw.println(mDismissKeyguardOnNextActivity); 2223 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState)); 2224 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout); 2225 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId); 2226 } 2227 2228 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2229 return getFocusedStack().getDumpActivitiesLocked(name); 2230 } 2231 2232 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2233 boolean needSep, String prefix) { 2234 if (activity != null) { 2235 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2236 if (needSep) { 2237 pw.println(); 2238 } 2239 pw.print(prefix); 2240 pw.println(activity); 2241 return true; 2242 } 2243 } 2244 return false; 2245 } 2246 2247 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2248 boolean dumpClient, String dumpPackage) { 2249 boolean printed = false; 2250 boolean needSep = false; 2251 final int numStacks = mStacks.size(); 2252 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2253 final ActivityStack stack = mStacks.get(stackNdx); 2254 StringBuilder stackHeader = new StringBuilder(128); 2255 stackHeader.append(" Stack #"); 2256 stackHeader.append(mStacks.indexOf(stack)); 2257 stackHeader.append(":"); 2258 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep, 2259 stackHeader.toString()); 2260 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, 2261 false, dumpPackage, true, " Running activities (most recent first):", null); 2262 2263 needSep = printed; 2264 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2265 " mPausingActivity: "); 2266 if (pr) { 2267 printed = true; 2268 needSep = false; 2269 } 2270 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2271 " mResumedActivity: "); 2272 if (pr) { 2273 printed = true; 2274 needSep = false; 2275 } 2276 if (dumpAll) { 2277 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2278 " mLastPausedActivity: "); 2279 if (pr) { 2280 printed = true; 2281 } 2282 } 2283 needSep = printed; 2284 } 2285 2286 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2287 false, dumpPackage, true, " Activities waiting to finish:", null); 2288 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2289 false, dumpPackage, true, " Activities waiting to stop:", null); 2290 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2291 false, dumpPackage, true, " Activities waiting for another to become visible:", 2292 null); 2293 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2294 false, dumpPackage, true, " Activities waiting to sleep:", null); 2295 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2296 false, dumpPackage, true, " Activities waiting to sleep:", null); 2297 2298 return printed; 2299 } 2300 2301 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2302 String prefix, String label, boolean complete, boolean brief, boolean client, 2303 String dumpPackage, boolean needNL, String header1, String header2) { 2304 TaskRecord lastTask = null; 2305 String innerPrefix = null; 2306 String[] args = null; 2307 boolean printed = false; 2308 for (int i=list.size()-1; i>=0; i--) { 2309 final ActivityRecord r = list.get(i); 2310 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2311 continue; 2312 } 2313 if (innerPrefix == null) { 2314 innerPrefix = prefix + " "; 2315 args = new String[0]; 2316 } 2317 printed = true; 2318 final boolean full = !brief && (complete || !r.isInHistory()); 2319 if (needNL) { 2320 pw.println(""); 2321 needNL = false; 2322 } 2323 if (header1 != null) { 2324 pw.println(header1); 2325 header1 = null; 2326 } 2327 if (header2 != null) { 2328 pw.println(header2); 2329 header2 = null; 2330 } 2331 if (lastTask != r.task) { 2332 lastTask = r.task; 2333 pw.print(prefix); 2334 pw.print(full ? "* " : " "); 2335 pw.println(lastTask); 2336 if (full) { 2337 lastTask.dump(pw, prefix + " "); 2338 } else if (complete) { 2339 // Complete + brief == give a summary. Isn't that obvious?!? 2340 if (lastTask.intent != null) { 2341 pw.print(prefix); pw.print(" "); 2342 pw.println(lastTask.intent.toInsecureStringWithClip()); 2343 } 2344 } 2345 } 2346 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2347 pw.print(" #"); pw.print(i); pw.print(": "); 2348 pw.println(r); 2349 if (full) { 2350 r.dump(pw, innerPrefix); 2351 } else if (complete) { 2352 // Complete + brief == give a summary. Isn't that obvious?!? 2353 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2354 if (r.app != null) { 2355 pw.print(innerPrefix); pw.println(r.app); 2356 } 2357 } 2358 if (client && r.app != null && r.app.thread != null) { 2359 // flush anything that is already in the PrintWriter since the thread is going 2360 // to write to the file descriptor directly 2361 pw.flush(); 2362 try { 2363 TransferPipe tp = new TransferPipe(); 2364 try { 2365 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2366 r.appToken, innerPrefix, args); 2367 // Short timeout, since blocking here can 2368 // deadlock with the application. 2369 tp.go(fd, 2000); 2370 } finally { 2371 tp.kill(); 2372 } 2373 } catch (IOException e) { 2374 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2375 } catch (RemoteException e) { 2376 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2377 } 2378 needNL = true; 2379 } 2380 } 2381 return printed; 2382 } 2383 2384 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2385 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2386 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2387 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2388 } 2389 2390 final void scheduleIdleLocked() { 2391 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2392 } 2393 2394 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2395 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2396 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2397 } 2398 2399 final void scheduleResumeTopActivities() { 2400 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2401 } 2402 2403 void removeSleepTimeouts() { 2404 mSleepTimeout = false; 2405 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2406 } 2407 2408 final void scheduleSleepTimeout() { 2409 removeSleepTimeouts(); 2410 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2411 } 2412 2413 private final class ActivityStackSupervisorHandler extends Handler { 2414 2415 public ActivityStackSupervisorHandler(Looper looper) { 2416 super(looper); 2417 } 2418 2419 void activityIdleInternal(ActivityRecord r) { 2420 synchronized (mService) { 2421 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2422 } 2423 } 2424 2425 @Override 2426 public void handleMessage(Message msg) { 2427 switch (msg.what) { 2428 case IDLE_TIMEOUT_MSG: { 2429 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" + 2430 Debug.getCallers(4)); 2431 if (mService.mDidDexOpt) { 2432 mService.mDidDexOpt = false; 2433 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2434 nmsg.obj = msg.obj; 2435 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2436 return; 2437 } 2438 // We don't at this point know if the activity is fullscreen, 2439 // so we need to be conservative and assume it isn't. 2440 activityIdleInternal((ActivityRecord)msg.obj); 2441 } break; 2442 case IDLE_NOW_MSG: { 2443 activityIdleInternal((ActivityRecord)msg.obj); 2444 } break; 2445 case RESUME_TOP_ACTIVITY_MSG: { 2446 synchronized (mService) { 2447 resumeTopActivitiesLocked(); 2448 } 2449 } break; 2450 case SLEEP_TIMEOUT_MSG: { 2451 synchronized (mService) { 2452 if (mService.isSleepingOrShuttingDown()) { 2453 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2454 mSleepTimeout = true; 2455 checkReadyForSleepLocked(); 2456 } 2457 } 2458 } break; 2459 } 2460 } 2461 } 2462 2463 private final class UserState { 2464 final ActivityStack mSavedFocusedStack; 2465 final int mSavedStackState; 2466 2467 public UserState() { 2468 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this; 2469 mSavedFocusedStack = supervisor.mFocusedStack; 2470 mSavedStackState = supervisor.mStackState; 2471 } 2472 2473 void restore() { 2474 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this; 2475 supervisor.mFocusedStack = mSavedFocusedStack; 2476 if (DEBUG_STACK) Slog.d(TAG, "UserState.restore: mStackState old=" + 2477 stackStateToString(mSavedStackState)); 2478 supervisor.mStackState = mSavedStackState; 2479 } 2480 } 2481} 2482