ActivityStackSupervisor.java revision 4a9f129874785d34930f165268dbc618e4bc2618
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 if (isFrontStack(mHomeStack)) { 1928 booting = mService.mBooting; 1929 mService.mBooting = false; 1930 } 1931 1932 if (mStartingUsers.size() > 0) { 1933 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1934 mStartingUsers.clear(); 1935 } 1936 1937 // Perform the following actions from unsynchronized state. 1938 final IApplicationThread thumbnailThread = sendThumbnail; 1939 mHandler.post(new Runnable() { 1940 @Override 1941 public void run() { 1942 if (thumbnailThread != null) { 1943 try { 1944 thumbnailThread.requestThumbnail(token); 1945 } catch (Exception e) { 1946 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 1947 mService.sendPendingThumbnail(null, token, null, null, true); 1948 } 1949 } 1950 1951 // Report back to any thumbnail receivers. 1952 for (int i = 0; i < NT; i++) { 1953 ActivityRecord r = thumbnails.get(i); 1954 mService.sendPendingThumbnail(r, null, null, null, true); 1955 } 1956 } 1957 }); 1958 1959 // Stop any activities that are scheduled to do so but have been 1960 // waiting for the next one to start. 1961 for (int i = 0; i < NS; i++) { 1962 r = stops.get(i); 1963 final ActivityStack stack = r.task.stack; 1964 if (r.finishing) { 1965 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1966 } else { 1967 stack.stopActivityLocked(r); 1968 } 1969 } 1970 1971 // Finish any activities that are scheduled to do so but have been 1972 // waiting for the next one to start. 1973 for (int i = 0; i < NF; i++) { 1974 r = finishes.get(i); 1975 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1976 } 1977 1978 if (booting) { 1979 mService.finishBooting(); 1980 } else if (startingUsers != null) { 1981 for (int i = 0; i < startingUsers.size(); i++) { 1982 mService.finishUserSwitch(startingUsers.get(i)); 1983 } 1984 } 1985 1986 mService.trimApplications(); 1987 //dump(); 1988 //mWindowManager.dump(); 1989 1990 if (enableScreen) { 1991 mService.enableScreenAfterBoot(); 1992 } 1993 1994 if (activityRemoved) { 1995 resumeTopActivitiesLocked(); 1996 } 1997 1998 return r; 1999 } 2000 2001 boolean handleAppDiedLocked(ProcessRecord app) { 2002 boolean hasVisibleActivities = false; 2003 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2004 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2005 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2006 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2007 } 2008 } 2009 return hasVisibleActivities; 2010 } 2011 2012 void closeSystemDialogsLocked() { 2013 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2014 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2015 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2016 stacks.get(stackNdx).closeSystemDialogsLocked(); 2017 } 2018 } 2019 } 2020 2021 void removeUserLocked(int userId) { 2022 mUserStackInFront.delete(userId); 2023 } 2024 2025 /** 2026 * @return true if some activity was finished (or would have finished if doit were true). 2027 */ 2028 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2029 boolean didSomething = false; 2030 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2031 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2032 final int numStacks = stacks.size(); 2033 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2034 final ActivityStack stack = stacks.get(stackNdx); 2035 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2036 didSomething = true; 2037 } 2038 } 2039 } 2040 return didSomething; 2041 } 2042 2043 void updatePreviousProcessLocked(ActivityRecord r) { 2044 // Now that this process has stopped, we may want to consider 2045 // it to be the previous app to try to keep around in case 2046 // the user wants to return to it. 2047 2048 // First, found out what is currently the foreground app, so that 2049 // we don't blow away the previous app if this activity is being 2050 // hosted by the process that is actually still the foreground. 2051 ProcessRecord fgApp = null; 2052 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2053 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2054 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2055 final ActivityStack stack = stacks.get(stackNdx); 2056 if (isFrontStack(stack)) { 2057 if (stack.mResumedActivity != null) { 2058 fgApp = stack.mResumedActivity.app; 2059 } else if (stack.mPausingActivity != null) { 2060 fgApp = stack.mPausingActivity.app; 2061 } 2062 break; 2063 } 2064 } 2065 } 2066 2067 // Now set this one as the previous process, only if that really 2068 // makes sense to. 2069 if (r.app != null && fgApp != null && r.app != fgApp 2070 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2071 && r.app != mService.mHomeProcess) { 2072 mService.mPreviousProcess = r.app; 2073 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2074 } 2075 } 2076 2077 boolean resumeTopActivitiesLocked() { 2078 return resumeTopActivitiesLocked(null, null, null); 2079 } 2080 2081 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2082 Bundle targetOptions) { 2083 if (targetStack == null) { 2084 targetStack = getFocusedStack(); 2085 } 2086 // Do targetStack first. 2087 boolean result = false; 2088 if (isFrontStack(targetStack)) { 2089 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2090 } 2091 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2092 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2093 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2094 final ActivityStack stack = stacks.get(stackNdx); 2095 if (stack == targetStack) { 2096 // Already started above. 2097 continue; 2098 } 2099 if (isFrontStack(stack)) { 2100 stack.resumeTopActivityLocked(null); 2101 } 2102 } 2103 } 2104 return result; 2105 } 2106 2107 void finishTopRunningActivityLocked(ProcessRecord app) { 2108 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2109 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2110 final int numStacks = stacks.size(); 2111 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2112 final ActivityStack stack = stacks.get(stackNdx); 2113 stack.finishTopRunningActivityLocked(app); 2114 } 2115 } 2116 } 2117 2118 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 2119 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2120 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2121 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2122 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 2123 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2124 + stacks.get(stackNdx)); 2125 return; 2126 } 2127 } 2128 } 2129 } 2130 2131 ActivityStack getStack(int stackId) { 2132 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2133 if (activityContainer != null) { 2134 return activityContainer.mStack; 2135 } 2136 return null; 2137 } 2138 2139 ArrayList<ActivityStack> getStacks() { 2140 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2141 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2142 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2143 } 2144 return allStacks; 2145 } 2146 2147 IBinder getHomeActivityToken() { 2148 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2149 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2150 final TaskRecord task = tasks.get(taskNdx); 2151 if (task.isHomeTask()) { 2152 final ArrayList<ActivityRecord> activities = task.mActivities; 2153 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2154 final ActivityRecord r = activities.get(activityNdx); 2155 if (r.isHomeActivity()) { 2156 return r.appToken; 2157 } 2158 } 2159 } 2160 } 2161 return null; 2162 } 2163 2164 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2165 IActivityContainerCallback callback) { 2166 ActivityContainer activityContainer = 2167 new VirtualActivityContainer(parentActivity, callback); 2168 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2169 if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer); 2170 parentActivity.mChildContainers.add(activityContainer); 2171 return activityContainer; 2172 } 2173 2174 void removeChildActivityContainers(ActivityRecord parentActivity) { 2175 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2176 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2177 ActivityContainer container = childStacks.remove(containerNdx); 2178 if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " + 2179 container); 2180 container.release(); 2181 } 2182 } 2183 2184 void deleteActivityContainer(IActivityContainer container) { 2185 ActivityContainer activityContainer = (ActivityContainer)container; 2186 if (activityContainer != null) { 2187 if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ", 2188 new RuntimeException("here").fillInStackTrace()); 2189 final int stackId = activityContainer.mStackId; 2190 mActivityContainers.remove(stackId); 2191 mWindowManager.removeStack(stackId); 2192 } 2193 } 2194 2195 private int createStackOnDisplay(int stackId, int displayId) { 2196 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2197 if (activityDisplay == null) { 2198 return -1; 2199 } 2200 2201 ActivityContainer activityContainer = new ActivityContainer(stackId); 2202 mActivityContainers.put(stackId, activityContainer); 2203 activityContainer.attachToDisplayLocked(activityDisplay); 2204 return stackId; 2205 } 2206 2207 int getNextStackId() { 2208 while (true) { 2209 if (++mLastStackId <= HOME_STACK_ID) { 2210 mLastStackId = HOME_STACK_ID + 1; 2211 } 2212 if (getStack(mLastStackId) == null) { 2213 break; 2214 } 2215 } 2216 return mLastStackId; 2217 } 2218 2219 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2220 final TaskRecord task = anyTaskForIdLocked(taskId); 2221 if (task == null) { 2222 return; 2223 } 2224 final ActivityStack stack = getStack(stackId); 2225 if (stack == null) { 2226 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2227 return; 2228 } 2229 task.stack.removeTask(task); 2230 stack.addTask(task, toTop); 2231 mWindowManager.addTask(taskId, stackId, toTop); 2232 resumeTopActivitiesLocked(); 2233 } 2234 2235 ActivityRecord findTaskLocked(ActivityRecord r) { 2236 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2237 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2238 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2239 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2240 final ActivityStack stack = stacks.get(stackNdx); 2241 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2242 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2243 continue; 2244 } 2245 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2246 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2247 stack); 2248 continue; 2249 } 2250 final ActivityRecord ar = stack.findTaskLocked(r); 2251 if (ar != null) { 2252 return ar; 2253 } 2254 } 2255 } 2256 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2257 return null; 2258 } 2259 2260 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2261 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2262 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2263 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2264 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2265 if (ar != null) { 2266 return ar; 2267 } 2268 } 2269 } 2270 return null; 2271 } 2272 2273 void goingToSleepLocked() { 2274 scheduleSleepTimeout(); 2275 if (!mGoingToSleep.isHeld()) { 2276 mGoingToSleep.acquire(); 2277 if (mLaunchingActivity.isHeld()) { 2278 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2279 throw new IllegalStateException("Calling must be system uid"); 2280 } 2281 mLaunchingActivity.release(); 2282 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2283 } 2284 } 2285 checkReadyForSleepLocked(); 2286 } 2287 2288 boolean shutdownLocked(int timeout) { 2289 goingToSleepLocked(); 2290 2291 boolean timedout = false; 2292 final long endTime = System.currentTimeMillis() + timeout; 2293 while (true) { 2294 boolean cantShutdown = false; 2295 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2296 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2297 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2298 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2299 } 2300 } 2301 if (cantShutdown) { 2302 long timeRemaining = endTime - System.currentTimeMillis(); 2303 if (timeRemaining > 0) { 2304 try { 2305 mService.wait(timeRemaining); 2306 } catch (InterruptedException e) { 2307 } 2308 } else { 2309 Slog.w(TAG, "Activity manager shutdown timed out"); 2310 timedout = true; 2311 break; 2312 } 2313 } else { 2314 break; 2315 } 2316 } 2317 2318 // Force checkReadyForSleep to complete. 2319 mSleepTimeout = true; 2320 checkReadyForSleepLocked(); 2321 2322 return timedout; 2323 } 2324 2325 void comeOutOfSleepIfNeededLocked() { 2326 removeSleepTimeouts(); 2327 if (mGoingToSleep.isHeld()) { 2328 mGoingToSleep.release(); 2329 } 2330 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2331 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2332 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2333 final ActivityStack stack = stacks.get(stackNdx); 2334 stack.awakeFromSleepingLocked(); 2335 if (isFrontStack(stack)) { 2336 resumeTopActivitiesLocked(); 2337 } 2338 } 2339 } 2340 mGoingToSleepActivities.clear(); 2341 } 2342 2343 void activitySleptLocked(ActivityRecord r) { 2344 mGoingToSleepActivities.remove(r); 2345 checkReadyForSleepLocked(); 2346 } 2347 2348 void checkReadyForSleepLocked() { 2349 if (!mService.isSleepingOrShuttingDown()) { 2350 // Do not care. 2351 return; 2352 } 2353 2354 if (!mSleepTimeout) { 2355 boolean dontSleep = false; 2356 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2357 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2358 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2359 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2360 } 2361 } 2362 2363 if (mStoppingActivities.size() > 0) { 2364 // Still need to tell some activities to stop; can't sleep yet. 2365 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2366 + mStoppingActivities.size() + " activities"); 2367 scheduleIdleLocked(); 2368 dontSleep = true; 2369 } 2370 2371 if (mGoingToSleepActivities.size() > 0) { 2372 // Still need to tell some activities to sleep; can't sleep yet. 2373 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2374 + mGoingToSleepActivities.size() + " activities"); 2375 dontSleep = true; 2376 } 2377 2378 if (dontSleep) { 2379 return; 2380 } 2381 } 2382 2383 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2384 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2385 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2386 stacks.get(stackNdx).goToSleep(); 2387 } 2388 } 2389 2390 removeSleepTimeouts(); 2391 2392 if (mGoingToSleep.isHeld()) { 2393 mGoingToSleep.release(); 2394 } 2395 if (mService.mShuttingDown) { 2396 mService.notifyAll(); 2397 } 2398 } 2399 2400 boolean reportResumedActivityLocked(ActivityRecord r) { 2401 final ActivityStack stack = r.task.stack; 2402 if (isFrontStack(stack)) { 2403 mService.updateUsageStats(r, true); 2404 } 2405 if (allResumedActivitiesComplete()) { 2406 ensureActivitiesVisibleLocked(null, 0); 2407 mWindowManager.executeAppTransition(); 2408 return true; 2409 } 2410 return false; 2411 } 2412 2413 void handleAppCrashLocked(ProcessRecord app) { 2414 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2415 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2416 final int numStacks = stacks.size(); 2417 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2418 final ActivityStack stack = stacks.get(stackNdx); 2419 stack.handleAppCrashLocked(app); 2420 } 2421 } 2422 } 2423 2424 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2425 // First the front stacks. In case any are not fullscreen and are in front of home. 2426 boolean showHomeBehindStack = false; 2427 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2428 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2429 final int topStackNdx = stacks.size() - 1; 2430 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2431 final ActivityStack stack = stacks.get(stackNdx); 2432 if (stackNdx == topStackNdx) { 2433 // Top stack. 2434 showHomeBehindStack = 2435 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2436 } else { 2437 // Back stack. 2438 stack.ensureActivitiesVisibleLocked(starting, configChanges, 2439 showHomeBehindStack); 2440 } 2441 } 2442 } 2443 } 2444 2445 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2446 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2447 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2448 final int numStacks = stacks.size(); 2449 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2450 final ActivityStack stack = stacks.get(stackNdx); 2451 stack.scheduleDestroyActivities(app, false, reason); 2452 } 2453 } 2454 } 2455 2456 boolean switchUserLocked(int userId, UserStartedState uss) { 2457 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2458 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2459 mCurrentUser = userId; 2460 2461 mStartingUsers.add(uss); 2462 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2463 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2464 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2465 final ActivityStack stack = stacks.get(stackNdx); 2466 stack.switchUserLocked(userId); 2467 mWindowManager.moveTaskToTop(stack.topTask().taskId); 2468 } 2469 } 2470 2471 ActivityStack stack = getStack(restoreStackId); 2472 if (stack == null) { 2473 stack = mHomeStack; 2474 } 2475 final boolean homeInFront = stack.isHomeStack(); 2476 if (stack.isOnHomeDisplay()) { 2477 moveHomeStack(homeInFront); 2478 mWindowManager.moveTaskToTop(stack.topTask().taskId); 2479 } else { 2480 // Stack was moved to another display while user was swapped out. 2481 resumeHomeActivity(null); 2482 } 2483 return homeInFront; 2484 } 2485 2486 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2487 int N = mStoppingActivities.size(); 2488 if (N <= 0) return null; 2489 2490 ArrayList<ActivityRecord> stops = null; 2491 2492 final boolean nowVisible = allResumedActivitiesVisible(); 2493 for (int i=0; i<N; i++) { 2494 ActivityRecord s = mStoppingActivities.get(i); 2495 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2496 + nowVisible + " waitingVisible=" + s.waitingVisible 2497 + " finishing=" + s.finishing); 2498 if (s.waitingVisible && nowVisible) { 2499 mWaitingVisibleActivities.remove(s); 2500 s.waitingVisible = false; 2501 if (s.finishing) { 2502 // If this activity is finishing, it is sitting on top of 2503 // everyone else but we now know it is no longer needed... 2504 // so get rid of it. Otherwise, we need to go through the 2505 // normal flow and hide it once we determine that it is 2506 // hidden by the activities in front of it. 2507 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2508 mWindowManager.setAppVisibility(s.appToken, false); 2509 } 2510 } 2511 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2512 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2513 if (stops == null) { 2514 stops = new ArrayList<ActivityRecord>(); 2515 } 2516 stops.add(s); 2517 mStoppingActivities.remove(i); 2518 N--; 2519 i--; 2520 } 2521 } 2522 2523 return stops; 2524 } 2525 2526 void validateTopActivitiesLocked() { 2527 // FIXME 2528/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2529 final ActivityStack stack = stacks.get(stackNdx); 2530 final ActivityRecord r = stack.topRunningActivityLocked(null); 2531 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2532 if (isFrontStack(stack)) { 2533 if (r == null) { 2534 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2535 } else { 2536 final ActivityRecord pausing = stack.mPausingActivity; 2537 if (pausing != null && pausing == r) { 2538 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2539 " state=" + state); 2540 } 2541 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2542 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2543 " state=" + state); 2544 } 2545 } 2546 } else { 2547 final ActivityRecord resumed = stack.mResumedActivity; 2548 if (resumed != null && resumed == r) { 2549 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2550 " state=" + state); 2551 } 2552 if (r != null && (state == ActivityState.INITIALIZING 2553 || state == ActivityState.RESUMED)) { 2554 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2555 " state=" + state); 2556 } 2557 } 2558 } 2559*/ 2560 } 2561 2562 public void dump(PrintWriter pw, String prefix) { 2563 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2564 pw.println(mDismissKeyguardOnNextActivity); 2565 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2566 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2567 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2568 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2569 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2570 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2571 } 2572 2573 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2574 return getFocusedStack().getDumpActivitiesLocked(name); 2575 } 2576 2577 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2578 boolean needSep, String prefix) { 2579 if (activity != null) { 2580 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2581 if (needSep) { 2582 pw.println(); 2583 } 2584 pw.print(prefix); 2585 pw.println(activity); 2586 return true; 2587 } 2588 } 2589 return false; 2590 } 2591 2592 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2593 boolean dumpClient, String dumpPackage) { 2594 boolean printed = false; 2595 boolean needSep = false; 2596 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2597 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2598 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2599 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2600 final int numStacks = stacks.size(); 2601 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2602 final ActivityStack stack = stacks.get(stackNdx); 2603 StringBuilder stackHeader = new StringBuilder(128); 2604 stackHeader.append(" Stack #"); 2605 stackHeader.append(stack.mStackId); 2606 stackHeader.append(":"); 2607 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2608 needSep, stackHeader.toString()); 2609 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2610 !dumpAll, false, dumpPackage, true, 2611 " Running activities (most recent first):", null); 2612 2613 needSep = printed; 2614 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2615 " mPausingActivity: "); 2616 if (pr) { 2617 printed = true; 2618 needSep = false; 2619 } 2620 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2621 " mResumedActivity: "); 2622 if (pr) { 2623 printed = true; 2624 needSep = false; 2625 } 2626 if (dumpAll) { 2627 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2628 " mLastPausedActivity: "); 2629 if (pr) { 2630 printed = true; 2631 needSep = true; 2632 } 2633 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2634 needSep, " mLastNoHistoryActivity: "); 2635 } 2636 needSep = printed; 2637 } 2638 } 2639 2640 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2641 false, dumpPackage, true, " Activities waiting to finish:", null); 2642 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2643 false, dumpPackage, true, " Activities waiting to stop:", null); 2644 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2645 false, dumpPackage, true, " Activities waiting for another to become visible:", 2646 null); 2647 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2648 false, dumpPackage, true, " Activities waiting to sleep:", null); 2649 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2650 false, dumpPackage, true, " Activities waiting to sleep:", null); 2651 2652 return printed; 2653 } 2654 2655 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2656 String prefix, String label, boolean complete, boolean brief, boolean client, 2657 String dumpPackage, boolean needNL, String header1, String header2) { 2658 TaskRecord lastTask = null; 2659 String innerPrefix = null; 2660 String[] args = null; 2661 boolean printed = false; 2662 for (int i=list.size()-1; i>=0; i--) { 2663 final ActivityRecord r = list.get(i); 2664 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2665 continue; 2666 } 2667 if (innerPrefix == null) { 2668 innerPrefix = prefix + " "; 2669 args = new String[0]; 2670 } 2671 printed = true; 2672 final boolean full = !brief && (complete || !r.isInHistory()); 2673 if (needNL) { 2674 pw.println(""); 2675 needNL = false; 2676 } 2677 if (header1 != null) { 2678 pw.println(header1); 2679 header1 = null; 2680 } 2681 if (header2 != null) { 2682 pw.println(header2); 2683 header2 = null; 2684 } 2685 if (lastTask != r.task) { 2686 lastTask = r.task; 2687 pw.print(prefix); 2688 pw.print(full ? "* " : " "); 2689 pw.println(lastTask); 2690 if (full) { 2691 lastTask.dump(pw, prefix + " "); 2692 } else if (complete) { 2693 // Complete + brief == give a summary. Isn't that obvious?!? 2694 if (lastTask.intent != null) { 2695 pw.print(prefix); pw.print(" "); 2696 pw.println(lastTask.intent.toInsecureStringWithClip()); 2697 } 2698 } 2699 } 2700 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2701 pw.print(" #"); pw.print(i); pw.print(": "); 2702 pw.println(r); 2703 if (full) { 2704 r.dump(pw, innerPrefix); 2705 } else if (complete) { 2706 // Complete + brief == give a summary. Isn't that obvious?!? 2707 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2708 if (r.app != null) { 2709 pw.print(innerPrefix); pw.println(r.app); 2710 } 2711 } 2712 if (client && r.app != null && r.app.thread != null) { 2713 // flush anything that is already in the PrintWriter since the thread is going 2714 // to write to the file descriptor directly 2715 pw.flush(); 2716 try { 2717 TransferPipe tp = new TransferPipe(); 2718 try { 2719 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2720 r.appToken, innerPrefix, args); 2721 // Short timeout, since blocking here can 2722 // deadlock with the application. 2723 tp.go(fd, 2000); 2724 } finally { 2725 tp.kill(); 2726 } 2727 } catch (IOException e) { 2728 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2729 } catch (RemoteException e) { 2730 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2731 } 2732 needNL = true; 2733 } 2734 } 2735 return printed; 2736 } 2737 2738 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2739 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2740 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2741 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2742 } 2743 2744 final void scheduleIdleLocked() { 2745 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2746 } 2747 2748 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2749 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2750 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2751 } 2752 2753 final void scheduleResumeTopActivities() { 2754 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2755 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2756 } 2757 } 2758 2759 void removeSleepTimeouts() { 2760 mSleepTimeout = false; 2761 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2762 } 2763 2764 final void scheduleSleepTimeout() { 2765 removeSleepTimeouts(); 2766 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2767 } 2768 2769 @Override 2770 public void onDisplayAdded(int displayId) { 2771 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2772 } 2773 2774 @Override 2775 public void onDisplayRemoved(int displayId) { 2776 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2777 } 2778 2779 @Override 2780 public void onDisplayChanged(int displayId) { 2781 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2782 } 2783 2784 public void handleDisplayAddedLocked(int displayId) { 2785 boolean newDisplay; 2786 synchronized (mService) { 2787 newDisplay = mActivityDisplays.get(displayId) == null; 2788 if (newDisplay) { 2789 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2790 mActivityDisplays.put(displayId, activityDisplay); 2791 } 2792 } 2793 if (newDisplay) { 2794 mWindowManager.onDisplayAdded(displayId); 2795 } 2796 } 2797 2798 public void handleDisplayRemovedLocked(int displayId) { 2799 synchronized (mService) { 2800 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2801 if (activityDisplay != null) { 2802 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2803 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2804 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2805 } 2806 mActivityDisplays.remove(displayId); 2807 } 2808 } 2809 mWindowManager.onDisplayRemoved(displayId); 2810 } 2811 2812 public void handleDisplayChangedLocked(int displayId) { 2813 synchronized (mService) { 2814 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2815 if (activityDisplay != null) { 2816 // TODO: Update the bounds. 2817 } 2818 } 2819 mWindowManager.onDisplayChanged(displayId); 2820 } 2821 2822 StackInfo getStackInfo(ActivityStack stack) { 2823 StackInfo info = new StackInfo(); 2824 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2825 info.displayId = Display.DEFAULT_DISPLAY; 2826 info.stackId = stack.mStackId; 2827 2828 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2829 final int numTasks = tasks.size(); 2830 int[] taskIds = new int[numTasks]; 2831 String[] taskNames = new String[numTasks]; 2832 for (int i = 0; i < numTasks; ++i) { 2833 final TaskRecord task = tasks.get(i); 2834 taskIds[i] = task.taskId; 2835 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2836 : task.realActivity != null ? task.realActivity.flattenToString() 2837 : task.getTopActivity() != null ? task.getTopActivity().packageName 2838 : "unknown"; 2839 } 2840 info.taskIds = taskIds; 2841 info.taskNames = taskNames; 2842 return info; 2843 } 2844 2845 StackInfo getStackInfoLocked(int stackId) { 2846 ActivityStack stack = getStack(stackId); 2847 if (stack != null) { 2848 return getStackInfo(stack); 2849 } 2850 return null; 2851 } 2852 2853 ArrayList<StackInfo> getAllStackInfosLocked() { 2854 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2855 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2856 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2857 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 2858 list.add(getStackInfo(stacks.get(ndx))); 2859 } 2860 } 2861 return list; 2862 } 2863 2864 private final class ActivityStackSupervisorHandler extends Handler { 2865 2866 public ActivityStackSupervisorHandler(Looper looper) { 2867 super(looper); 2868 } 2869 2870 void activityIdleInternal(ActivityRecord r) { 2871 synchronized (mService) { 2872 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2873 } 2874 } 2875 2876 @Override 2877 public void handleMessage(Message msg) { 2878 switch (msg.what) { 2879 case IDLE_TIMEOUT_MSG: { 2880 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2881 if (mService.mDidDexOpt) { 2882 mService.mDidDexOpt = false; 2883 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2884 nmsg.obj = msg.obj; 2885 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2886 return; 2887 } 2888 // We don't at this point know if the activity is fullscreen, 2889 // so we need to be conservative and assume it isn't. 2890 activityIdleInternal((ActivityRecord)msg.obj); 2891 } break; 2892 case IDLE_NOW_MSG: { 2893 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2894 activityIdleInternal((ActivityRecord)msg.obj); 2895 } break; 2896 case RESUME_TOP_ACTIVITY_MSG: { 2897 synchronized (mService) { 2898 resumeTopActivitiesLocked(); 2899 } 2900 } break; 2901 case SLEEP_TIMEOUT_MSG: { 2902 synchronized (mService) { 2903 if (mService.isSleepingOrShuttingDown()) { 2904 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2905 mSleepTimeout = true; 2906 checkReadyForSleepLocked(); 2907 } 2908 } 2909 } break; 2910 case LAUNCH_TIMEOUT_MSG: { 2911 if (mService.mDidDexOpt) { 2912 mService.mDidDexOpt = false; 2913 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2914 return; 2915 } 2916 synchronized (mService) { 2917 if (mLaunchingActivity.isHeld()) { 2918 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2919 if (VALIDATE_WAKE_LOCK_CALLER 2920 && Binder.getCallingUid() != Process.myUid()) { 2921 throw new IllegalStateException("Calling must be system uid"); 2922 } 2923 mLaunchingActivity.release(); 2924 } 2925 } 2926 } break; 2927 case HANDLE_DISPLAY_ADDED: { 2928 handleDisplayAddedLocked(msg.arg1); 2929 } break; 2930 case HANDLE_DISPLAY_CHANGED: { 2931 handleDisplayChangedLocked(msg.arg1); 2932 } break; 2933 case HANDLE_DISPLAY_REMOVED: { 2934 handleDisplayRemovedLocked(msg.arg1); 2935 } break; 2936 case CONTAINER_CALLBACK_VISIBILITY: { 2937 final ActivityContainer container = (ActivityContainer) msg.obj; 2938 final IActivityContainerCallback callback = container.mCallback; 2939 if (callback != null) { 2940 try { 2941 callback.setVisible(container.asBinder(), msg.arg1 == 1); 2942 } catch (RemoteException e) { 2943 } 2944 } 2945 } break; 2946 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 2947 final ActivityContainer container = (ActivityContainer) msg.obj; 2948 final IActivityContainerCallback callback = container.mCallback; 2949 if (callback != null) { 2950 try { 2951 callback.onAllActivitiesComplete(container.asBinder()); 2952 } catch (RemoteException e) { 2953 } 2954 } 2955 } break; 2956 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: { 2957 synchronized (mService) { 2958 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " + 2959 msg.obj); 2960 ((ActivityContainer) msg.obj).onTaskListEmptyLocked(); 2961 } 2962 } break; 2963 } 2964 } 2965 } 2966 2967 class ActivityContainer extends android.app.IActivityContainer.Stub { 2968 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 2969 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 2970 final int mStackId; 2971 IActivityContainerCallback mCallback = null; 2972 final ActivityStack mStack; 2973 ActivityRecord mParentActivity = null; 2974 String mIdString; 2975 2976 boolean mVisible = true; 2977 2978 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 2979 ActivityDisplay mActivityDisplay; 2980 2981 final static int CONTAINER_STATE_HAS_SURFACE = 0; 2982 final static int CONTAINER_STATE_NO_SURFACE = 1; 2983 final static int CONTAINER_STATE_FINISHING = 2; 2984 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 2985 2986 ActivityContainer(int stackId) { 2987 synchronized (mService) { 2988 mStackId = stackId; 2989 mStack = new ActivityStack(this); 2990 mIdString = "ActivtyContainer{" + mStackId + "}"; 2991 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 2992 } 2993 } 2994 2995 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 2996 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 2997 + " to display=" + activityDisplay); 2998 mActivityDisplay = activityDisplay; 2999 mStack.mDisplayId = activityDisplay.mDisplayId; 3000 mStack.mStacks = activityDisplay.mStacks; 3001 3002 activityDisplay.attachActivities(mStack); 3003 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3004 } 3005 3006 @Override 3007 public void attachToDisplay(int displayId) { 3008 synchronized (mService) { 3009 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3010 if (activityDisplay == null) { 3011 return; 3012 } 3013 attachToDisplayLocked(activityDisplay); 3014 } 3015 } 3016 3017 @Override 3018 public int getDisplayId() { 3019 synchronized (mService) { 3020 if (mActivityDisplay != null) { 3021 return mActivityDisplay.mDisplayId; 3022 } 3023 } 3024 return -1; 3025 } 3026 3027 @Override 3028 public boolean injectEvent(InputEvent event) { 3029 final long origId = Binder.clearCallingIdentity(); 3030 try { 3031 synchronized (mService) { 3032 if (mActivityDisplay != null) { 3033 return mInputManagerInternal.injectInputEvent(event, 3034 mActivityDisplay.mDisplayId, 3035 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3036 } 3037 } 3038 return false; 3039 } finally { 3040 Binder.restoreCallingIdentity(origId); 3041 } 3042 } 3043 3044 @Override 3045 public void release() { 3046 synchronized (mService) { 3047 if (mContainerState == CONTAINER_STATE_FINISHING) { 3048 return; 3049 } 3050 mContainerState = CONTAINER_STATE_FINISHING; 3051 final Message msg = 3052 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3053 mHandler.sendMessageDelayed(msg, 1000); 3054 mStack.finishAllActivitiesLocked(); 3055 } 3056 } 3057 3058 private void detachLocked() { 3059 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3060 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3061 if (mActivityDisplay != null) { 3062 mActivityDisplay.detachActivitiesLocked(mStack); 3063 mActivityDisplay = null; 3064 mStack.mDisplayId = -1; 3065 mStack.mStacks = null; 3066 mWindowManager.detachStack(mStackId); 3067 } 3068 } 3069 3070 @Override 3071 public final int startActivity(Intent intent) { 3072 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3073 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3074 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3075 // TODO: Switch to user app stacks here. 3076 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3077 String mimeType = intent.getType(); 3078 if (mimeType == null && intent.getData() != null 3079 && "content".equals(intent.getData().getScheme())) { 3080 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3081 } 3082 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null, 3083 null, null, null, null, userId, this); 3084 } 3085 3086 @Override 3087 public final int startActivityIntentSender(IIntentSender intentSender) { 3088 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3089 3090 if (!(intentSender instanceof PendingIntentRecord)) { 3091 throw new IllegalArgumentException("Bad PendingIntent object"); 3092 } 3093 3094 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3095 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3096 } 3097 3098 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3099 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3100 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3101 if (resolvedType == null) { 3102 resolvedType = intent.getType(); 3103 if (resolvedType == null && intent.getData() != null 3104 && "content".equals(intent.getData().getScheme())) { 3105 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3106 } 3107 } 3108 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3109 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3110 throw new SecurityException( 3111 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3112 } 3113 } 3114 3115 /** Throw a SecurityException if allowEmbedded is not true */ 3116 @Override 3117 public final void checkEmbeddedAllowed(Intent intent) { 3118 checkEmbeddedAllowedInner(intent, null); 3119 } 3120 3121 /** Throw a SecurityException if allowEmbedded is not true */ 3122 @Override 3123 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3124 if (!(intentSender instanceof PendingIntentRecord)) { 3125 throw new IllegalArgumentException("Bad PendingIntent object"); 3126 } 3127 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3128 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3129 pendingIntent.key.requestResolvedType); 3130 } 3131 3132 @Override 3133 public IBinder asBinder() { 3134 return this; 3135 } 3136 3137 @Override 3138 public void setSurface(Surface surface, int width, int height, int density) { 3139 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3140 } 3141 3142 ActivityStackSupervisor getOuter() { 3143 return ActivityStackSupervisor.this; 3144 } 3145 3146 boolean isAttachedLocked() { 3147 return mActivityDisplay != null; 3148 } 3149 3150 void getBounds(Point outBounds) { 3151 synchronized (mService) { 3152 if (mActivityDisplay != null) { 3153 mActivityDisplay.getBounds(outBounds); 3154 } else { 3155 outBounds.set(0, 0); 3156 } 3157 } 3158 } 3159 3160 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3161 void setVisible(boolean visible) { 3162 if (mVisible != visible) { 3163 mVisible = visible; 3164 if (mCallback != null) { 3165 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3166 0 /* unused */, this).sendToTarget(); 3167 } 3168 } 3169 } 3170 3171 void setDrawn() { 3172 } 3173 3174 // You can always start a new task on a regular ActivityStack. 3175 boolean isEligibleForNewTasks() { 3176 return true; 3177 } 3178 3179 void onTaskListEmptyLocked() { 3180 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3181 if (!mStack.isHomeStack()) { 3182 detachLocked(); 3183 deleteActivityContainer(this); 3184 } 3185 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3186 } 3187 3188 @Override 3189 public String toString() { 3190 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3191 } 3192 } 3193 3194 private class VirtualActivityContainer extends ActivityContainer { 3195 Surface mSurface; 3196 boolean mDrawn = false; 3197 3198 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3199 super(getNextStackId()); 3200 mParentActivity = parent; 3201 mCallback = callback; 3202 mContainerState = CONTAINER_STATE_NO_SURFACE; 3203 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3204 } 3205 3206 @Override 3207 public void setSurface(Surface surface, int width, int height, int density) { 3208 super.setSurface(surface, width, height, density); 3209 3210 synchronized (mService) { 3211 final long origId = Binder.clearCallingIdentity(); 3212 try { 3213 setSurfaceLocked(surface, width, height, density); 3214 } finally { 3215 Binder.restoreCallingIdentity(origId); 3216 } 3217 } 3218 } 3219 3220 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3221 if (mContainerState == CONTAINER_STATE_FINISHING) { 3222 return; 3223 } 3224 VirtualActivityDisplay virtualActivityDisplay = 3225 (VirtualActivityDisplay) mActivityDisplay; 3226 if (virtualActivityDisplay == null) { 3227 virtualActivityDisplay = 3228 new VirtualActivityDisplay(width, height, density); 3229 mActivityDisplay = virtualActivityDisplay; 3230 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3231 attachToDisplayLocked(virtualActivityDisplay); 3232 } 3233 3234 if (mSurface != null) { 3235 mSurface.release(); 3236 } 3237 3238 mSurface = surface; 3239 if (surface != null) { 3240 mStack.resumeTopActivityLocked(null); 3241 } else { 3242 mContainerState = CONTAINER_STATE_NO_SURFACE; 3243 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3244 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3245 mStack.startPausingLocked(false, true); 3246 } 3247 } 3248 3249 setSurfaceIfReadyLocked(); 3250 3251 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3252 + virtualActivityDisplay); 3253 } 3254 3255 @Override 3256 boolean isAttachedLocked() { 3257 return mSurface != null && super.isAttachedLocked(); 3258 } 3259 3260 @Override 3261 void setDrawn() { 3262 synchronized (mService) { 3263 mDrawn = true; 3264 setSurfaceIfReadyLocked(); 3265 } 3266 } 3267 3268 // Never start a new task on an ActivityView if it isn't explicitly specified. 3269 @Override 3270 boolean isEligibleForNewTasks() { 3271 return false; 3272 } 3273 3274 private void setSurfaceIfReadyLocked() { 3275 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 3276 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3277 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3278 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3279 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3280 } 3281 } 3282 } 3283 3284 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3285 * attached {@link ActivityStack}s */ 3286 class ActivityDisplay { 3287 /** Actual Display this object tracks. */ 3288 int mDisplayId; 3289 Display mDisplay; 3290 DisplayInfo mDisplayInfo = new DisplayInfo(); 3291 3292 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3293 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3294 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3295 3296 ActivityDisplay() { 3297 } 3298 3299 ActivityDisplay(int displayId) { 3300 init(mDisplayManager.getDisplay(displayId)); 3301 } 3302 3303 void init(Display display) { 3304 mDisplay = display; 3305 mDisplayId = display.getDisplayId(); 3306 mDisplay.getDisplayInfo(mDisplayInfo); 3307 } 3308 3309 void attachActivities(ActivityStack stack) { 3310 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3311 + mDisplayId); 3312 mStacks.add(stack); 3313 } 3314 3315 void detachActivitiesLocked(ActivityStack stack) { 3316 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3317 + " from displayId=" + mDisplayId); 3318 mStacks.remove(stack); 3319 } 3320 3321 void getBounds(Point bounds) { 3322 mDisplay.getDisplayInfo(mDisplayInfo); 3323 bounds.x = mDisplayInfo.appWidth; 3324 bounds.y = mDisplayInfo.appHeight; 3325 } 3326 3327 @Override 3328 public String toString() { 3329 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3330 } 3331 } 3332 3333 class VirtualActivityDisplay extends ActivityDisplay { 3334 VirtualDisplay mVirtualDisplay; 3335 3336 VirtualActivityDisplay(int width, int height, int density) { 3337 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3338 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME, 3339 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3340 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3341 3342 init(mVirtualDisplay.getDisplay()); 3343 3344 mWindowManager.handleDisplayAdded(mDisplayId); 3345 } 3346 3347 void setSurface(Surface surface) { 3348 if (mVirtualDisplay != null) { 3349 mVirtualDisplay.setSurface(surface); 3350 } 3351 } 3352 3353 @Override 3354 void detachActivitiesLocked(ActivityStack stack) { 3355 super.detachActivitiesLocked(stack); 3356 if (mVirtualDisplay != null) { 3357 mVirtualDisplay.release(); 3358 mVirtualDisplay = null; 3359 } 3360 } 3361 3362 @Override 3363 public String toString() { 3364 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3365 } 3366 } 3367} 3368