ActivityStackSupervisor.java revision a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72e
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_RESULTS; 26import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH; 27import static com.android.server.am.ActivityManagerService.DEBUG_TASKS; 28import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; 29import static com.android.server.am.ActivityManagerService.TAG; 30 31import android.app.Activity; 32import android.app.ActivityManager; 33import android.app.ActivityOptions; 34import android.app.AppGlobals; 35import android.app.IApplicationThread; 36import android.app.IThumbnailReceiver; 37import android.app.PendingIntent; 38import android.app.ActivityManager.RunningTaskInfo; 39import android.app.IActivityManager.WaitResult; 40import android.app.ResultInfo; 41import android.content.ComponentName; 42import android.content.Context; 43import android.content.IIntentSender; 44import android.content.Intent; 45import android.content.IntentSender; 46import android.content.pm.ActivityInfo; 47import android.content.pm.ApplicationInfo; 48import android.content.pm.PackageManager; 49import android.content.pm.ResolveInfo; 50import android.content.res.Configuration; 51import android.os.Binder; 52import android.os.Bundle; 53import android.os.IBinder; 54import android.os.Looper; 55import android.os.Message; 56import android.os.ParcelFileDescriptor; 57import android.os.RemoteException; 58import android.os.SystemClock; 59import android.os.UserHandle; 60import android.util.EventLog; 61import android.util.Slog; 62 63import com.android.internal.app.HeavyWeightSwitcherActivity; 64import com.android.server.am.ActivityManagerService.PendingActivityLaunch; 65import com.android.server.am.ActivityStack.ActivityState; 66import com.android.server.wm.StackBox; 67 68import java.io.FileDescriptor; 69import java.io.IOException; 70import java.io.PrintWriter; 71import java.util.ArrayList; 72import java.util.List; 73 74public class ActivityStackSupervisor { 75 static final boolean DEBUG_STACK = ActivityManagerService.DEBUG_STACK; 76 77 static final boolean DEBUG = ActivityManagerService.DEBUG || false; 78 static final boolean DEBUG_ADD_REMOVE = DEBUG || false; 79 static final boolean DEBUG_APP = DEBUG || false; 80 static final boolean DEBUG_SAVED_STATE = DEBUG || false; 81 static final boolean DEBUG_STATES = DEBUG || false; 82 83 public static final int HOME_STACK_ID = 0; 84 85 final ActivityManagerService mService; 86 final Context mContext; 87 final Looper mLooper; 88 89 /** Dismiss the keyguard after the next activity is displayed? */ 90 private boolean mDismissKeyguardOnNextActivity = false; 91 92 /** Identifier counter for all ActivityStacks */ 93 private int mLastStackId = HOME_STACK_ID; 94 95 /** Task identifier that activities are currently being started in. Incremented each time a 96 * new task is created. */ 97 private int mCurTaskId = 0; 98 99 /** The current user */ 100 private int mCurrentUser; 101 102 /** The stack containing the launcher app */ 103 private ActivityStack mHomeStack; 104 105 /** The non-home stack currently receiving input or launching the next activity. If home is 106 * in front then mHomeStack overrides mFocusedStack. */ 107 private ActivityStack mFocusedStack; 108 109 /** All the non-launcher stacks */ 110 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 111 112 private static final int STACK_STATE_HOME_IN_FRONT = 0; 113 private static final int STACK_STATE_HOME_TO_BACK = 1; 114 private static final int STACK_STATE_HOME_IN_BACK = 2; 115 private static final int STACK_STATE_HOME_TO_FRONT = 3; 116 private int mStackState = STACK_STATE_HOME_IN_FRONT; 117 118 /** List of activities that are waiting for a new activity to become visible before completing 119 * whatever operation they are supposed to do. */ 120 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); 121 122 /** List of activities that are ready to be stopped, but waiting for the next activity to 123 * settle down before doing so. */ 124 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); 125 126 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 127 * is being brought in front of us. */ 128 boolean mUserLeaving = false; 129 130 public ActivityStackSupervisor(ActivityManagerService service, Context context, 131 Looper looper) { 132 mService = service; 133 mContext = context; 134 mLooper = looper; 135 } 136 137 void init(int userId) { 138 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID, this, userId); 139 mStacks.add(mHomeStack); 140 } 141 142 void dismissKeyguard() { 143 if (mDismissKeyguardOnNextActivity) { 144 mDismissKeyguardOnNextActivity = false; 145 mService.mWindowManager.dismissKeyguard(); 146 } 147 } 148 149 ActivityStack getTopStack() { 150 switch (mStackState) { 151 case STACK_STATE_HOME_IN_FRONT: 152 case STACK_STATE_HOME_TO_FRONT: 153 return mHomeStack; 154 case STACK_STATE_HOME_IN_BACK: 155 case STACK_STATE_HOME_TO_BACK: 156 default: 157 return mFocusedStack; 158 } 159 } 160 161 ActivityStack getLastStack() { 162 switch (mStackState) { 163 case STACK_STATE_HOME_IN_FRONT: 164 case STACK_STATE_HOME_TO_BACK: 165 return mHomeStack; 166 case STACK_STATE_HOME_TO_FRONT: 167 case STACK_STATE_HOME_IN_BACK: 168 default: 169 return mFocusedStack; 170 } 171 } 172 173 boolean isFrontStack(ActivityStack stack) { 174 return !(stack.isHomeStack() ^ getTopStack().isHomeStack()); 175 } 176 177 boolean homeIsInFront() { 178 return isFrontStack(mHomeStack); 179 } 180 181 void moveHomeStack(boolean toFront) { 182 final boolean homeInFront = isFrontStack(mHomeStack); 183 if (homeInFront ^ toFront) { 184 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT; 185 } 186 } 187 188 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r, 189 ActivityStack stack) { 190 if (stack == mHomeStack) { 191 return; 192 } 193 if ((sourceRecord == null && getLastStack() == mHomeStack) || 194 (sourceRecord != null && sourceRecord.isHomeActivity)) { 195 if (r == null) { 196 r = stack.topRunningActivityLocked(null); 197 } 198 if (r != null && !r.isHomeActivity && r.isRootActivity()) { 199 r.mLaunchHomeTaskNext = true; 200 } 201 } 202 } 203 204 void setDismissKeyguard(boolean dismiss) { 205 mDismissKeyguardOnNextActivity = dismiss; 206 } 207 208 TaskRecord anyTaskForIdLocked(int id) { 209 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 210 ActivityStack stack = mStacks.get(stackNdx); 211 TaskRecord task = stack.taskForIdLocked(id); 212 if (task != null) { 213 return task; 214 } 215 } 216 return null; 217 } 218 219 ActivityRecord isInAnyStackLocked(IBinder token) { 220 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 221 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token); 222 if (r != null) { 223 return r; 224 } 225 } 226 return null; 227 } 228 229 int getNextTaskId() { 230 do { 231 mCurTaskId++; 232 if (mCurTaskId <= 0) { 233 mCurTaskId = 1; 234 } 235 } while (anyTaskForIdLocked(mCurTaskId) != null); 236 return mCurTaskId; 237 } 238 239 void removeTask(TaskRecord task) { 240 final ActivityStack stack = task.stack; 241 if (stack.removeTask(task) && !stack.isHomeStack()) { 242 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); 243 mStacks.remove(stack); 244 final int stackId = stack.mStackId; 245 final int nextStackId = mService.mWindowManager.removeStack(stackId); 246 // TODO: Perhaps we need to let the ActivityManager determine the next focus... 247 if (mFocusedStack.mStackId == stackId) { 248 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId); 249 } 250 } 251 } 252 253 ActivityRecord resumedAppLocked() { 254 ActivityStack stack = getTopStack(); 255 ActivityRecord resumedActivity = stack.mResumedActivity; 256 if (resumedActivity == null || resumedActivity.app == null) { 257 resumedActivity = stack.mPausingActivity; 258 if (resumedActivity == null || resumedActivity.app == null) { 259 resumedActivity = stack.topRunningActivityLocked(null); 260 } 261 } 262 return resumedActivity; 263 } 264 265 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception { 266 boolean didSomething = false; 267 final String processName = app.processName; 268 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 269 final ActivityStack stack = mStacks.get(stackNdx); 270 ActivityRecord hr = stack.topRunningActivityLocked(null); 271 if (hr != null) { 272 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 273 && processName.equals(hr.processName)) { 274 try { 275 if (headless) { 276 Slog.e(TAG, "Starting activities not supported on headless device: " 277 + hr); 278 } else if (realStartActivityLocked(hr, app, true, true)) { 279 didSomething = true; 280 } 281 } catch (Exception e) { 282 Slog.w(TAG, "Exception in new application when starting activity " 283 + hr.intent.getComponent().flattenToShortString(), e); 284 throw e; 285 } 286 } else { 287 stack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 288 } 289 } 290 } 291 return didSomething; 292 } 293 294 boolean allResumedActivitiesIdle() { 295 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 296 final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity; 297 if (resumedActivity == null || !resumedActivity.idle) { 298 return false; 299 } 300 } 301 return true; 302 } 303 304 boolean allResumedActivitiesComplete() { 305 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 306 final ActivityStack stack = mStacks.get(stackNdx); 307 if (isFrontStack(stack)) { 308 final ActivityRecord r = stack.mResumedActivity; 309 if (r != null && r.state != ActivityState.RESUMED) { 310 return false; 311 } 312 } 313 } 314 // TODO: Not sure if this should check if all Paused are complete too. 315 switch (mStackState) { 316 case STACK_STATE_HOME_TO_BACK: 317 mStackState = STACK_STATE_HOME_IN_BACK; 318 break; 319 case STACK_STATE_HOME_TO_FRONT: 320 mStackState = STACK_STATE_HOME_IN_FRONT; 321 break; 322 } 323 return true; 324 } 325 326 boolean allResumedActivitiesVisible() { 327 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 328 final ActivityStack stack = mStacks.get(stackNdx); 329 final ActivityRecord r = stack.mResumedActivity; 330 if (r != null && (!r.nowVisible || r.waitingVisible)) { 331 return false; 332 } 333 } 334 return true; 335 } 336 337 boolean allPausedActivitiesComplete() { 338 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 339 final ActivityStack stack = mStacks.get(stackNdx); 340 if (isFrontStack(stack)) { 341 final ActivityRecord r = stack.mLastPausedActivity; 342 if (r != null && r.state != ActivityState.PAUSED 343 && r.state != ActivityState.STOPPED 344 && r.state != ActivityState.STOPPING) { 345 return false; 346 } 347 } 348 } 349 // TODO: Not sure if this should check if all Resumed are complete too. 350 switch (mStackState) { 351 case STACK_STATE_HOME_TO_BACK: 352 mStackState = STACK_STATE_HOME_IN_BACK; 353 break; 354 case STACK_STATE_HOME_TO_FRONT: 355 mStackState = STACK_STATE_HOME_IN_FRONT; 356 break; 357 } 358 return true; 359 } 360 361 ActivityRecord topRunningActivityLocked() { 362 ActivityRecord r = null; 363 if (mFocusedStack != null) { 364 r = mFocusedStack.topRunningActivityLocked(null); 365 if (r != null) { 366 return r; 367 } 368 } 369 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 370 final ActivityStack stack = mStacks.get(stackNdx); 371 if (stack != mFocusedStack && isFrontStack(stack)) { 372 r = stack.topRunningActivityLocked(null); 373 if (r != null) { 374 return r; 375 } 376 } 377 } 378 return null; 379 } 380 381 void resumeTopActivitiesLocked() { 382 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 383 final ActivityStack stack = mStacks.get(stackNdx); 384 if (isFrontStack(stack)) { 385 stack.resumeTopActivityLocked(null); 386 } 387 } 388 } 389 390 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, 391 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) { 392 ActivityRecord r = null; 393 final int numStacks = mStacks.size(); 394 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 395 final ActivityStack stack = mStacks.get(stackNdx); 396 final ActivityRecord ar = 397 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list); 398 if (isFrontStack(stack)) { 399 r = ar; 400 } 401 } 402 return r; 403 } 404 405 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 406 String profileFile, ParcelFileDescriptor profileFd, int userId) { 407 // Collect information about the target of the Intent. 408 ActivityInfo aInfo; 409 try { 410 ResolveInfo rInfo = 411 AppGlobals.getPackageManager().resolveIntent( 412 intent, resolvedType, 413 PackageManager.MATCH_DEFAULT_ONLY 414 | ActivityManagerService.STOCK_PM_FLAGS, userId); 415 aInfo = rInfo != null ? rInfo.activityInfo : null; 416 } catch (RemoteException e) { 417 aInfo = null; 418 } 419 420 if (aInfo != null) { 421 // Store the found target back into the intent, because now that 422 // we have it we never want to do this again. For example, if the 423 // user navigates back to this point in the history, we should 424 // always restart the exact same activity. 425 intent.setComponent(new ComponentName( 426 aInfo.applicationInfo.packageName, aInfo.name)); 427 428 // Don't debug things in the system process 429 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 430 if (!aInfo.processName.equals("system")) { 431 mService.setDebugApp(aInfo.processName, true, false); 432 } 433 } 434 435 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 436 if (!aInfo.processName.equals("system")) { 437 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 438 } 439 } 440 441 if (profileFile != null) { 442 if (!aInfo.processName.equals("system")) { 443 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, 444 profileFile, profileFd, 445 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0); 446 } 447 } 448 } 449 return aInfo; 450 } 451 452 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 453 moveHomeStack(true); 454 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, 455 null, false, null); 456 } 457 458 final int startActivityMayWait(IApplicationThread caller, int callingUid, 459 String callingPackage, Intent intent, String resolvedType, IBinder resultTo, 460 String resultWho, int requestCode, int startFlags, String profileFile, 461 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, 462 Bundle options, int userId) { 463 // Refuse possible leaked file descriptors 464 if (intent != null && intent.hasFileDescriptors()) { 465 throw new IllegalArgumentException("File descriptors passed in Intent"); 466 } 467 boolean componentSpecified = intent.getComponent() != null; 468 469 // Don't modify the client's object! 470 intent = new Intent(intent); 471 472 // Collect information about the target of the Intent. 473 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 474 profileFile, profileFd, userId); 475 476 synchronized (mService) { 477 int callingPid; 478 if (callingUid >= 0) { 479 callingPid = -1; 480 } else if (caller == null) { 481 callingPid = Binder.getCallingPid(); 482 callingUid = Binder.getCallingUid(); 483 } else { 484 callingPid = callingUid = -1; 485 } 486 487 final ActivityStack stack = getTopStack(); 488 stack.mConfigWillChange = config != null 489 && mService.mConfiguration.diff(config) != 0; 490 if (DEBUG_CONFIGURATION) Slog.v(TAG, 491 "Starting activity when config will change = " + stack.mConfigWillChange); 492 493 final long origId = Binder.clearCallingIdentity(); 494 495 if (aInfo != null && 496 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 497 // This may be a heavy-weight process! Check to see if we already 498 // have another, different heavy-weight process running. 499 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 500 if (mService.mHeavyWeightProcess != null && 501 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 502 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 503 int realCallingPid = callingPid; 504 int realCallingUid = callingUid; 505 if (caller != null) { 506 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 507 if (callerApp != null) { 508 realCallingPid = callerApp.pid; 509 realCallingUid = callerApp.info.uid; 510 } else { 511 Slog.w(TAG, "Unable to find app for caller " + caller 512 + " (pid=" + realCallingPid + ") when starting: " 513 + intent.toString()); 514 ActivityOptions.abort(options); 515 return ActivityManager.START_PERMISSION_DENIED; 516 } 517 } 518 519 IIntentSender target = mService.getIntentSenderLocked( 520 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 521 realCallingUid, userId, null, null, 0, new Intent[] { intent }, 522 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 523 | PendingIntent.FLAG_ONE_SHOT, null); 524 525 Intent newIntent = new Intent(); 526 if (requestCode >= 0) { 527 // Caller is requesting a result. 528 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 529 } 530 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 531 new IntentSender(target)); 532 if (mService.mHeavyWeightProcess.activities.size() > 0) { 533 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 534 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 535 hist.packageName); 536 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 537 hist.task.taskId); 538 } 539 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 540 aInfo.packageName); 541 newIntent.setFlags(intent.getFlags()); 542 newIntent.setClassName("android", 543 HeavyWeightSwitcherActivity.class.getName()); 544 intent = newIntent; 545 resolvedType = null; 546 caller = null; 547 callingUid = Binder.getCallingUid(); 548 callingPid = Binder.getCallingPid(); 549 componentSpecified = true; 550 try { 551 ResolveInfo rInfo = 552 AppGlobals.getPackageManager().resolveIntent( 553 intent, null, 554 PackageManager.MATCH_DEFAULT_ONLY 555 | ActivityManagerService.STOCK_PM_FLAGS, userId); 556 aInfo = rInfo != null ? rInfo.activityInfo : null; 557 aInfo = mService.getActivityInfoForUser(aInfo, userId); 558 } catch (RemoteException e) { 559 aInfo = null; 560 } 561 } 562 } 563 } 564 565 int res = startActivityLocked(caller, intent, resolvedType, 566 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, 567 callingPackage, startFlags, options, componentSpecified, null); 568 569 if (stack.mConfigWillChange) { 570 // If the caller also wants to switch to a new configuration, 571 // do so now. This allows a clean switch, as we are waiting 572 // for the current activity to pause (so we will not destroy 573 // it), and have not yet started the next activity. 574 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 575 "updateConfiguration()"); 576 stack.mConfigWillChange = false; 577 if (DEBUG_CONFIGURATION) Slog.v(TAG, 578 "Updating to new configuration after starting activity."); 579 mService.updateConfigurationLocked(config, null, false, false); 580 } 581 582 Binder.restoreCallingIdentity(origId); 583 584 if (outResult != null) { 585 outResult.result = res; 586 if (res == ActivityManager.START_SUCCESS) { 587 stack.mWaitingActivityLaunched.add(outResult); 588 do { 589 try { 590 mService.wait(); 591 } catch (InterruptedException e) { 592 } 593 } while (!outResult.timeout && outResult.who == null); 594 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 595 ActivityRecord r = stack.topRunningActivityLocked(null); 596 if (r.nowVisible) { 597 outResult.timeout = false; 598 outResult.who = new ComponentName(r.info.packageName, r.info.name); 599 outResult.totalTime = 0; 600 outResult.thisTime = 0; 601 } else { 602 outResult.thisTime = SystemClock.uptimeMillis(); 603 stack.mWaitingActivityVisible.add(outResult); 604 do { 605 try { 606 mService.wait(); 607 } catch (InterruptedException e) { 608 } 609 } while (!outResult.timeout && outResult.who == null); 610 } 611 } 612 } 613 614 return res; 615 } 616 } 617 618 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 619 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 620 Bundle options, int userId) { 621 if (intents == null) { 622 throw new NullPointerException("intents is null"); 623 } 624 if (resolvedTypes == null) { 625 throw new NullPointerException("resolvedTypes is null"); 626 } 627 if (intents.length != resolvedTypes.length) { 628 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 629 } 630 631 ActivityRecord[] outActivity = new ActivityRecord[1]; 632 633 int callingPid; 634 if (callingUid >= 0) { 635 callingPid = -1; 636 } else if (caller == null) { 637 callingPid = Binder.getCallingPid(); 638 callingUid = Binder.getCallingUid(); 639 } else { 640 callingPid = callingUid = -1; 641 } 642 final long origId = Binder.clearCallingIdentity(); 643 try { 644 synchronized (mService) { 645 646 for (int i=0; i<intents.length; i++) { 647 Intent intent = intents[i]; 648 if (intent == null) { 649 continue; 650 } 651 652 // Refuse possible leaked file descriptors 653 if (intent != null && intent.hasFileDescriptors()) { 654 throw new IllegalArgumentException("File descriptors passed in Intent"); 655 } 656 657 boolean componentSpecified = intent.getComponent() != null; 658 659 // Don't modify the client's object! 660 intent = new Intent(intent); 661 662 // Collect information about the target of the Intent. 663 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 664 0, null, null, userId); 665 // TODO: New, check if this is correct 666 aInfo = mService.getActivityInfoForUser(aInfo, userId); 667 668 if (aInfo != null && 669 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 670 != 0) { 671 throw new IllegalArgumentException( 672 "FLAG_CANT_SAVE_STATE not supported here"); 673 } 674 675 Bundle theseOptions; 676 if (options != null && i == intents.length-1) { 677 theseOptions = options; 678 } else { 679 theseOptions = null; 680 } 681 int res = startActivityLocked(caller, intent, resolvedTypes[i], 682 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, 683 0, theseOptions, componentSpecified, outActivity); 684 if (res < 0) { 685 return res; 686 } 687 688 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 689 } 690 } 691 } finally { 692 Binder.restoreCallingIdentity(origId); 693 } 694 695 return ActivityManager.START_SUCCESS; 696 } 697 698 final boolean realStartActivityLocked(ActivityRecord r, 699 ProcessRecord app, boolean andResume, boolean checkConfig) 700 throws RemoteException { 701 702 r.startFreezingScreenLocked(app, 0); 703 mService.mWindowManager.setAppVisibility(r.appToken, true); 704 705 // schedule launch ticks to collect information about slow apps. 706 r.startLaunchTickingLocked(); 707 708 // Have the window manager re-evaluate the orientation of 709 // the screen based on the new activity order. Note that 710 // as a result of this, it can call back into the activity 711 // manager with a new orientation. We don't care about that, 712 // because the activity is not currently running so we are 713 // just restarting it anyway. 714 if (checkConfig) { 715 Configuration config = mService.mWindowManager.updateOrientationFromAppTokens( 716 mService.mConfiguration, 717 r.mayFreezeScreenLocked(app) ? r.appToken : null); 718 mService.updateConfigurationLocked(config, r, false, false); 719 } 720 721 r.app = app; 722 app.waitingToKill = null; 723 r.launchCount++; 724 r.lastLaunchTime = SystemClock.uptimeMillis(); 725 726 if (localLOGV) Slog.v(TAG, "Launching: " + r); 727 728 int idx = app.activities.indexOf(r); 729 if (idx < 0) { 730 app.activities.add(r); 731 } 732 mService.updateLruProcessLocked(app, true); 733 734 final ActivityStack stack = r.task.stack; 735 try { 736 if (app.thread == null) { 737 throw new RemoteException(); 738 } 739 List<ResultInfo> results = null; 740 List<Intent> newIntents = null; 741 if (andResume) { 742 results = r.results; 743 newIntents = r.newIntents; 744 } 745 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 746 + " icicle=" + r.icicle 747 + " with results=" + results + " newIntents=" + newIntents 748 + " andResume=" + andResume); 749 if (andResume) { 750 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 751 r.userId, System.identityHashCode(r), 752 r.task.taskId, r.shortComponentName); 753 } 754 if (r.isHomeActivity) { 755 mService.mHomeProcess = app; 756 } 757 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 758 r.sleeping = false; 759 r.forceNewConfig = false; 760 mService.showAskCompatModeDialogLocked(r); 761 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 762 String profileFile = null; 763 ParcelFileDescriptor profileFd = null; 764 boolean profileAutoStop = false; 765 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 766 if (mService.mProfileProc == null || mService.mProfileProc == app) { 767 mService.mProfileProc = app; 768 profileFile = mService.mProfileFile; 769 profileFd = mService.mProfileFd; 770 profileAutoStop = mService.mAutoStopProfiler; 771 } 772 } 773 app.hasShownUi = true; 774 app.pendingUiClean = true; 775 if (profileFd != null) { 776 try { 777 profileFd = profileFd.dup(); 778 } catch (IOException e) { 779 if (profileFd != null) { 780 try { 781 profileFd.close(); 782 } catch (IOException o) { 783 } 784 profileFd = null; 785 } 786 } 787 } 788 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 789 System.identityHashCode(r), r.info, 790 new Configuration(mService.mConfiguration), 791 r.compat, r.icicle, results, newIntents, !andResume, 792 mService.isNextTransitionForward(), profileFile, profileFd, 793 profileAutoStop); 794 795 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 796 // This may be a heavy-weight process! Note that the package 797 // manager will ensure that only activity can run in the main 798 // process of the .apk, which is the only thing that will be 799 // considered heavy-weight. 800 if (app.processName.equals(app.info.packageName)) { 801 if (mService.mHeavyWeightProcess != null 802 && mService.mHeavyWeightProcess != app) { 803 Slog.w(TAG, "Starting new heavy weight process " + app 804 + " when already running " 805 + mService.mHeavyWeightProcess); 806 } 807 mService.mHeavyWeightProcess = app; 808 Message msg = mService.mHandler.obtainMessage( 809 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 810 msg.obj = r; 811 mService.mHandler.sendMessage(msg); 812 } 813 } 814 815 } catch (RemoteException e) { 816 if (r.launchFailed) { 817 // This is the second time we failed -- finish activity 818 // and give up. 819 Slog.e(TAG, "Second failure launching " 820 + r.intent.getComponent().flattenToShortString() 821 + ", giving up", e); 822 mService.appDiedLocked(app, app.pid, app.thread); 823 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 824 "2nd-crash", false); 825 return false; 826 } 827 828 // This is the first time we failed -- restart process and 829 // retry. 830 app.activities.remove(r); 831 throw e; 832 } 833 834 r.launchFailed = false; 835 if (stack.updateLRUListLocked(r)) { 836 Slog.w(TAG, "Activity " + r 837 + " being launched, but already in LRU list"); 838 } 839 840 if (andResume) { 841 // As part of the process of launching, ActivityThread also performs 842 // a resume. 843 stack.minimalResumeActivityLocked(r); 844 } else { 845 // This activity is not starting in the resumed state... which 846 // should look like we asked it to pause+stop (but remain visible), 847 // and it has done so and reported back the current icicle and 848 // other state. 849 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 850 + " (starting in stopped state)"); 851 r.state = ActivityState.STOPPED; 852 r.stopped = true; 853 } 854 855 // Launch the new version setup screen if needed. We do this -after- 856 // launching the initial activity (that is, home), so that it can have 857 // a chance to initialize itself while in the background, making the 858 // switch back to it faster and look better. 859 if (isFrontStack(stack)) { 860 mService.startSetupActivityLocked(); 861 } 862 863 return true; 864 } 865 866 void startSpecificActivityLocked(ActivityRecord r, 867 boolean andResume, boolean checkConfig) { 868 // Is this activity's application already running? 869 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 870 r.info.applicationInfo.uid); 871 872 r.task.stack.setLaunchTime(r); 873 874 if (app != null && app.thread != null) { 875 try { 876 app.addPackage(r.info.packageName); 877 realStartActivityLocked(r, app, andResume, checkConfig); 878 return; 879 } catch (RemoteException e) { 880 Slog.w(TAG, "Exception when starting activity " 881 + r.intent.getComponent().flattenToShortString(), e); 882 } 883 884 // If a dead object exception was thrown -- fall through to 885 // restart the application. 886 } 887 888 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 889 "activity", r.intent.getComponent(), false, false); 890 } 891 892 final int startActivityLocked(IApplicationThread caller, 893 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, 894 String resultWho, int requestCode, 895 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 896 boolean componentSpecified, ActivityRecord[] outActivity) { 897 int err = ActivityManager.START_SUCCESS; 898 899 ProcessRecord callerApp = null; 900 if (caller != null) { 901 callerApp = mService.getRecordForAppLocked(caller); 902 if (callerApp != null) { 903 callingPid = callerApp.pid; 904 callingUid = callerApp.info.uid; 905 } else { 906 Slog.w(TAG, "Unable to find app for caller " + caller 907 + " (pid=" + callingPid + ") when starting: " 908 + intent.toString()); 909 err = ActivityManager.START_PERMISSION_DENIED; 910 } 911 } 912 913 if (err == ActivityManager.START_SUCCESS) { 914 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 915 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 916 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); 917 } 918 919 ActivityRecord sourceRecord = null; 920 ActivityRecord resultRecord = null; 921 if (resultTo != null) { 922 sourceRecord = isInAnyStackLocked(resultTo); 923 if (DEBUG_RESULTS) Slog.v( 924 TAG, "Will send result to " + resultTo + " " + sourceRecord); 925 if (sourceRecord != null) { 926 if (requestCode >= 0 && !sourceRecord.finishing) { 927 resultRecord = sourceRecord; 928 } 929 } 930 } 931 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 932 933 int launchFlags = intent.getFlags(); 934 935 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 936 && sourceRecord != null) { 937 // Transfer the result target from the source activity to the new 938 // one being started, including any failures. 939 if (requestCode >= 0) { 940 ActivityOptions.abort(options); 941 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 942 } 943 resultRecord = sourceRecord.resultTo; 944 resultWho = sourceRecord.resultWho; 945 requestCode = sourceRecord.requestCode; 946 sourceRecord.resultTo = null; 947 if (resultRecord != null) { 948 resultRecord.removeResultsLocked( 949 sourceRecord, resultWho, requestCode); 950 } 951 } 952 953 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 954 // We couldn't find a class that can handle the given Intent. 955 // That's the end of that! 956 err = ActivityManager.START_INTENT_NOT_RESOLVED; 957 } 958 959 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 960 // We couldn't find the specific class specified in the Intent. 961 // Also the end of the line. 962 err = ActivityManager.START_CLASS_NOT_FOUND; 963 } 964 965 if (err != ActivityManager.START_SUCCESS) { 966 if (resultRecord != null) { 967 resultStack.sendActivityResultLocked(-1, 968 resultRecord, resultWho, requestCode, 969 Activity.RESULT_CANCELED, null); 970 } 971 setDismissKeyguard(false); 972 ActivityOptions.abort(options); 973 return err; 974 } 975 976 final int startAnyPerm = mService.checkPermission( 977 START_ANY_ACTIVITY, callingPid, callingUid); 978 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 979 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 980 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 981 if (resultRecord != null) { 982 resultStack.sendActivityResultLocked(-1, 983 resultRecord, resultWho, requestCode, 984 Activity.RESULT_CANCELED, null); 985 } 986 setDismissKeyguard(false); 987 String msg; 988 if (!aInfo.exported) { 989 msg = "Permission Denial: starting " + intent.toString() 990 + " from " + callerApp + " (pid=" + callingPid 991 + ", uid=" + callingUid + ")" 992 + " not exported from uid " + aInfo.applicationInfo.uid; 993 } else { 994 msg = "Permission Denial: starting " + intent.toString() 995 + " from " + callerApp + " (pid=" + callingPid 996 + ", uid=" + callingUid + ")" 997 + " requires " + aInfo.permission; 998 } 999 Slog.w(TAG, msg); 1000 throw new SecurityException(msg); 1001 } 1002 1003 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, 1004 callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo); 1005 1006 if (mService.mController != null) { 1007 try { 1008 // The Intent we give to the watcher has the extra data 1009 // stripped off, since it can contain private information. 1010 Intent watchIntent = intent.cloneFilter(); 1011 abort |= !mService.mController.activityStarting(watchIntent, 1012 aInfo.applicationInfo.packageName); 1013 } catch (RemoteException e) { 1014 mService.mController = null; 1015 } 1016 } 1017 1018 if (abort) { 1019 if (resultRecord != null) { 1020 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1021 Activity.RESULT_CANCELED, null); 1022 } 1023 // We pretend to the caller that it was really started, but 1024 // they will just get a cancel result. 1025 setDismissKeyguard(false); 1026 ActivityOptions.abort(options); 1027 return ActivityManager.START_SUCCESS; 1028 } 1029 1030 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1031 intent, resolvedType, aInfo, mService.mConfiguration, 1032 resultRecord, resultWho, requestCode, componentSpecified, this); 1033 if (outActivity != null) { 1034 outActivity[0] = r; 1035 } 1036 1037 final ActivityStack stack = getTopStack(); 1038 if (stack.mResumedActivity == null 1039 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { 1040 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1041 PendingActivityLaunch pal = 1042 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1043 mService.mPendingActivityLaunches.add(pal); 1044 setDismissKeyguard(false); 1045 ActivityOptions.abort(options); 1046 return ActivityManager.START_SWITCHES_CANCELED; 1047 } 1048 } 1049 1050 if (mService.mDidAppSwitch) { 1051 // This is the second allowed switch since we stopped switches, 1052 // so now just generally allow switches. Use case: user presses 1053 // home (switches disabled, switch to home, mDidAppSwitch now true); 1054 // user taps a home icon (coming from home so allowed, we hit here 1055 // and now allow anyone to switch again). 1056 mService.mAppSwitchesAllowedTime = 0; 1057 } else { 1058 mService.mDidAppSwitch = true; 1059 } 1060 1061 mService.doPendingActivityLaunchesLocked(false); 1062 1063 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); 1064 if (stack.mPausingActivity == null) { 1065 // Someone asked to have the keyguard dismissed on the next 1066 // activity start, but we are not actually doing an activity 1067 // switch... just dismiss the keyguard now, because we 1068 // probably want to see whatever is behind it. 1069 dismissKeyguard(); 1070 } 1071 return err; 1072 } 1073 1074 ActivityStack getCorrectStack(ActivityRecord r) { 1075 if (!r.isHomeActivity) { 1076 if (mStacks.size() == 1) { 1077 // Time to create the first app stack. 1078 int stackId = mService.createStack(-1, HOME_STACK_ID, 1079 StackBox.TASK_STACK_GOES_OVER, 1.0f); 1080 mFocusedStack = getStack(stackId); 1081 } 1082 return mFocusedStack; 1083 } 1084 return mHomeStack; 1085 } 1086 1087 void setFocusedStack(ActivityRecord r) { 1088 if (r == null) { 1089 return; 1090 } 1091 if (r.isHomeActivity) { 1092 if (mStackState != STACK_STATE_HOME_IN_FRONT) { 1093 mStackState = STACK_STATE_HOME_TO_FRONT; 1094 } 1095 } else { 1096 mFocusedStack = r.task.stack; 1097 if (mStackState != STACK_STATE_HOME_IN_BACK) { 1098 mStackState = STACK_STATE_HOME_TO_BACK; 1099 } 1100 } 1101 } 1102 1103 final int startActivityUncheckedLocked(ActivityRecord r, 1104 ActivityRecord sourceRecord, int startFlags, boolean doResume, 1105 Bundle options) { 1106 final Intent intent = r.intent; 1107 final int callingUid = r.launchedFromUid; 1108 1109 int launchFlags = intent.getFlags(); 1110 1111 // We'll invoke onUserLeaving before onPause only if the launching 1112 // activity did not explicitly state that this is an automated launch. 1113 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1114 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1115 1116 // If the caller has asked not to resume at this point, we make note 1117 // of this in the record so that we can skip it when trying to find 1118 // the top running activity. 1119 if (!doResume) { 1120 r.delayedResume = true; 1121 } 1122 1123 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1124 1125 // If the onlyIfNeeded flag is set, then we can do this if the activity 1126 // being launched is the same as the one making the call... or, as 1127 // a special case, if we do not know the caller then we count the 1128 // current top activity as the caller. 1129 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1130 ActivityRecord checkedCaller = sourceRecord; 1131 if (checkedCaller == null) { 1132 checkedCaller = getTopStack().topRunningNonDelayedActivityLocked(notTop); 1133 } 1134 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1135 // Caller is not the same as launcher, so always needed. 1136 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1137 } 1138 } 1139 1140 if (sourceRecord == null) { 1141 // This activity is not being started from another... in this 1142 // case we -always- start a new task. 1143 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1144 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1145 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1146 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1147 } 1148 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1149 // The original activity who is starting us is running as a single 1150 // instance... this new activity it is starting must go on its 1151 // own task. 1152 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1153 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1154 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1155 // The activity being started is a single instance... it always 1156 // gets launched into its own task. 1157 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1158 } 1159 1160 final ActivityStack sourceStack; 1161 final TaskRecord sourceTask; 1162 if (sourceRecord != null) { 1163 sourceTask = sourceRecord.task; 1164 sourceStack = sourceTask.stack; 1165 } else { 1166 sourceTask = null; 1167 sourceStack = null; 1168 } 1169 1170 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1171 // For whatever reason this activity is being launched into a new 1172 // task... yet the caller has requested a result back. Well, that 1173 // is pretty messed up, so instead immediately send back a cancel 1174 // and let the new task continue launched as normal without a 1175 // dependency on its originator. 1176 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1177 r.resultTo.task.stack.sendActivityResultLocked(-1, 1178 r.resultTo, r.resultWho, r.requestCode, 1179 Activity.RESULT_CANCELED, null); 1180 r.resultTo = null; 1181 } 1182 1183 boolean addingToTask = false; 1184 boolean movedHome = false; 1185 TaskRecord reuseTask = null; 1186 ActivityStack targetStack; 1187 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1188 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1189 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1190 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1191 // If bring to front is requested, and no result is requested, and 1192 // we can find a task that was started with this same 1193 // component, then instead of launching bring that one to the front. 1194 if (r.resultTo == null) { 1195 // See if there is a task to bring to the front. If this is 1196 // a SINGLE_INSTANCE activity, there can be one and only one 1197 // instance of it in the history, and it is always in its own 1198 // unique task, so we do a special search. 1199 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1200 ? findTaskLocked(intent, r.info) 1201 : findActivityLocked(intent, r.info); 1202 if (intentActivity != null) { 1203 if (r.task == null) { 1204 r.task = intentActivity.task; 1205 } 1206 targetStack = intentActivity.task.stack; 1207 moveHomeStack(targetStack.isHomeStack()); 1208 if (intentActivity.task.intent == null) { 1209 // This task was started because of movement of 1210 // the activity based on affinity... now that we 1211 // are actually launching it, we can assign the 1212 // base intent. 1213 intentActivity.task.setIntent(intent, r.info); 1214 } 1215 // If the target task is not in the front, then we need 1216 // to bring it to the front... except... well, with 1217 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1218 // to have the same behavior as if a new instance was 1219 // being started, which means not bringing it to the front 1220 // if the caller is not itself in the front. 1221 ActivityRecord curTop = 1222 targetStack.topRunningNonDelayedActivityLocked(notTop); 1223 if (curTop != null && curTop.task != intentActivity.task) { 1224 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1225 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) { 1226 // We really do want to push this one into the 1227 // user's face, right now. 1228 movedHome = true; 1229 if ((launchFlags & 1230 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1231 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1232 // Caller wants to appear on home activity, so before starting 1233 // their own activity we will bring home to the front. 1234 r.mLaunchHomeTaskNext = true; 1235 } 1236 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1237 options = null; 1238 } 1239 } 1240 // If the caller has requested that the target task be 1241 // reset, then do so. 1242 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1243 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1244 } 1245 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1246 // We don't need to start a new activity, and 1247 // the client said not to do anything if that 1248 // is the case, so this is it! And for paranoia, make 1249 // sure we have correctly resumed the top activity. 1250 if (doResume) { 1251 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1252 targetStack.resumeTopActivityLocked(null, options); 1253 } else { 1254 ActivityOptions.abort(options); 1255 } 1256 if (r.task == null) Slog.v(TAG, 1257 "startActivityUncheckedLocked: task left null", 1258 new RuntimeException("here").fillInStackTrace()); 1259 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1260 } 1261 if ((launchFlags & 1262 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1263 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1264 // The caller has requested to completely replace any 1265 // existing task with its new activity. Well that should 1266 // not be too hard... 1267 reuseTask = intentActivity.task; 1268 reuseTask.performClearTaskLocked(); 1269 reuseTask.setIntent(r.intent, r.info); 1270 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1271 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1272 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1273 // In this situation we want to remove all activities 1274 // from the task up to the one being started. In most 1275 // cases this means we are resetting the task to its 1276 // initial state. 1277 ActivityRecord top = 1278 intentActivity.task.performClearTaskLocked(r, launchFlags); 1279 if (top != null) { 1280 if (top.frontOfTask) { 1281 // Activity aliases may mean we use different 1282 // intents for the top activity, so make sure 1283 // the task now has the identity of the new 1284 // intent. 1285 top.task.setIntent(r.intent, r.info); 1286 } 1287 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1288 r, top.task); 1289 top.deliverNewIntentLocked(callingUid, r.intent); 1290 } else { 1291 // A special case: we need to 1292 // start the activity because it is not currently 1293 // running, and the caller has asked to clear the 1294 // current task to have this activity at the top. 1295 addingToTask = true; 1296 // Now pretend like this activity is being started 1297 // by the top of its task, so it is put in the 1298 // right place. 1299 sourceRecord = intentActivity; 1300 } 1301 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1302 // In this case the top activity on the task is the 1303 // same as the one being launched, so we take that 1304 // as a request to bring the task to the foreground. 1305 // If the top activity in the task is the root 1306 // activity, deliver this new intent to it if it 1307 // desires. 1308 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1309 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1310 && intentActivity.realActivity.equals(r.realActivity)) { 1311 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1312 intentActivity.task); 1313 if (intentActivity.frontOfTask) { 1314 intentActivity.task.setIntent(r.intent, r.info); 1315 } 1316 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1317 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1318 // In this case we are launching the root activity 1319 // of the task, but with a different intent. We 1320 // should start a new instance on top. 1321 addingToTask = true; 1322 sourceRecord = intentActivity; 1323 } 1324 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1325 // In this case an activity is being launched in to an 1326 // existing task, without resetting that task. This 1327 // is typically the situation of launching an activity 1328 // from a notification or shortcut. We want to place 1329 // the new activity on top of the current task. 1330 addingToTask = true; 1331 sourceRecord = intentActivity; 1332 } else if (!intentActivity.task.rootWasReset) { 1333 // In this case we are launching in to an existing task 1334 // that has not yet been started from its front door. 1335 // The current task has been brought to the front. 1336 // Ideally, we'd probably like to place this new task 1337 // at the bottom of its stack, but that's a little hard 1338 // to do with the current organization of the code so 1339 // for now we'll just drop it. 1340 intentActivity.task.setIntent(r.intent, r.info); 1341 } 1342 if (!addingToTask && reuseTask == null) { 1343 // We didn't do anything... but it was needed (a.k.a., client 1344 // don't use that intent!) And for paranoia, make 1345 // sure we have correctly resumed the top activity. 1346 if (doResume) { 1347 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack); 1348 targetStack.resumeTopActivityLocked(null, options); 1349 } else { 1350 ActivityOptions.abort(options); 1351 } 1352 if (r.task == null) Slog.v(TAG, 1353 "startActivityUncheckedLocked: task left null", 1354 new RuntimeException("here").fillInStackTrace()); 1355 return ActivityManager.START_TASK_TO_FRONT; 1356 } 1357 } 1358 } 1359 } 1360 1361 //String uri = r.intent.toURI(); 1362 //Intent intent2 = new Intent(uri); 1363 //Slog.i(TAG, "Given intent: " + r.intent); 1364 //Slog.i(TAG, "URI is: " + uri); 1365 //Slog.i(TAG, "To intent: " + intent2); 1366 1367 if (r.packageName != null) { 1368 // If the activity being launched is the same as the one currently 1369 // at the top, then we need to check if it should only be launched 1370 // once. 1371 ActivityStack topStack = getTopStack(); 1372 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1373 if (top != null && r.resultTo == null) { 1374 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1375 if (top.app != null && top.app.thread != null) { 1376 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1377 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1378 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1379 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1380 top.task); 1381 // For paranoia, make sure we have correctly 1382 // resumed the top activity. 1383 if (doResume) { 1384 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack); 1385 topStack.resumeTopActivityLocked(null); 1386 } 1387 ActivityOptions.abort(options); 1388 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1389 // We don't need to start a new activity, and 1390 // the client said not to do anything if that 1391 // is the case, so this is it! 1392 if (r.task == null) Slog.v(TAG, 1393 "startActivityUncheckedLocked: task left null", 1394 new RuntimeException("here").fillInStackTrace()); 1395 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1396 } 1397 top.deliverNewIntentLocked(callingUid, r.intent); 1398 if (r.task == null) Slog.v(TAG, 1399 "startActivityUncheckedLocked: task left null", 1400 new RuntimeException("here").fillInStackTrace()); 1401 return ActivityManager.START_DELIVERED_TO_TOP; 1402 } 1403 } 1404 } 1405 } 1406 1407 } else { 1408 if (r.resultTo != null) { 1409 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1410 r.requestCode, Activity.RESULT_CANCELED, null); 1411 } 1412 ActivityOptions.abort(options); 1413 if (r.task == null) Slog.v(TAG, 1414 "startActivityUncheckedLocked: task left null", 1415 new RuntimeException("here").fillInStackTrace()); 1416 return ActivityManager.START_CLASS_NOT_FOUND; 1417 } 1418 1419 boolean newTask = false; 1420 boolean keepCurTransition = false; 1421 1422 // Should this be considered a new task? 1423 if (r.resultTo == null && !addingToTask 1424 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1425 targetStack = getCorrectStack(r); 1426 moveHomeStack(targetStack.isHomeStack()); 1427 if (reuseTask == null) { 1428 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1429 null, true); 1430 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1431 r.task); 1432 } else { 1433 r.setTask(reuseTask, reuseTask, true); 1434 } 1435 newTask = true; 1436 if (!movedHome) { 1437 if ((launchFlags & 1438 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1439 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1440 // Caller wants to appear on home activity, so before starting 1441 // their own activity we will bring home to the front. 1442 r.mLaunchHomeTaskNext = true; 1443 } 1444 } 1445 } else if (sourceRecord != null) { 1446 targetStack = sourceRecord.task.stack; 1447 moveHomeStack(targetStack.isHomeStack()); 1448 if (!addingToTask && 1449 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1450 // In this case, we are adding the activity to an existing 1451 // task, but the caller has asked to clear that task if the 1452 // activity is already running. 1453 ActivityRecord top = sourceRecord.task.performClearTaskLocked(r, launchFlags); 1454 keepCurTransition = true; 1455 if (top != null) { 1456 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1457 top.deliverNewIntentLocked(callingUid, r.intent); 1458 // For paranoia, make sure we have correctly 1459 // resumed the top activity. 1460 if (doResume) { 1461 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1462 targetStack.resumeTopActivityLocked(null); 1463 } 1464 ActivityOptions.abort(options); 1465 if (r.task == null) Slog.v(TAG, 1466 "startActivityUncheckedLocked: task left null", 1467 new RuntimeException("here").fillInStackTrace()); 1468 return ActivityManager.START_DELIVERED_TO_TOP; 1469 } 1470 } else if (!addingToTask && 1471 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1472 // In this case, we are launching an activity in our own task 1473 // that may already be running somewhere in the history, and 1474 // we want to shuffle it to the front of the stack if so. 1475 final ActivityRecord top = 1476 targetStack.findActivityInHistoryLocked(r, sourceRecord.task); 1477 if (top != null) { 1478 final TaskRecord task = top.task; 1479 task.moveActivityToFrontLocked(top); 1480 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1481 top.updateOptionsLocked(options); 1482 top.deliverNewIntentLocked(callingUid, r.intent); 1483 if (doResume) { 1484 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1485 targetStack.resumeTopActivityLocked(null); 1486 } 1487 if (r.task == null) Slog.v(TAG, 1488 "startActivityUncheckedLocked: task left null", 1489 new RuntimeException("here").fillInStackTrace()); 1490 return ActivityManager.START_DELIVERED_TO_TOP; 1491 } 1492 } 1493 // An existing activity is starting this new activity, so we want 1494 // to keep the new one in the same task as the one that is starting 1495 // it. 1496 r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false); 1497 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1498 + " in existing task " + r.task); 1499 1500 } else { 1501 // This not being started from an existing activity, and not part 1502 // of a new task... just put it in the top task, though these days 1503 // this case should never happen. 1504 targetStack = getLastStack(); 1505 moveHomeStack(targetStack.isHomeStack()); 1506 ActivityRecord prev = targetStack.topActivity(); 1507 r.setTask(prev != null ? prev.task 1508 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1509 null, true); 1510 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1511 + " in new guessed " + r.task); 1512 } 1513 1514 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1515 intent, r.getUriPermissionsLocked()); 1516 1517 if (newTask) { 1518 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1519 } 1520 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1521 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack); 1522 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1523 return ActivityManager.START_SUCCESS; 1524 } 1525 1526 void handleAppDiedLocked(ProcessRecord app, boolean restarting) { 1527 // Just in case. 1528 final int numStacks = mStacks.size(); 1529 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1530 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting); 1531 } 1532 } 1533 1534 void closeSystemDialogsLocked() { 1535 final int numStacks = mStacks.size(); 1536 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1537 final ActivityStack stack = mStacks.get(stackNdx); 1538 stack.closeSystemDialogsLocked(); 1539 } 1540 } 1541 1542 /** 1543 * @return true if some activity was finished (or would have finished if doit were true). 1544 */ 1545 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 1546 boolean didSomething = false; 1547 final int numStacks = mStacks.size(); 1548 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1549 final ActivityStack stack = mStacks.get(stackNdx); 1550 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 1551 didSomething = true; 1552 } 1553 } 1554 return didSomething; 1555 } 1556 1557 void resumeTopActivityLocked() { 1558 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1559 mStacks.get(stackNdx).resumeTopActivityLocked(null); 1560 } 1561 } 1562 1563 void finishTopRunningActivityLocked(ProcessRecord app) { 1564 final int numStacks = mStacks.size(); 1565 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1566 final ActivityStack stack = mStacks.get(stackNdx); 1567 stack.finishTopRunningActivityLocked(app); 1568 } 1569 } 1570 1571 void scheduleIdleLocked() { 1572 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1573 mStacks.get(stackNdx).scheduleIdleLocked(); 1574 } 1575 } 1576 1577 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 1578 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1579 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 1580 return; 1581 } 1582 } 1583 } 1584 1585 ActivityStack getStack(int stackId) { 1586 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1587 final ActivityStack stack = mStacks.get(stackNdx); 1588 if (stack.getStackId() == stackId) { 1589 return stack; 1590 } 1591 } 1592 return null; 1593 } 1594 1595 ArrayList<ActivityStack> getStacks() { 1596 return new ArrayList<ActivityStack>(mStacks); 1597 } 1598 1599 int createStack() { 1600 synchronized (this) { 1601 while (true) { 1602 if (++mLastStackId <= HOME_STACK_ID) { 1603 mLastStackId = HOME_STACK_ID + 1; 1604 } 1605 if (getStack(mLastStackId) == null) { 1606 break; 1607 } 1608 } 1609 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId, this, 1610 mCurrentUser)); 1611 return mLastStackId; 1612 } 1613 } 1614 1615 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 1616 final ActivityStack stack = getStack(stackId); 1617 if (stack == null) { 1618 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 1619 return; 1620 } 1621 stack.moveTask(taskId, toTop); 1622 stack.resumeTopActivityLocked(null); 1623 } 1624 1625 ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) { 1626 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1627 final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info); 1628 if (ar != null) { 1629 return ar; 1630 } 1631 } 1632 return null; 1633 } 1634 1635 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 1636 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1637 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info); 1638 if (ar != null) { 1639 return ar; 1640 } 1641 } 1642 return null; 1643 } 1644 1645 void goingToSleepLocked() { 1646 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1647 mStacks.get(stackNdx).stopIfSleepingLocked(); 1648 } 1649 } 1650 1651 boolean shutdownLocked(int timeout) { 1652 boolean timedout = false; 1653 final int numStacks = mStacks.size(); 1654 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1655 final ActivityStack stack = mStacks.get(stackNdx); 1656 if (stack.mResumedActivity != null) { 1657 stack.stopIfSleepingLocked(); 1658 final long endTime = System.currentTimeMillis() + timeout; 1659 while (stack.mResumedActivity != null || stack.mPausingActivity != null) { 1660 long delay = endTime - System.currentTimeMillis(); 1661 if (delay <= 0) { 1662 Slog.w(TAG, "Activity manager shutdown timed out"); 1663 timedout = true; 1664 break; 1665 } 1666 try { 1667 mService.wait(); 1668 } catch (InterruptedException e) { 1669 } 1670 } 1671 } 1672 } 1673 return timedout; 1674 } 1675 1676 void comeOutOfSleepIfNeededLocked() { 1677 final boolean homeIsBack = !homeIsInFront(); 1678 final int numStacks = mStacks.size(); 1679 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1680 final ActivityStack stack = mStacks.get(stackNdx); 1681 if (stack.isHomeStack() ^ homeIsBack) { 1682 stack.awakeFromSleepingLocked(); 1683 stack.resumeTopActivityLocked(null); 1684 } 1685 } 1686 } 1687 1688 void handleAppCrashLocked(ProcessRecord app) { 1689 final int numStacks = mStacks.size(); 1690 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1691 final ActivityStack stack = mStacks.get(stackNdx); 1692 stack.handleAppCrashLocked(app); 1693 } 1694 } 1695 1696 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 1697 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1698 mStacks.get(stackNdx).ensureActivitiesVisibleLocked(starting, configChanges); 1699 } 1700 } 1701 1702 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 1703 final int numStacks = mStacks.size(); 1704 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1705 final ActivityStack stack = mStacks.get(stackNdx); 1706 stack.scheduleDestroyActivities(app, false, reason); 1707 } 1708 } 1709 1710 boolean switchUserLocked(int userId, UserStartedState uss) { 1711 mCurrentUser = userId; 1712 boolean homeInBack = !homeIsInFront(); 1713 boolean haveActivities = false; 1714 final int numStacks = mStacks.size(); 1715 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1716 final ActivityStack stack = mStacks.get(stackNdx); 1717 if (stack.isHomeStack() ^ homeInBack) { 1718 haveActivities |= stack.switchUserLocked(userId, uss); 1719 } 1720 } 1721 return haveActivities; 1722 } 1723 1724 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 1725 int N = mStoppingActivities.size(); 1726 if (N <= 0) return null; 1727 1728 ArrayList<ActivityRecord> stops = null; 1729 1730 final boolean nowVisible = allResumedActivitiesVisible(); 1731 for (int i=0; i<N; i++) { 1732 ActivityRecord s = mStoppingActivities.get(i); 1733 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 1734 + nowVisible + " waitingVisible=" + s.waitingVisible 1735 + " finishing=" + s.finishing); 1736 if (s.waitingVisible && nowVisible) { 1737 mWaitingVisibleActivities.remove(s); 1738 s.waitingVisible = false; 1739 if (s.finishing) { 1740 // If this activity is finishing, it is sitting on top of 1741 // everyone else but we now know it is no longer needed... 1742 // so get rid of it. Otherwise, we need to go through the 1743 // normal flow and hide it once we determine that it is 1744 // hidden by the activities in front of it. 1745 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 1746 mService.mWindowManager.setAppVisibility(s.appToken, false); 1747 } 1748 } 1749 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 1750 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 1751 if (stops == null) { 1752 stops = new ArrayList<ActivityRecord>(); 1753 } 1754 stops.add(s); 1755 mStoppingActivities.remove(i); 1756 N--; 1757 i--; 1758 } 1759 } 1760 1761 return stops; 1762 } 1763 1764 public void dump(PrintWriter pw, String prefix) { 1765 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:"); 1766 pw.println(mDismissKeyguardOnNextActivity); 1767 } 1768 1769 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 1770 return getTopStack().getDumpActivitiesLocked(name); 1771 } 1772 1773 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 1774 boolean dumpClient, String dumpPackage) { 1775 final int numStacks = mStacks.size(); 1776 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1777 final ActivityStack stack = mStacks.get(stackNdx); 1778 pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":"); 1779 stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage); 1780 pw.println(" "); 1781 pw.println(" Running activities (most recent first):"); 1782 dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false, 1783 dumpPackage); 1784 if (stack.mGoingToSleepActivities.size() > 0) { 1785 pw.println(" "); 1786 pw.println(" Activities waiting to sleep:"); 1787 dumpHistoryList(fd, pw, stack.mGoingToSleepActivities, " ", "Sleep", false, 1788 !dumpAll, false, dumpPackage); 1789 } 1790 if (stack.mFinishingActivities.size() > 0) { 1791 pw.println(" "); 1792 pw.println(" Activities waiting to finish:"); 1793 dumpHistoryList(fd, pw, stack.mFinishingActivities, " ", "Fin", false, 1794 !dumpAll, false, dumpPackage); 1795 } 1796 1797 pw.print(" Stack #"); pw.println(mStacks.indexOf(stack)); 1798 if (stack.mPausingActivity != null) { 1799 pw.println(" mPausingActivity: " + stack.mPausingActivity); 1800 } 1801 pw.println(" mResumedActivity: " + stack.mResumedActivity); 1802 if (dumpAll) { 1803 pw.println(" mLastPausedActivity: " + stack.mLastPausedActivity); 1804 pw.println(" mSleepTimeout: " + stack.mSleepTimeout); 1805 } 1806 } 1807 1808 if (mStoppingActivities.size() > 0) { 1809 pw.println(" "); 1810 pw.println(" Activities waiting to stop:"); 1811 dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, false, 1812 dumpPackage); 1813 } 1814 1815 if (mWaitingVisibleActivities.size() > 0) { 1816 pw.println(" "); 1817 pw.println(" Activities waiting for another to become visible:"); 1818 dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 1819 false, dumpPackage); 1820 } 1821 1822 if (dumpAll) { 1823 pw.println(" "); 1824 pw.println(" mCurTaskId: " + mCurTaskId); 1825 } 1826 return true; 1827 } 1828 1829 static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 1830 String prefix, String label, boolean complete, boolean brief, boolean client, 1831 String dumpPackage) { 1832 TaskRecord lastTask = null; 1833 boolean needNL = false; 1834 final String innerPrefix = prefix + " "; 1835 final String[] args = new String[0]; 1836 for (int i=list.size()-1; i>=0; i--) { 1837 final ActivityRecord r = list.get(i); 1838 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 1839 continue; 1840 } 1841 final boolean full = !brief && (complete || !r.isInHistory()); 1842 if (needNL) { 1843 pw.println(" "); 1844 needNL = false; 1845 } 1846 if (lastTask != r.task) { 1847 lastTask = r.task; 1848 pw.print(prefix); 1849 pw.print(full ? "* " : " "); 1850 pw.println(lastTask); 1851 if (full) { 1852 lastTask.dump(pw, prefix + " "); 1853 } else if (complete) { 1854 // Complete + brief == give a summary. Isn't that obvious?!? 1855 if (lastTask.intent != null) { 1856 pw.print(prefix); pw.print(" "); 1857 pw.println(lastTask.intent.toInsecureStringWithClip()); 1858 } 1859 } 1860 } 1861 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 1862 pw.print(" #"); pw.print(i); pw.print(": "); 1863 pw.println(r); 1864 if (full) { 1865 r.dump(pw, innerPrefix); 1866 } else if (complete) { 1867 // Complete + brief == give a summary. Isn't that obvious?!? 1868 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 1869 if (r.app != null) { 1870 pw.print(innerPrefix); pw.println(r.app); 1871 } 1872 } 1873 if (client && r.app != null && r.app.thread != null) { 1874 // flush anything that is already in the PrintWriter since the thread is going 1875 // to write to the file descriptor directly 1876 pw.flush(); 1877 try { 1878 TransferPipe tp = new TransferPipe(); 1879 try { 1880 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 1881 r.appToken, innerPrefix, args); 1882 // Short timeout, since blocking here can 1883 // deadlock with the application. 1884 tp.go(fd, 2000); 1885 } finally { 1886 tp.kill(); 1887 } 1888 } catch (IOException e) { 1889 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 1890 } catch (RemoteException e) { 1891 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 1892 } 1893 needNL = true; 1894 } 1895 } 1896 } 1897} 1898