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