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