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