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