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