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