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