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