ActivityStackSupervisor.java revision a002604af0c9b1204556610537b85685d7055996
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, r.task.voiceInteractor, 1027 app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, 1028 mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop, 1029 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 final boolean newDocument = intent.isDocument(); 1475 if (sourceRecord == null) { 1476 // This activity is not being started from another... in this 1477 // case we -always- start a new task. 1478 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1479 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1480 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1481 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1482 } 1483 } else if (newDocument) { 1484 if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) { 1485 Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\""); 1486 r.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 1487 } 1488 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1489 // The original activity who is starting us is running as a single 1490 // instance... this new activity it is starting must go on its 1491 // own task. 1492 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1493 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1494 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1495 // The activity being started is a single instance... it always 1496 // gets launched into its own task. 1497 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1498 } 1499 1500 ActivityInfo newTaskInfo = null; 1501 Intent newTaskIntent = null; 1502 final ActivityStack sourceStack; 1503 if (sourceRecord != null) { 1504 if (sourceRecord.finishing) { 1505 // If the source is finishing, we can't further count it as our source. This 1506 // is because the task it is associated with may now be empty and on its way out, 1507 // so we don't want to blindly throw it in to that task. Instead we will take 1508 // the NEW_TASK flow and try to find a task for it. But save the task information 1509 // so it can be used when creating the new task. 1510 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1511 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1512 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1513 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1514 newTaskInfo = sourceRecord.info; 1515 newTaskIntent = sourceRecord.task.intent; 1516 } 1517 sourceRecord = null; 1518 sourceStack = null; 1519 } else { 1520 sourceStack = sourceRecord.task.stack; 1521 } 1522 } else { 1523 sourceStack = null; 1524 } 1525 1526 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1527 // For whatever reason this activity is being launched into a new 1528 // task... yet the caller has requested a result back. Well, that 1529 // is pretty messed up, so instead immediately send back a cancel 1530 // and let the new task continue launched as normal without a 1531 // dependency on its originator. 1532 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1533 r.resultTo.task.stack.sendActivityResultLocked(-1, 1534 r.resultTo, r.resultWho, r.requestCode, 1535 Activity.RESULT_CANCELED, null); 1536 r.resultTo = null; 1537 } 1538 1539 boolean addingToTask = false; 1540 boolean movedHome = false; 1541 TaskRecord reuseTask = null; 1542 ActivityStack targetStack; 1543 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1544 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1545 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1546 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1547 // If bring to front is requested, and no result is requested, and 1548 // we can find a task that was started with this same 1549 // component, then instead of launching bring that one to the front. 1550 if (r.resultTo == null) { 1551 // See if there is a task to bring to the front. If this is 1552 // a SINGLE_INSTANCE activity, there can be one and only one 1553 // instance of it in the history, and it is always in its own 1554 // unique task, so we do a special search. 1555 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1556 ? findTaskLocked(r) 1557 : findActivityLocked(intent, r.info); 1558 if (intentActivity != null) { 1559 if (isLockTaskModeViolation(intentActivity.task)) { 1560 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 1561 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1562 } 1563 if (r.task == null) { 1564 r.task = intentActivity.task; 1565 } 1566 targetStack = intentActivity.task.stack; 1567 targetStack.mLastPausedActivity = null; 1568 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1569 + " from " + intentActivity); 1570 targetStack.moveToFront(); 1571 if (intentActivity.task.intent == null) { 1572 // This task was started because of movement of 1573 // the activity based on affinity... now that we 1574 // are actually launching it, we can assign the 1575 // base intent. 1576 intentActivity.task.setIntent(intent, r.info); 1577 } 1578 // If the target task is not in the front, then we need 1579 // to bring it to the front... except... well, with 1580 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1581 // to have the same behavior as if a new instance was 1582 // being started, which means not bringing it to the front 1583 // if the caller is not itself in the front. 1584 final ActivityStack lastStack = getLastStack(); 1585 ActivityRecord curTop = lastStack == null? 1586 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1587 if (curTop != null && (curTop.task != intentActivity.task || 1588 curTop.task != lastStack.topTask())) { 1589 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1590 if (sourceRecord == null || (sourceStack.topActivity() != null && 1591 sourceStack.topActivity().task == sourceRecord.task)) { 1592 // We really do want to push this one into the 1593 // user's face, right now. 1594 movedHome = true; 1595 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1596 if ((launchFlags & 1597 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1598 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1599 // Caller wants to appear on home activity. 1600 intentActivity.task.mOnTopOfHome = true; 1601 } 1602 options = null; 1603 } 1604 } 1605 // If the caller has requested that the target task be 1606 // reset, then do so. 1607 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1608 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1609 } 1610 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1611 // We don't need to start a new activity, and 1612 // the client said not to do anything if that 1613 // is the case, so this is it! And for paranoia, make 1614 // sure we have correctly resumed the top activity. 1615 if (doResume) { 1616 resumeTopActivitiesLocked(targetStack, null, options); 1617 } else { 1618 ActivityOptions.abort(options); 1619 } 1620 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1621 } 1622 if ((launchFlags & 1623 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1624 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1625 // The caller has requested to completely replace any 1626 // existing task with its new activity. Well that should 1627 // not be too hard... 1628 reuseTask = intentActivity.task; 1629 reuseTask.performClearTaskLocked(); 1630 reuseTask.setIntent(r.intent, r.info); 1631 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1632 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1633 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1634 // In this situation we want to remove all activities 1635 // from the task up to the one being started. In most 1636 // cases this means we are resetting the task to its 1637 // initial state. 1638 ActivityRecord top = 1639 intentActivity.task.performClearTaskLocked(r, launchFlags); 1640 if (top != null) { 1641 if (top.frontOfTask) { 1642 // Activity aliases may mean we use different 1643 // intents for the top activity, so make sure 1644 // the task now has the identity of the new 1645 // intent. 1646 top.task.setIntent(r.intent, r.info); 1647 } 1648 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1649 r, top.task); 1650 top.deliverNewIntentLocked(callingUid, r.intent); 1651 } else { 1652 // A special case: we need to 1653 // start the activity because it is not currently 1654 // running, and the caller has asked to clear the 1655 // current task to have this activity at the top. 1656 addingToTask = true; 1657 // Now pretend like this activity is being started 1658 // by the top of its task, so it is put in the 1659 // right place. 1660 sourceRecord = intentActivity; 1661 } 1662 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1663 // In this case the top activity on the task is the 1664 // same as the one being launched, so we take that 1665 // as a request to bring the task to the foreground. 1666 // If the top activity in the task is the root 1667 // activity, deliver this new intent to it if it 1668 // desires. 1669 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1670 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1671 && intentActivity.realActivity.equals(r.realActivity)) { 1672 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1673 intentActivity.task); 1674 if (intentActivity.frontOfTask) { 1675 intentActivity.task.setIntent(r.intent, r.info); 1676 } 1677 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1678 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1679 // In this case we are launching the root activity 1680 // of the task, but with a different intent. We 1681 // should start a new instance on top. 1682 addingToTask = true; 1683 sourceRecord = intentActivity; 1684 } 1685 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1686 // In this case an activity is being launched in to an 1687 // existing task, without resetting that task. This 1688 // is typically the situation of launching an activity 1689 // from a notification or shortcut. We want to place 1690 // the new activity on top of the current task. 1691 addingToTask = true; 1692 sourceRecord = intentActivity; 1693 } else if (!intentActivity.task.rootWasReset) { 1694 // In this case we are launching in to an existing task 1695 // that has not yet been started from its front door. 1696 // The current task has been brought to the front. 1697 // Ideally, we'd probably like to place this new task 1698 // at the bottom of its stack, but that's a little hard 1699 // to do with the current organization of the code so 1700 // for now we'll just drop it. 1701 intentActivity.task.setIntent(r.intent, r.info); 1702 } 1703 if (!addingToTask && reuseTask == null) { 1704 // We didn't do anything... but it was needed (a.k.a., client 1705 // don't use that intent!) And for paranoia, make 1706 // sure we have correctly resumed the top activity. 1707 if (doResume) { 1708 targetStack.resumeTopActivityLocked(null, options); 1709 } else { 1710 ActivityOptions.abort(options); 1711 } 1712 return ActivityManager.START_TASK_TO_FRONT; 1713 } 1714 } 1715 } 1716 } 1717 1718 //String uri = r.intent.toURI(); 1719 //Intent intent2 = new Intent(uri); 1720 //Slog.i(TAG, "Given intent: " + r.intent); 1721 //Slog.i(TAG, "URI is: " + uri); 1722 //Slog.i(TAG, "To intent: " + intent2); 1723 1724 if (r.packageName != null) { 1725 // If the activity being launched is the same as the one currently 1726 // at the top, then we need to check if it should only be launched 1727 // once. 1728 ActivityStack topStack = getFocusedStack(); 1729 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1730 if (top != null && r.resultTo == null) { 1731 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1732 if (top.app != null && top.app.thread != null) { 1733 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1734 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1735 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1736 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1737 top.task); 1738 // For paranoia, make sure we have correctly 1739 // resumed the top activity. 1740 topStack.mLastPausedActivity = null; 1741 if (doResume) { 1742 resumeTopActivitiesLocked(); 1743 } 1744 ActivityOptions.abort(options); 1745 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1746 // We don't need to start a new activity, and 1747 // the client said not to do anything if that 1748 // is the case, so this is it! 1749 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1750 } 1751 top.deliverNewIntentLocked(callingUid, r.intent); 1752 return ActivityManager.START_DELIVERED_TO_TOP; 1753 } 1754 } 1755 } 1756 } 1757 1758 } else { 1759 if (r.resultTo != null) { 1760 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1761 r.requestCode, Activity.RESULT_CANCELED, null); 1762 } 1763 ActivityOptions.abort(options); 1764 return ActivityManager.START_CLASS_NOT_FOUND; 1765 } 1766 1767 boolean newTask = false; 1768 boolean keepCurTransition = false; 1769 1770 // Should this be considered a new task? 1771 if (r.resultTo == null && !addingToTask 1772 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1773 if (isLockTaskModeViolation(reuseTask)) { 1774 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1775 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1776 } 1777 targetStack = adjustStackFocus(r); 1778 targetStack.moveToFront(); 1779 if (reuseTask == null) { 1780 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1781 newTaskInfo != null ? newTaskInfo : r.info, 1782 newTaskIntent != null ? newTaskIntent : intent, 1783 voiceSession, voiceInteractor, true), null, true); 1784 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1785 r.task); 1786 } else { 1787 r.setTask(reuseTask, reuseTask, true); 1788 } 1789 newTask = true; 1790 if (!movedHome) { 1791 if ((launchFlags & 1792 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1793 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1794 // Caller wants to appear on home activity, so before starting 1795 // their own activity we will bring home to the front. 1796 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); 1797 } 1798 } 1799 } else if (sourceRecord != null) { 1800 TaskRecord sourceTask = sourceRecord.task; 1801 if (isLockTaskModeViolation(sourceTask)) { 1802 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1803 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1804 } 1805 targetStack = sourceTask.stack; 1806 targetStack.moveToFront(); 1807 mWindowManager.moveTaskToTop(sourceTask.taskId); 1808 if (!addingToTask && 1809 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1810 // In this case, we are adding the activity to an existing 1811 // task, but the caller has asked to clear that task if the 1812 // activity is already running. 1813 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1814 keepCurTransition = true; 1815 if (top != null) { 1816 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1817 top.deliverNewIntentLocked(callingUid, r.intent); 1818 // For paranoia, make sure we have correctly 1819 // resumed the top activity. 1820 targetStack.mLastPausedActivity = null; 1821 if (doResume) { 1822 targetStack.resumeTopActivityLocked(null); 1823 } 1824 ActivityOptions.abort(options); 1825 return ActivityManager.START_DELIVERED_TO_TOP; 1826 } 1827 } else if (!addingToTask && 1828 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1829 // In this case, we are launching an activity in our own task 1830 // that may already be running somewhere in the history, and 1831 // we want to shuffle it to the front of the stack if so. 1832 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1833 if (top != null) { 1834 final TaskRecord task = top.task; 1835 task.moveActivityToFrontLocked(top); 1836 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1837 top.updateOptionsLocked(options); 1838 top.deliverNewIntentLocked(callingUid, r.intent); 1839 targetStack.mLastPausedActivity = null; 1840 if (doResume) { 1841 targetStack.resumeTopActivityLocked(null); 1842 } 1843 return ActivityManager.START_DELIVERED_TO_TOP; 1844 } 1845 } 1846 // An existing activity is starting this new activity, so we want 1847 // to keep the new one in the same task as the one that is starting 1848 // it. 1849 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1850 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1851 + " in existing task " + r.task + " from source " + sourceRecord); 1852 1853 } else { 1854 // This not being started from an existing activity, and not part 1855 // of a new task... just put it in the top task, though these days 1856 // this case should never happen. 1857 targetStack = adjustStackFocus(r); 1858 targetStack.moveToFront(); 1859 ActivityRecord prev = targetStack.topActivity(); 1860 r.setTask(prev != null ? prev.task 1861 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, null, null, true), 1862 null, true); 1863 mWindowManager.moveTaskToTop(r.task.taskId); 1864 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1865 + " in new guessed " + r.task); 1866 } 1867 1868 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1869 intent, r.getUriPermissionsLocked()); 1870 1871 if (newTask) { 1872 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1873 } 1874 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1875 targetStack.mLastPausedActivity = null; 1876 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1877 mService.setFocusedActivityLocked(r); 1878 return ActivityManager.START_SUCCESS; 1879 } 1880 1881 void acquireLaunchWakelock() { 1882 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1883 throw new IllegalStateException("Calling must be system uid"); 1884 } 1885 mLaunchingActivity.acquire(); 1886 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1887 // To be safe, don't allow the wake lock to be held for too long. 1888 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1889 } 1890 } 1891 1892 // Checked. 1893 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1894 Configuration config) { 1895 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1896 1897 ArrayList<ActivityRecord> stops = null; 1898 ArrayList<ActivityRecord> finishes = null; 1899 ArrayList<UserStartedState> startingUsers = null; 1900 int NS = 0; 1901 int NF = 0; 1902 boolean booting = false; 1903 boolean enableScreen = false; 1904 boolean activityRemoved = false; 1905 1906 ActivityRecord r = ActivityRecord.forToken(token); 1907 if (r != null) { 1908 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1909 Debug.getCallers(4)); 1910 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1911 r.finishLaunchTickingLocked(); 1912 if (fromTimeout) { 1913 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1914 } 1915 1916 // This is a hack to semi-deal with a race condition 1917 // in the client where it can be constructed with a 1918 // newer configuration from when we asked it to launch. 1919 // We'll update with whatever configuration it now says 1920 // it used to launch. 1921 if (config != null) { 1922 r.configuration = config; 1923 } 1924 1925 // We are now idle. If someone is waiting for a thumbnail from 1926 // us, we can now deliver. 1927 r.idle = true; 1928 1929 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1930 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1931 mService.mBooted = true; 1932 enableScreen = true; 1933 } 1934 } 1935 1936 if (allResumedActivitiesIdle()) { 1937 if (r != null) { 1938 mService.scheduleAppGcsLocked(); 1939 } 1940 1941 if (mLaunchingActivity.isHeld()) { 1942 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1943 if (VALIDATE_WAKE_LOCK_CALLER && 1944 Binder.getCallingUid() != Process.myUid()) { 1945 throw new IllegalStateException("Calling must be system uid"); 1946 } 1947 mLaunchingActivity.release(); 1948 } 1949 ensureActivitiesVisibleLocked(null, 0); 1950 } 1951 1952 // Atomically retrieve all of the other things to do. 1953 stops = processStoppingActivitiesLocked(true); 1954 NS = stops != null ? stops.size() : 0; 1955 if ((NF=mFinishingActivities.size()) > 0) { 1956 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1957 mFinishingActivities.clear(); 1958 } 1959 1960 if (isFrontStack(mHomeStack)) { 1961 booting = mService.mBooting; 1962 mService.mBooting = false; 1963 } 1964 1965 if (mStartingUsers.size() > 0) { 1966 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1967 mStartingUsers.clear(); 1968 } 1969 1970 // Stop any activities that are scheduled to do so but have been 1971 // waiting for the next one to start. 1972 for (int i = 0; i < NS; i++) { 1973 r = stops.get(i); 1974 final ActivityStack stack = r.task.stack; 1975 if (r.finishing) { 1976 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1977 } else { 1978 stack.stopActivityLocked(r); 1979 } 1980 } 1981 1982 // Finish any activities that are scheduled to do so but have been 1983 // waiting for the next one to start. 1984 for (int i = 0; i < NF; i++) { 1985 r = finishes.get(i); 1986 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1987 } 1988 1989 if (booting) { 1990 mService.finishBooting(); 1991 } else if (startingUsers != null) { 1992 for (int i = 0; i < startingUsers.size(); i++) { 1993 mService.finishUserSwitch(startingUsers.get(i)); 1994 } 1995 } 1996 1997 mService.trimApplications(); 1998 //dump(); 1999 //mWindowManager.dump(); 2000 2001 if (enableScreen) { 2002 mService.enableScreenAfterBoot(); 2003 } 2004 2005 if (activityRemoved) { 2006 resumeTopActivitiesLocked(); 2007 } 2008 2009 return r; 2010 } 2011 2012 boolean handleAppDiedLocked(ProcessRecord app) { 2013 boolean hasVisibleActivities = false; 2014 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2015 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2016 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2017 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2018 } 2019 } 2020 return hasVisibleActivities; 2021 } 2022 2023 void closeSystemDialogsLocked() { 2024 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2025 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2026 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2027 stacks.get(stackNdx).closeSystemDialogsLocked(); 2028 } 2029 } 2030 } 2031 2032 void removeUserLocked(int userId) { 2033 mUserStackInFront.delete(userId); 2034 } 2035 2036 /** 2037 * @return true if some activity was finished (or would have finished if doit were true). 2038 */ 2039 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2040 boolean didSomething = false; 2041 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2042 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2043 final int numStacks = stacks.size(); 2044 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2045 final ActivityStack stack = stacks.get(stackNdx); 2046 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2047 didSomething = true; 2048 } 2049 } 2050 } 2051 return didSomething; 2052 } 2053 2054 void updatePreviousProcessLocked(ActivityRecord r) { 2055 // Now that this process has stopped, we may want to consider 2056 // it to be the previous app to try to keep around in case 2057 // the user wants to return to it. 2058 2059 // First, found out what is currently the foreground app, so that 2060 // we don't blow away the previous app if this activity is being 2061 // hosted by the process that is actually still the foreground. 2062 ProcessRecord fgApp = null; 2063 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2064 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2065 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2066 final ActivityStack stack = stacks.get(stackNdx); 2067 if (isFrontStack(stack)) { 2068 if (stack.mResumedActivity != null) { 2069 fgApp = stack.mResumedActivity.app; 2070 } else if (stack.mPausingActivity != null) { 2071 fgApp = stack.mPausingActivity.app; 2072 } 2073 break; 2074 } 2075 } 2076 } 2077 2078 // Now set this one as the previous process, only if that really 2079 // makes sense to. 2080 if (r.app != null && fgApp != null && r.app != fgApp 2081 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2082 && r.app != mService.mHomeProcess) { 2083 mService.mPreviousProcess = r.app; 2084 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2085 } 2086 } 2087 2088 boolean resumeTopActivitiesLocked() { 2089 return resumeTopActivitiesLocked(null, null, null); 2090 } 2091 2092 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2093 Bundle targetOptions) { 2094 if (targetStack == null) { 2095 targetStack = getFocusedStack(); 2096 } 2097 // Do targetStack first. 2098 boolean result = false; 2099 if (isFrontStack(targetStack)) { 2100 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2101 } 2102 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2103 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2104 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2105 final ActivityStack stack = stacks.get(stackNdx); 2106 if (stack == targetStack) { 2107 // Already started above. 2108 continue; 2109 } 2110 if (isFrontStack(stack)) { 2111 stack.resumeTopActivityLocked(null); 2112 } 2113 } 2114 } 2115 return result; 2116 } 2117 2118 void finishTopRunningActivityLocked(ProcessRecord app) { 2119 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2120 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2121 final int numStacks = stacks.size(); 2122 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2123 final ActivityStack stack = stacks.get(stackNdx); 2124 stack.finishTopRunningActivityLocked(app); 2125 } 2126 } 2127 } 2128 2129 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2130 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2131 mUserLeaving = true; 2132 } 2133 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2134 // Caller wants the home activity moved with it. To accomplish this, 2135 // we'll just indicate that this task returns to the home task. 2136 task.mOnTopOfHome = true; 2137 } 2138 task.stack.moveTaskToFrontLocked(task, null, options); 2139 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2140 + task.stack); 2141 } 2142 2143 ActivityStack getStack(int stackId) { 2144 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2145 if (activityContainer != null) { 2146 return activityContainer.mStack; 2147 } 2148 return null; 2149 } 2150 2151 ArrayList<ActivityStack> getStacks() { 2152 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2153 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2154 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2155 } 2156 return allStacks; 2157 } 2158 2159 IBinder getHomeActivityToken() { 2160 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2161 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2162 final TaskRecord task = tasks.get(taskNdx); 2163 if (task.isHomeTask()) { 2164 final ArrayList<ActivityRecord> activities = task.mActivities; 2165 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2166 final ActivityRecord r = activities.get(activityNdx); 2167 if (r.isHomeActivity()) { 2168 return r.appToken; 2169 } 2170 } 2171 } 2172 } 2173 return null; 2174 } 2175 2176 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2177 IActivityContainerCallback callback) { 2178 ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback); 2179 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2180 parentActivity.mChildContainers.add(activityContainer); 2181 return activityContainer; 2182 } 2183 2184 void removeChildActivityContainers(ActivityRecord parentActivity) { 2185 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2186 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2187 ActivityContainer container = childStacks.remove(containerNdx); 2188 container.release(); 2189 } 2190 } 2191 2192 void deleteActivityContainer(IActivityContainer container) { 2193 ActivityContainer activityContainer = (ActivityContainer)container; 2194 if (activityContainer != null) { 2195 activityContainer.mStack.finishAllActivitiesLocked(); 2196 final ActivityRecord parent = activityContainer.mParentActivity; 2197 if (parent != null) { 2198 parent.mChildContainers.remove(activityContainer); 2199 } 2200 final int stackId = activityContainer.mStackId; 2201 mActivityContainers.remove(stackId); 2202 mWindowManager.removeStack(stackId); 2203 } 2204 } 2205 2206 private int createStackOnDisplay(int stackId, int displayId) { 2207 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2208 if (activityDisplay == null) { 2209 return -1; 2210 } 2211 2212 ActivityContainer activityContainer = new ActivityContainer(stackId); 2213 mActivityContainers.put(stackId, activityContainer); 2214 activityContainer.attachToDisplayLocked(activityDisplay); 2215 return stackId; 2216 } 2217 2218 int getNextStackId() { 2219 while (true) { 2220 if (++mLastStackId <= HOME_STACK_ID) { 2221 mLastStackId = HOME_STACK_ID + 1; 2222 } 2223 if (getStack(mLastStackId) == null) { 2224 break; 2225 } 2226 } 2227 return mLastStackId; 2228 } 2229 2230 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2231 final TaskRecord task = anyTaskForIdLocked(taskId); 2232 if (task == null) { 2233 return; 2234 } 2235 final ActivityStack stack = getStack(stackId); 2236 if (stack == null) { 2237 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2238 return; 2239 } 2240 task.stack.removeTask(task, true); 2241 stack.addTask(task, toTop, true); 2242 mWindowManager.addTask(taskId, stackId, toTop); 2243 resumeTopActivitiesLocked(); 2244 } 2245 2246 ActivityRecord findTaskLocked(ActivityRecord r) { 2247 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2248 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2249 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2250 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2251 final ActivityStack stack = stacks.get(stackNdx); 2252 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2253 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); 2254 continue; 2255 } 2256 final ActivityRecord ar = stack.findTaskLocked(r); 2257 if (ar != null) { 2258 return ar; 2259 } 2260 } 2261 } 2262 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2263 return null; 2264 } 2265 2266 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2267 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2268 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2269 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2270 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2271 if (ar != null) { 2272 return ar; 2273 } 2274 } 2275 } 2276 return null; 2277 } 2278 2279 void goingToSleepLocked() { 2280 scheduleSleepTimeout(); 2281 if (!mGoingToSleep.isHeld()) { 2282 mGoingToSleep.acquire(); 2283 if (mLaunchingActivity.isHeld()) { 2284 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2285 throw new IllegalStateException("Calling must be system uid"); 2286 } 2287 mLaunchingActivity.release(); 2288 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2289 } 2290 } 2291 checkReadyForSleepLocked(); 2292 setLockTaskModeLocked(null); 2293 } 2294 2295 boolean shutdownLocked(int timeout) { 2296 goingToSleepLocked(); 2297 2298 boolean timedout = false; 2299 final long endTime = System.currentTimeMillis() + timeout; 2300 while (true) { 2301 boolean cantShutdown = false; 2302 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2303 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2304 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2305 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2306 } 2307 } 2308 if (cantShutdown) { 2309 long timeRemaining = endTime - System.currentTimeMillis(); 2310 if (timeRemaining > 0) { 2311 try { 2312 mService.wait(timeRemaining); 2313 } catch (InterruptedException e) { 2314 } 2315 } else { 2316 Slog.w(TAG, "Activity manager shutdown timed out"); 2317 timedout = true; 2318 break; 2319 } 2320 } else { 2321 break; 2322 } 2323 } 2324 2325 // Force checkReadyForSleep to complete. 2326 mSleepTimeout = true; 2327 checkReadyForSleepLocked(); 2328 2329 return timedout; 2330 } 2331 2332 void comeOutOfSleepIfNeededLocked() { 2333 removeSleepTimeouts(); 2334 if (mGoingToSleep.isHeld()) { 2335 mGoingToSleep.release(); 2336 } 2337 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2338 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2339 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2340 final ActivityStack stack = stacks.get(stackNdx); 2341 stack.awakeFromSleepingLocked(); 2342 if (isFrontStack(stack)) { 2343 resumeTopActivitiesLocked(); 2344 } 2345 } 2346 } 2347 mGoingToSleepActivities.clear(); 2348 } 2349 2350 void activitySleptLocked(ActivityRecord r) { 2351 mGoingToSleepActivities.remove(r); 2352 checkReadyForSleepLocked(); 2353 } 2354 2355 void checkReadyForSleepLocked() { 2356 if (!mService.isSleepingOrShuttingDown()) { 2357 // Do not care. 2358 return; 2359 } 2360 2361 if (!mSleepTimeout) { 2362 boolean dontSleep = false; 2363 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2364 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2365 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2366 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2367 } 2368 } 2369 2370 if (mStoppingActivities.size() > 0) { 2371 // Still need to tell some activities to stop; can't sleep yet. 2372 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2373 + mStoppingActivities.size() + " activities"); 2374 scheduleIdleLocked(); 2375 dontSleep = true; 2376 } 2377 2378 if (mGoingToSleepActivities.size() > 0) { 2379 // Still need to tell some activities to sleep; can't sleep yet. 2380 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2381 + mGoingToSleepActivities.size() + " activities"); 2382 dontSleep = true; 2383 } 2384 2385 if (dontSleep) { 2386 return; 2387 } 2388 } 2389 2390 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2391 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2392 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2393 stacks.get(stackNdx).goToSleep(); 2394 } 2395 } 2396 2397 removeSleepTimeouts(); 2398 2399 if (mGoingToSleep.isHeld()) { 2400 mGoingToSleep.release(); 2401 } 2402 if (mService.mShuttingDown) { 2403 mService.notifyAll(); 2404 } 2405 } 2406 2407 boolean reportResumedActivityLocked(ActivityRecord r) { 2408 final ActivityStack stack = r.task.stack; 2409 if (isFrontStack(stack)) { 2410 mService.updateUsageStats(r, true); 2411 } 2412 if (allResumedActivitiesComplete()) { 2413 ensureActivitiesVisibleLocked(null, 0); 2414 mWindowManager.executeAppTransition(); 2415 return true; 2416 } 2417 return false; 2418 } 2419 2420 void handleAppCrashLocked(ProcessRecord app) { 2421 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2422 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2423 final int numStacks = stacks.size(); 2424 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2425 final ActivityStack stack = stacks.get(stackNdx); 2426 stack.handleAppCrashLocked(app); 2427 } 2428 } 2429 } 2430 2431 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2432 // First the front stacks. In case any are not fullscreen and are in front of home. 2433 boolean showHomeBehindStack = false; 2434 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2435 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2436 final int topStackNdx = stacks.size() - 1; 2437 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2438 final ActivityStack stack = stacks.get(stackNdx); 2439 if (stackNdx == topStackNdx) { 2440 // Top stack. 2441 showHomeBehindStack = 2442 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2443 } else { 2444 // Back stack. 2445 stack.ensureActivitiesVisibleLocked(starting, configChanges, 2446 showHomeBehindStack); 2447 } 2448 } 2449 } 2450 } 2451 2452 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2453 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2454 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2455 final int numStacks = stacks.size(); 2456 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2457 final ActivityStack stack = stacks.get(stackNdx); 2458 stack.scheduleDestroyActivities(app, false, reason); 2459 } 2460 } 2461 } 2462 2463 boolean switchUserLocked(int userId, UserStartedState uss) { 2464 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2465 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2466 mCurrentUser = userId; 2467 2468 mStartingUsers.add(uss); 2469 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2470 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2471 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2472 final ActivityStack stack = stacks.get(stackNdx); 2473 stack.switchUserLocked(userId); 2474 TaskRecord task = stack.topTask(); 2475 if (task != null) { 2476 mWindowManager.moveTaskToTop(task.taskId); 2477 } 2478 } 2479 } 2480 2481 ActivityStack stack = getStack(restoreStackId); 2482 if (stack == null) { 2483 stack = mHomeStack; 2484 } 2485 final boolean homeInFront = stack.isHomeStack(); 2486 if (stack.isOnHomeDisplay()) { 2487 moveHomeStack(homeInFront); 2488 TaskRecord task = stack.topTask(); 2489 if (task != null) { 2490 mWindowManager.moveTaskToTop(task.taskId); 2491 } 2492 } else { 2493 // Stack was moved to another display while user was swapped out. 2494 resumeHomeActivity(null); 2495 } 2496 return homeInFront; 2497 } 2498 2499 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2500 int N = mStoppingActivities.size(); 2501 if (N <= 0) return null; 2502 2503 ArrayList<ActivityRecord> stops = null; 2504 2505 final boolean nowVisible = allResumedActivitiesVisible(); 2506 for (int i=0; i<N; i++) { 2507 ActivityRecord s = mStoppingActivities.get(i); 2508 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2509 + nowVisible + " waitingVisible=" + s.waitingVisible 2510 + " finishing=" + s.finishing); 2511 if (s.waitingVisible && nowVisible) { 2512 mWaitingVisibleActivities.remove(s); 2513 s.waitingVisible = false; 2514 if (s.finishing) { 2515 // If this activity is finishing, it is sitting on top of 2516 // everyone else but we now know it is no longer needed... 2517 // so get rid of it. Otherwise, we need to go through the 2518 // normal flow and hide it once we determine that it is 2519 // hidden by the activities in front of it. 2520 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2521 mWindowManager.setAppVisibility(s.appToken, false); 2522 } 2523 } 2524 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2525 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2526 if (stops == null) { 2527 stops = new ArrayList<ActivityRecord>(); 2528 } 2529 stops.add(s); 2530 mStoppingActivities.remove(i); 2531 N--; 2532 i--; 2533 } 2534 } 2535 2536 return stops; 2537 } 2538 2539 void validateTopActivitiesLocked() { 2540 // FIXME 2541/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2542 final ActivityStack stack = stacks.get(stackNdx); 2543 final ActivityRecord r = stack.topRunningActivityLocked(null); 2544 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2545 if (isFrontStack(stack)) { 2546 if (r == null) { 2547 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2548 } else { 2549 final ActivityRecord pausing = stack.mPausingActivity; 2550 if (pausing != null && pausing == r) { 2551 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2552 " state=" + state); 2553 } 2554 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2555 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2556 " state=" + state); 2557 } 2558 } 2559 } else { 2560 final ActivityRecord resumed = stack.mResumedActivity; 2561 if (resumed != null && resumed == r) { 2562 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2563 " state=" + state); 2564 } 2565 if (r != null && (state == ActivityState.INITIALIZING 2566 || state == ActivityState.RESUMED)) { 2567 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2568 " state=" + state); 2569 } 2570 } 2571 } 2572*/ 2573 } 2574 2575 public void dump(PrintWriter pw, String prefix) { 2576 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2577 pw.println(mDismissKeyguardOnNextActivity); 2578 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2579 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2580 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2581 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2582 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2583 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2584 } 2585 2586 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2587 return getFocusedStack().getDumpActivitiesLocked(name); 2588 } 2589 2590 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2591 boolean needSep, String prefix) { 2592 if (activity != null) { 2593 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2594 if (needSep) { 2595 pw.println(); 2596 } 2597 pw.print(prefix); 2598 pw.println(activity); 2599 return true; 2600 } 2601 } 2602 return false; 2603 } 2604 2605 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2606 boolean dumpClient, String dumpPackage) { 2607 boolean printed = false; 2608 boolean needSep = false; 2609 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2610 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2611 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2612 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2613 final int numStacks = stacks.size(); 2614 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2615 final ActivityStack stack = stacks.get(stackNdx); 2616 StringBuilder stackHeader = new StringBuilder(128); 2617 stackHeader.append(" Stack #"); 2618 stackHeader.append(stack.mStackId); 2619 stackHeader.append(":"); 2620 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2621 needSep, stackHeader.toString()); 2622 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2623 !dumpAll, false, dumpPackage, true, 2624 " Running activities (most recent first):", null); 2625 2626 needSep = printed; 2627 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2628 " mPausingActivity: "); 2629 if (pr) { 2630 printed = true; 2631 needSep = false; 2632 } 2633 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2634 " mResumedActivity: "); 2635 if (pr) { 2636 printed = true; 2637 needSep = false; 2638 } 2639 if (dumpAll) { 2640 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2641 " mLastPausedActivity: "); 2642 if (pr) { 2643 printed = true; 2644 needSep = true; 2645 } 2646 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2647 needSep, " mLastNoHistoryActivity: "); 2648 } 2649 needSep = printed; 2650 } 2651 } 2652 2653 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2654 false, dumpPackage, true, " Activities waiting to finish:", null); 2655 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2656 false, dumpPackage, true, " Activities waiting to stop:", null); 2657 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2658 false, dumpPackage, true, " Activities waiting for another to become visible:", 2659 null); 2660 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2661 false, dumpPackage, true, " Activities waiting to sleep:", null); 2662 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2663 false, dumpPackage, true, " Activities waiting to sleep:", null); 2664 2665 return printed; 2666 } 2667 2668 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2669 String prefix, String label, boolean complete, boolean brief, boolean client, 2670 String dumpPackage, boolean needNL, String header1, String header2) { 2671 TaskRecord lastTask = null; 2672 String innerPrefix = null; 2673 String[] args = null; 2674 boolean printed = false; 2675 for (int i=list.size()-1; i>=0; i--) { 2676 final ActivityRecord r = list.get(i); 2677 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2678 continue; 2679 } 2680 if (innerPrefix == null) { 2681 innerPrefix = prefix + " "; 2682 args = new String[0]; 2683 } 2684 printed = true; 2685 final boolean full = !brief && (complete || !r.isInHistory()); 2686 if (needNL) { 2687 pw.println(""); 2688 needNL = false; 2689 } 2690 if (header1 != null) { 2691 pw.println(header1); 2692 header1 = null; 2693 } 2694 if (header2 != null) { 2695 pw.println(header2); 2696 header2 = null; 2697 } 2698 if (lastTask != r.task) { 2699 lastTask = r.task; 2700 pw.print(prefix); 2701 pw.print(full ? "* " : " "); 2702 pw.println(lastTask); 2703 if (full) { 2704 lastTask.dump(pw, prefix + " "); 2705 } else if (complete) { 2706 // Complete + brief == give a summary. Isn't that obvious?!? 2707 if (lastTask.intent != null) { 2708 pw.print(prefix); pw.print(" "); 2709 pw.println(lastTask.intent.toInsecureStringWithClip()); 2710 } 2711 } 2712 } 2713 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2714 pw.print(" #"); pw.print(i); pw.print(": "); 2715 pw.println(r); 2716 if (full) { 2717 r.dump(pw, innerPrefix); 2718 } else if (complete) { 2719 // Complete + brief == give a summary. Isn't that obvious?!? 2720 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2721 if (r.app != null) { 2722 pw.print(innerPrefix); pw.println(r.app); 2723 } 2724 } 2725 if (client && r.app != null && r.app.thread != null) { 2726 // flush anything that is already in the PrintWriter since the thread is going 2727 // to write to the file descriptor directly 2728 pw.flush(); 2729 try { 2730 TransferPipe tp = new TransferPipe(); 2731 try { 2732 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2733 r.appToken, innerPrefix, args); 2734 // Short timeout, since blocking here can 2735 // deadlock with the application. 2736 tp.go(fd, 2000); 2737 } finally { 2738 tp.kill(); 2739 } 2740 } catch (IOException e) { 2741 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2742 } catch (RemoteException e) { 2743 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2744 } 2745 needNL = true; 2746 } 2747 } 2748 return printed; 2749 } 2750 2751 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2752 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2753 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2754 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2755 } 2756 2757 final void scheduleIdleLocked() { 2758 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2759 } 2760 2761 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2762 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2763 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2764 } 2765 2766 final void scheduleResumeTopActivities() { 2767 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2768 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2769 } 2770 } 2771 2772 void removeSleepTimeouts() { 2773 mSleepTimeout = false; 2774 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2775 } 2776 2777 final void scheduleSleepTimeout() { 2778 removeSleepTimeouts(); 2779 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2780 } 2781 2782 @Override 2783 public void onDisplayAdded(int displayId) { 2784 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2785 } 2786 2787 @Override 2788 public void onDisplayRemoved(int displayId) { 2789 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2790 } 2791 2792 @Override 2793 public void onDisplayChanged(int displayId) { 2794 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2795 } 2796 2797 public void handleDisplayAddedLocked(int displayId) { 2798 boolean newDisplay; 2799 synchronized (mService) { 2800 newDisplay = mActivityDisplays.get(displayId) == null; 2801 if (newDisplay) { 2802 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2803 mActivityDisplays.put(displayId, activityDisplay); 2804 } 2805 } 2806 if (newDisplay) { 2807 mWindowManager.onDisplayAdded(displayId); 2808 } 2809 } 2810 2811 public void handleDisplayRemovedLocked(int displayId) { 2812 synchronized (mService) { 2813 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2814 if (activityDisplay != null) { 2815 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2816 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2817 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2818 } 2819 mActivityDisplays.remove(displayId); 2820 } 2821 } 2822 mWindowManager.onDisplayRemoved(displayId); 2823 } 2824 2825 public void handleDisplayChangedLocked(int displayId) { 2826 synchronized (mService) { 2827 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2828 if (activityDisplay != null) { 2829 // TODO: Update the bounds. 2830 } 2831 } 2832 mWindowManager.onDisplayChanged(displayId); 2833 } 2834 2835 StackInfo getStackInfo(ActivityStack stack) { 2836 StackInfo info = new StackInfo(); 2837 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2838 info.displayId = Display.DEFAULT_DISPLAY; 2839 info.stackId = stack.mStackId; 2840 2841 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2842 final int numTasks = tasks.size(); 2843 int[] taskIds = new int[numTasks]; 2844 String[] taskNames = new String[numTasks]; 2845 for (int i = 0; i < numTasks; ++i) { 2846 final TaskRecord task = tasks.get(i); 2847 taskIds[i] = task.taskId; 2848 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2849 : task.realActivity != null ? task.realActivity.flattenToString() 2850 : task.getTopActivity() != null ? task.getTopActivity().packageName 2851 : "unknown"; 2852 } 2853 info.taskIds = taskIds; 2854 info.taskNames = taskNames; 2855 return info; 2856 } 2857 2858 StackInfo getStackInfoLocked(int stackId) { 2859 ActivityStack stack = getStack(stackId); 2860 if (stack != null) { 2861 return getStackInfo(stack); 2862 } 2863 return null; 2864 } 2865 2866 ArrayList<StackInfo> getAllStackInfosLocked() { 2867 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2868 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2869 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2870 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 2871 list.add(getStackInfo(stacks.get(ndx))); 2872 } 2873 } 2874 return list; 2875 } 2876 2877 void setLockTaskModeLocked(TaskRecord task) { 2878 if (task == null) { 2879 // Take out of lock task mode. 2880 mLockTaskModeTask = null; 2881 return; 2882 } 2883 if (isLockTaskModeViolation(task)) { 2884 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 2885 return; 2886 } 2887 mLockTaskModeTask = task; 2888 findTaskToMoveToFrontLocked(task, 0, null); 2889 resumeTopActivitiesLocked(); 2890 } 2891 2892 boolean isLockTaskModeViolation(TaskRecord task) { 2893 return mLockTaskModeTask != null && mLockTaskModeTask != task; 2894 } 2895 2896 void endLockTaskModeIfTaskEnding(TaskRecord task) { 2897 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 2898 mLockTaskModeTask = null; 2899 } 2900 } 2901 2902 boolean isInLockTaskMode() { 2903 return mLockTaskModeTask != null; 2904 } 2905 2906 private final class ActivityStackSupervisorHandler extends Handler { 2907 2908 public ActivityStackSupervisorHandler(Looper looper) { 2909 super(looper); 2910 } 2911 2912 void activityIdleInternal(ActivityRecord r) { 2913 synchronized (mService) { 2914 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2915 } 2916 } 2917 2918 @Override 2919 public void handleMessage(Message msg) { 2920 switch (msg.what) { 2921 case IDLE_TIMEOUT_MSG: { 2922 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2923 if (mService.mDidDexOpt) { 2924 mService.mDidDexOpt = false; 2925 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2926 nmsg.obj = msg.obj; 2927 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2928 return; 2929 } 2930 // We don't at this point know if the activity is fullscreen, 2931 // so we need to be conservative and assume it isn't. 2932 activityIdleInternal((ActivityRecord)msg.obj); 2933 } break; 2934 case IDLE_NOW_MSG: { 2935 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2936 activityIdleInternal((ActivityRecord)msg.obj); 2937 } break; 2938 case RESUME_TOP_ACTIVITY_MSG: { 2939 synchronized (mService) { 2940 resumeTopActivitiesLocked(); 2941 } 2942 } break; 2943 case SLEEP_TIMEOUT_MSG: { 2944 synchronized (mService) { 2945 if (mService.isSleepingOrShuttingDown()) { 2946 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2947 mSleepTimeout = true; 2948 checkReadyForSleepLocked(); 2949 } 2950 } 2951 } break; 2952 case LAUNCH_TIMEOUT_MSG: { 2953 if (mService.mDidDexOpt) { 2954 mService.mDidDexOpt = false; 2955 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2956 return; 2957 } 2958 synchronized (mService) { 2959 if (mLaunchingActivity.isHeld()) { 2960 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2961 if (VALIDATE_WAKE_LOCK_CALLER 2962 && Binder.getCallingUid() != Process.myUid()) { 2963 throw new IllegalStateException("Calling must be system uid"); 2964 } 2965 mLaunchingActivity.release(); 2966 } 2967 } 2968 } break; 2969 case HANDLE_DISPLAY_ADDED: { 2970 handleDisplayAddedLocked(msg.arg1); 2971 } break; 2972 case HANDLE_DISPLAY_CHANGED: { 2973 handleDisplayChangedLocked(msg.arg1); 2974 } break; 2975 case HANDLE_DISPLAY_REMOVED: { 2976 handleDisplayRemovedLocked(msg.arg1); 2977 } break; 2978 case CONTAINER_CALLBACK_VISIBILITY: { 2979 final ActivityContainer container = (ActivityContainer) msg.obj; 2980 try { 2981 // We only send this message if mCallback is non-null. 2982 container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1); 2983 } catch (RemoteException e) { 2984 } 2985 } 2986 } 2987 } 2988 } 2989 2990 class ActivityContainer extends android.app.IActivityContainer.Stub { 2991 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 2992 Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 2993 final int mStackId; 2994 IActivityContainerCallback mCallback = null; 2995 final ActivityStack mStack; 2996 ActivityRecord mParentActivity = null; 2997 String mIdString; 2998 2999 boolean mVisible = true; 3000 3001 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3002 ActivityDisplay mActivityDisplay; 3003 3004 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3005 final static int CONTAINER_STATE_NO_SURFACE = 1; 3006 final static int CONTAINER_STATE_FINISHING = 2; 3007 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3008 3009 ActivityContainer(int stackId) { 3010 synchronized (mService) { 3011 mStackId = stackId; 3012 mStack = new ActivityStack(this); 3013 mIdString = "ActivtyContainer{" + mStackId + "}"; 3014 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3015 } 3016 } 3017 3018 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3019 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3020 + " to display=" + activityDisplay); 3021 mActivityDisplay = activityDisplay; 3022 mStack.mDisplayId = activityDisplay.mDisplayId; 3023 mStack.mStacks = activityDisplay.mStacks; 3024 3025 activityDisplay.attachActivities(mStack); 3026 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3027 } 3028 3029 @Override 3030 public void attachToDisplay(int displayId) { 3031 synchronized (mService) { 3032 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3033 if (activityDisplay == null) { 3034 return; 3035 } 3036 attachToDisplayLocked(activityDisplay); 3037 } 3038 } 3039 3040 @Override 3041 public int getDisplayId() { 3042 if (mActivityDisplay != null) { 3043 return mActivityDisplay.mDisplayId; 3044 } 3045 return -1; 3046 } 3047 3048 @Override 3049 public boolean injectEvent(InputEvent event) { 3050 final long origId = Binder.clearCallingIdentity(); 3051 try { 3052 if (mActivityDisplay != null) { 3053 return mInputManagerInternal.injectInputEvent(event, 3054 mActivityDisplay.mDisplayId, 3055 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3056 } 3057 return false; 3058 } finally { 3059 Binder.restoreCallingIdentity(origId); 3060 } 3061 } 3062 3063 @Override 3064 public void release() { 3065 mContainerState = CONTAINER_STATE_FINISHING; 3066 mStack.finishAllActivitiesLocked(); 3067 detachLocked(); 3068 mWindowManager.removeStack(mStackId); 3069 } 3070 3071 private void detachLocked() { 3072 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3073 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3074 if (mActivityDisplay != null) { 3075 mActivityDisplay.detachActivitiesLocked(mStack); 3076 mActivityDisplay = null; 3077 mStack.mDisplayId = -1; 3078 mStack.mStacks = null; 3079 mWindowManager.detachStack(mStackId); 3080 } 3081 } 3082 3083 @Override 3084 public final int startActivity(Intent intent) { 3085 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3086 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3087 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3088 // TODO: Switch to user app stacks here. 3089 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3090 String mimeType = intent.getType(); 3091 if (mimeType == null && intent.getData() != null 3092 && "content".equals(intent.getData().getScheme())) { 3093 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3094 } 3095 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null, 3096 null, null, null, null, userId, this); 3097 } 3098 3099 @Override 3100 public final int startActivityIntentSender(IIntentSender intentSender) { 3101 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3102 3103 if (!(intentSender instanceof PendingIntentRecord)) { 3104 throw new IllegalArgumentException("Bad PendingIntent object"); 3105 } 3106 3107 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3108 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3109 } 3110 3111 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3112 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3113 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3114 if (resolvedType == null) { 3115 resolvedType = intent.getType(); 3116 if (resolvedType == null && intent.getData() != null 3117 && "content".equals(intent.getData().getScheme())) { 3118 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3119 } 3120 } 3121 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3122 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3123 throw new SecurityException( 3124 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3125 } 3126 } 3127 3128 /** Throw a SecurityException if allowEmbedded is not true */ 3129 @Override 3130 public final void checkEmbeddedAllowed(Intent intent) { 3131 checkEmbeddedAllowedInner(intent, null); 3132 } 3133 3134 /** Throw a SecurityException if allowEmbedded is not true */ 3135 @Override 3136 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3137 if (!(intentSender instanceof PendingIntentRecord)) { 3138 throw new IllegalArgumentException("Bad PendingIntent object"); 3139 } 3140 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3141 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3142 pendingIntent.key.requestResolvedType); 3143 } 3144 3145 @Override 3146 public IBinder asBinder() { 3147 return this; 3148 } 3149 3150 @Override 3151 public void setSurface(Surface surface, int width, int height, int density) { 3152 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3153 } 3154 3155 ActivityStackSupervisor getOuter() { 3156 return ActivityStackSupervisor.this; 3157 } 3158 3159 boolean isAttached() { 3160 return mActivityDisplay != null; 3161 } 3162 3163 void getBounds(Point outBounds) { 3164 if (mActivityDisplay != null) { 3165 mActivityDisplay.getBounds(outBounds); 3166 } else { 3167 outBounds.set(0, 0); 3168 } 3169 } 3170 3171 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3172 void setVisible(boolean visible) { 3173 if (mVisible != visible) { 3174 mVisible = visible; 3175 if (mCallback != null) { 3176 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3177 0 /* unused */, this).sendToTarget(); 3178 } 3179 } 3180 } 3181 3182 void setDrawn() { 3183 } 3184 3185 @Override 3186 public String toString() { 3187 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3188 } 3189 } 3190 3191 private class VirtualActivityContainer extends ActivityContainer { 3192 Surface mSurface; 3193 boolean mDrawn = false; 3194 3195 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3196 super(getNextStackId()); 3197 mParentActivity = parent; 3198 mCallback = callback; 3199 mContainerState = CONTAINER_STATE_NO_SURFACE; 3200 mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3201 } 3202 3203 @Override 3204 public void setSurface(Surface surface, int width, int height, int density) { 3205 super.setSurface(surface, width, height, density); 3206 3207 synchronized (mService) { 3208 final long origId = Binder.clearCallingIdentity(); 3209 try { 3210 setSurfaceLocked(surface, width, height, density); 3211 } finally { 3212 Binder.restoreCallingIdentity(origId); 3213 } 3214 } 3215 } 3216 3217 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3218 if (mContainerState == CONTAINER_STATE_FINISHING) { 3219 return; 3220 } 3221 VirtualActivityDisplay virtualActivityDisplay = 3222 (VirtualActivityDisplay) mActivityDisplay; 3223 if (virtualActivityDisplay == null) { 3224 virtualActivityDisplay = 3225 new VirtualActivityDisplay(width, height, density); 3226 mActivityDisplay = virtualActivityDisplay; 3227 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3228 attachToDisplayLocked(virtualActivityDisplay); 3229 } 3230 3231 if (mSurface != null) { 3232 mSurface.release(); 3233 } 3234 3235 mSurface = surface; 3236 if (surface != null) { 3237 mStack.resumeTopActivityLocked(null); 3238 } else { 3239 mContainerState = CONTAINER_STATE_NO_SURFACE; 3240 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3241 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3242 mStack.startPausingLocked(false, true); 3243 } 3244 } 3245 3246 setSurfaceIfReady(); 3247 3248 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3249 + virtualActivityDisplay); 3250 } 3251 3252 @Override 3253 boolean isAttached() { 3254 return mSurface != null && super.isAttached(); 3255 } 3256 3257 @Override 3258 void setDrawn() { 3259 synchronized (mService) { 3260 mDrawn = true; 3261 setSurfaceIfReady(); 3262 } 3263 } 3264 3265 private void setSurfaceIfReady() { 3266 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn + 3267 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3268 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3269 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3270 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3271 } 3272 } 3273 } 3274 3275 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3276 * attached {@link ActivityStack}s */ 3277 class ActivityDisplay { 3278 /** Actual Display this object tracks. */ 3279 int mDisplayId; 3280 Display mDisplay; 3281 DisplayInfo mDisplayInfo = new DisplayInfo(); 3282 3283 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3284 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3285 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3286 3287 ActivityDisplay() { 3288 } 3289 3290 ActivityDisplay(int displayId) { 3291 init(mDisplayManager.getDisplay(displayId)); 3292 } 3293 3294 void init(Display display) { 3295 mDisplay = display; 3296 mDisplayId = display.getDisplayId(); 3297 mDisplay.getDisplayInfo(mDisplayInfo); 3298 } 3299 3300 void attachActivities(ActivityStack stack) { 3301 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3302 + mDisplayId); 3303 mStacks.add(stack); 3304 } 3305 3306 void detachActivitiesLocked(ActivityStack stack) { 3307 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3308 + " from displayId=" + mDisplayId); 3309 mStacks.remove(stack); 3310 } 3311 3312 void getBounds(Point bounds) { 3313 mDisplay.getDisplayInfo(mDisplayInfo); 3314 bounds.x = mDisplayInfo.appWidth; 3315 bounds.y = mDisplayInfo.appHeight; 3316 } 3317 3318 @Override 3319 public String toString() { 3320 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3321 } 3322 } 3323 3324 class VirtualActivityDisplay extends ActivityDisplay { 3325 VirtualDisplay mVirtualDisplay; 3326 3327 VirtualActivityDisplay(int width, int height, int density) { 3328 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3329 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME, 3330 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3331 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3332 3333 init(mVirtualDisplay.getDisplay()); 3334 3335 mWindowManager.handleDisplayAdded(mDisplayId); 3336 } 3337 3338 void setSurface(Surface surface) { 3339 if (mVirtualDisplay != null) { 3340 mVirtualDisplay.setSurface(surface); 3341 } 3342 } 3343 3344 @Override 3345 void detachActivitiesLocked(ActivityStack stack) { 3346 super.detachActivitiesLocked(stack); 3347 if (mVirtualDisplay != null) { 3348 mVirtualDisplay.release(); 3349 mVirtualDisplay = null; 3350 } 3351 } 3352 3353 @Override 3354 public String toString() { 3355 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3356 } 3357 } 3358} 3359