ActivityStackSupervisor.java revision d94b47f3b671f5afbc79b061a9b8fa7aa8b22f87
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.START_ANY_ACTIVITY; 20import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.server.am.ActivityManagerService.localLOGV; 24import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION; 25import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS; 26import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE; 27import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS; 28import static com.android.server.am.ActivityManagerService.DEBUG_STACK; 29import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH; 30import static com.android.server.am.ActivityManagerService.DEBUG_TASKS; 31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; 32import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 33import static com.android.server.am.ActivityManagerService.TAG; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManager.StackInfo; 38import android.app.ActivityOptions; 39import android.app.AppGlobals; 40import android.app.IActivityContainer; 41import android.app.IActivityContainerCallback; 42import android.app.IActivityManager; 43import android.app.IApplicationThread; 44import android.app.IThumbnailReceiver; 45import android.app.PendingIntent; 46import android.app.ActivityManager.RunningTaskInfo; 47import android.app.IActivityManager.WaitResult; 48import android.app.ResultInfo; 49import android.content.ComponentName; 50import android.content.Context; 51import android.content.IIntentSender; 52import android.content.Intent; 53import android.content.IntentSender; 54import android.content.pm.ActivityInfo; 55import android.content.pm.ApplicationInfo; 56import android.content.pm.PackageManager; 57import android.content.pm.ResolveInfo; 58import android.content.res.Configuration; 59import android.graphics.Point; 60import android.hardware.display.DisplayManager; 61import android.hardware.display.DisplayManager.DisplayListener; 62import android.hardware.display.DisplayManagerGlobal; 63import android.hardware.display.VirtualDisplay; 64import android.hardware.input.InputManager; 65import android.hardware.input.InputManagerInternal; 66import android.os.Binder; 67import android.os.Bundle; 68import android.os.Debug; 69import android.os.Handler; 70import android.os.IBinder; 71import android.os.Looper; 72import android.os.Message; 73import android.os.ParcelFileDescriptor; 74import android.os.PowerManager; 75import android.os.Process; 76import android.os.RemoteException; 77import android.os.SystemClock; 78import android.os.UserHandle; 79import android.util.EventLog; 80import android.util.Slog; 81import android.util.SparseArray; 82 83import android.util.SparseIntArray; 84import android.view.Display; 85import android.view.DisplayInfo; 86import android.view.InputEvent; 87import android.view.Surface; 88import com.android.internal.app.HeavyWeightSwitcherActivity; 89import com.android.internal.os.TransferPipe; 90import com.android.server.LocalServices; 91import com.android.server.am.ActivityManagerService.PendingActivityLaunch; 92import com.android.server.am.ActivityStack.ActivityState; 93import com.android.server.wm.WindowManagerService; 94 95import java.io.FileDescriptor; 96import java.io.IOException; 97import java.io.PrintWriter; 98import java.util.ArrayList; 99import java.util.List; 100 101public final class ActivityStackSupervisor implements DisplayListener { 102 static final boolean DEBUG = ActivityManagerService.DEBUG || false; 103 static final boolean DEBUG_ADD_REMOVE = DEBUG || false; 104 static final boolean DEBUG_APP = DEBUG || false; 105 static final boolean DEBUG_SAVED_STATE = DEBUG || false; 106 static final boolean DEBUG_STATES = DEBUG || false; 107 static final boolean DEBUG_IDLE = DEBUG || false; 108 109 public static final int HOME_STACK_ID = 0; 110 111 /** How long we wait until giving up on the last activity telling us it is idle. */ 112 static final int IDLE_TIMEOUT = 10*1000; 113 114 /** How long we can hold the sleep wake lock before giving up. */ 115 static final int SLEEP_TIMEOUT = 5*1000; 116 117 // How long we can hold the launch wake lock before giving up. 118 static final int LAUNCH_TIMEOUT = 10*1000; 119 120 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 121 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 122 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 123 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 124 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 125 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; 126 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 127 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; 128 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8; 129 static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 9; 130 131 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; 132 133 // For debugging to make sure the caller when acquiring/releasing our 134 // wake lock is the system process. 135 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 136 137 final ActivityManagerService mService; 138 139 final ActivityStackSupervisorHandler mHandler; 140 141 /** Short cut */ 142 WindowManagerService mWindowManager; 143 DisplayManager mDisplayManager; 144 145 /** Dismiss the keyguard after the next activity is displayed? */ 146 boolean mDismissKeyguardOnNextActivity = false; 147 148 /** Identifier counter for all ActivityStacks */ 149 private int mLastStackId = HOME_STACK_ID; 150 151 /** Task identifier that activities are currently being started in. Incremented each time a 152 * new task is created. */ 153 private int mCurTaskId = 0; 154 155 /** The current user */ 156 private int mCurrentUser; 157 158 /** The stack containing the launcher app. Assumed to always be attached to 159 * Display.DEFAULT_DISPLAY. */ 160 private ActivityStack mHomeStack; 161 162 /** The stack currently receiving input or launching the next activity. */ 163 private ActivityStack mFocusedStack; 164 165 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 166 * been resumed. If stacks are changing position this will hold the old stack until the new 167 * stack becomes resumed after which it will be set to mFocusedStack. */ 168 private ActivityStack mLastFocusedStack; 169 170 /** List of activities that are waiting for a new activity to become visible before completing 171 * whatever operation they are supposed to do. */ 172 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); 173 174 /** List of processes waiting to find out about the next visible activity. */ 175 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = 176 new ArrayList<IActivityManager.WaitResult>(); 177 178 /** List of processes waiting to find out about the next launched activity. */ 179 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = 180 new ArrayList<IActivityManager.WaitResult>(); 181 182 /** List of activities that are ready to be stopped, but waiting for the next activity to 183 * settle down before doing so. */ 184 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); 185 186 /** List of activities that are ready to be finished, but waiting for the previous activity to 187 * settle down before doing so. It contains ActivityRecord objects. */ 188 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>(); 189 190 /** List of activities that are in the process of going to sleep. */ 191 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>(); 192 193 /** List of ActivityRecord objects that have been finished and must still report back to a 194 * pending thumbnail receiver. */ 195 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>(); 196 197 /** Used on user changes */ 198 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>(); 199 200 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 201 * is being brought in front of us. */ 202 boolean mUserLeaving = false; 203 204 /** Set when we have taken too long waiting to go to sleep. */ 205 boolean mSleepTimeout = false; 206 207 /** 208 * We don't want to allow the device to go to sleep while in the process 209 * of launching an activity. This is primarily to allow alarm intent 210 * receivers to launch an activity and get that to run before the device 211 * goes back to sleep. 212 */ 213 final PowerManager.WakeLock mLaunchingActivity; 214 215 /** 216 * Set when the system is going to sleep, until we have 217 * successfully paused the current activity and released our wake lock. 218 * At that point the system is allowed to actually sleep. 219 */ 220 final PowerManager.WakeLock mGoingToSleep; 221 222 /** Stack id of the front stack when user switched, indexed by userId. */ 223 SparseIntArray mUserStackInFront = new SparseIntArray(2); 224 225 // TODO: Add listener for removal of references. 226 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ 227 SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>(); 228 229 /** Mapping from displayId to display current state */ 230 private final SparseArray<ActivityDisplay> mActivityDisplays = 231 new SparseArray<ActivityDisplay>(); 232 233 InputManagerInternal mInputManagerInternal; 234 235 public ActivityStackSupervisor(ActivityManagerService service) { 236 mService = service; 237 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); 238 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 239 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); 240 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 241 throw new IllegalStateException("Calling must be system uid"); 242 } 243 mLaunchingActivity = 244 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 245 mLaunchingActivity.setReferenceCounted(false); 246 } 247 248 void setWindowManager(WindowManagerService wm) { 249 synchronized (mService) { 250 mWindowManager = wm; 251 252 mDisplayManager = 253 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); 254 mDisplayManager.registerDisplayListener(this, null); 255 256 Display[] displays = mDisplayManager.getDisplays(); 257 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { 258 final int displayId = displays[displayNdx].getDisplayId(); 259 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 260 mActivityDisplays.put(displayId, activityDisplay); 261 } 262 263 createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY); 264 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID); 265 266 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 267 } 268 } 269 270 void dismissKeyguard() { 271 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); 272 if (mDismissKeyguardOnNextActivity) { 273 mDismissKeyguardOnNextActivity = false; 274 mWindowManager.dismissKeyguard(); 275 } 276 } 277 278 ActivityStack getFocusedStack() { 279 return mFocusedStack; 280 } 281 282 ActivityStack getLastStack() { 283 return mLastFocusedStack; 284 } 285 286 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the 287 // top of all visible stacks. 288 boolean isFrontStack(ActivityStack stack) { 289 final ActivityRecord parent = stack.mActivityContainer.mParentActivity; 290 if (parent != null) { 291 stack = parent.task.stack; 292 } 293 ArrayList<ActivityStack> stacks = stack.mStacks; 294 if (stacks != null && !stacks.isEmpty()) { 295 return stack == stacks.get(stacks.size() - 1); 296 } 297 return false; 298 } 299 300 void moveHomeStack(boolean toFront) { 301 ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 302 int topNdx = stacks.size() - 1; 303 if (topNdx <= 0) { 304 return; 305 } 306 ActivityStack topStack = stacks.get(topNdx); 307 final boolean homeInFront = topStack == mHomeStack; 308 if (homeInFront != toFront) { 309 mLastFocusedStack = topStack; 310 stacks.remove(mHomeStack); 311 stacks.add(toFront ? topNdx : 0, mHomeStack); 312 mFocusedStack = stacks.get(topNdx); 313 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new=" 314 + mFocusedStack); 315 } 316 } 317 318 void moveHomeToTop() { 319 moveHomeStack(true); 320 mHomeStack.moveHomeTaskToTop(); 321 } 322 323 boolean resumeHomeActivity(ActivityRecord prev) { 324 moveHomeToTop(); 325 if (prev != null) { 326 prev.task.mOnTopOfHome = false; 327 } 328 ActivityRecord r = mHomeStack.topRunningActivityLocked(null); 329 if (r != null && r.isHomeActivity()) { 330 mService.setFocusedActivityLocked(r); 331 return resumeTopActivitiesLocked(mHomeStack, prev, null); 332 } 333 return mService.startHomeActivityLocked(mCurrentUser); 334 } 335 336 void setDismissKeyguard(boolean dismiss) { 337 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss); 338 mDismissKeyguardOnNextActivity = dismiss; 339 } 340 341 TaskRecord anyTaskForIdLocked(int id) { 342 int numDisplays = mActivityDisplays.size(); 343 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 344 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 345 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 346 ActivityStack stack = stacks.get(stackNdx); 347 TaskRecord task = stack.taskForIdLocked(id); 348 if (task != null) { 349 return task; 350 } 351 } 352 } 353 return null; 354 } 355 356 ActivityRecord isInAnyStackLocked(IBinder token) { 357 int numDisplays = mActivityDisplays.size(); 358 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 359 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 360 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 361 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token); 362 if (r != null) { 363 return r; 364 } 365 } 366 } 367 return null; 368 } 369 370 int getNextTaskId() { 371 do { 372 mCurTaskId++; 373 if (mCurTaskId <= 0) { 374 mCurTaskId = 1; 375 } 376 } while (anyTaskForIdLocked(mCurTaskId) != null); 377 return mCurTaskId; 378 } 379 380 ActivityRecord resumedAppLocked() { 381 ActivityStack stack = getFocusedStack(); 382 if (stack == null) { 383 return null; 384 } 385 ActivityRecord resumedActivity = stack.mResumedActivity; 386 if (resumedActivity == null || resumedActivity.app == null) { 387 resumedActivity = stack.mPausingActivity; 388 if (resumedActivity == null || resumedActivity.app == null) { 389 resumedActivity = stack.topRunningActivityLocked(null); 390 } 391 } 392 return resumedActivity; 393 } 394 395 boolean attachApplicationLocked(ProcessRecord app) throws Exception { 396 final String processName = app.processName; 397 boolean didSomething = false; 398 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 399 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 400 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 401 final ActivityStack stack = stacks.get(stackNdx); 402 if (!isFrontStack(stack)) { 403 continue; 404 } 405 ActivityRecord hr = stack.topRunningActivityLocked(null); 406 if (hr != null) { 407 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 408 && processName.equals(hr.processName)) { 409 try { 410 if (realStartActivityLocked(hr, app, true, true)) { 411 didSomething = true; 412 } 413 } catch (Exception e) { 414 Slog.w(TAG, "Exception in new application when starting activity " 415 + hr.intent.getComponent().flattenToShortString(), e); 416 throw e; 417 } 418 } 419 } 420 } 421 } 422 if (!didSomething) { 423 ensureActivitiesVisibleLocked(null, 0); 424 } 425 return didSomething; 426 } 427 428 boolean allResumedActivitiesIdle() { 429 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 430 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 431 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 432 final ActivityStack stack = stacks.get(stackNdx); 433 if (!isFrontStack(stack) || stack.numActivities() == 0) { 434 continue; 435 } 436 final ActivityRecord resumedActivity = stack.mResumedActivity; 437 if (resumedActivity == null || !resumedActivity.idle) { 438 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack=" 439 + stack.mStackId + " " + resumedActivity + " not idle"); 440 return false; 441 } 442 } 443 } 444 return true; 445 } 446 447 boolean allResumedActivitiesComplete() { 448 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 449 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 450 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 451 final ActivityStack stack = stacks.get(stackNdx); 452 if (isFrontStack(stack)) { 453 final ActivityRecord r = stack.mResumedActivity; 454 if (r != null && r.state != ActivityState.RESUMED) { 455 return false; 456 } 457 } 458 } 459 } 460 // TODO: Not sure if this should check if all Paused are complete too. 461 if (DEBUG_STACK) Slog.d(TAG, 462 "allResumedActivitiesComplete: mLastFocusedStack changing from=" + 463 mLastFocusedStack + " to=" + mFocusedStack); 464 mLastFocusedStack = mFocusedStack; 465 return true; 466 } 467 468 boolean allResumedActivitiesVisible() { 469 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 470 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 471 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 472 final ActivityStack stack = stacks.get(stackNdx); 473 final ActivityRecord r = stack.mResumedActivity; 474 if (r != null && (!r.nowVisible || r.waitingVisible)) { 475 return false; 476 } 477 } 478 } 479 return true; 480 } 481 482 /** 483 * Pause all activities in either all of the stacks or just the back stacks. 484 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). 485 * @return true if any activity was paused as a result of this call. 486 */ 487 boolean pauseBackStacks(boolean userLeaving) { 488 boolean someActivityPaused = false; 489 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 490 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 491 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 492 final ActivityStack stack = stacks.get(stackNdx); 493 if (!isFrontStack(stack) && stack.mResumedActivity != null) { 494 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + 495 " mResumedActivity=" + stack.mResumedActivity); 496 stack.startPausingLocked(userLeaving, false); 497 someActivityPaused = true; 498 } 499 } 500 } 501 return someActivityPaused; 502 } 503 504 boolean allPausedActivitiesComplete() { 505 boolean pausing = true; 506 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 507 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 508 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 509 final ActivityStack stack = stacks.get(stackNdx); 510 final ActivityRecord r = stack.mPausingActivity; 511 if (r != null && r.state != ActivityState.PAUSED 512 && r.state != ActivityState.STOPPED 513 && r.state != ActivityState.STOPPING) { 514 if (DEBUG_STATES) { 515 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state); 516 pausing = false; 517 } else { 518 return false; 519 } 520 } 521 } 522 } 523 return pausing; 524 } 525 526 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) { 527 // TODO: Put all stacks in supervisor and iterate through them instead. 528 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 529 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 530 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 531 final ActivityStack stack = stacks.get(stackNdx); 532 if (stack.mResumedActivity != null && 533 stack.mActivityContainer.mParentActivity == parent) { 534 stack.startPausingLocked(userLeaving, uiSleeping); 535 } 536 } 537 } 538 } 539 540 void reportActivityVisibleLocked(ActivityRecord r) { 541 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 542 WaitResult w = mWaitingActivityVisible.get(i); 543 w.timeout = false; 544 if (r != null) { 545 w.who = new ComponentName(r.info.packageName, r.info.name); 546 } 547 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 548 w.thisTime = w.totalTime; 549 } 550 mService.notifyAll(); 551 dismissKeyguard(); 552 } 553 554 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 555 long thisTime, long totalTime) { 556 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 557 WaitResult w = mWaitingActivityLaunched.remove(i); 558 w.timeout = timeout; 559 if (r != null) { 560 w.who = new ComponentName(r.info.packageName, r.info.name); 561 } 562 w.thisTime = thisTime; 563 w.totalTime = totalTime; 564 } 565 mService.notifyAll(); 566 } 567 568 ActivityRecord topRunningActivityLocked() { 569 final ActivityStack focusedStack = getFocusedStack(); 570 ActivityRecord r = focusedStack.topRunningActivityLocked(null); 571 if (r != null) { 572 return r; 573 } 574 575 // Return to the home stack. 576 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 577 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 578 final ActivityStack stack = stacks.get(stackNdx); 579 if (stack != focusedStack && isFrontStack(stack)) { 580 r = stack.topRunningActivityLocked(null); 581 if (r != null) { 582 return r; 583 } 584 } 585 } 586 return null; 587 } 588 589 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, 590 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) { 591 ActivityRecord r = null; 592 593 // Gather all of the running tasks for each stack into runningTaskLists. 594 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = 595 new ArrayList<ArrayList<RunningTaskInfo>>(); 596 final int numDisplays = mActivityDisplays.size(); 597 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 598 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 599 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 600 final ActivityStack stack = stacks.get(stackNdx); 601 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>(); 602 runningTaskLists.add(stackTaskList); 603 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList); 604 if (r == null && isFrontStack(stack)) { 605 r = ar; 606 } 607 } 608 } 609 610 // The lists are already sorted from most recent to oldest. Just pull the most recent off 611 // each list and add it to list. Stop when all lists are empty or maxNum reached. 612 while (maxNum > 0) { 613 long mostRecentActiveTime = Long.MIN_VALUE; 614 ArrayList<RunningTaskInfo> selectedStackList = null; 615 final int numTaskLists = runningTaskLists.size(); 616 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { 617 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); 618 if (!stackTaskList.isEmpty()) { 619 final long lastActiveTime = stackTaskList.get(0).lastActiveTime; 620 if (lastActiveTime > mostRecentActiveTime) { 621 mostRecentActiveTime = lastActiveTime; 622 selectedStackList = stackTaskList; 623 } 624 } 625 } 626 if (selectedStackList != null) { 627 list.add(selectedStackList.remove(0)); 628 --maxNum; 629 } else { 630 break; 631 } 632 } 633 634 return r; 635 } 636 637 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 638 String profileFile, ParcelFileDescriptor profileFd, int userId) { 639 // Collect information about the target of the Intent. 640 ActivityInfo aInfo; 641 try { 642 ResolveInfo rInfo = 643 AppGlobals.getPackageManager().resolveIntent( 644 intent, resolvedType, 645 PackageManager.MATCH_DEFAULT_ONLY 646 | ActivityManagerService.STOCK_PM_FLAGS, userId); 647 aInfo = rInfo != null ? rInfo.activityInfo : null; 648 } catch (RemoteException e) { 649 aInfo = null; 650 } 651 652 if (aInfo != null) { 653 // Store the found target back into the intent, because now that 654 // we have it we never want to do this again. For example, if the 655 // user navigates back to this point in the history, we should 656 // always restart the exact same activity. 657 intent.setComponent(new ComponentName( 658 aInfo.applicationInfo.packageName, aInfo.name)); 659 660 // Don't debug things in the system process 661 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 662 if (!aInfo.processName.equals("system")) { 663 mService.setDebugApp(aInfo.processName, true, false); 664 } 665 } 666 667 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 668 if (!aInfo.processName.equals("system")) { 669 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 670 } 671 } 672 673 if (profileFile != null) { 674 if (!aInfo.processName.equals("system")) { 675 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, 676 profileFile, profileFd, 677 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0); 678 } 679 } 680 } 681 return aInfo; 682 } 683 684 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 685 moveHomeToTop(); 686 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, 687 null, false, null, null); 688 } 689 690 final int startActivityMayWait(IApplicationThread caller, int callingUid, 691 String callingPackage, Intent intent, String resolvedType, IBinder resultTo, 692 String resultWho, int requestCode, int startFlags, String profileFile, 693 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, 694 Bundle options, int userId, IActivityContainer iContainer) { 695 // Refuse possible leaked file descriptors 696 if (intent != null && intent.hasFileDescriptors()) { 697 throw new IllegalArgumentException("File descriptors passed in Intent"); 698 } 699 boolean componentSpecified = intent.getComponent() != null; 700 701 // Don't modify the client's object! 702 intent = new Intent(intent); 703 704 // Collect information about the target of the Intent. 705 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 706 profileFile, profileFd, userId); 707 708 ActivityContainer container = (ActivityContainer)iContainer; 709 synchronized (mService) { 710 int callingPid; 711 if (callingUid >= 0) { 712 callingPid = -1; 713 } else if (caller == null) { 714 callingPid = Binder.getCallingPid(); 715 callingUid = Binder.getCallingUid(); 716 } else { 717 callingPid = callingUid = -1; 718 } 719 720 final ActivityStack stack; 721 if (container == null || container.mStack.isOnHomeDisplay()) { 722 stack = getFocusedStack(); 723 } else { 724 stack = container.mStack; 725 } 726 stack.mConfigWillChange = config != null 727 && mService.mConfiguration.diff(config) != 0; 728 if (DEBUG_CONFIGURATION) Slog.v(TAG, 729 "Starting activity when config will change = " + stack.mConfigWillChange); 730 731 final long origId = Binder.clearCallingIdentity(); 732 733 if (aInfo != null && 734 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 735 // This may be a heavy-weight process! Check to see if we already 736 // have another, different heavy-weight process running. 737 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 738 if (mService.mHeavyWeightProcess != null && 739 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 740 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 741 int realCallingUid = callingUid; 742 if (caller != null) { 743 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 744 if (callerApp != null) { 745 realCallingUid = callerApp.info.uid; 746 } else { 747 Slog.w(TAG, "Unable to find app for caller " + caller 748 + " (pid=" + callingPid + ") when starting: " 749 + intent.toString()); 750 ActivityOptions.abort(options); 751 return ActivityManager.START_PERMISSION_DENIED; 752 } 753 } 754 755 IIntentSender target = mService.getIntentSenderLocked( 756 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 757 realCallingUid, userId, null, null, 0, new Intent[] { intent }, 758 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 759 | PendingIntent.FLAG_ONE_SHOT, null); 760 761 Intent newIntent = new Intent(); 762 if (requestCode >= 0) { 763 // Caller is requesting a result. 764 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 765 } 766 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 767 new IntentSender(target)); 768 if (mService.mHeavyWeightProcess.activities.size() > 0) { 769 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 770 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 771 hist.packageName); 772 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 773 hist.task.taskId); 774 } 775 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 776 aInfo.packageName); 777 newIntent.setFlags(intent.getFlags()); 778 newIntent.setClassName("android", 779 HeavyWeightSwitcherActivity.class.getName()); 780 intent = newIntent; 781 resolvedType = null; 782 caller = null; 783 callingUid = Binder.getCallingUid(); 784 callingPid = Binder.getCallingPid(); 785 componentSpecified = true; 786 try { 787 ResolveInfo rInfo = 788 AppGlobals.getPackageManager().resolveIntent( 789 intent, null, 790 PackageManager.MATCH_DEFAULT_ONLY 791 | ActivityManagerService.STOCK_PM_FLAGS, userId); 792 aInfo = rInfo != null ? rInfo.activityInfo : null; 793 aInfo = mService.getActivityInfoForUser(aInfo, userId); 794 } catch (RemoteException e) { 795 aInfo = null; 796 } 797 } 798 } 799 } 800 801 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho, 802 requestCode, callingPid, callingUid, callingPackage, startFlags, options, 803 componentSpecified, null, container); 804 805 if (stack.mConfigWillChange) { 806 // If the caller also wants to switch to a new configuration, 807 // do so now. This allows a clean switch, as we are waiting 808 // for the current activity to pause (so we will not destroy 809 // it), and have not yet started the next activity. 810 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 811 "updateConfiguration()"); 812 stack.mConfigWillChange = false; 813 if (DEBUG_CONFIGURATION) Slog.v(TAG, 814 "Updating to new configuration after starting activity."); 815 mService.updateConfigurationLocked(config, null, false, false); 816 } 817 818 Binder.restoreCallingIdentity(origId); 819 820 if (outResult != null) { 821 outResult.result = res; 822 if (res == ActivityManager.START_SUCCESS) { 823 mWaitingActivityLaunched.add(outResult); 824 do { 825 try { 826 mService.wait(); 827 } catch (InterruptedException e) { 828 } 829 } while (!outResult.timeout && outResult.who == null); 830 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 831 ActivityRecord r = stack.topRunningActivityLocked(null); 832 if (r.nowVisible) { 833 outResult.timeout = false; 834 outResult.who = new ComponentName(r.info.packageName, r.info.name); 835 outResult.totalTime = 0; 836 outResult.thisTime = 0; 837 } else { 838 outResult.thisTime = SystemClock.uptimeMillis(); 839 mWaitingActivityVisible.add(outResult); 840 do { 841 try { 842 mService.wait(); 843 } catch (InterruptedException e) { 844 } 845 } while (!outResult.timeout && outResult.who == null); 846 } 847 } 848 } 849 850 return res; 851 } 852 } 853 854 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 855 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 856 Bundle options, int userId) { 857 if (intents == null) { 858 throw new NullPointerException("intents is null"); 859 } 860 if (resolvedTypes == null) { 861 throw new NullPointerException("resolvedTypes is null"); 862 } 863 if (intents.length != resolvedTypes.length) { 864 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 865 } 866 867 868 int callingPid; 869 if (callingUid >= 0) { 870 callingPid = -1; 871 } else if (caller == null) { 872 callingPid = Binder.getCallingPid(); 873 callingUid = Binder.getCallingUid(); 874 } else { 875 callingPid = callingUid = -1; 876 } 877 final long origId = Binder.clearCallingIdentity(); 878 try { 879 synchronized (mService) { 880 ActivityRecord[] outActivity = new ActivityRecord[1]; 881 for (int i=0; i<intents.length; i++) { 882 Intent intent = intents[i]; 883 if (intent == null) { 884 continue; 885 } 886 887 // Refuse possible leaked file descriptors 888 if (intent != null && intent.hasFileDescriptors()) { 889 throw new IllegalArgumentException("File descriptors passed in Intent"); 890 } 891 892 boolean componentSpecified = intent.getComponent() != null; 893 894 // Don't modify the client's object! 895 intent = new Intent(intent); 896 897 // Collect information about the target of the Intent. 898 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 899 0, null, null, userId); 900 // TODO: New, check if this is correct 901 aInfo = mService.getActivityInfoForUser(aInfo, userId); 902 903 if (aInfo != null && 904 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 905 != 0) { 906 throw new IllegalArgumentException( 907 "FLAG_CANT_SAVE_STATE not supported here"); 908 } 909 910 Bundle theseOptions; 911 if (options != null && i == intents.length-1) { 912 theseOptions = options; 913 } else { 914 theseOptions = null; 915 } 916 int res = startActivityLocked(caller, intent, resolvedTypes[i], 917 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, 918 0, theseOptions, componentSpecified, outActivity, null); 919 if (res < 0) { 920 return res; 921 } 922 923 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 924 } 925 } 926 } finally { 927 Binder.restoreCallingIdentity(origId); 928 } 929 930 return ActivityManager.START_SUCCESS; 931 } 932 933 final boolean realStartActivityLocked(ActivityRecord r, 934 ProcessRecord app, boolean andResume, boolean checkConfig) 935 throws RemoteException { 936 937 r.startFreezingScreenLocked(app, 0); 938 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true"); 939 mWindowManager.setAppVisibility(r.appToken, true); 940 941 // schedule launch ticks to collect information about slow apps. 942 r.startLaunchTickingLocked(); 943 944 // Have the window manager re-evaluate the orientation of 945 // the screen based on the new activity order. Note that 946 // as a result of this, it can call back into the activity 947 // manager with a new orientation. We don't care about that, 948 // because the activity is not currently running so we are 949 // just restarting it anyway. 950 if (checkConfig) { 951 Configuration config = mWindowManager.updateOrientationFromAppTokens( 952 mService.mConfiguration, 953 r.mayFreezeScreenLocked(app) ? r.appToken : null); 954 mService.updateConfigurationLocked(config, r, false, false); 955 } 956 957 r.app = app; 958 app.waitingToKill = null; 959 r.launchCount++; 960 r.lastLaunchTime = SystemClock.uptimeMillis(); 961 962 if (localLOGV) Slog.v(TAG, "Launching: " + r); 963 964 int idx = app.activities.indexOf(r); 965 if (idx < 0) { 966 app.activities.add(r); 967 } 968 mService.updateLruProcessLocked(app, true, null); 969 mService.updateOomAdjLocked(); 970 971 final ActivityStack stack = r.task.stack; 972 try { 973 if (app.thread == null) { 974 throw new RemoteException(); 975 } 976 List<ResultInfo> results = null; 977 List<Intent> newIntents = null; 978 if (andResume) { 979 results = r.results; 980 newIntents = r.newIntents; 981 } 982 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 983 + " icicle=" + r.icicle 984 + " with results=" + results + " newIntents=" + newIntents 985 + " andResume=" + andResume); 986 if (andResume) { 987 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 988 r.userId, System.identityHashCode(r), 989 r.task.taskId, r.shortComponentName); 990 } 991 if (r.isHomeActivity() && r.isNotResolverActivity()) { 992 // Home process is the root process of the task. 993 mService.mHomeProcess = r.task.mActivities.get(0).app; 994 } 995 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 996 r.sleeping = false; 997 r.forceNewConfig = false; 998 mService.showAskCompatModeDialogLocked(r); 999 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 1000 String profileFile = null; 1001 ParcelFileDescriptor profileFd = null; 1002 boolean profileAutoStop = false; 1003 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 1004 if (mService.mProfileProc == null || mService.mProfileProc == app) { 1005 mService.mProfileProc = app; 1006 profileFile = mService.mProfileFile; 1007 profileFd = mService.mProfileFd; 1008 profileAutoStop = mService.mAutoStopProfiler; 1009 } 1010 } 1011 app.hasShownUi = true; 1012 app.pendingUiClean = true; 1013 if (profileFd != null) { 1014 try { 1015 profileFd = profileFd.dup(); 1016 } catch (IOException e) { 1017 if (profileFd != null) { 1018 try { 1019 profileFd.close(); 1020 } catch (IOException o) { 1021 } 1022 profileFd = null; 1023 } 1024 } 1025 } 1026 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); 1027 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1028 System.identityHashCode(r), r.info, 1029 new Configuration(mService.mConfiguration), r.compat, 1030 app.repProcState, r.icicle, results, newIntents, !andResume, 1031 mService.isNextTransitionForward(), profileFile, profileFd, 1032 profileAutoStop); 1033 1034 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 1035 // This may be a heavy-weight process! Note that the package 1036 // manager will ensure that only activity can run in the main 1037 // process of the .apk, which is the only thing that will be 1038 // considered heavy-weight. 1039 if (app.processName.equals(app.info.packageName)) { 1040 if (mService.mHeavyWeightProcess != null 1041 && mService.mHeavyWeightProcess != app) { 1042 Slog.w(TAG, "Starting new heavy weight process " + app 1043 + " when already running " 1044 + mService.mHeavyWeightProcess); 1045 } 1046 mService.mHeavyWeightProcess = app; 1047 Message msg = mService.mHandler.obtainMessage( 1048 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1049 msg.obj = r; 1050 mService.mHandler.sendMessage(msg); 1051 } 1052 } 1053 1054 } catch (RemoteException e) { 1055 if (r.launchFailed) { 1056 // This is the second time we failed -- finish activity 1057 // and give up. 1058 Slog.e(TAG, "Second failure launching " 1059 + r.intent.getComponent().flattenToShortString() 1060 + ", giving up", e); 1061 mService.appDiedLocked(app, app.pid, app.thread); 1062 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1063 "2nd-crash", false); 1064 return false; 1065 } 1066 1067 // This is the first time we failed -- restart process and 1068 // retry. 1069 app.activities.remove(r); 1070 throw e; 1071 } 1072 1073 r.launchFailed = false; 1074 if (stack.updateLRUListLocked(r)) { 1075 Slog.w(TAG, "Activity " + r 1076 + " being launched, but already in LRU list"); 1077 } 1078 1079 if (andResume) { 1080 // As part of the process of launching, ActivityThread also performs 1081 // a resume. 1082 stack.minimalResumeActivityLocked(r); 1083 } else { 1084 // This activity is not starting in the resumed state... which 1085 // should look like we asked it to pause+stop (but remain visible), 1086 // and it has done so and reported back the current icicle and 1087 // other state. 1088 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 1089 + " (starting in stopped state)"); 1090 r.state = ActivityState.STOPPED; 1091 r.stopped = true; 1092 } 1093 1094 // Launch the new version setup screen if needed. We do this -after- 1095 // launching the initial activity (that is, home), so that it can have 1096 // a chance to initialize itself while in the background, making the 1097 // switch back to it faster and look better. 1098 if (isFrontStack(stack)) { 1099 mService.startSetupActivityLocked(); 1100 } 1101 1102 return true; 1103 } 1104 1105 void startSpecificActivityLocked(ActivityRecord r, 1106 boolean andResume, boolean checkConfig) { 1107 // Is this activity's application already running? 1108 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1109 r.info.applicationInfo.uid, true); 1110 1111 r.task.stack.setLaunchTime(r); 1112 1113 if (app != null && app.thread != null) { 1114 try { 1115 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1116 || !"android".equals(r.info.packageName)) { 1117 // Don't add this if it is a platform component that is marked 1118 // to run in multiple processes, because this is actually 1119 // part of the framework so doesn't make sense to track as a 1120 // separate apk in the process. 1121 app.addPackage(r.info.packageName, mService.mProcessStats); 1122 } 1123 realStartActivityLocked(r, app, andResume, checkConfig); 1124 return; 1125 } catch (RemoteException e) { 1126 Slog.w(TAG, "Exception when starting activity " 1127 + r.intent.getComponent().flattenToShortString(), e); 1128 } 1129 1130 // If a dead object exception was thrown -- fall through to 1131 // restart the application. 1132 } 1133 1134 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1135 "activity", r.intent.getComponent(), false, false, true); 1136 } 1137 1138 final int startActivityLocked(IApplicationThread caller, 1139 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, 1140 String resultWho, int requestCode, 1141 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1142 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) { 1143 int err = ActivityManager.START_SUCCESS; 1144 1145 ProcessRecord callerApp = null; 1146 if (caller != null) { 1147 callerApp = mService.getRecordForAppLocked(caller); 1148 if (callerApp != null) { 1149 callingPid = callerApp.pid; 1150 callingUid = callerApp.info.uid; 1151 } else { 1152 Slog.w(TAG, "Unable to find app for caller " + caller 1153 + " (pid=" + callingPid + ") when starting: " 1154 + intent.toString()); 1155 err = ActivityManager.START_PERMISSION_DENIED; 1156 } 1157 } 1158 1159 if (err == ActivityManager.START_SUCCESS) { 1160 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1161 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1162 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid) 1163 + " on display " + (container == null ? (mFocusedStack == null ? 1164 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : 1165 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : 1166 container.mActivityDisplay.mDisplayId))); 1167 } 1168 1169 ActivityRecord sourceRecord = null; 1170 ActivityRecord resultRecord = null; 1171 if (resultTo != null) { 1172 sourceRecord = isInAnyStackLocked(resultTo); 1173 if (DEBUG_RESULTS) Slog.v( 1174 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1175 if (sourceRecord != null) { 1176 if (requestCode >= 0 && !sourceRecord.finishing) { 1177 resultRecord = sourceRecord; 1178 } 1179 } 1180 } 1181 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1182 1183 int launchFlags = intent.getFlags(); 1184 1185 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1186 && sourceRecord != null) { 1187 // Transfer the result target from the source activity to the new 1188 // one being started, including any failures. 1189 if (requestCode >= 0) { 1190 ActivityOptions.abort(options); 1191 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1192 } 1193 resultRecord = sourceRecord.resultTo; 1194 resultWho = sourceRecord.resultWho; 1195 requestCode = sourceRecord.requestCode; 1196 sourceRecord.resultTo = null; 1197 if (resultRecord != null) { 1198 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 1199 } 1200 if (sourceRecord.launchedFromUid == callingUid) { 1201 // The new activity is being launched from the same uid as the previous 1202 // activity in the flow, and asking to forward its result back to the 1203 // previous. In this case the activity is serving as a trampoline between 1204 // the two, so we also want to update its launchedFromPackage to be the 1205 // same as the previous activity. Note that this is safe, since we know 1206 // these two packages come from the same uid; the caller could just as 1207 // well have supplied that same package name itself. This specifially 1208 // deals with the case of an intent picker/chooser being launched in the app 1209 // flow to redirect to an activity picked by the user, where we want the final 1210 // activity to consider it to have been launched by the previous app activity. 1211 callingPackage = sourceRecord.launchedFromPackage; 1212 } 1213 } 1214 1215 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1216 // We couldn't find a class that can handle the given Intent. 1217 // That's the end of that! 1218 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1219 } 1220 1221 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1222 // We couldn't find the specific class specified in the Intent. 1223 // Also the end of the line. 1224 err = ActivityManager.START_CLASS_NOT_FOUND; 1225 } 1226 1227 if (err != ActivityManager.START_SUCCESS) { 1228 if (resultRecord != null) { 1229 resultStack.sendActivityResultLocked(-1, 1230 resultRecord, resultWho, requestCode, 1231 Activity.RESULT_CANCELED, null); 1232 } 1233 setDismissKeyguard(false); 1234 ActivityOptions.abort(options); 1235 return err; 1236 } 1237 1238 final int startAnyPerm = mService.checkPermission( 1239 START_ANY_ACTIVITY, callingPid, callingUid); 1240 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1241 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1242 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1243 if (resultRecord != null) { 1244 resultStack.sendActivityResultLocked(-1, 1245 resultRecord, resultWho, requestCode, 1246 Activity.RESULT_CANCELED, null); 1247 } 1248 setDismissKeyguard(false); 1249 String msg; 1250 if (!aInfo.exported) { 1251 msg = "Permission Denial: starting " + intent.toString() 1252 + " from " + callerApp + " (pid=" + callingPid 1253 + ", uid=" + callingUid + ")" 1254 + " not exported from uid " + aInfo.applicationInfo.uid; 1255 } else { 1256 msg = "Permission Denial: starting " + intent.toString() 1257 + " from " + callerApp + " (pid=" + callingPid 1258 + ", uid=" + callingUid + ")" 1259 + " requires " + aInfo.permission; 1260 } 1261 Slog.w(TAG, msg); 1262 throw new SecurityException(msg); 1263 } 1264 1265 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1266 callingPid, resolvedType, aInfo.applicationInfo); 1267 1268 if (mService.mController != null) { 1269 try { 1270 // The Intent we give to the watcher has the extra data 1271 // stripped off, since it can contain private information. 1272 Intent watchIntent = intent.cloneFilter(); 1273 abort |= !mService.mController.activityStarting(watchIntent, 1274 aInfo.applicationInfo.packageName); 1275 } catch (RemoteException e) { 1276 mService.mController = null; 1277 } 1278 } 1279 1280 if (abort) { 1281 if (resultRecord != null) { 1282 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1283 Activity.RESULT_CANCELED, null); 1284 } 1285 // We pretend to the caller that it was really started, but 1286 // they will just get a cancel result. 1287 setDismissKeyguard(false); 1288 ActivityOptions.abort(options); 1289 return ActivityManager.START_SUCCESS; 1290 } 1291 1292 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1293 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1294 requestCode, componentSpecified, this, container); 1295 if (outActivity != null) { 1296 outActivity[0] = r; 1297 } 1298 1299 final ActivityStack stack = getFocusedStack(); 1300 if (stack.mResumedActivity == null 1301 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { 1302 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1303 PendingActivityLaunch pal = 1304 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1305 mService.mPendingActivityLaunches.add(pal); 1306 setDismissKeyguard(false); 1307 ActivityOptions.abort(options); 1308 return ActivityManager.START_SWITCHES_CANCELED; 1309 } 1310 } 1311 1312 if (mService.mDidAppSwitch) { 1313 // This is the second allowed switch since we stopped switches, 1314 // so now just generally allow switches. Use case: user presses 1315 // home (switches disabled, switch to home, mDidAppSwitch now true); 1316 // user taps a home icon (coming from home so allowed, we hit here 1317 // and now allow anyone to switch again). 1318 mService.mAppSwitchesAllowedTime = 0; 1319 } else { 1320 mService.mDidAppSwitch = true; 1321 } 1322 1323 mService.doPendingActivityLaunchesLocked(false); 1324 1325 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); 1326 1327 if (allPausedActivitiesComplete()) { 1328 // If someone asked to have the keyguard dismissed on the next 1329 // activity start, but we are not actually doing an activity 1330 // switch... just dismiss the keyguard now, because we 1331 // probably want to see whatever is behind it. 1332 dismissKeyguard(); 1333 } 1334 return err; 1335 } 1336 1337 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { 1338 final TaskRecord task = r.task; 1339 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1340 if (task != null) { 1341 final ActivityStack taskStack = task.stack; 1342 if (taskStack.isOnHomeDisplay()) { 1343 if (mFocusedStack != taskStack) { 1344 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1345 "focused stack to r=" + r + " task=" + task); 1346 mFocusedStack = taskStack; 1347 } else { 1348 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1349 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1350 } 1351 } 1352 return taskStack; 1353 } 1354 1355 final ActivityContainer container = r.mInitialActivityContainer; 1356 if (container != null) { 1357 // The first time put it on the desired stack, after this put on task stack. 1358 r.mInitialActivityContainer = null; 1359 return container.mStack; 1360 } 1361 1362 if (mFocusedStack != mHomeStack && (!newTask || 1363 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1364 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1365 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1366 return mFocusedStack; 1367 } 1368 1369 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1370 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1371 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1372 if (!stack.isHomeStack()) { 1373 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1374 "adjustStackFocus: Setting focused stack=" + stack); 1375 mFocusedStack = stack; 1376 return mFocusedStack; 1377 } 1378 } 1379 1380 // Need to create an app stack for this user. 1381 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1382 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1383 " stackId=" + stackId); 1384 mFocusedStack = getStack(stackId); 1385 return mFocusedStack; 1386 } 1387 return mHomeStack; 1388 } 1389 1390 void setFocusedStack(ActivityRecord r) { 1391 if (r != null) { 1392 final TaskRecord task = r.task; 1393 boolean isHomeActivity = !r.isApplicationActivity(); 1394 if (!isHomeActivity && task != null) { 1395 isHomeActivity = !task.isApplicationTask(); 1396 } 1397 if (!isHomeActivity && task != null) { 1398 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity; 1399 isHomeActivity = parent != null && parent.isHomeActivity(); 1400 } 1401 moveHomeStack(isHomeActivity); 1402 } 1403 } 1404 1405 final int startActivityUncheckedLocked(ActivityRecord r, 1406 ActivityRecord sourceRecord, int startFlags, boolean doResume, 1407 Bundle options) { 1408 final Intent intent = r.intent; 1409 final int callingUid = r.launchedFromUid; 1410 1411 int launchFlags = intent.getFlags(); 1412 1413 // We'll invoke onUserLeaving before onPause only if the launching 1414 // activity did not explicitly state that this is an automated launch. 1415 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1416 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1417 1418 // If the caller has asked not to resume at this point, we make note 1419 // of this in the record so that we can skip it when trying to find 1420 // the top running activity. 1421 if (!doResume) { 1422 r.delayedResume = true; 1423 } 1424 1425 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1426 1427 // If the onlyIfNeeded flag is set, then we can do this if the activity 1428 // being launched is the same as the one making the call... or, as 1429 // a special case, if we do not know the caller then we count the 1430 // current top activity as the caller. 1431 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1432 ActivityRecord checkedCaller = sourceRecord; 1433 if (checkedCaller == null) { 1434 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1435 } 1436 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1437 // Caller is not the same as launcher, so always needed. 1438 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1439 } 1440 } 1441 1442 if (sourceRecord == null) { 1443 // This activity is not being started from another... in this 1444 // case we -always- start a new task. 1445 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1446 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1447 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1448 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1449 } 1450 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1451 // The original activity who is starting us is running as a single 1452 // instance... this new activity it is starting must go on its 1453 // own task. 1454 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1455 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1456 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1457 // The activity being started is a single instance... it always 1458 // gets launched into its own task. 1459 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1460 } 1461 1462 ActivityInfo newTaskInfo = null; 1463 Intent newTaskIntent = null; 1464 final ActivityStack sourceStack; 1465 if (sourceRecord != null) { 1466 if (sourceRecord.finishing) { 1467 // If the source is finishing, we can't further count it as our source. This 1468 // is because the task it is associated with may now be empty and on its way out, 1469 // so we don't want to blindly throw it in to that task. Instead we will take 1470 // the NEW_TASK flow and try to find a task for it. But save the task information 1471 // so it can be used when creating the new task. 1472 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1473 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1474 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1475 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1476 newTaskInfo = sourceRecord.info; 1477 newTaskIntent = sourceRecord.task.intent; 1478 } 1479 sourceRecord = null; 1480 sourceStack = null; 1481 } else { 1482 sourceStack = sourceRecord.task.stack; 1483 } 1484 } else { 1485 sourceStack = null; 1486 } 1487 1488 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1489 // For whatever reason this activity is being launched into a new 1490 // task... yet the caller has requested a result back. Well, that 1491 // is pretty messed up, so instead immediately send back a cancel 1492 // and let the new task continue launched as normal without a 1493 // dependency on its originator. 1494 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1495 r.resultTo.task.stack.sendActivityResultLocked(-1, 1496 r.resultTo, r.resultWho, r.requestCode, 1497 Activity.RESULT_CANCELED, null); 1498 r.resultTo = null; 1499 } 1500 1501 boolean addingToTask = false; 1502 boolean movedHome = false; 1503 TaskRecord reuseTask = null; 1504 ActivityStack targetStack; 1505 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1506 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1507 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1508 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1509 // If bring to front is requested, and no result is requested, and 1510 // we can find a task that was started with this same 1511 // component, then instead of launching bring that one to the front. 1512 if (r.resultTo == null) { 1513 // See if there is a task to bring to the front. If this is 1514 // a SINGLE_INSTANCE activity, there can be one and only one 1515 // instance of it in the history, and it is always in its own 1516 // unique task, so we do a special search. 1517 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1518 ? findTaskLocked(r) 1519 : findActivityLocked(intent, r.info); 1520 if (intentActivity != null) { 1521 if (r.task == null) { 1522 r.task = intentActivity.task; 1523 } 1524 targetStack = intentActivity.task.stack; 1525 targetStack.mLastPausedActivity = null; 1526 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1527 + " from " + intentActivity); 1528 targetStack.moveToFront(); 1529 if (intentActivity.task.intent == null) { 1530 // This task was started because of movement of 1531 // the activity based on affinity... now that we 1532 // are actually launching it, we can assign the 1533 // base intent. 1534 intentActivity.task.setIntent(intent, r.info); 1535 } 1536 // If the target task is not in the front, then we need 1537 // to bring it to the front... except... well, with 1538 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1539 // to have the same behavior as if a new instance was 1540 // being started, which means not bringing it to the front 1541 // if the caller is not itself in the front. 1542 final ActivityStack lastStack = getLastStack(); 1543 ActivityRecord curTop = lastStack == null? 1544 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1545 if (curTop != null && (curTop.task != intentActivity.task || 1546 curTop.task != lastStack.topTask())) { 1547 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1548 if (sourceRecord == null || (sourceStack.topActivity() != null && 1549 sourceStack.topActivity().task == sourceRecord.task)) { 1550 // We really do want to push this one into the 1551 // user's face, right now. 1552 movedHome = true; 1553 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1554 if ((launchFlags & 1555 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1556 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1557 // Caller wants to appear on home activity. 1558 intentActivity.task.mOnTopOfHome = true; 1559 } 1560 options = null; 1561 } 1562 } 1563 // If the caller has requested that the target task be 1564 // reset, then do so. 1565 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1566 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1567 } 1568 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1569 // We don't need to start a new activity, and 1570 // the client said not to do anything if that 1571 // is the case, so this is it! And for paranoia, make 1572 // sure we have correctly resumed the top activity. 1573 if (doResume) { 1574 resumeTopActivitiesLocked(targetStack, null, options); 1575 } else { 1576 ActivityOptions.abort(options); 1577 } 1578 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1579 } 1580 if ((launchFlags & 1581 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1582 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1583 // The caller has requested to completely replace any 1584 // existing task with its new activity. Well that should 1585 // not be too hard... 1586 reuseTask = intentActivity.task; 1587 reuseTask.performClearTaskLocked(); 1588 reuseTask.setIntent(r.intent, r.info); 1589 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1590 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1591 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1592 // In this situation we want to remove all activities 1593 // from the task up to the one being started. In most 1594 // cases this means we are resetting the task to its 1595 // initial state. 1596 ActivityRecord top = 1597 intentActivity.task.performClearTaskLocked(r, launchFlags); 1598 if (top != null) { 1599 if (top.frontOfTask) { 1600 // Activity aliases may mean we use different 1601 // intents for the top activity, so make sure 1602 // the task now has the identity of the new 1603 // intent. 1604 top.task.setIntent(r.intent, r.info); 1605 } 1606 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1607 r, top.task); 1608 top.deliverNewIntentLocked(callingUid, r.intent); 1609 } else { 1610 // A special case: we need to 1611 // start the activity because it is not currently 1612 // running, and the caller has asked to clear the 1613 // current task to have this activity at the top. 1614 addingToTask = true; 1615 // Now pretend like this activity is being started 1616 // by the top of its task, so it is put in the 1617 // right place. 1618 sourceRecord = intentActivity; 1619 } 1620 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1621 // In this case the top activity on the task is the 1622 // same as the one being launched, so we take that 1623 // as a request to bring the task to the foreground. 1624 // If the top activity in the task is the root 1625 // activity, deliver this new intent to it if it 1626 // desires. 1627 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1628 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1629 && intentActivity.realActivity.equals(r.realActivity)) { 1630 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1631 intentActivity.task); 1632 if (intentActivity.frontOfTask) { 1633 intentActivity.task.setIntent(r.intent, r.info); 1634 } 1635 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1636 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1637 // In this case we are launching the root activity 1638 // of the task, but with a different intent. We 1639 // should start a new instance on top. 1640 addingToTask = true; 1641 sourceRecord = intentActivity; 1642 } 1643 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1644 // In this case an activity is being launched in to an 1645 // existing task, without resetting that task. This 1646 // is typically the situation of launching an activity 1647 // from a notification or shortcut. We want to place 1648 // the new activity on top of the current task. 1649 addingToTask = true; 1650 sourceRecord = intentActivity; 1651 } else if (!intentActivity.task.rootWasReset) { 1652 // In this case we are launching in to an existing task 1653 // that has not yet been started from its front door. 1654 // The current task has been brought to the front. 1655 // Ideally, we'd probably like to place this new task 1656 // at the bottom of its stack, but that's a little hard 1657 // to do with the current organization of the code so 1658 // for now we'll just drop it. 1659 intentActivity.task.setIntent(r.intent, r.info); 1660 } 1661 if (!addingToTask && reuseTask == null) { 1662 // We didn't do anything... but it was needed (a.k.a., client 1663 // don't use that intent!) And for paranoia, make 1664 // sure we have correctly resumed the top activity. 1665 if (doResume) { 1666 targetStack.resumeTopActivityLocked(null, options); 1667 } else { 1668 ActivityOptions.abort(options); 1669 } 1670 return ActivityManager.START_TASK_TO_FRONT; 1671 } 1672 } 1673 } 1674 } 1675 1676 //String uri = r.intent.toURI(); 1677 //Intent intent2 = new Intent(uri); 1678 //Slog.i(TAG, "Given intent: " + r.intent); 1679 //Slog.i(TAG, "URI is: " + uri); 1680 //Slog.i(TAG, "To intent: " + intent2); 1681 1682 if (r.packageName != null) { 1683 // If the activity being launched is the same as the one currently 1684 // at the top, then we need to check if it should only be launched 1685 // once. 1686 ActivityStack topStack = getFocusedStack(); 1687 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1688 if (top != null && r.resultTo == null) { 1689 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1690 if (top.app != null && top.app.thread != null) { 1691 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1692 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1693 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1694 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1695 top.task); 1696 // For paranoia, make sure we have correctly 1697 // resumed the top activity. 1698 topStack.mLastPausedActivity = null; 1699 if (doResume) { 1700 resumeTopActivitiesLocked(); 1701 } 1702 ActivityOptions.abort(options); 1703 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1704 // We don't need to start a new activity, and 1705 // the client said not to do anything if that 1706 // is the case, so this is it! 1707 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1708 } 1709 top.deliverNewIntentLocked(callingUid, r.intent); 1710 return ActivityManager.START_DELIVERED_TO_TOP; 1711 } 1712 } 1713 } 1714 } 1715 1716 } else { 1717 if (r.resultTo != null) { 1718 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1719 r.requestCode, Activity.RESULT_CANCELED, null); 1720 } 1721 ActivityOptions.abort(options); 1722 return ActivityManager.START_CLASS_NOT_FOUND; 1723 } 1724 1725 boolean newTask = false; 1726 boolean keepCurTransition = false; 1727 1728 // Should this be considered a new task? 1729 if (r.resultTo == null && !addingToTask 1730 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1731 newTask = true; 1732 targetStack = adjustStackFocus(r, newTask); 1733 targetStack.moveToFront(); 1734 if (reuseTask == null) { 1735 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1736 newTaskInfo != null ? newTaskInfo : r.info, 1737 newTaskIntent != null ? newTaskIntent : intent, 1738 true), null, true); 1739 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1740 r.task); 1741 } else { 1742 r.setTask(reuseTask, reuseTask, true); 1743 } 1744 if (!movedHome) { 1745 if ((launchFlags & 1746 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1747 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1748 // Caller wants to appear on home activity, so before starting 1749 // their own activity we will bring home to the front. 1750 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); 1751 } 1752 } 1753 } else if (sourceRecord != null) { 1754 TaskRecord sourceTask = sourceRecord.task; 1755 targetStack = sourceTask.stack; 1756 targetStack.moveToFront(); 1757 mWindowManager.moveTaskToTop(sourceTask.taskId); 1758 if (!addingToTask && 1759 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1760 // In this case, we are adding the activity to an existing 1761 // task, but the caller has asked to clear that task if the 1762 // activity is already running. 1763 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1764 keepCurTransition = true; 1765 if (top != null) { 1766 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1767 top.deliverNewIntentLocked(callingUid, r.intent); 1768 // For paranoia, make sure we have correctly 1769 // resumed the top activity. 1770 targetStack.mLastPausedActivity = null; 1771 if (doResume) { 1772 targetStack.resumeTopActivityLocked(null); 1773 } 1774 ActivityOptions.abort(options); 1775 return ActivityManager.START_DELIVERED_TO_TOP; 1776 } 1777 } else if (!addingToTask && 1778 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1779 // In this case, we are launching an activity in our own task 1780 // that may already be running somewhere in the history, and 1781 // we want to shuffle it to the front of the stack if so. 1782 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1783 if (top != null) { 1784 final TaskRecord task = top.task; 1785 task.moveActivityToFrontLocked(top); 1786 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1787 top.updateOptionsLocked(options); 1788 top.deliverNewIntentLocked(callingUid, r.intent); 1789 targetStack.mLastPausedActivity = null; 1790 if (doResume) { 1791 targetStack.resumeTopActivityLocked(null); 1792 } 1793 return ActivityManager.START_DELIVERED_TO_TOP; 1794 } 1795 } 1796 // An existing activity is starting this new activity, so we want 1797 // to keep the new one in the same task as the one that is starting 1798 // it. 1799 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1800 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1801 + " in existing task " + r.task + " from source " + sourceRecord); 1802 1803 } else { 1804 // This not being started from an existing activity, and not part 1805 // of a new task... just put it in the top task, though these days 1806 // this case should never happen. 1807 targetStack = adjustStackFocus(r, newTask); 1808 targetStack.moveToFront(); 1809 ActivityRecord prev = targetStack.topActivity(); 1810 r.setTask(prev != null ? prev.task 1811 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1812 null, true); 1813 mWindowManager.moveTaskToTop(r.task.taskId); 1814 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1815 + " in new guessed " + r.task); 1816 } 1817 1818 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1819 intent, r.getUriPermissionsLocked()); 1820 1821 if (newTask) { 1822 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1823 } 1824 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1825 targetStack.mLastPausedActivity = null; 1826 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1827 mService.setFocusedActivityLocked(r); 1828 return ActivityManager.START_SUCCESS; 1829 } 1830 1831 void acquireLaunchWakelock() { 1832 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1833 throw new IllegalStateException("Calling must be system uid"); 1834 } 1835 mLaunchingActivity.acquire(); 1836 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1837 // To be safe, don't allow the wake lock to be held for too long. 1838 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1839 } 1840 } 1841 1842 // Checked. 1843 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1844 Configuration config) { 1845 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1846 1847 ArrayList<ActivityRecord> stops = null; 1848 ArrayList<ActivityRecord> finishes = null; 1849 ArrayList<UserStartedState> startingUsers = null; 1850 int NS = 0; 1851 int NF = 0; 1852 IApplicationThread sendThumbnail = null; 1853 boolean booting = false; 1854 boolean enableScreen = false; 1855 boolean activityRemoved = false; 1856 1857 ActivityRecord r = ActivityRecord.forToken(token); 1858 if (r != null) { 1859 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1860 Debug.getCallers(4)); 1861 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1862 r.finishLaunchTickingLocked(); 1863 if (fromTimeout) { 1864 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1865 } 1866 1867 // This is a hack to semi-deal with a race condition 1868 // in the client where it can be constructed with a 1869 // newer configuration from when we asked it to launch. 1870 // We'll update with whatever configuration it now says 1871 // it used to launch. 1872 if (config != null) { 1873 r.configuration = config; 1874 } 1875 1876 // We are now idle. If someone is waiting for a thumbnail from 1877 // us, we can now deliver. 1878 r.idle = true; 1879 1880 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 1881 sendThumbnail = r.app.thread; 1882 r.thumbnailNeeded = false; 1883 } 1884 1885 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1886 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1887 mService.mBooted = true; 1888 enableScreen = true; 1889 } 1890 } 1891 1892 if (allResumedActivitiesIdle()) { 1893 if (r != null) { 1894 mService.scheduleAppGcsLocked(); 1895 } 1896 1897 if (mLaunchingActivity.isHeld()) { 1898 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1899 if (VALIDATE_WAKE_LOCK_CALLER && 1900 Binder.getCallingUid() != Process.myUid()) { 1901 throw new IllegalStateException("Calling must be system uid"); 1902 } 1903 mLaunchingActivity.release(); 1904 } 1905 ensureActivitiesVisibleLocked(null, 0); 1906 } 1907 1908 // Atomically retrieve all of the other things to do. 1909 stops = processStoppingActivitiesLocked(true); 1910 NS = stops != null ? stops.size() : 0; 1911 if ((NF=mFinishingActivities.size()) > 0) { 1912 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1913 mFinishingActivities.clear(); 1914 } 1915 1916 final ArrayList<ActivityRecord> thumbnails; 1917 final int NT = mCancelledThumbnails.size(); 1918 if (NT > 0) { 1919 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); 1920 mCancelledThumbnails.clear(); 1921 } else { 1922 thumbnails = null; 1923 } 1924 1925 if (isFrontStack(mHomeStack)) { 1926 booting = mService.mBooting; 1927 mService.mBooting = false; 1928 } 1929 1930 if (mStartingUsers.size() > 0) { 1931 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1932 mStartingUsers.clear(); 1933 } 1934 1935 // Perform the following actions from unsynchronized state. 1936 final IApplicationThread thumbnailThread = sendThumbnail; 1937 mHandler.post(new Runnable() { 1938 @Override 1939 public void run() { 1940 if (thumbnailThread != null) { 1941 try { 1942 thumbnailThread.requestThumbnail(token); 1943 } catch (Exception e) { 1944 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 1945 mService.sendPendingThumbnail(null, token, null, null, true); 1946 } 1947 } 1948 1949 // Report back to any thumbnail receivers. 1950 for (int i = 0; i < NT; i++) { 1951 ActivityRecord r = thumbnails.get(i); 1952 mService.sendPendingThumbnail(r, null, null, null, true); 1953 } 1954 } 1955 }); 1956 1957 // Stop any activities that are scheduled to do so but have been 1958 // waiting for the next one to start. 1959 for (int i = 0; i < NS; i++) { 1960 r = stops.get(i); 1961 final ActivityStack stack = r.task.stack; 1962 if (r.finishing) { 1963 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1964 } else { 1965 stack.stopActivityLocked(r); 1966 } 1967 } 1968 1969 // Finish any activities that are scheduled to do so but have been 1970 // waiting for the next one to start. 1971 for (int i = 0; i < NF; i++) { 1972 r = finishes.get(i); 1973 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1974 } 1975 1976 if (booting) { 1977 mService.finishBooting(); 1978 } else if (startingUsers != null) { 1979 for (int i = 0; i < startingUsers.size(); i++) { 1980 mService.finishUserSwitch(startingUsers.get(i)); 1981 } 1982 } 1983 1984 mService.trimApplications(); 1985 //dump(); 1986 //mWindowManager.dump(); 1987 1988 if (enableScreen) { 1989 mService.enableScreenAfterBoot(); 1990 } 1991 1992 if (activityRemoved) { 1993 resumeTopActivitiesLocked(); 1994 } 1995 1996 return r; 1997 } 1998 1999 boolean handleAppDiedLocked(ProcessRecord app) { 2000 boolean hasVisibleActivities = false; 2001 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2002 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2003 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2004 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2005 } 2006 } 2007 return hasVisibleActivities; 2008 } 2009 2010 void closeSystemDialogsLocked() { 2011 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2012 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2013 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2014 stacks.get(stackNdx).closeSystemDialogsLocked(); 2015 } 2016 } 2017 } 2018 2019 void removeUserLocked(int userId) { 2020 mUserStackInFront.delete(userId); 2021 } 2022 2023 /** 2024 * @return true if some activity was finished (or would have finished if doit were true). 2025 */ 2026 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2027 boolean didSomething = false; 2028 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2029 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2030 final int numStacks = stacks.size(); 2031 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2032 final ActivityStack stack = stacks.get(stackNdx); 2033 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2034 didSomething = true; 2035 } 2036 } 2037 } 2038 return didSomething; 2039 } 2040 2041 void updatePreviousProcessLocked(ActivityRecord r) { 2042 // Now that this process has stopped, we may want to consider 2043 // it to be the previous app to try to keep around in case 2044 // the user wants to return to it. 2045 2046 // First, found out what is currently the foreground app, so that 2047 // we don't blow away the previous app if this activity is being 2048 // hosted by the process that is actually still the foreground. 2049 ProcessRecord fgApp = null; 2050 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2051 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2052 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2053 final ActivityStack stack = stacks.get(stackNdx); 2054 if (isFrontStack(stack)) { 2055 if (stack.mResumedActivity != null) { 2056 fgApp = stack.mResumedActivity.app; 2057 } else if (stack.mPausingActivity != null) { 2058 fgApp = stack.mPausingActivity.app; 2059 } 2060 break; 2061 } 2062 } 2063 } 2064 2065 // Now set this one as the previous process, only if that really 2066 // makes sense to. 2067 if (r.app != null && fgApp != null && r.app != fgApp 2068 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2069 && r.app != mService.mHomeProcess) { 2070 mService.mPreviousProcess = r.app; 2071 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2072 } 2073 } 2074 2075 boolean resumeTopActivitiesLocked() { 2076 return resumeTopActivitiesLocked(null, null, null); 2077 } 2078 2079 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2080 Bundle targetOptions) { 2081 if (targetStack == null) { 2082 targetStack = getFocusedStack(); 2083 } 2084 // Do targetStack first. 2085 boolean result = false; 2086 if (isFrontStack(targetStack)) { 2087 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2088 } 2089 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2090 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2091 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2092 final ActivityStack stack = stacks.get(stackNdx); 2093 if (stack == targetStack) { 2094 // Already started above. 2095 continue; 2096 } 2097 if (isFrontStack(stack)) { 2098 stack.resumeTopActivityLocked(null); 2099 } 2100 } 2101 } 2102 return result; 2103 } 2104 2105 void finishTopRunningActivityLocked(ProcessRecord app) { 2106 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2107 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2108 final int numStacks = stacks.size(); 2109 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2110 final ActivityStack stack = stacks.get(stackNdx); 2111 stack.finishTopRunningActivityLocked(app); 2112 } 2113 } 2114 } 2115 2116 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 2117 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2118 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2119 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2120 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 2121 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2122 + stacks.get(stackNdx)); 2123 return; 2124 } 2125 } 2126 } 2127 } 2128 2129 ActivityStack getStack(int stackId) { 2130 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2131 if (activityContainer != null) { 2132 return activityContainer.mStack; 2133 } 2134 return null; 2135 } 2136 2137 ArrayList<ActivityStack> getStacks() { 2138 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2139 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2140 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2141 } 2142 return allStacks; 2143 } 2144 2145 IBinder getHomeActivityToken() { 2146 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2147 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2148 final TaskRecord task = tasks.get(taskNdx); 2149 if (task.isHomeTask()) { 2150 final ArrayList<ActivityRecord> activities = task.mActivities; 2151 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2152 final ActivityRecord r = activities.get(activityNdx); 2153 if (r.isHomeActivity()) { 2154 return r.appToken; 2155 } 2156 } 2157 } 2158 } 2159 return null; 2160 } 2161 2162 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2163 IActivityContainerCallback callback) { 2164 ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback); 2165 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2166 parentActivity.mChildContainers.add(activityContainer); 2167 return activityContainer; 2168 } 2169 2170 void removeChildActivityContainers(ActivityRecord parentActivity) { 2171 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2172 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2173 ActivityContainer container = childStacks.remove(containerNdx); 2174 container.release(); 2175 } 2176 } 2177 2178 void deleteActivityContainer(IActivityContainer container) { 2179 ActivityContainer activityContainer = (ActivityContainer)container; 2180 if (activityContainer != null) { 2181 activityContainer.mStack.finishAllActivitiesLocked(); 2182 final ActivityRecord parent = activityContainer.mParentActivity; 2183 if (parent != null) { 2184 parent.mChildContainers.remove(activityContainer); 2185 } 2186 final int stackId = activityContainer.mStackId; 2187 mActivityContainers.remove(stackId); 2188 mWindowManager.removeStack(stackId); 2189 } 2190 } 2191 2192 private int createStackOnDisplay(int stackId, int displayId) { 2193 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2194 if (activityDisplay == null) { 2195 return -1; 2196 } 2197 2198 ActivityContainer activityContainer = new ActivityContainer(stackId); 2199 mActivityContainers.put(stackId, activityContainer); 2200 activityContainer.attachToDisplayLocked(activityDisplay); 2201 return stackId; 2202 } 2203 2204 int getNextStackId() { 2205 while (true) { 2206 if (++mLastStackId <= HOME_STACK_ID) { 2207 mLastStackId = HOME_STACK_ID + 1; 2208 } 2209 if (getStack(mLastStackId) == null) { 2210 break; 2211 } 2212 } 2213 return mLastStackId; 2214 } 2215 2216 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2217 final TaskRecord task = anyTaskForIdLocked(taskId); 2218 if (task == null) { 2219 return; 2220 } 2221 final ActivityStack stack = getStack(stackId); 2222 if (stack == null) { 2223 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2224 return; 2225 } 2226 task.stack.removeTask(task); 2227 stack.addTask(task, toTop); 2228 mWindowManager.addTask(taskId, stackId, toTop); 2229 resumeTopActivitiesLocked(); 2230 } 2231 2232 ActivityRecord findTaskLocked(ActivityRecord r) { 2233 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2234 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2235 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2236 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2237 final ActivityStack stack = stacks.get(stackNdx); 2238 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2239 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2240 continue; 2241 } 2242 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2243 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2244 stack); 2245 continue; 2246 } 2247 final ActivityRecord ar = stack.findTaskLocked(r); 2248 if (ar != null) { 2249 return ar; 2250 } 2251 } 2252 } 2253 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2254 return null; 2255 } 2256 2257 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2258 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2259 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2260 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2261 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2262 if (ar != null) { 2263 return ar; 2264 } 2265 } 2266 } 2267 return null; 2268 } 2269 2270 void goingToSleepLocked() { 2271 scheduleSleepTimeout(); 2272 if (!mGoingToSleep.isHeld()) { 2273 mGoingToSleep.acquire(); 2274 if (mLaunchingActivity.isHeld()) { 2275 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2276 throw new IllegalStateException("Calling must be system uid"); 2277 } 2278 mLaunchingActivity.release(); 2279 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2280 } 2281 } 2282 checkReadyForSleepLocked(); 2283 } 2284 2285 boolean shutdownLocked(int timeout) { 2286 goingToSleepLocked(); 2287 2288 boolean timedout = false; 2289 final long endTime = System.currentTimeMillis() + timeout; 2290 while (true) { 2291 boolean cantShutdown = false; 2292 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2293 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2294 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2295 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2296 } 2297 } 2298 if (cantShutdown) { 2299 long timeRemaining = endTime - System.currentTimeMillis(); 2300 if (timeRemaining > 0) { 2301 try { 2302 mService.wait(timeRemaining); 2303 } catch (InterruptedException e) { 2304 } 2305 } else { 2306 Slog.w(TAG, "Activity manager shutdown timed out"); 2307 timedout = true; 2308 break; 2309 } 2310 } else { 2311 break; 2312 } 2313 } 2314 2315 // Force checkReadyForSleep to complete. 2316 mSleepTimeout = true; 2317 checkReadyForSleepLocked(); 2318 2319 return timedout; 2320 } 2321 2322 void comeOutOfSleepIfNeededLocked() { 2323 removeSleepTimeouts(); 2324 if (mGoingToSleep.isHeld()) { 2325 mGoingToSleep.release(); 2326 } 2327 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2328 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2329 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2330 final ActivityStack stack = stacks.get(stackNdx); 2331 stack.awakeFromSleepingLocked(); 2332 if (isFrontStack(stack)) { 2333 resumeTopActivitiesLocked(); 2334 } 2335 } 2336 } 2337 mGoingToSleepActivities.clear(); 2338 } 2339 2340 void activitySleptLocked(ActivityRecord r) { 2341 mGoingToSleepActivities.remove(r); 2342 checkReadyForSleepLocked(); 2343 } 2344 2345 void checkReadyForSleepLocked() { 2346 if (!mService.isSleepingOrShuttingDown()) { 2347 // Do not care. 2348 return; 2349 } 2350 2351 if (!mSleepTimeout) { 2352 boolean dontSleep = false; 2353 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2354 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2355 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2356 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2357 } 2358 } 2359 2360 if (mStoppingActivities.size() > 0) { 2361 // Still need to tell some activities to stop; can't sleep yet. 2362 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2363 + mStoppingActivities.size() + " activities"); 2364 scheduleIdleLocked(); 2365 dontSleep = true; 2366 } 2367 2368 if (mGoingToSleepActivities.size() > 0) { 2369 // Still need to tell some activities to sleep; can't sleep yet. 2370 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2371 + mGoingToSleepActivities.size() + " activities"); 2372 dontSleep = true; 2373 } 2374 2375 if (dontSleep) { 2376 return; 2377 } 2378 } 2379 2380 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2381 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2382 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2383 stacks.get(stackNdx).goToSleep(); 2384 } 2385 } 2386 2387 removeSleepTimeouts(); 2388 2389 if (mGoingToSleep.isHeld()) { 2390 mGoingToSleep.release(); 2391 } 2392 if (mService.mShuttingDown) { 2393 mService.notifyAll(); 2394 } 2395 } 2396 2397 boolean reportResumedActivityLocked(ActivityRecord r) { 2398 final ActivityStack stack = r.task.stack; 2399 if (isFrontStack(stack)) { 2400 mService.updateUsageStats(r, true); 2401 } 2402 if (allResumedActivitiesComplete()) { 2403 ensureActivitiesVisibleLocked(null, 0); 2404 mWindowManager.executeAppTransition(); 2405 return true; 2406 } 2407 return false; 2408 } 2409 2410 void handleAppCrashLocked(ProcessRecord app) { 2411 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2412 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2413 final int numStacks = stacks.size(); 2414 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2415 final ActivityStack stack = stacks.get(stackNdx); 2416 stack.handleAppCrashLocked(app); 2417 } 2418 } 2419 } 2420 2421 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2422 // First the front stacks. In case any are not fullscreen and are in front of home. 2423 boolean showHomeBehindStack = false; 2424 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2425 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2426 final int topStackNdx = stacks.size() - 1; 2427 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2428 final ActivityStack stack = stacks.get(stackNdx); 2429 if (stackNdx == topStackNdx) { 2430 // Top stack. 2431 showHomeBehindStack = 2432 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2433 } else { 2434 // Back stack. 2435 stack.ensureActivitiesVisibleLocked(starting, configChanges, 2436 showHomeBehindStack); 2437 } 2438 } 2439 } 2440 } 2441 2442 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2443 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2444 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2445 final int numStacks = stacks.size(); 2446 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2447 final ActivityStack stack = stacks.get(stackNdx); 2448 stack.scheduleDestroyActivities(app, false, reason); 2449 } 2450 } 2451 } 2452 2453 boolean switchUserLocked(int userId, UserStartedState uss) { 2454 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2455 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2456 mCurrentUser = userId; 2457 2458 mStartingUsers.add(uss); 2459 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2460 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2461 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2462 final ActivityStack stack = stacks.get(stackNdx); 2463 stack.switchUserLocked(userId); 2464 mWindowManager.moveTaskToTop(stack.topTask().taskId); 2465 } 2466 } 2467 2468 ActivityStack stack = getStack(restoreStackId); 2469 if (stack == null) { 2470 stack = mHomeStack; 2471 } 2472 final boolean homeInFront = stack.isHomeStack(); 2473 if (stack.isOnHomeDisplay()) { 2474 moveHomeStack(homeInFront); 2475 mWindowManager.moveTaskToTop(stack.topTask().taskId); 2476 } else { 2477 // Stack was moved to another display while user was swapped out. 2478 resumeHomeActivity(null); 2479 } 2480 return homeInFront; 2481 } 2482 2483 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2484 int N = mStoppingActivities.size(); 2485 if (N <= 0) return null; 2486 2487 ArrayList<ActivityRecord> stops = null; 2488 2489 final boolean nowVisible = allResumedActivitiesVisible(); 2490 for (int i=0; i<N; i++) { 2491 ActivityRecord s = mStoppingActivities.get(i); 2492 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2493 + nowVisible + " waitingVisible=" + s.waitingVisible 2494 + " finishing=" + s.finishing); 2495 if (s.waitingVisible && nowVisible) { 2496 mWaitingVisibleActivities.remove(s); 2497 s.waitingVisible = false; 2498 if (s.finishing) { 2499 // If this activity is finishing, it is sitting on top of 2500 // everyone else but we now know it is no longer needed... 2501 // so get rid of it. Otherwise, we need to go through the 2502 // normal flow and hide it once we determine that it is 2503 // hidden by the activities in front of it. 2504 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2505 mWindowManager.setAppVisibility(s.appToken, false); 2506 } 2507 } 2508 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2509 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2510 if (stops == null) { 2511 stops = new ArrayList<ActivityRecord>(); 2512 } 2513 stops.add(s); 2514 mStoppingActivities.remove(i); 2515 N--; 2516 i--; 2517 } 2518 } 2519 2520 return stops; 2521 } 2522 2523 void validateTopActivitiesLocked() { 2524 // FIXME 2525/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2526 final ActivityStack stack = stacks.get(stackNdx); 2527 final ActivityRecord r = stack.topRunningActivityLocked(null); 2528 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2529 if (isFrontStack(stack)) { 2530 if (r == null) { 2531 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2532 } else { 2533 final ActivityRecord pausing = stack.mPausingActivity; 2534 if (pausing != null && pausing == r) { 2535 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2536 " state=" + state); 2537 } 2538 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2539 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2540 " state=" + state); 2541 } 2542 } 2543 } else { 2544 final ActivityRecord resumed = stack.mResumedActivity; 2545 if (resumed != null && resumed == r) { 2546 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2547 " state=" + state); 2548 } 2549 if (r != null && (state == ActivityState.INITIALIZING 2550 || state == ActivityState.RESUMED)) { 2551 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2552 " state=" + state); 2553 } 2554 } 2555 } 2556*/ 2557 } 2558 2559 public void dump(PrintWriter pw, String prefix) { 2560 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2561 pw.println(mDismissKeyguardOnNextActivity); 2562 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2563 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2564 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2565 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2566 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2567 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2568 } 2569 2570 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2571 return getFocusedStack().getDumpActivitiesLocked(name); 2572 } 2573 2574 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2575 boolean needSep, String prefix) { 2576 if (activity != null) { 2577 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2578 if (needSep) { 2579 pw.println(); 2580 } 2581 pw.print(prefix); 2582 pw.println(activity); 2583 return true; 2584 } 2585 } 2586 return false; 2587 } 2588 2589 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2590 boolean dumpClient, String dumpPackage) { 2591 boolean printed = false; 2592 boolean needSep = false; 2593 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2594 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2595 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2596 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2597 final int numStacks = stacks.size(); 2598 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2599 final ActivityStack stack = stacks.get(stackNdx); 2600 StringBuilder stackHeader = new StringBuilder(128); 2601 stackHeader.append(" Stack #"); 2602 stackHeader.append(stack.mStackId); 2603 stackHeader.append(":"); 2604 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2605 needSep, stackHeader.toString()); 2606 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2607 !dumpAll, false, dumpPackage, true, 2608 " Running activities (most recent first):", null); 2609 2610 needSep = printed; 2611 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2612 " mPausingActivity: "); 2613 if (pr) { 2614 printed = true; 2615 needSep = false; 2616 } 2617 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2618 " mResumedActivity: "); 2619 if (pr) { 2620 printed = true; 2621 needSep = false; 2622 } 2623 if (dumpAll) { 2624 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2625 " mLastPausedActivity: "); 2626 if (pr) { 2627 printed = true; 2628 needSep = true; 2629 } 2630 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2631 needSep, " mLastNoHistoryActivity: "); 2632 } 2633 needSep = printed; 2634 } 2635 } 2636 2637 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2638 false, dumpPackage, true, " Activities waiting to finish:", null); 2639 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2640 false, dumpPackage, true, " Activities waiting to stop:", null); 2641 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2642 false, dumpPackage, true, " Activities waiting for another to become visible:", 2643 null); 2644 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2645 false, dumpPackage, true, " Activities waiting to sleep:", null); 2646 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2647 false, dumpPackage, true, " Activities waiting to sleep:", null); 2648 2649 return printed; 2650 } 2651 2652 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2653 String prefix, String label, boolean complete, boolean brief, boolean client, 2654 String dumpPackage, boolean needNL, String header1, String header2) { 2655 TaskRecord lastTask = null; 2656 String innerPrefix = null; 2657 String[] args = null; 2658 boolean printed = false; 2659 for (int i=list.size()-1; i>=0; i--) { 2660 final ActivityRecord r = list.get(i); 2661 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2662 continue; 2663 } 2664 if (innerPrefix == null) { 2665 innerPrefix = prefix + " "; 2666 args = new String[0]; 2667 } 2668 printed = true; 2669 final boolean full = !brief && (complete || !r.isInHistory()); 2670 if (needNL) { 2671 pw.println(""); 2672 needNL = false; 2673 } 2674 if (header1 != null) { 2675 pw.println(header1); 2676 header1 = null; 2677 } 2678 if (header2 != null) { 2679 pw.println(header2); 2680 header2 = null; 2681 } 2682 if (lastTask != r.task) { 2683 lastTask = r.task; 2684 pw.print(prefix); 2685 pw.print(full ? "* " : " "); 2686 pw.println(lastTask); 2687 if (full) { 2688 lastTask.dump(pw, prefix + " "); 2689 } else if (complete) { 2690 // Complete + brief == give a summary. Isn't that obvious?!? 2691 if (lastTask.intent != null) { 2692 pw.print(prefix); pw.print(" "); 2693 pw.println(lastTask.intent.toInsecureStringWithClip()); 2694 } 2695 } 2696 } 2697 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2698 pw.print(" #"); pw.print(i); pw.print(": "); 2699 pw.println(r); 2700 if (full) { 2701 r.dump(pw, innerPrefix); 2702 } else if (complete) { 2703 // Complete + brief == give a summary. Isn't that obvious?!? 2704 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2705 if (r.app != null) { 2706 pw.print(innerPrefix); pw.println(r.app); 2707 } 2708 } 2709 if (client && r.app != null && r.app.thread != null) { 2710 // flush anything that is already in the PrintWriter since the thread is going 2711 // to write to the file descriptor directly 2712 pw.flush(); 2713 try { 2714 TransferPipe tp = new TransferPipe(); 2715 try { 2716 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2717 r.appToken, innerPrefix, args); 2718 // Short timeout, since blocking here can 2719 // deadlock with the application. 2720 tp.go(fd, 2000); 2721 } finally { 2722 tp.kill(); 2723 } 2724 } catch (IOException e) { 2725 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2726 } catch (RemoteException e) { 2727 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2728 } 2729 needNL = true; 2730 } 2731 } 2732 return printed; 2733 } 2734 2735 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2736 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2737 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2738 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2739 } 2740 2741 final void scheduleIdleLocked() { 2742 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2743 } 2744 2745 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2746 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2747 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2748 } 2749 2750 final void scheduleResumeTopActivities() { 2751 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2752 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2753 } 2754 } 2755 2756 void removeSleepTimeouts() { 2757 mSleepTimeout = false; 2758 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2759 } 2760 2761 final void scheduleSleepTimeout() { 2762 removeSleepTimeouts(); 2763 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2764 } 2765 2766 @Override 2767 public void onDisplayAdded(int displayId) { 2768 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2769 } 2770 2771 @Override 2772 public void onDisplayRemoved(int displayId) { 2773 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2774 } 2775 2776 @Override 2777 public void onDisplayChanged(int displayId) { 2778 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2779 } 2780 2781 public void handleDisplayAddedLocked(int displayId) { 2782 boolean newDisplay; 2783 synchronized (mService) { 2784 newDisplay = mActivityDisplays.get(displayId) == null; 2785 if (newDisplay) { 2786 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2787 mActivityDisplays.put(displayId, activityDisplay); 2788 } 2789 } 2790 if (newDisplay) { 2791 mWindowManager.onDisplayAdded(displayId); 2792 } 2793 } 2794 2795 public void handleDisplayRemovedLocked(int displayId) { 2796 synchronized (mService) { 2797 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2798 if (activityDisplay != null) { 2799 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2800 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2801 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2802 } 2803 mActivityDisplays.remove(displayId); 2804 } 2805 } 2806 mWindowManager.onDisplayRemoved(displayId); 2807 } 2808 2809 public void handleDisplayChangedLocked(int displayId) { 2810 synchronized (mService) { 2811 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2812 if (activityDisplay != null) { 2813 // TODO: Update the bounds. 2814 } 2815 } 2816 mWindowManager.onDisplayChanged(displayId); 2817 } 2818 2819 StackInfo getStackInfo(ActivityStack stack) { 2820 StackInfo info = new StackInfo(); 2821 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2822 info.displayId = Display.DEFAULT_DISPLAY; 2823 info.stackId = stack.mStackId; 2824 2825 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2826 final int numTasks = tasks.size(); 2827 int[] taskIds = new int[numTasks]; 2828 String[] taskNames = new String[numTasks]; 2829 for (int i = 0; i < numTasks; ++i) { 2830 final TaskRecord task = tasks.get(i); 2831 taskIds[i] = task.taskId; 2832 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2833 : task.realActivity != null ? task.realActivity.flattenToString() 2834 : task.getTopActivity() != null ? task.getTopActivity().packageName 2835 : "unknown"; 2836 } 2837 info.taskIds = taskIds; 2838 info.taskNames = taskNames; 2839 return info; 2840 } 2841 2842 StackInfo getStackInfoLocked(int stackId) { 2843 ActivityStack stack = getStack(stackId); 2844 if (stack != null) { 2845 return getStackInfo(stack); 2846 } 2847 return null; 2848 } 2849 2850 ArrayList<StackInfo> getAllStackInfosLocked() { 2851 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2852 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2853 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2854 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 2855 list.add(getStackInfo(stacks.get(ndx))); 2856 } 2857 } 2858 return list; 2859 } 2860 2861 private final class ActivityStackSupervisorHandler extends Handler { 2862 2863 public ActivityStackSupervisorHandler(Looper looper) { 2864 super(looper); 2865 } 2866 2867 void activityIdleInternal(ActivityRecord r) { 2868 synchronized (mService) { 2869 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2870 } 2871 } 2872 2873 @Override 2874 public void handleMessage(Message msg) { 2875 switch (msg.what) { 2876 case IDLE_TIMEOUT_MSG: { 2877 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2878 if (mService.mDidDexOpt) { 2879 mService.mDidDexOpt = false; 2880 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2881 nmsg.obj = msg.obj; 2882 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2883 return; 2884 } 2885 // We don't at this point know if the activity is fullscreen, 2886 // so we need to be conservative and assume it isn't. 2887 activityIdleInternal((ActivityRecord)msg.obj); 2888 } break; 2889 case IDLE_NOW_MSG: { 2890 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2891 activityIdleInternal((ActivityRecord)msg.obj); 2892 } break; 2893 case RESUME_TOP_ACTIVITY_MSG: { 2894 synchronized (mService) { 2895 resumeTopActivitiesLocked(); 2896 } 2897 } break; 2898 case SLEEP_TIMEOUT_MSG: { 2899 synchronized (mService) { 2900 if (mService.isSleepingOrShuttingDown()) { 2901 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2902 mSleepTimeout = true; 2903 checkReadyForSleepLocked(); 2904 } 2905 } 2906 } break; 2907 case LAUNCH_TIMEOUT_MSG: { 2908 if (mService.mDidDexOpt) { 2909 mService.mDidDexOpt = false; 2910 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2911 return; 2912 } 2913 synchronized (mService) { 2914 if (mLaunchingActivity.isHeld()) { 2915 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2916 if (VALIDATE_WAKE_LOCK_CALLER 2917 && Binder.getCallingUid() != Process.myUid()) { 2918 throw new IllegalStateException("Calling must be system uid"); 2919 } 2920 mLaunchingActivity.release(); 2921 } 2922 } 2923 } break; 2924 case HANDLE_DISPLAY_ADDED: { 2925 handleDisplayAddedLocked(msg.arg1); 2926 } break; 2927 case HANDLE_DISPLAY_CHANGED: { 2928 handleDisplayChangedLocked(msg.arg1); 2929 } break; 2930 case HANDLE_DISPLAY_REMOVED: { 2931 handleDisplayRemovedLocked(msg.arg1); 2932 } break; 2933 case CONTAINER_CALLBACK_VISIBILITY: { 2934 final ActivityContainer container = (ActivityContainer) msg.obj; 2935 final IActivityContainerCallback callback = container.mCallback; 2936 if (callback != null) { 2937 try { 2938 callback.setVisible(container.asBinder(), msg.arg1 == 1); 2939 } catch (RemoteException e) { 2940 } 2941 } 2942 } break; 2943 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 2944 final ActivityContainer container = (ActivityContainer) msg.obj; 2945 final IActivityContainerCallback callback = container.mCallback; 2946 if (callback != null) { 2947 try { 2948 callback.onAllActivitiesComplete(container.asBinder()); 2949 } catch (RemoteException e) { 2950 } 2951 } 2952 } break; 2953 } 2954 } 2955 } 2956 2957 class ActivityContainer extends android.app.IActivityContainer.Stub { 2958 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 2959 Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 2960 final int mStackId; 2961 IActivityContainerCallback mCallback = null; 2962 final ActivityStack mStack; 2963 ActivityRecord mParentActivity = null; 2964 String mIdString; 2965 2966 boolean mVisible = true; 2967 2968 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 2969 ActivityDisplay mActivityDisplay; 2970 2971 final static int CONTAINER_STATE_HAS_SURFACE = 0; 2972 final static int CONTAINER_STATE_NO_SURFACE = 1; 2973 final static int CONTAINER_STATE_FINISHING = 2; 2974 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 2975 2976 ActivityContainer(int stackId) { 2977 synchronized (mService) { 2978 mStackId = stackId; 2979 mStack = new ActivityStack(this); 2980 mIdString = "ActivtyContainer{" + mStackId + "}"; 2981 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 2982 } 2983 } 2984 2985 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 2986 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 2987 + " to display=" + activityDisplay); 2988 mActivityDisplay = activityDisplay; 2989 mStack.mDisplayId = activityDisplay.mDisplayId; 2990 mStack.mStacks = activityDisplay.mStacks; 2991 2992 activityDisplay.attachActivities(mStack); 2993 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 2994 } 2995 2996 @Override 2997 public void attachToDisplay(int displayId) { 2998 synchronized (mService) { 2999 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3000 if (activityDisplay == null) { 3001 return; 3002 } 3003 attachToDisplayLocked(activityDisplay); 3004 } 3005 } 3006 3007 @Override 3008 public int getDisplayId() { 3009 if (mActivityDisplay != null) { 3010 return mActivityDisplay.mDisplayId; 3011 } 3012 return -1; 3013 } 3014 3015 @Override 3016 public boolean injectEvent(InputEvent event) { 3017 final long origId = Binder.clearCallingIdentity(); 3018 try { 3019 if (mActivityDisplay != null) { 3020 return mInputManagerInternal.injectInputEvent(event, 3021 mActivityDisplay.mDisplayId, 3022 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3023 } 3024 return false; 3025 } finally { 3026 Binder.restoreCallingIdentity(origId); 3027 } 3028 } 3029 3030 @Override 3031 public void release() { 3032 mContainerState = CONTAINER_STATE_FINISHING; 3033 mStack.finishAllActivitiesLocked(); 3034 detachLocked(); 3035 mWindowManager.removeStack(mStackId); 3036 } 3037 3038 private void detachLocked() { 3039 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3040 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3041 if (mActivityDisplay != null) { 3042 mActivityDisplay.detachActivitiesLocked(mStack); 3043 mActivityDisplay = null; 3044 mStack.mDisplayId = -1; 3045 mStack.mStacks = null; 3046 mWindowManager.detachStack(mStackId); 3047 } 3048 } 3049 3050 @Override 3051 public final int startActivity(Intent intent) { 3052 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3053 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3054 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3055 // TODO: Switch to user app stacks here. 3056 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3057 String mimeType = intent.getType(); 3058 if (mimeType == null && intent.getData() != null 3059 && "content".equals(intent.getData().getScheme())) { 3060 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3061 } 3062 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null, 3063 null, null, null, null, userId, this); 3064 } 3065 3066 @Override 3067 public final int startActivityIntentSender(IIntentSender intentSender) { 3068 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3069 3070 if (!(intentSender instanceof PendingIntentRecord)) { 3071 throw new IllegalArgumentException("Bad PendingIntent object"); 3072 } 3073 3074 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3075 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3076 } 3077 3078 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3079 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3080 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3081 if (resolvedType == null) { 3082 resolvedType = intent.getType(); 3083 if (resolvedType == null && intent.getData() != null 3084 && "content".equals(intent.getData().getScheme())) { 3085 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3086 } 3087 } 3088 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3089 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3090 throw new SecurityException( 3091 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3092 } 3093 } 3094 3095 /** Throw a SecurityException if allowEmbedded is not true */ 3096 @Override 3097 public final void checkEmbeddedAllowed(Intent intent) { 3098 checkEmbeddedAllowedInner(intent, null); 3099 } 3100 3101 /** Throw a SecurityException if allowEmbedded is not true */ 3102 @Override 3103 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3104 if (!(intentSender instanceof PendingIntentRecord)) { 3105 throw new IllegalArgumentException("Bad PendingIntent object"); 3106 } 3107 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3108 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3109 pendingIntent.key.requestResolvedType); 3110 } 3111 3112 @Override 3113 public IBinder asBinder() { 3114 return this; 3115 } 3116 3117 @Override 3118 public void setSurface(Surface surface, int width, int height, int density) { 3119 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3120 } 3121 3122 ActivityStackSupervisor getOuter() { 3123 return ActivityStackSupervisor.this; 3124 } 3125 3126 boolean isAttached() { 3127 return mActivityDisplay != null; 3128 } 3129 3130 void getBounds(Point outBounds) { 3131 if (mActivityDisplay != null) { 3132 mActivityDisplay.getBounds(outBounds); 3133 } else { 3134 outBounds.set(0, 0); 3135 } 3136 } 3137 3138 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3139 void setVisible(boolean visible) { 3140 if (mVisible != visible) { 3141 mVisible = visible; 3142 if (mCallback != null) { 3143 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3144 0 /* unused */, this).sendToTarget(); 3145 } 3146 } 3147 } 3148 3149 void setDrawn() { 3150 } 3151 3152 // You can always start a new task on a regular ActivityStack. 3153 boolean isEligibleForNewTasks() { 3154 return true; 3155 } 3156 3157 void onTaskListEmpty() { 3158 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3159 } 3160 3161 @Override 3162 public String toString() { 3163 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3164 } 3165 } 3166 3167 private class VirtualActivityContainer extends ActivityContainer { 3168 Surface mSurface; 3169 boolean mDrawn = false; 3170 3171 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3172 super(getNextStackId()); 3173 mParentActivity = parent; 3174 mCallback = callback; 3175 mContainerState = CONTAINER_STATE_NO_SURFACE; 3176 mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3177 } 3178 3179 @Override 3180 public void setSurface(Surface surface, int width, int height, int density) { 3181 super.setSurface(surface, width, height, density); 3182 3183 synchronized (mService) { 3184 final long origId = Binder.clearCallingIdentity(); 3185 try { 3186 setSurfaceLocked(surface, width, height, density); 3187 } finally { 3188 Binder.restoreCallingIdentity(origId); 3189 } 3190 } 3191 } 3192 3193 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3194 if (mContainerState == CONTAINER_STATE_FINISHING) { 3195 return; 3196 } 3197 VirtualActivityDisplay virtualActivityDisplay = 3198 (VirtualActivityDisplay) mActivityDisplay; 3199 if (virtualActivityDisplay == null) { 3200 virtualActivityDisplay = 3201 new VirtualActivityDisplay(width, height, density); 3202 mActivityDisplay = virtualActivityDisplay; 3203 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3204 attachToDisplayLocked(virtualActivityDisplay); 3205 } 3206 3207 if (mSurface != null) { 3208 mSurface.release(); 3209 } 3210 3211 mSurface = surface; 3212 if (surface != null) { 3213 mStack.resumeTopActivityLocked(null); 3214 } else { 3215 mContainerState = CONTAINER_STATE_NO_SURFACE; 3216 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3217 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3218 mStack.startPausingLocked(false, true); 3219 } 3220 } 3221 3222 setSurfaceIfReady(); 3223 3224 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3225 + virtualActivityDisplay); 3226 } 3227 3228 @Override 3229 boolean isAttached() { 3230 return mSurface != null && super.isAttached(); 3231 } 3232 3233 @Override 3234 void setDrawn() { 3235 synchronized (mService) { 3236 mDrawn = true; 3237 setSurfaceIfReady(); 3238 } 3239 } 3240 3241 // Never start a new task on an ActivityView if it isn't explicitly specified. 3242 @Override 3243 boolean isEligibleForNewTasks() { 3244 return false; 3245 } 3246 3247 private void setSurfaceIfReady() { 3248 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn + 3249 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3250 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3251 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3252 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3253 } 3254 } 3255 } 3256 3257 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3258 * attached {@link ActivityStack}s */ 3259 class ActivityDisplay { 3260 /** Actual Display this object tracks. */ 3261 int mDisplayId; 3262 Display mDisplay; 3263 DisplayInfo mDisplayInfo = new DisplayInfo(); 3264 3265 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3266 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3267 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3268 3269 ActivityDisplay() { 3270 } 3271 3272 ActivityDisplay(int displayId) { 3273 init(mDisplayManager.getDisplay(displayId)); 3274 } 3275 3276 void init(Display display) { 3277 mDisplay = display; 3278 mDisplayId = display.getDisplayId(); 3279 mDisplay.getDisplayInfo(mDisplayInfo); 3280 } 3281 3282 void attachActivities(ActivityStack stack) { 3283 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3284 + mDisplayId); 3285 mStacks.add(stack); 3286 } 3287 3288 void detachActivitiesLocked(ActivityStack stack) { 3289 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3290 + " from displayId=" + mDisplayId); 3291 mStacks.remove(stack); 3292 } 3293 3294 void getBounds(Point bounds) { 3295 mDisplay.getDisplayInfo(mDisplayInfo); 3296 bounds.x = mDisplayInfo.appWidth; 3297 bounds.y = mDisplayInfo.appHeight; 3298 } 3299 3300 @Override 3301 public String toString() { 3302 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3303 } 3304 } 3305 3306 class VirtualActivityDisplay extends ActivityDisplay { 3307 VirtualDisplay mVirtualDisplay; 3308 3309 VirtualActivityDisplay(int width, int height, int density) { 3310 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3311 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME, 3312 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3313 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3314 3315 init(mVirtualDisplay.getDisplay()); 3316 3317 mWindowManager.handleDisplayAdded(mDisplayId); 3318 } 3319 3320 void setSurface(Surface surface) { 3321 if (mVirtualDisplay != null) { 3322 mVirtualDisplay.setSurface(surface); 3323 } 3324 } 3325 3326 @Override 3327 void detachActivitiesLocked(ActivityStack stack) { 3328 super.detachActivitiesLocked(stack); 3329 if (mVirtualDisplay != null) { 3330 mVirtualDisplay.release(); 3331 mVirtualDisplay = null; 3332 } 3333 } 3334 3335 @Override 3336 public String toString() { 3337 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3338 } 3339 } 3340} 3341