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