ActivityStackSupervisor.java revision f1cca18ae460b66242988a8a6204c4a42b6fa1c1
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.ActivityOptions; 38import android.app.AppGlobals; 39import android.app.IActivityManager; 40import android.app.IApplicationThread; 41import android.app.IThumbnailReceiver; 42import android.app.PendingIntent; 43import android.app.ActivityManager.RunningTaskInfo; 44import android.app.IActivityManager.WaitResult; 45import android.app.ResultInfo; 46import android.content.ComponentName; 47import android.content.Context; 48import android.content.IIntentSender; 49import android.content.Intent; 50import android.content.IntentSender; 51import android.content.pm.ActivityInfo; 52import android.content.pm.ApplicationInfo; 53import android.content.pm.PackageManager; 54import android.content.pm.ResolveInfo; 55import android.content.res.Configuration; 56import android.os.Binder; 57import android.os.Bundle; 58import android.os.Debug; 59import android.os.Handler; 60import android.os.IBinder; 61import android.os.Looper; 62import android.os.Message; 63import android.os.ParcelFileDescriptor; 64import android.os.PowerManager; 65import android.os.Process; 66import android.os.RemoteException; 67import android.os.SystemClock; 68import android.os.UserHandle; 69import android.util.EventLog; 70import android.util.Slog; 71import android.util.SparseArray; 72 73import com.android.internal.app.HeavyWeightSwitcherActivity; 74import com.android.internal.os.TransferPipe; 75import com.android.server.am.ActivityManagerService.PendingActivityLaunch; 76import com.android.server.am.ActivityStack.ActivityState; 77import com.android.server.wm.StackBox; 78import com.android.server.wm.WindowManagerService; 79 80import java.io.FileDescriptor; 81import java.io.IOException; 82import java.io.PrintWriter; 83import java.util.ArrayList; 84import java.util.List; 85 86public final class ActivityStackSupervisor { 87 static final boolean DEBUG = ActivityManagerService.DEBUG || false; 88 static final boolean DEBUG_ADD_REMOVE = DEBUG || false; 89 static final boolean DEBUG_APP = DEBUG || false; 90 static final boolean DEBUG_SAVED_STATE = DEBUG || false; 91 static final boolean DEBUG_STATES = DEBUG || false; 92 static final boolean DEBUG_IDLE = DEBUG || false; 93 94 public static final int HOME_STACK_ID = 0; 95 96 /** How long we wait until giving up on the last activity telling us it is idle. */ 97 static final int IDLE_TIMEOUT = 10*1000; 98 99 /** How long we can hold the sleep wake lock before giving up. */ 100 static final int SLEEP_TIMEOUT = 5*1000; 101 102 // How long we can hold the launch wake lock before giving up. 103 static final int LAUNCH_TIMEOUT = 10*1000; 104 105 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 106 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 107 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 108 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 109 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 110 111 // For debugging to make sure the caller when acquiring/releasing our 112 // wake lock is the system process. 113 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 114 115 final ActivityManagerService mService; 116 final Context mContext; 117 final Looper mLooper; 118 119 final ActivityStackSupervisorHandler mHandler; 120 121 /** Short cut */ 122 WindowManagerService mWindowManager; 123 124 /** Dismiss the keyguard after the next activity is displayed? */ 125 private boolean mDismissKeyguardOnNextActivity = false; 126 127 /** Identifier counter for all ActivityStacks */ 128 private int mLastStackId = HOME_STACK_ID; 129 130 /** Task identifier that activities are currently being started in. Incremented each time a 131 * new task is created. */ 132 private int mCurTaskId = 0; 133 134 /** The current user */ 135 private int mCurrentUser; 136 137 /** The stack containing the launcher app */ 138 private ActivityStack mHomeStack; 139 140 /** The non-home stack currently receiving input or launching the next activity. If home is 141 * in front then mHomeStack overrides mFocusedStack. 142 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */ 143 private ActivityStack mFocusedStack; 144 145 /** All the non-launcher stacks */ 146 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 147 148 private static final int STACK_STATE_HOME_IN_FRONT = 0; 149 private static final int STACK_STATE_HOME_TO_BACK = 1; 150 private static final int STACK_STATE_HOME_IN_BACK = 2; 151 private static final int STACK_STATE_HOME_TO_FRONT = 3; 152 private int mStackState = STACK_STATE_HOME_IN_FRONT; 153 154 /** List of activities that are waiting for a new activity to become visible before completing 155 * whatever operation they are supposed to do. */ 156 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); 157 158 /** List of processes waiting to find out about the next visible activity. */ 159 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = 160 new ArrayList<IActivityManager.WaitResult>(); 161 162 /** List of processes waiting to find out about the next launched activity. */ 163 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = 164 new ArrayList<IActivityManager.WaitResult>(); 165 166 /** List of activities that are ready to be stopped, but waiting for the next activity to 167 * settle down before doing so. */ 168 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); 169 170 /** List of activities that are ready to be finished, but waiting for the previous activity to 171 * settle down before doing so. It contains ActivityRecord objects. */ 172 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>(); 173 174 /** List of activities that are in the process of going to sleep. */ 175 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>(); 176 177 /** List of ActivityRecord objects that have been finished and must still report back to a 178 * pending thumbnail receiver. */ 179 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>(); 180 181 /** Used on user changes */ 182 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>(); 183 184 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 185 * is being brought in front of us. */ 186 boolean mUserLeaving = false; 187 188 /** Set when we have taken too long waiting to go to sleep. */ 189 boolean mSleepTimeout = false; 190 191 /** 192 * We don't want to allow the device to go to sleep while in the process 193 * of launching an activity. This is primarily to allow alarm intent 194 * receivers to launch an activity and get that to run before the device 195 * goes back to sleep. 196 */ 197 final PowerManager.WakeLock mLaunchingActivity; 198 199 /** 200 * Set when the system is going to sleep, until we have 201 * successfully paused the current activity and released our wake lock. 202 * At that point the system is allowed to actually sleep. 203 */ 204 final PowerManager.WakeLock mGoingToSleep; 205 206 /** 207 * The name of the current home activity for each user. 208 * TODO: Remove entries when user is deleted. 209 */ 210 final SparseArray<String> mHomePackageNames = new SparseArray<String>(); 211 212 public ActivityStackSupervisor(ActivityManagerService service, Context context, 213 Looper looper) { 214 mService = service; 215 mContext = context; 216 mLooper = looper; 217 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 218 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 219 mHandler = new ActivityStackSupervisorHandler(looper); 220 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 221 throw new IllegalStateException("Calling must be system uid"); 222 } 223 mLaunchingActivity = 224 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 225 mLaunchingActivity.setReferenceCounted(false); 226 } 227 228 void setWindowManager(WindowManagerService wm) { 229 mWindowManager = wm; 230 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID); 231 mStacks.add(mHomeStack); 232 } 233 234 void dismissKeyguard() { 235 if (mDismissKeyguardOnNextActivity) { 236 mDismissKeyguardOnNextActivity = false; 237 mWindowManager.dismissKeyguard(); 238 } 239 } 240 241 ActivityStack getFocusedStack() { 242 if (mFocusedStack == null) { 243 return mHomeStack; 244 } 245 switch (mStackState) { 246 case STACK_STATE_HOME_IN_FRONT: 247 case STACK_STATE_HOME_TO_FRONT: 248 return mHomeStack; 249 case STACK_STATE_HOME_IN_BACK: 250 case STACK_STATE_HOME_TO_BACK: 251 default: 252 return mFocusedStack; 253 } 254 } 255 256 ActivityStack getLastStack() { 257 switch (mStackState) { 258 case STACK_STATE_HOME_IN_FRONT: 259 case STACK_STATE_HOME_TO_BACK: 260 return mHomeStack; 261 case STACK_STATE_HOME_TO_FRONT: 262 case STACK_STATE_HOME_IN_BACK: 263 default: 264 return mFocusedStack; 265 } 266 } 267 268 boolean isFrontStack(ActivityStack stack) { 269 return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); 270 } 271 272 void moveHomeStack(boolean toFront) { 273 final boolean homeInFront = isFrontStack(mHomeStack); 274 if (homeInFront ^ toFront) { 275 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" + 276 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ? 277 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT)); 278 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT; 279 } 280 } 281 282 boolean resumeHomeActivity(ActivityRecord prev) { 283 moveHomeStack(true); 284 if (prev != null) { 285 prev.mLaunchHomeTaskNext = false; 286 } 287 ActivityRecord r = mHomeStack.topRunningActivityLocked(null); 288 if (r != null) { 289 mService.setFocusedActivityLocked(r); 290 return resumeTopActivitiesLocked(mHomeStack, prev, null); 291 } 292 return mService.startHomeActivityLocked(mCurrentUser); 293 } 294 295 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r, 296 ActivityStack stack) { 297 if (stack == mHomeStack) { 298 return; 299 } 300 if ((sourceRecord == null && getLastStack() == mHomeStack) || 301 (sourceRecord != null && sourceRecord.isHomeActivity())) { 302 if (r == null) { 303 r = stack.topRunningActivityLocked(null); 304 } 305 if (r != null && !r.isHomeActivity() && r.isRootActivity()) { 306 r.mLaunchHomeTaskNext = true; 307 } 308 } 309 } 310 311 void setDismissKeyguard(boolean dismiss) { 312 mDismissKeyguardOnNextActivity = dismiss; 313 } 314 315 TaskRecord anyTaskForIdLocked(int id) { 316 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 317 ActivityStack stack = mStacks.get(stackNdx); 318 TaskRecord task = stack.taskForIdLocked(id); 319 if (task != null) { 320 return task; 321 } 322 } 323 return null; 324 } 325 326 ActivityRecord isInAnyStackLocked(IBinder token) { 327 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 328 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token); 329 if (r != null) { 330 return r; 331 } 332 } 333 return null; 334 } 335 336 int getNextTaskId() { 337 do { 338 mCurTaskId++; 339 if (mCurTaskId <= 0) { 340 mCurTaskId = 1; 341 } 342 } while (anyTaskForIdLocked(mCurTaskId) != null); 343 return mCurTaskId; 344 } 345 346 void removeTask(TaskRecord task) { 347 mWindowManager.removeTask(task.taskId); 348 final ActivityStack stack = task.stack; 349 final ActivityRecord r = stack.mResumedActivity; 350 if (r != null && r.task == task) { 351 stack.mResumedActivity = null; 352 } 353 if (stack.removeTask(task) && !stack.isHomeStack()) { 354 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); 355 mStacks.remove(stack); 356 final int stackId = stack.mStackId; 357 final int nextStackId = mWindowManager.removeStack(stackId); 358 // TODO: Perhaps we need to let the ActivityManager determine the next focus... 359 if (mFocusedStack == null || mFocusedStack.mStackId == stackId) { 360 // If this is the last app stack, set mFocusedStack to null. 361 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId); 362 } 363 } 364 } 365 366 ActivityRecord resumedAppLocked() { 367 ActivityStack stack = getFocusedStack(); 368 if (stack == null) { 369 return null; 370 } 371 ActivityRecord resumedActivity = stack.mResumedActivity; 372 if (resumedActivity == null || resumedActivity.app == null) { 373 resumedActivity = stack.mPausingActivity; 374 if (resumedActivity == null || resumedActivity.app == null) { 375 resumedActivity = stack.topRunningActivityLocked(null); 376 } 377 } 378 return resumedActivity; 379 } 380 381 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception { 382 boolean didSomething = false; 383 final String processName = app.processName; 384 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 385 final ActivityStack stack = mStacks.get(stackNdx); 386 if (!isFrontStack(stack)) { 387 continue; 388 } 389 ActivityRecord hr = stack.topRunningActivityLocked(null); 390 if (hr != null) { 391 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 392 && processName.equals(hr.processName)) { 393 try { 394 if (headless) { 395 Slog.e(TAG, "Starting activities not supported on headless device: " 396 + hr); 397 } else if (realStartActivityLocked(hr, app, true, true)) { 398 didSomething = true; 399 } 400 } catch (Exception e) { 401 Slog.w(TAG, "Exception in new application when starting activity " 402 + hr.intent.getComponent().flattenToShortString(), e); 403 throw e; 404 } 405 } 406 } 407 } 408 if (!didSomething) { 409 ensureActivitiesVisibleLocked(null, 0); 410 } 411 return didSomething; 412 } 413 414 boolean allResumedActivitiesIdle() { 415 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 416 final ActivityStack stack = mStacks.get(stackNdx); 417 if (!isFrontStack(stack)) { 418 continue; 419 } 420 final ActivityRecord resumedActivity = stack.mResumedActivity; 421 if (resumedActivity == null || !resumedActivity.idle) { 422 return false; 423 } 424 } 425 return true; 426 } 427 428 boolean allResumedActivitiesComplete() { 429 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 430 final ActivityStack stack = mStacks.get(stackNdx); 431 if (isFrontStack(stack)) { 432 final ActivityRecord r = stack.mResumedActivity; 433 if (r != null && r.state != ActivityState.RESUMED) { 434 return false; 435 } 436 } 437 } 438 // TODO: Not sure if this should check if all Paused are complete too. 439 switch (mStackState) { 440 case STACK_STATE_HOME_TO_BACK: 441 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + 442 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" + 443 stackStateToString(STACK_STATE_HOME_IN_BACK)); 444 mStackState = STACK_STATE_HOME_IN_BACK; 445 break; 446 case STACK_STATE_HOME_TO_FRONT: 447 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + 448 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" + 449 stackStateToString(STACK_STATE_HOME_IN_FRONT)); 450 mStackState = STACK_STATE_HOME_IN_FRONT; 451 break; 452 } 453 return true; 454 } 455 456 boolean allResumedActivitiesVisible() { 457 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 458 final ActivityStack stack = mStacks.get(stackNdx); 459 final ActivityRecord r = stack.mResumedActivity; 460 if (r != null && (!r.nowVisible || r.waitingVisible)) { 461 return false; 462 } 463 } 464 return true; 465 } 466 467 boolean pauseBackStacks(boolean userLeaving) { 468 boolean someActivityPaused = false; 469 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 470 final ActivityStack stack = mStacks.get(stackNdx); 471 if (!isFrontStack(stack) && stack.mResumedActivity != null) { 472 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + 473 " mResumedActivity=" + stack.mResumedActivity); 474 stack.startPausingLocked(userLeaving, false); 475 someActivityPaused = true; 476 } 477 } 478 return someActivityPaused; 479 } 480 481 boolean allPausedActivitiesComplete() { 482 boolean pausing = true; 483 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 484 final ActivityStack stack = mStacks.get(stackNdx); 485 final ActivityRecord r = stack.mPausingActivity; 486 if (r != null && r.state != ActivityState.PAUSED 487 && r.state != ActivityState.STOPPED 488 && r.state != ActivityState.STOPPING) { 489 if (DEBUG_STATES) { 490 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state); 491 pausing = false; 492 } else { 493 return false; 494 } 495 } 496 } 497 return pausing; 498 } 499 500 void reportActivityVisibleLocked(ActivityRecord r) { 501 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 502 WaitResult w = mWaitingActivityVisible.get(i); 503 w.timeout = false; 504 if (r != null) { 505 w.who = new ComponentName(r.info.packageName, r.info.name); 506 } 507 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 508 w.thisTime = w.totalTime; 509 } 510 mService.notifyAll(); 511 dismissKeyguard(); 512 } 513 514 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 515 long thisTime, long totalTime) { 516 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 517 WaitResult w = mWaitingActivityLaunched.remove(i); 518 w.timeout = timeout; 519 if (r != null) { 520 w.who = new ComponentName(r.info.packageName, r.info.name); 521 } 522 w.thisTime = thisTime; 523 w.totalTime = totalTime; 524 } 525 mService.notifyAll(); 526 } 527 528 ActivityRecord topRunningActivityLocked() { 529 final ActivityStack focusedStack = getFocusedStack(); 530 ActivityRecord r = focusedStack.topRunningActivityLocked(null); 531 if (r != null) { 532 return r; 533 } 534 535 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 536 final ActivityStack stack = mStacks.get(stackNdx); 537 if (stack != focusedStack && isFrontStack(stack)) { 538 r = stack.topRunningActivityLocked(null); 539 if (r != null) { 540 return r; 541 } 542 } 543 } 544 return null; 545 } 546 547 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, 548 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) { 549 ActivityRecord r = null; 550 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 551 final ActivityStack stack = mStacks.get(stackNdx); 552 final ActivityRecord ar = 553 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list); 554 if (isFrontStack(stack)) { 555 r = ar; 556 } 557 } 558 return r; 559 } 560 561 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 562 String profileFile, ParcelFileDescriptor profileFd, int userId) { 563 // Collect information about the target of the Intent. 564 ActivityInfo aInfo; 565 try { 566 ResolveInfo rInfo = 567 AppGlobals.getPackageManager().resolveIntent( 568 intent, resolvedType, 569 PackageManager.MATCH_DEFAULT_ONLY 570 | ActivityManagerService.STOCK_PM_FLAGS, userId); 571 aInfo = rInfo != null ? rInfo.activityInfo : null; 572 } catch (RemoteException e) { 573 aInfo = null; 574 } 575 576 if (aInfo != null) { 577 // Store the found target back into the intent, because now that 578 // we have it we never want to do this again. For example, if the 579 // user navigates back to this point in the history, we should 580 // always restart the exact same activity. 581 intent.setComponent(new ComponentName( 582 aInfo.applicationInfo.packageName, aInfo.name)); 583 584 // Don't debug things in the system process 585 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 586 if (!aInfo.processName.equals("system")) { 587 mService.setDebugApp(aInfo.processName, true, false); 588 } 589 } 590 591 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 592 if (!aInfo.processName.equals("system")) { 593 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 594 } 595 } 596 597 if (profileFile != null) { 598 if (!aInfo.processName.equals("system")) { 599 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, 600 profileFile, profileFd, 601 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0); 602 } 603 } 604 } 605 return aInfo; 606 } 607 608 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 609 moveHomeStack(true); 610 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, 611 null, false, null); 612 } 613 614 final int startActivityMayWait(IApplicationThread caller, int callingUid, 615 String callingPackage, Intent intent, String resolvedType, IBinder resultTo, 616 String resultWho, int requestCode, int startFlags, String profileFile, 617 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, 618 Bundle options, int userId) { 619 // Refuse possible leaked file descriptors 620 if (intent != null && intent.hasFileDescriptors()) { 621 throw new IllegalArgumentException("File descriptors passed in Intent"); 622 } 623 boolean componentSpecified = intent.getComponent() != null; 624 625 // Don't modify the client's object! 626 intent = new Intent(intent); 627 628 // Collect information about the target of the Intent. 629 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 630 profileFile, profileFd, userId); 631 632 synchronized (mService) { 633 int callingPid; 634 if (callingUid >= 0) { 635 callingPid = -1; 636 } else if (caller == null) { 637 callingPid = Binder.getCallingPid(); 638 callingUid = Binder.getCallingUid(); 639 } else { 640 callingPid = callingUid = -1; 641 } 642 643 final ActivityStack stack = getFocusedStack(); 644 stack.mConfigWillChange = config != null 645 && mService.mConfiguration.diff(config) != 0; 646 if (DEBUG_CONFIGURATION) Slog.v(TAG, 647 "Starting activity when config will change = " + stack.mConfigWillChange); 648 649 final long origId = Binder.clearCallingIdentity(); 650 651 if (aInfo != null && 652 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 653 // This may be a heavy-weight process! Check to see if we already 654 // have another, different heavy-weight process running. 655 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 656 if (mService.mHeavyWeightProcess != null && 657 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 658 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 659 int realCallingUid = callingUid; 660 if (caller != null) { 661 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 662 if (callerApp != null) { 663 realCallingUid = callerApp.info.uid; 664 } else { 665 Slog.w(TAG, "Unable to find app for caller " + caller 666 + " (pid=" + callingPid + ") when starting: " 667 + intent.toString()); 668 ActivityOptions.abort(options); 669 return ActivityManager.START_PERMISSION_DENIED; 670 } 671 } 672 673 IIntentSender target = mService.getIntentSenderLocked( 674 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 675 realCallingUid, userId, null, null, 0, new Intent[] { intent }, 676 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 677 | PendingIntent.FLAG_ONE_SHOT, null); 678 679 Intent newIntent = new Intent(); 680 if (requestCode >= 0) { 681 // Caller is requesting a result. 682 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 683 } 684 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 685 new IntentSender(target)); 686 if (mService.mHeavyWeightProcess.activities.size() > 0) { 687 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 688 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 689 hist.packageName); 690 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 691 hist.task.taskId); 692 } 693 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 694 aInfo.packageName); 695 newIntent.setFlags(intent.getFlags()); 696 newIntent.setClassName("android", 697 HeavyWeightSwitcherActivity.class.getName()); 698 intent = newIntent; 699 resolvedType = null; 700 caller = null; 701 callingUid = Binder.getCallingUid(); 702 callingPid = Binder.getCallingPid(); 703 componentSpecified = true; 704 try { 705 ResolveInfo rInfo = 706 AppGlobals.getPackageManager().resolveIntent( 707 intent, null, 708 PackageManager.MATCH_DEFAULT_ONLY 709 | ActivityManagerService.STOCK_PM_FLAGS, userId); 710 aInfo = rInfo != null ? rInfo.activityInfo : null; 711 aInfo = mService.getActivityInfoForUser(aInfo, userId); 712 } catch (RemoteException e) { 713 aInfo = null; 714 } 715 } 716 } 717 } 718 719 int res = startActivityLocked(caller, intent, resolvedType, 720 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, 721 callingPackage, startFlags, options, componentSpecified, null); 722 723 if (stack.mConfigWillChange) { 724 // If the caller also wants to switch to a new configuration, 725 // do so now. This allows a clean switch, as we are waiting 726 // for the current activity to pause (so we will not destroy 727 // it), and have not yet started the next activity. 728 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 729 "updateConfiguration()"); 730 stack.mConfigWillChange = false; 731 if (DEBUG_CONFIGURATION) Slog.v(TAG, 732 "Updating to new configuration after starting activity."); 733 mService.updateConfigurationLocked(config, null, false, false); 734 } 735 736 Binder.restoreCallingIdentity(origId); 737 738 if (outResult != null) { 739 outResult.result = res; 740 if (res == ActivityManager.START_SUCCESS) { 741 mWaitingActivityLaunched.add(outResult); 742 do { 743 try { 744 mService.wait(); 745 } catch (InterruptedException e) { 746 } 747 } while (!outResult.timeout && outResult.who == null); 748 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 749 ActivityRecord r = stack.topRunningActivityLocked(null); 750 if (r.nowVisible) { 751 outResult.timeout = false; 752 outResult.who = new ComponentName(r.info.packageName, r.info.name); 753 outResult.totalTime = 0; 754 outResult.thisTime = 0; 755 } else { 756 outResult.thisTime = SystemClock.uptimeMillis(); 757 mWaitingActivityVisible.add(outResult); 758 do { 759 try { 760 mService.wait(); 761 } catch (InterruptedException e) { 762 } 763 } while (!outResult.timeout && outResult.who == null); 764 } 765 } 766 } 767 768 return res; 769 } 770 } 771 772 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 773 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 774 Bundle options, int userId) { 775 if (intents == null) { 776 throw new NullPointerException("intents is null"); 777 } 778 if (resolvedTypes == null) { 779 throw new NullPointerException("resolvedTypes is null"); 780 } 781 if (intents.length != resolvedTypes.length) { 782 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 783 } 784 785 786 int callingPid; 787 if (callingUid >= 0) { 788 callingPid = -1; 789 } else if (caller == null) { 790 callingPid = Binder.getCallingPid(); 791 callingUid = Binder.getCallingUid(); 792 } else { 793 callingPid = callingUid = -1; 794 } 795 final long origId = Binder.clearCallingIdentity(); 796 try { 797 synchronized (mService) { 798 ActivityRecord[] outActivity = new ActivityRecord[1]; 799 for (int i=0; i<intents.length; i++) { 800 Intent intent = intents[i]; 801 if (intent == null) { 802 continue; 803 } 804 805 // Refuse possible leaked file descriptors 806 if (intent != null && intent.hasFileDescriptors()) { 807 throw new IllegalArgumentException("File descriptors passed in Intent"); 808 } 809 810 boolean componentSpecified = intent.getComponent() != null; 811 812 // Don't modify the client's object! 813 intent = new Intent(intent); 814 815 // Collect information about the target of the Intent. 816 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 817 0, null, null, userId); 818 // TODO: New, check if this is correct 819 aInfo = mService.getActivityInfoForUser(aInfo, userId); 820 821 if (aInfo != null && 822 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 823 != 0) { 824 throw new IllegalArgumentException( 825 "FLAG_CANT_SAVE_STATE not supported here"); 826 } 827 828 Bundle theseOptions; 829 if (options != null && i == intents.length-1) { 830 theseOptions = options; 831 } else { 832 theseOptions = null; 833 } 834 int res = startActivityLocked(caller, intent, resolvedTypes[i], 835 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, 836 0, theseOptions, componentSpecified, outActivity); 837 if (res < 0) { 838 return res; 839 } 840 841 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 842 } 843 } 844 } finally { 845 Binder.restoreCallingIdentity(origId); 846 } 847 848 return ActivityManager.START_SUCCESS; 849 } 850 851 final boolean realStartActivityLocked(ActivityRecord r, 852 ProcessRecord app, boolean andResume, boolean checkConfig) 853 throws RemoteException { 854 855 r.startFreezingScreenLocked(app, 0); 856 mWindowManager.setAppVisibility(r.appToken, true); 857 858 // schedule launch ticks to collect information about slow apps. 859 r.startLaunchTickingLocked(); 860 861 // Have the window manager re-evaluate the orientation of 862 // the screen based on the new activity order. Note that 863 // as a result of this, it can call back into the activity 864 // manager with a new orientation. We don't care about that, 865 // because the activity is not currently running so we are 866 // just restarting it anyway. 867 if (checkConfig) { 868 Configuration config = mWindowManager.updateOrientationFromAppTokens( 869 mService.mConfiguration, 870 r.mayFreezeScreenLocked(app) ? r.appToken : null); 871 mService.updateConfigurationLocked(config, r, false, false); 872 } 873 874 r.app = app; 875 app.waitingToKill = null; 876 r.launchCount++; 877 r.lastLaunchTime = SystemClock.uptimeMillis(); 878 879 if (localLOGV) Slog.v(TAG, "Launching: " + r); 880 881 int idx = app.activities.indexOf(r); 882 if (idx < 0) { 883 app.activities.add(r); 884 } 885 mService.updateLruProcessLocked(app, true); 886 887 final ActivityStack stack = r.task.stack; 888 try { 889 if (app.thread == null) { 890 throw new RemoteException(); 891 } 892 List<ResultInfo> results = null; 893 List<Intent> newIntents = null; 894 if (andResume) { 895 results = r.results; 896 newIntents = r.newIntents; 897 } 898 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 899 + " icicle=" + r.icicle 900 + " with results=" + results + " newIntents=" + newIntents 901 + " andResume=" + andResume); 902 if (andResume) { 903 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 904 r.userId, System.identityHashCode(r), 905 r.task.taskId, r.shortComponentName); 906 } 907 if (r.isHomeActivity() && r.isNotResolverActivity()) { 908 mService.mHomeProcess = app; 909 } 910 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 911 r.sleeping = false; 912 r.forceNewConfig = false; 913 mService.showAskCompatModeDialogLocked(r); 914 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 915 String profileFile = null; 916 ParcelFileDescriptor profileFd = null; 917 boolean profileAutoStop = false; 918 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 919 if (mService.mProfileProc == null || mService.mProfileProc == app) { 920 mService.mProfileProc = app; 921 profileFile = mService.mProfileFile; 922 profileFd = mService.mProfileFd; 923 profileAutoStop = mService.mAutoStopProfiler; 924 } 925 } 926 app.hasShownUi = true; 927 app.pendingUiClean = true; 928 if (profileFd != null) { 929 try { 930 profileFd = profileFd.dup(); 931 } catch (IOException e) { 932 if (profileFd != null) { 933 try { 934 profileFd.close(); 935 } catch (IOException o) { 936 } 937 profileFd = null; 938 } 939 } 940 } 941 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); 942 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 943 System.identityHashCode(r), r.info, 944 new Configuration(mService.mConfiguration), r.compat, 945 app.repProcState, r.icicle, results, newIntents, !andResume, 946 mService.isNextTransitionForward(), profileFile, profileFd, 947 profileAutoStop); 948 949 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 950 // This may be a heavy-weight process! Note that the package 951 // manager will ensure that only activity can run in the main 952 // process of the .apk, which is the only thing that will be 953 // considered heavy-weight. 954 if (app.processName.equals(app.info.packageName)) { 955 if (mService.mHeavyWeightProcess != null 956 && mService.mHeavyWeightProcess != app) { 957 Slog.w(TAG, "Starting new heavy weight process " + app 958 + " when already running " 959 + mService.mHeavyWeightProcess); 960 } 961 mService.mHeavyWeightProcess = app; 962 Message msg = mService.mHandler.obtainMessage( 963 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 964 msg.obj = r; 965 mService.mHandler.sendMessage(msg); 966 } 967 } 968 969 } catch (RemoteException e) { 970 if (r.launchFailed) { 971 // This is the second time we failed -- finish activity 972 // and give up. 973 Slog.e(TAG, "Second failure launching " 974 + r.intent.getComponent().flattenToShortString() 975 + ", giving up", e); 976 mService.appDiedLocked(app, app.pid, app.thread); 977 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 978 "2nd-crash", false); 979 return false; 980 } 981 982 // This is the first time we failed -- restart process and 983 // retry. 984 app.activities.remove(r); 985 throw e; 986 } 987 988 r.launchFailed = false; 989 if (stack.updateLRUListLocked(r)) { 990 Slog.w(TAG, "Activity " + r 991 + " being launched, but already in LRU list"); 992 } 993 994 if (andResume) { 995 // As part of the process of launching, ActivityThread also performs 996 // a resume. 997 stack.minimalResumeActivityLocked(r); 998 } else { 999 // This activity is not starting in the resumed state... which 1000 // should look like we asked it to pause+stop (but remain visible), 1001 // and it has done so and reported back the current icicle and 1002 // other state. 1003 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 1004 + " (starting in stopped state)"); 1005 r.state = ActivityState.STOPPED; 1006 r.stopped = true; 1007 } 1008 1009 // Launch the new version setup screen if needed. We do this -after- 1010 // launching the initial activity (that is, home), so that it can have 1011 // a chance to initialize itself while in the background, making the 1012 // switch back to it faster and look better. 1013 if (isFrontStack(stack)) { 1014 mService.startSetupActivityLocked(); 1015 } 1016 1017 return true; 1018 } 1019 1020 void startSpecificActivityLocked(ActivityRecord r, 1021 boolean andResume, boolean checkConfig) { 1022 // Is this activity's application already running? 1023 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1024 r.info.applicationInfo.uid); 1025 1026 r.task.stack.setLaunchTime(r); 1027 1028 if (app != null && app.thread != null) { 1029 try { 1030 app.addPackage(r.info.packageName, mService.mProcessTracker); 1031 realStartActivityLocked(r, app, andResume, checkConfig); 1032 return; 1033 } catch (RemoteException e) { 1034 Slog.w(TAG, "Exception when starting activity " 1035 + r.intent.getComponent().flattenToShortString(), e); 1036 } 1037 1038 // If a dead object exception was thrown -- fall through to 1039 // restart the application. 1040 } 1041 1042 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1043 "activity", r.intent.getComponent(), false, false); 1044 } 1045 1046 final int startActivityLocked(IApplicationThread caller, 1047 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, 1048 String resultWho, int requestCode, 1049 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1050 boolean componentSpecified, ActivityRecord[] outActivity) { 1051 int err = ActivityManager.START_SUCCESS; 1052 1053 ProcessRecord callerApp = null; 1054 if (caller != null) { 1055 callerApp = mService.getRecordForAppLocked(caller); 1056 if (callerApp != null) { 1057 callingPid = callerApp.pid; 1058 callingUid = callerApp.info.uid; 1059 } else { 1060 Slog.w(TAG, "Unable to find app for caller " + caller 1061 + " (pid=" + callingPid + ") when starting: " 1062 + intent.toString()); 1063 err = ActivityManager.START_PERMISSION_DENIED; 1064 } 1065 } 1066 1067 if (err == ActivityManager.START_SUCCESS) { 1068 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1069 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1070 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); 1071 } 1072 1073 ActivityRecord sourceRecord = null; 1074 ActivityRecord resultRecord = null; 1075 if (resultTo != null) { 1076 sourceRecord = isInAnyStackLocked(resultTo); 1077 if (DEBUG_RESULTS) Slog.v( 1078 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1079 if (sourceRecord != null) { 1080 if (requestCode >= 0 && !sourceRecord.finishing) { 1081 resultRecord = sourceRecord; 1082 } 1083 } 1084 } 1085 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1086 1087 int launchFlags = intent.getFlags(); 1088 1089 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1090 && sourceRecord != null) { 1091 // Transfer the result target from the source activity to the new 1092 // one being started, including any failures. 1093 if (requestCode >= 0) { 1094 ActivityOptions.abort(options); 1095 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1096 } 1097 resultRecord = sourceRecord.resultTo; 1098 resultWho = sourceRecord.resultWho; 1099 requestCode = sourceRecord.requestCode; 1100 sourceRecord.resultTo = null; 1101 if (resultRecord != null) { 1102 resultRecord.removeResultsLocked( 1103 sourceRecord, resultWho, requestCode); 1104 } 1105 } 1106 1107 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1108 // We couldn't find a class that can handle the given Intent. 1109 // That's the end of that! 1110 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1111 } 1112 1113 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1114 // We couldn't find the specific class specified in the Intent. 1115 // Also the end of the line. 1116 err = ActivityManager.START_CLASS_NOT_FOUND; 1117 } 1118 1119 if (err != ActivityManager.START_SUCCESS) { 1120 if (resultRecord != null) { 1121 resultStack.sendActivityResultLocked(-1, 1122 resultRecord, resultWho, requestCode, 1123 Activity.RESULT_CANCELED, null); 1124 } 1125 setDismissKeyguard(false); 1126 ActivityOptions.abort(options); 1127 return err; 1128 } 1129 1130 final int startAnyPerm = mService.checkPermission( 1131 START_ANY_ACTIVITY, callingPid, callingUid); 1132 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1133 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1134 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1135 if (resultRecord != null) { 1136 resultStack.sendActivityResultLocked(-1, 1137 resultRecord, resultWho, requestCode, 1138 Activity.RESULT_CANCELED, null); 1139 } 1140 setDismissKeyguard(false); 1141 String msg; 1142 if (!aInfo.exported) { 1143 msg = "Permission Denial: starting " + intent.toString() 1144 + " from " + callerApp + " (pid=" + callingPid 1145 + ", uid=" + callingUid + ")" 1146 + " not exported from uid " + aInfo.applicationInfo.uid; 1147 } else { 1148 msg = "Permission Denial: starting " + intent.toString() 1149 + " from " + callerApp + " (pid=" + callingPid 1150 + ", uid=" + callingUid + ")" 1151 + " requires " + aInfo.permission; 1152 } 1153 Slog.w(TAG, msg); 1154 throw new SecurityException(msg); 1155 } 1156 1157 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, 1158 callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo); 1159 1160 if (mService.mController != null) { 1161 try { 1162 // The Intent we give to the watcher has the extra data 1163 // stripped off, since it can contain private information. 1164 Intent watchIntent = intent.cloneFilter(); 1165 abort |= !mService.mController.activityStarting(watchIntent, 1166 aInfo.applicationInfo.packageName); 1167 } catch (RemoteException e) { 1168 mService.mController = null; 1169 } 1170 } 1171 1172 if (abort) { 1173 if (resultRecord != null) { 1174 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1175 Activity.RESULT_CANCELED, null); 1176 } 1177 // We pretend to the caller that it was really started, but 1178 // they will just get a cancel result. 1179 setDismissKeyguard(false); 1180 ActivityOptions.abort(options); 1181 return ActivityManager.START_SUCCESS; 1182 } 1183 1184 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1185 intent, resolvedType, aInfo, mService.mConfiguration, 1186 resultRecord, resultWho, requestCode, componentSpecified, this); 1187 if (outActivity != null) { 1188 outActivity[0] = r; 1189 } 1190 1191 final ActivityStack stack = getFocusedStack(); 1192 if (stack.mResumedActivity == null 1193 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { 1194 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1195 PendingActivityLaunch pal = 1196 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1197 mService.mPendingActivityLaunches.add(pal); 1198 setDismissKeyguard(false); 1199 ActivityOptions.abort(options); 1200 return ActivityManager.START_SWITCHES_CANCELED; 1201 } 1202 } 1203 1204 if (mService.mDidAppSwitch) { 1205 // This is the second allowed switch since we stopped switches, 1206 // so now just generally allow switches. Use case: user presses 1207 // home (switches disabled, switch to home, mDidAppSwitch now true); 1208 // user taps a home icon (coming from home so allowed, we hit here 1209 // and now allow anyone to switch again). 1210 mService.mAppSwitchesAllowedTime = 0; 1211 } else { 1212 mService.mDidAppSwitch = true; 1213 } 1214 1215 mService.doPendingActivityLaunchesLocked(false); 1216 1217 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); 1218 if (stack.mPausingActivity == null) { 1219 // Someone asked to have the keyguard dismissed on the next 1220 // activity start, but we are not actually doing an activity 1221 // switch... just dismiss the keyguard now, because we 1222 // probably want to see whatever is behind it. 1223 dismissKeyguard(); 1224 } 1225 return err; 1226 } 1227 1228 ActivityStack adjustStackFocus(ActivityRecord r) { 1229 final TaskRecord task = r.task; 1230 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1231 if (task != null) { 1232 if (mFocusedStack != task.stack) { 1233 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1234 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task); 1235 mFocusedStack = task.stack; 1236 } else { 1237 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1238 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1239 } 1240 return mFocusedStack; 1241 } 1242 1243 if (mFocusedStack != null) { 1244 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1245 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1246 return mFocusedStack; 1247 } 1248 1249 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) { 1250 ActivityStack stack = mStacks.get(stackNdx); 1251 if (!stack.isHomeStack()) { 1252 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1253 "adjustStackFocus: Setting focused stack=" + stack); 1254 mFocusedStack = stack; 1255 return mFocusedStack; 1256 } 1257 } 1258 1259 // Time to create the first app stack for this user. 1260 int stackId = mService.createStack(-1, HOME_STACK_ID, 1261 StackBox.TASK_STACK_GOES_OVER, 1.0f); 1262 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1263 " stackId=" + stackId); 1264 mFocusedStack = getStack(stackId); 1265 return mFocusedStack; 1266 } 1267 return mHomeStack; 1268 } 1269 1270 void setFocusedStack(ActivityRecord r) { 1271 if (r == null) { 1272 return; 1273 } 1274 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) { 1275 if (mStackState != STACK_STATE_HOME_IN_FRONT) { 1276 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" + 1277 stackStateToString(mStackState) + " new=" + 1278 stackStateToString(STACK_STATE_HOME_TO_FRONT) + 1279 " Callers=" + Debug.getCallers(3)); 1280 mStackState = STACK_STATE_HOME_TO_FRONT; 1281 } 1282 } else { 1283 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1284 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task + 1285 " Callers=" + Debug.getCallers(3)); 1286 mFocusedStack = r.task.stack; 1287 if (mStackState != STACK_STATE_HOME_IN_BACK) { 1288 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" + 1289 stackStateToString(mStackState) + " new=" + 1290 stackStateToString(STACK_STATE_HOME_TO_BACK) + 1291 " Callers=" + Debug.getCallers(3)); 1292 mStackState = STACK_STATE_HOME_TO_BACK; 1293 } 1294 } 1295 } 1296 1297 final int startActivityUncheckedLocked(ActivityRecord r, 1298 ActivityRecord sourceRecord, int startFlags, boolean doResume, 1299 Bundle options) { 1300 final Intent intent = r.intent; 1301 final int callingUid = r.launchedFromUid; 1302 1303 int launchFlags = intent.getFlags(); 1304 1305 // We'll invoke onUserLeaving before onPause only if the launching 1306 // activity did not explicitly state that this is an automated launch. 1307 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1308 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1309 1310 // If the caller has asked not to resume at this point, we make note 1311 // of this in the record so that we can skip it when trying to find 1312 // the top running activity. 1313 if (!doResume) { 1314 r.delayedResume = true; 1315 } 1316 1317 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1318 1319 // If the onlyIfNeeded flag is set, then we can do this if the activity 1320 // being launched is the same as the one making the call... or, as 1321 // a special case, if we do not know the caller then we count the 1322 // current top activity as the caller. 1323 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1324 ActivityRecord checkedCaller = sourceRecord; 1325 if (checkedCaller == null) { 1326 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1327 } 1328 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1329 // Caller is not the same as launcher, so always needed. 1330 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1331 } 1332 } 1333 1334 if (sourceRecord == null) { 1335 // This activity is not being started from another... in this 1336 // case we -always- start a new task. 1337 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1338 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1339 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1340 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1341 } 1342 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1343 // The original activity who is starting us is running as a single 1344 // instance... this new activity it is starting must go on its 1345 // own task. 1346 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1347 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1348 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1349 // The activity being started is a single instance... it always 1350 // gets launched into its own task. 1351 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1352 } 1353 1354 final ActivityStack sourceStack; 1355 TaskRecord sourceTask; 1356 if (sourceRecord != null) { 1357 sourceTask = sourceRecord.task; 1358 sourceStack = sourceTask.stack; 1359 } else { 1360 sourceTask = null; 1361 sourceStack = null; 1362 } 1363 1364 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1365 // For whatever reason this activity is being launched into a new 1366 // task... yet the caller has requested a result back. Well, that 1367 // is pretty messed up, so instead immediately send back a cancel 1368 // and let the new task continue launched as normal without a 1369 // dependency on its originator. 1370 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1371 r.resultTo.task.stack.sendActivityResultLocked(-1, 1372 r.resultTo, r.resultWho, r.requestCode, 1373 Activity.RESULT_CANCELED, null); 1374 r.resultTo = null; 1375 } 1376 1377 boolean addingToTask = false; 1378 boolean movedHome = false; 1379 TaskRecord reuseTask = null; 1380 ActivityStack targetStack; 1381 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1382 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1383 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1384 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1385 // If bring to front is requested, and no result is requested, and 1386 // we can find a task that was started with this same 1387 // component, then instead of launching bring that one to the front. 1388 if (r.resultTo == null) { 1389 // See if there is a task to bring to the front. If this is 1390 // a SINGLE_INSTANCE activity, there can be one and only one 1391 // instance of it in the history, and it is always in its own 1392 // unique task, so we do a special search. 1393 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1394 ? findTaskLocked(r) 1395 : findActivityLocked(intent, r.info); 1396 if (intentActivity != null) { 1397 if (r.task == null) { 1398 r.task = intentActivity.task; 1399 } 1400 targetStack = intentActivity.task.stack; 1401 moveHomeStack(targetStack.isHomeStack()); 1402 if (intentActivity.task.intent == null) { 1403 // This task was started because of movement of 1404 // the activity based on affinity... now that we 1405 // are actually launching it, we can assign the 1406 // base intent. 1407 intentActivity.task.setIntent(intent, r.info); 1408 } 1409 // If the target task is not in the front, then we need 1410 // to bring it to the front... except... well, with 1411 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1412 // to have the same behavior as if a new instance was 1413 // being started, which means not bringing it to the front 1414 // if the caller is not itself in the front. 1415 final ActivityStack lastStack = getLastStack(); 1416 ActivityRecord curTop = lastStack == null? 1417 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1418 if (curTop != null && curTop.task != intentActivity.task) { 1419 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1420 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) { 1421 // We really do want to push this one into the 1422 // user's face, right now. 1423 movedHome = true; 1424 if ((launchFlags & 1425 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1426 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1427 // Caller wants to appear on home activity, so before starting 1428 // their own activity we will bring home to the front. 1429 r.mLaunchHomeTaskNext = true; 1430 } 1431 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1432 options = null; 1433 } 1434 } 1435 // If the caller has requested that the target task be 1436 // reset, then do so. 1437 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1438 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1439 } 1440 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1441 // We don't need to start a new activity, and 1442 // the client said not to do anything if that 1443 // is the case, so this is it! And for paranoia, make 1444 // sure we have correctly resumed the top activity. 1445 if (doResume) { 1446 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1447 resumeTopActivitiesLocked(targetStack, null, options); 1448 } else { 1449 ActivityOptions.abort(options); 1450 } 1451 if (r.task == null) Slog.v(TAG, 1452 "startActivityUncheckedLocked: task left null", 1453 new RuntimeException("here").fillInStackTrace()); 1454 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1455 } 1456 if ((launchFlags & 1457 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1458 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1459 // The caller has requested to completely replace any 1460 // existing task with its new activity. Well that should 1461 // not be too hard... 1462 reuseTask = intentActivity.task; 1463 reuseTask.performClearTaskLocked(); 1464 reuseTask.setIntent(r.intent, r.info); 1465 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1466 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1467 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1468 // In this situation we want to remove all activities 1469 // from the task up to the one being started. In most 1470 // cases this means we are resetting the task to its 1471 // initial state. 1472 ActivityRecord top = 1473 intentActivity.task.performClearTaskLocked(r, launchFlags); 1474 if (top != null) { 1475 if (top.frontOfTask) { 1476 // Activity aliases may mean we use different 1477 // intents for the top activity, so make sure 1478 // the task now has the identity of the new 1479 // intent. 1480 top.task.setIntent(r.intent, r.info); 1481 } 1482 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1483 r, top.task); 1484 top.deliverNewIntentLocked(callingUid, r.intent); 1485 } else { 1486 // A special case: we need to 1487 // start the activity because it is not currently 1488 // running, and the caller has asked to clear the 1489 // current task to have this activity at the top. 1490 addingToTask = true; 1491 // Now pretend like this activity is being started 1492 // by the top of its task, so it is put in the 1493 // right place. 1494 sourceRecord = intentActivity; 1495 } 1496 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1497 // In this case the top activity on the task is the 1498 // same as the one being launched, so we take that 1499 // as a request to bring the task to the foreground. 1500 // If the top activity in the task is the root 1501 // activity, deliver this new intent to it if it 1502 // desires. 1503 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1504 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1505 && intentActivity.realActivity.equals(r.realActivity)) { 1506 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1507 intentActivity.task); 1508 if (intentActivity.frontOfTask) { 1509 intentActivity.task.setIntent(r.intent, r.info); 1510 } 1511 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1512 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1513 // In this case we are launching the root activity 1514 // of the task, but with a different intent. We 1515 // should start a new instance on top. 1516 addingToTask = true; 1517 sourceRecord = intentActivity; 1518 } 1519 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1520 // In this case an activity is being launched in to an 1521 // existing task, without resetting that task. This 1522 // is typically the situation of launching an activity 1523 // from a notification or shortcut. We want to place 1524 // the new activity on top of the current task. 1525 addingToTask = true; 1526 sourceRecord = intentActivity; 1527 } else if (!intentActivity.task.rootWasReset) { 1528 // In this case we are launching in to an existing task 1529 // that has not yet been started from its front door. 1530 // The current task has been brought to the front. 1531 // Ideally, we'd probably like to place this new task 1532 // at the bottom of its stack, but that's a little hard 1533 // to do with the current organization of the code so 1534 // for now we'll just drop it. 1535 intentActivity.task.setIntent(r.intent, r.info); 1536 } 1537 if (!addingToTask && reuseTask == null) { 1538 // We didn't do anything... but it was needed (a.k.a., client 1539 // don't use that intent!) And for paranoia, make 1540 // sure we have correctly resumed the top activity. 1541 if (doResume) { 1542 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack); 1543 targetStack.resumeTopActivityLocked(null, options); 1544 } else { 1545 ActivityOptions.abort(options); 1546 } 1547 if (r.task == null) Slog.v(TAG, 1548 "startActivityUncheckedLocked: task left null", 1549 new RuntimeException("here").fillInStackTrace()); 1550 return ActivityManager.START_TASK_TO_FRONT; 1551 } 1552 } 1553 } 1554 } 1555 1556 //String uri = r.intent.toURI(); 1557 //Intent intent2 = new Intent(uri); 1558 //Slog.i(TAG, "Given intent: " + r.intent); 1559 //Slog.i(TAG, "URI is: " + uri); 1560 //Slog.i(TAG, "To intent: " + intent2); 1561 1562 if (r.packageName != null) { 1563 // If the activity being launched is the same as the one currently 1564 // at the top, then we need to check if it should only be launched 1565 // once. 1566 ActivityStack topStack = getFocusedStack(); 1567 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1568 if (top != null && r.resultTo == null) { 1569 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1570 if (top.app != null && top.app.thread != null) { 1571 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1572 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1573 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1574 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1575 top.task); 1576 // For paranoia, make sure we have correctly 1577 // resumed the top activity. 1578 if (doResume) { 1579 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack); 1580 resumeTopActivitiesLocked(); 1581 } 1582 ActivityOptions.abort(options); 1583 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1584 // We don't need to start a new activity, and 1585 // the client said not to do anything if that 1586 // is the case, so this is it! 1587 if (r.task == null) Slog.v(TAG, 1588 "startActivityUncheckedLocked: task left null", 1589 new RuntimeException("here").fillInStackTrace()); 1590 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1591 } 1592 top.deliverNewIntentLocked(callingUid, r.intent); 1593 if (r.task == null) Slog.v(TAG, 1594 "startActivityUncheckedLocked: task left null", 1595 new RuntimeException("here").fillInStackTrace()); 1596 return ActivityManager.START_DELIVERED_TO_TOP; 1597 } 1598 } 1599 } 1600 } 1601 1602 } else { 1603 if (r.resultTo != null) { 1604 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1605 r.requestCode, Activity.RESULT_CANCELED, null); 1606 } 1607 ActivityOptions.abort(options); 1608 if (r.task == null) Slog.v(TAG, 1609 "startActivityUncheckedLocked: task left null", 1610 new RuntimeException("here").fillInStackTrace()); 1611 return ActivityManager.START_CLASS_NOT_FOUND; 1612 } 1613 1614 boolean newTask = false; 1615 boolean keepCurTransition = false; 1616 1617 // Should this be considered a new task? 1618 if (r.resultTo == null && !addingToTask 1619 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1620 targetStack = adjustStackFocus(r); 1621 moveHomeStack(targetStack.isHomeStack()); 1622 if (reuseTask == null) { 1623 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1624 null, true); 1625 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1626 r.task); 1627 } else { 1628 r.setTask(reuseTask, reuseTask, true); 1629 } 1630 newTask = true; 1631 if (!movedHome) { 1632 if ((launchFlags & 1633 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1634 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1635 // Caller wants to appear on home activity, so before starting 1636 // their own activity we will bring home to the front. 1637 r.mLaunchHomeTaskNext = true; 1638 } 1639 } 1640 } else if (sourceRecord != null) { 1641 sourceTask = sourceRecord.task; 1642 targetStack = sourceTask.stack; 1643 moveHomeStack(targetStack.isHomeStack()); 1644 if (!addingToTask && 1645 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1646 // In this case, we are adding the activity to an existing 1647 // task, but the caller has asked to clear that task if the 1648 // activity is already running. 1649 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1650 keepCurTransition = true; 1651 if (top != null) { 1652 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1653 top.deliverNewIntentLocked(callingUid, r.intent); 1654 // For paranoia, make sure we have correctly 1655 // resumed the top activity. 1656 if (doResume) { 1657 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1658 targetStack.resumeTopActivityLocked(null); 1659 } 1660 ActivityOptions.abort(options); 1661 if (r.task == null) Slog.v(TAG, 1662 "startActivityUncheckedLocked: task left null", 1663 new RuntimeException("here").fillInStackTrace()); 1664 return ActivityManager.START_DELIVERED_TO_TOP; 1665 } 1666 } else if (!addingToTask && 1667 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1668 // In this case, we are launching an activity in our own task 1669 // that may already be running somewhere in the history, and 1670 // we want to shuffle it to the front of the stack if so. 1671 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1672 if (top != null) { 1673 final TaskRecord task = top.task; 1674 task.moveActivityToFrontLocked(top); 1675 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1676 top.updateOptionsLocked(options); 1677 top.deliverNewIntentLocked(callingUid, r.intent); 1678 if (doResume) { 1679 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1680 targetStack.resumeTopActivityLocked(null); 1681 } 1682 if (r.task == null) Slog.v(TAG, 1683 "startActivityUncheckedLocked: task left null", 1684 new RuntimeException("here").fillInStackTrace()); 1685 return ActivityManager.START_DELIVERED_TO_TOP; 1686 } 1687 } 1688 // An existing activity is starting this new activity, so we want 1689 // to keep the new one in the same task as the one that is starting 1690 // it. 1691 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1692 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1693 + " in existing task " + r.task); 1694 1695 } else { 1696 // This not being started from an existing activity, and not part 1697 // of a new task... just put it in the top task, though these days 1698 // this case should never happen. 1699 targetStack = adjustStackFocus(r); 1700 moveHomeStack(targetStack.isHomeStack()); 1701 ActivityRecord prev = targetStack.topActivity(); 1702 r.setTask(prev != null ? prev.task 1703 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1704 null, true); 1705 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1706 + " in new guessed " + r.task); 1707 } 1708 1709 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1710 intent, r.getUriPermissionsLocked()); 1711 1712 if (newTask) { 1713 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1714 } 1715 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1716 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack); 1717 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1718 mService.setFocusedActivityLocked(r); 1719 return ActivityManager.START_SUCCESS; 1720 } 1721 1722 void acquireLaunchWakelock() { 1723 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1724 throw new IllegalStateException("Calling must be system uid"); 1725 } 1726 mLaunchingActivity.acquire(); 1727 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1728 // To be safe, don't allow the wake lock to be held for too long. 1729 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1730 } 1731 } 1732 1733 // Checked. 1734 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1735 Configuration config) { 1736 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1737 1738 ArrayList<ActivityRecord> stops = null; 1739 ArrayList<ActivityRecord> finishes = null; 1740 ArrayList<UserStartedState> startingUsers = null; 1741 int NS = 0; 1742 int NF = 0; 1743 IApplicationThread sendThumbnail = null; 1744 boolean booting = false; 1745 boolean enableScreen = false; 1746 boolean activityRemoved = false; 1747 1748 ActivityRecord r = ActivityRecord.forToken(token); 1749 if (r != null) { 1750 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1751 Debug.getCallers(4)); 1752 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1753 r.finishLaunchTickingLocked(); 1754 if (fromTimeout) { 1755 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1756 } 1757 1758 // This is a hack to semi-deal with a race condition 1759 // in the client where it can be constructed with a 1760 // newer configuration from when we asked it to launch. 1761 // We'll update with whatever configuration it now says 1762 // it used to launch. 1763 if (config != null) { 1764 r.configuration = config; 1765 } 1766 1767 // We are now idle. If someone is waiting for a thumbnail from 1768 // us, we can now deliver. 1769 r.idle = true; 1770 1771 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 1772 sendThumbnail = r.app.thread; 1773 r.thumbnailNeeded = false; 1774 } 1775 1776 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1777 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1778 mService.mBooted = true; 1779 enableScreen = true; 1780 } 1781 } 1782 1783 if (allResumedActivitiesIdle()) { 1784 if (r != null) { 1785 mService.scheduleAppGcsLocked(); 1786 } 1787 1788 if (mLaunchingActivity.isHeld()) { 1789 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1790 if (VALIDATE_WAKE_LOCK_CALLER && 1791 Binder.getCallingUid() != Process.myUid()) { 1792 throw new IllegalStateException("Calling must be system uid"); 1793 } 1794 mLaunchingActivity.release(); 1795 } 1796 ensureActivitiesVisibleLocked(null, 0); 1797 } 1798 1799 // Atomically retrieve all of the other things to do. 1800 stops = processStoppingActivitiesLocked(true); 1801 NS = stops != null ? stops.size() : 0; 1802 if ((NF=mFinishingActivities.size()) > 0) { 1803 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1804 mFinishingActivities.clear(); 1805 } 1806 1807 final ArrayList<ActivityRecord> thumbnails; 1808 final int NT = mCancelledThumbnails.size(); 1809 if (NT > 0) { 1810 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); 1811 mCancelledThumbnails.clear(); 1812 } else { 1813 thumbnails = null; 1814 } 1815 1816 if (isFrontStack(mHomeStack)) { 1817 booting = mService.mBooting; 1818 mService.mBooting = false; 1819 } 1820 1821 if (mStartingUsers.size() > 0) { 1822 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1823 mStartingUsers.clear(); 1824 } 1825 1826 // Perform the following actions from unsynchronized state. 1827 final IApplicationThread thumbnailThread = sendThumbnail; 1828 mHandler.post(new Runnable() { 1829 @Override 1830 public void run() { 1831 if (thumbnailThread != null) { 1832 try { 1833 thumbnailThread.requestThumbnail(token); 1834 } catch (Exception e) { 1835 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 1836 mService.sendPendingThumbnail(null, token, null, null, true); 1837 } 1838 } 1839 1840 // Report back to any thumbnail receivers. 1841 for (int i = 0; i < NT; i++) { 1842 ActivityRecord r = thumbnails.get(i); 1843 mService.sendPendingThumbnail(r, null, null, null, true); 1844 } 1845 } 1846 }); 1847 1848 // Stop any activities that are scheduled to do so but have been 1849 // waiting for the next one to start. 1850 for (int i = 0; i < NS; i++) { 1851 r = stops.get(i); 1852 final ActivityStack stack = r.task.stack; 1853 if (r.finishing) { 1854 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1855 } else { 1856 stack.stopActivityLocked(r); 1857 } 1858 } 1859 1860 // Finish any activities that are scheduled to do so but have been 1861 // waiting for the next one to start. 1862 for (int i = 0; i < NF; i++) { 1863 r = finishes.get(i); 1864 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1865 } 1866 1867 if (booting) { 1868 mService.finishBooting(); 1869 } else if (startingUsers != null) { 1870 for (int i = 0; i < startingUsers.size(); i++) { 1871 mService.finishUserSwitch(startingUsers.get(i)); 1872 } 1873 } 1874 1875 mService.trimApplications(); 1876 //dump(); 1877 //mWindowManager.dump(); 1878 1879 if (enableScreen) { 1880 mService.enableScreenAfterBoot(); 1881 } 1882 1883 if (activityRemoved) { 1884 resumeTopActivitiesLocked(); 1885 } 1886 1887 return r; 1888 } 1889 1890 void handleAppDiedLocked(ProcessRecord app, boolean restarting) { 1891 // Just in case. 1892 final int numStacks = mStacks.size(); 1893 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1894 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting); 1895 } 1896 } 1897 1898 void closeSystemDialogsLocked() { 1899 final int numStacks = mStacks.size(); 1900 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1901 final ActivityStack stack = mStacks.get(stackNdx); 1902 stack.closeSystemDialogsLocked(); 1903 } 1904 } 1905 1906 /** 1907 * @return true if some activity was finished (or would have finished if doit were true). 1908 */ 1909 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 1910 boolean didSomething = false; 1911 final int numStacks = mStacks.size(); 1912 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1913 final ActivityStack stack = mStacks.get(stackNdx); 1914 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 1915 didSomething = true; 1916 } 1917 } 1918 return didSomething; 1919 } 1920 1921 void updatePreviousProcessLocked(ActivityRecord r) { 1922 // Now that this process has stopped, we may want to consider 1923 // it to be the previous app to try to keep around in case 1924 // the user wants to return to it. 1925 1926 // First, found out what is currently the foreground app, so that 1927 // we don't blow away the previous app if this activity is being 1928 // hosted by the process that is actually still the foreground. 1929 ProcessRecord fgApp = null; 1930 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1931 final ActivityStack stack = mStacks.get(stackNdx); 1932 if (isFrontStack(stack)) { 1933 if (stack.mResumedActivity != null) { 1934 fgApp = stack.mResumedActivity.app; 1935 } else if (stack.mPausingActivity != null) { 1936 fgApp = stack.mPausingActivity.app; 1937 } 1938 break; 1939 } 1940 } 1941 1942 // Now set this one as the previous process, only if that really 1943 // makes sense to. 1944 if (r.app != null && fgApp != null && r.app != fgApp 1945 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 1946 && r.app != mService.mHomeProcess) { 1947 mService.mPreviousProcess = r.app; 1948 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 1949 } 1950 } 1951 1952 boolean resumeTopActivitiesLocked() { 1953 return resumeTopActivitiesLocked(null, null, null); 1954 } 1955 1956 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 1957 Bundle targetOptions) { 1958 if (targetStack == null) { 1959 targetStack = getFocusedStack(); 1960 } 1961 boolean result = false; 1962 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1963 final ActivityStack stack = mStacks.get(stackNdx); 1964 if (isFrontStack(stack)) { 1965 if (stack == targetStack) { 1966 result = stack.resumeTopActivityLocked(target, targetOptions); 1967 } else { 1968 stack.resumeTopActivityLocked(null); 1969 } 1970 } 1971 } 1972 return result; 1973 } 1974 1975 void finishTopRunningActivityLocked(ProcessRecord app) { 1976 final int numStacks = mStacks.size(); 1977 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1978 final ActivityStack stack = mStacks.get(stackNdx); 1979 stack.finishTopRunningActivityLocked(app); 1980 } 1981 } 1982 1983 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 1984 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1985 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 1986 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + 1987 mStacks.get(stackNdx)); 1988 return; 1989 } 1990 } 1991 } 1992 1993 ActivityStack getStack(int stackId) { 1994 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1995 final ActivityStack stack = mStacks.get(stackNdx); 1996 if (stack.getStackId() == stackId) { 1997 return stack; 1998 } 1999 } 2000 return null; 2001 } 2002 2003 ArrayList<ActivityStack> getStacks() { 2004 return new ArrayList<ActivityStack>(mStacks); 2005 } 2006 2007 int createStack() { 2008 while (true) { 2009 if (++mLastStackId <= HOME_STACK_ID) { 2010 mLastStackId = HOME_STACK_ID + 1; 2011 } 2012 if (getStack(mLastStackId) == null) { 2013 break; 2014 } 2015 } 2016 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); 2017 return mLastStackId; 2018 } 2019 2020 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2021 final TaskRecord task = anyTaskForIdLocked(taskId); 2022 if (task == null) { 2023 return; 2024 } 2025 final ActivityStack stack = getStack(stackId); 2026 if (stack == null) { 2027 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2028 return; 2029 } 2030 removeTask(task); 2031 stack.addTask(task, toTop); 2032 mWindowManager.addTask(taskId, stackId, toTop); 2033 resumeTopActivitiesLocked(); 2034 } 2035 2036 ActivityRecord findTaskLocked(ActivityRecord r) { 2037 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2038 final ActivityStack stack = mStacks.get(stackNdx); 2039 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2040 continue; 2041 } 2042 final ActivityRecord ar = stack.findTaskLocked(r); 2043 if (ar != null) { 2044 return ar; 2045 } 2046 } 2047 return null; 2048 } 2049 2050 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2051 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2052 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info); 2053 if (ar != null) { 2054 return ar; 2055 } 2056 } 2057 return null; 2058 } 2059 2060 void goingToSleepLocked() { 2061 scheduleSleepTimeout(); 2062 if (!mGoingToSleep.isHeld()) { 2063 mGoingToSleep.acquire(); 2064 if (mLaunchingActivity.isHeld()) { 2065 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2066 throw new IllegalStateException("Calling must be system uid"); 2067 } 2068 mLaunchingActivity.release(); 2069 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2070 } 2071 } 2072 } 2073 2074 boolean shutdownLocked(int timeout) { 2075 boolean timedout = false; 2076 goingToSleepLocked(); 2077 checkReadyForSleepLocked(); 2078 2079 final long endTime = System.currentTimeMillis() + timeout; 2080 while (true) { 2081 boolean cantShutdown = false; 2082 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2083 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked(); 2084 } 2085 if (cantShutdown) { 2086 long timeRemaining = endTime - System.currentTimeMillis(); 2087 if (timeRemaining > 0) { 2088 try { 2089 mService.wait(timeRemaining); 2090 } catch (InterruptedException e) { 2091 } 2092 } else { 2093 Slog.w(TAG, "Activity manager shutdown timed out"); 2094 timedout = true; 2095 break; 2096 } 2097 } else { 2098 break; 2099 } 2100 } 2101 2102 // Force checkReadyForSleep to complete. 2103 mSleepTimeout = true; 2104 checkReadyForSleepLocked(); 2105 2106 return timedout; 2107 } 2108 2109 void comeOutOfSleepIfNeededLocked() { 2110 removeSleepTimeouts(); 2111 if (mGoingToSleep.isHeld()) { 2112 mGoingToSleep.release(); 2113 } 2114 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2115 final ActivityStack stack = mStacks.get(stackNdx); 2116 stack.awakeFromSleepingLocked(); 2117 if (isFrontStack(stack)) { 2118 resumeTopActivitiesLocked(); 2119 } 2120 } 2121 mGoingToSleepActivities.clear(); 2122 } 2123 2124 void activitySleptLocked(ActivityRecord r) { 2125 mGoingToSleepActivities.remove(r); 2126 checkReadyForSleepLocked(); 2127 } 2128 2129 void checkReadyForSleepLocked() { 2130 if (!mService.isSleepingOrShuttingDown()) { 2131 // Do not care. 2132 return; 2133 } 2134 2135 if (!mSleepTimeout) { 2136 boolean dontSleep = false; 2137 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2138 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked(); 2139 } 2140 2141 if (mStoppingActivities.size() > 0) { 2142 // Still need to tell some activities to stop; can't sleep yet. 2143 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2144 + mStoppingActivities.size() + " activities"); 2145 scheduleIdleLocked(); 2146 dontSleep = true; 2147 } 2148 2149 if (mGoingToSleepActivities.size() > 0) { 2150 // Still need to tell some activities to sleep; can't sleep yet. 2151 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2152 + mGoingToSleepActivities.size() + " activities"); 2153 dontSleep = true; 2154 } 2155 2156 if (dontSleep) { 2157 return; 2158 } 2159 } 2160 2161 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2162 mStacks.get(stackNdx).goToSleep(); 2163 } 2164 2165 removeSleepTimeouts(); 2166 2167 if (mGoingToSleep.isHeld()) { 2168 mGoingToSleep.release(); 2169 } 2170 if (mService.mShuttingDown) { 2171 mService.notifyAll(); 2172 } 2173 } 2174 2175 boolean reportResumedActivityLocked(ActivityRecord r) { 2176 final ActivityStack stack = r.task.stack; 2177 if (isFrontStack(stack)) { 2178 mService.updateUsageStats(r, true); 2179 } 2180 if (allResumedActivitiesComplete()) { 2181 ensureActivitiesVisibleLocked(null, 0); 2182 mWindowManager.executeAppTransition(); 2183 return true; 2184 } 2185 return false; 2186 } 2187 2188 void handleAppCrashLocked(ProcessRecord app) { 2189 final int numStacks = mStacks.size(); 2190 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2191 final ActivityStack stack = mStacks.get(stackNdx); 2192 stack.handleAppCrashLocked(app); 2193 } 2194 } 2195 2196 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2197 // First the front stacks. In case any are not fullscreen and are in front of home. 2198 boolean showHomeBehindStack = false; 2199 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2200 final ActivityStack stack = mStacks.get(stackNdx); 2201 if (isFrontStack(stack)) { 2202 showHomeBehindStack = 2203 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2204 } 2205 } 2206 // Now do back stacks. 2207 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2208 final ActivityStack stack = mStacks.get(stackNdx); 2209 if (!isFrontStack(stack)) { 2210 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack); 2211 } 2212 } 2213 } 2214 2215 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2216 final int numStacks = mStacks.size(); 2217 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2218 final ActivityStack stack = mStacks.get(stackNdx); 2219 stack.scheduleDestroyActivities(app, false, reason); 2220 } 2221 } 2222 2223 boolean switchUserLocked(int userId, UserStartedState uss) { 2224 mCurrentUser = userId; 2225 2226 final String homePackageName = mService.getHomePackageName(); 2227 if (homePackageName != null) { 2228 setHomePackageName(mCurrentUser, homePackageName); 2229 } 2230 2231 mStartingUsers.add(uss); 2232 boolean haveActivities = false; 2233 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2234 haveActivities |= mStacks.get(stackNdx).switchUserLocked(userId); 2235 } 2236 2237 resumeTopActivitiesLocked(); 2238 2239 return haveActivities; 2240 } 2241 2242 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2243 int N = mStoppingActivities.size(); 2244 if (N <= 0) return null; 2245 2246 ArrayList<ActivityRecord> stops = null; 2247 2248 final boolean nowVisible = allResumedActivitiesVisible(); 2249 for (int i=0; i<N; i++) { 2250 ActivityRecord s = mStoppingActivities.get(i); 2251 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2252 + nowVisible + " waitingVisible=" + s.waitingVisible 2253 + " finishing=" + s.finishing); 2254 if (s.waitingVisible && nowVisible) { 2255 mWaitingVisibleActivities.remove(s); 2256 s.waitingVisible = false; 2257 if (s.finishing) { 2258 // If this activity is finishing, it is sitting on top of 2259 // everyone else but we now know it is no longer needed... 2260 // so get rid of it. Otherwise, we need to go through the 2261 // normal flow and hide it once we determine that it is 2262 // hidden by the activities in front of it. 2263 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2264 mWindowManager.setAppVisibility(s.appToken, false); 2265 } 2266 } 2267 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2268 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2269 if (stops == null) { 2270 stops = new ArrayList<ActivityRecord>(); 2271 } 2272 stops.add(s); 2273 mStoppingActivities.remove(i); 2274 N--; 2275 i--; 2276 } 2277 } 2278 2279 return stops; 2280 } 2281 2282 void validateTopActivitiesLocked() { 2283 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2284 final ActivityStack stack = mStacks.get(stackNdx); 2285 final ActivityRecord r = stack.topRunningActivityLocked(null); 2286 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2287 if (isFrontStack(stack)) { 2288 if (r == null) { 2289 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2290 } else { 2291 final ActivityRecord pausing = stack.mPausingActivity; 2292 if (pausing != null && pausing == r) { 2293 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2294 " state=" + state); 2295 } 2296 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2297 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2298 " state=" + state); 2299 } 2300 } 2301 } else { 2302 final ActivityRecord resumed = stack.mResumedActivity; 2303 if (resumed != null && resumed == r) { 2304 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2305 " state=" + state); 2306 } 2307 if (r != null && (state == ActivityState.INITIALIZING 2308 || state == ActivityState.RESUMED)) { 2309 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2310 " state=" + state); 2311 } 2312 } 2313 } 2314 } 2315 2316 private static String stackStateToString(int stackState) { 2317 switch (stackState) { 2318 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT"; 2319 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK"; 2320 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK"; 2321 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT"; 2322 default: return "Unknown stackState=" + stackState; 2323 } 2324 } 2325 2326 public void dump(PrintWriter pw, String prefix) { 2327 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:"); 2328 pw.println(mDismissKeyguardOnNextActivity); 2329 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState)); 2330 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout); 2331 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId); 2332 pw.print(prefix); pw.print("mHomePackageNames:"); 2333 for (int i = 0; i < mHomePackageNames.size(); ++i) { 2334 pw.print(" ("); pw.print(mHomePackageNames.keyAt(i)); pw.print(","); 2335 pw.print(mHomePackageNames.valueAt(i)); pw.print(")"); 2336 } 2337 pw.println(); 2338 } 2339 2340 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2341 return getFocusedStack().getDumpActivitiesLocked(name); 2342 } 2343 2344 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2345 boolean needSep, String prefix) { 2346 if (activity != null) { 2347 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2348 if (needSep) { 2349 pw.println(); 2350 } 2351 pw.print(prefix); 2352 pw.println(activity); 2353 return true; 2354 } 2355 } 2356 return false; 2357 } 2358 2359 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2360 boolean dumpClient, String dumpPackage) { 2361 boolean printed = false; 2362 boolean needSep = false; 2363 final int numStacks = mStacks.size(); 2364 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2365 final ActivityStack stack = mStacks.get(stackNdx); 2366 StringBuilder stackHeader = new StringBuilder(128); 2367 stackHeader.append(" Stack #"); 2368 stackHeader.append(mStacks.indexOf(stack)); 2369 stackHeader.append(":"); 2370 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep, 2371 stackHeader.toString()); 2372 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, 2373 false, dumpPackage, true, " Running activities (most recent first):", null); 2374 2375 needSep = printed; 2376 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2377 " mPausingActivity: "); 2378 if (pr) { 2379 printed = true; 2380 needSep = false; 2381 } 2382 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2383 " mResumedActivity: "); 2384 if (pr) { 2385 printed = true; 2386 needSep = false; 2387 } 2388 if (dumpAll) { 2389 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2390 " mLastPausedActivity: "); 2391 if (pr) { 2392 printed = true; 2393 } 2394 } 2395 needSep = printed; 2396 } 2397 2398 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2399 false, dumpPackage, true, " Activities waiting to finish:", null); 2400 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2401 false, dumpPackage, true, " Activities waiting to stop:", null); 2402 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2403 false, dumpPackage, true, " Activities waiting for another to become visible:", 2404 null); 2405 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2406 false, dumpPackage, true, " Activities waiting to sleep:", null); 2407 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2408 false, dumpPackage, true, " Activities waiting to sleep:", null); 2409 2410 return printed; 2411 } 2412 2413 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2414 String prefix, String label, boolean complete, boolean brief, boolean client, 2415 String dumpPackage, boolean needNL, String header1, String header2) { 2416 TaskRecord lastTask = null; 2417 String innerPrefix = null; 2418 String[] args = null; 2419 boolean printed = false; 2420 for (int i=list.size()-1; i>=0; i--) { 2421 final ActivityRecord r = list.get(i); 2422 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2423 continue; 2424 } 2425 if (innerPrefix == null) { 2426 innerPrefix = prefix + " "; 2427 args = new String[0]; 2428 } 2429 printed = true; 2430 final boolean full = !brief && (complete || !r.isInHistory()); 2431 if (needNL) { 2432 pw.println(""); 2433 needNL = false; 2434 } 2435 if (header1 != null) { 2436 pw.println(header1); 2437 header1 = null; 2438 } 2439 if (header2 != null) { 2440 pw.println(header2); 2441 header2 = null; 2442 } 2443 if (lastTask != r.task) { 2444 lastTask = r.task; 2445 pw.print(prefix); 2446 pw.print(full ? "* " : " "); 2447 pw.println(lastTask); 2448 if (full) { 2449 lastTask.dump(pw, prefix + " "); 2450 } else if (complete) { 2451 // Complete + brief == give a summary. Isn't that obvious?!? 2452 if (lastTask.intent != null) { 2453 pw.print(prefix); pw.print(" "); 2454 pw.println(lastTask.intent.toInsecureStringWithClip()); 2455 } 2456 } 2457 } 2458 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2459 pw.print(" #"); pw.print(i); pw.print(": "); 2460 pw.println(r); 2461 if (full) { 2462 r.dump(pw, innerPrefix); 2463 } else if (complete) { 2464 // Complete + brief == give a summary. Isn't that obvious?!? 2465 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2466 if (r.app != null) { 2467 pw.print(innerPrefix); pw.println(r.app); 2468 } 2469 } 2470 if (client && r.app != null && r.app.thread != null) { 2471 // flush anything that is already in the PrintWriter since the thread is going 2472 // to write to the file descriptor directly 2473 pw.flush(); 2474 try { 2475 TransferPipe tp = new TransferPipe(); 2476 try { 2477 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2478 r.appToken, innerPrefix, args); 2479 // Short timeout, since blocking here can 2480 // deadlock with the application. 2481 tp.go(fd, 2000); 2482 } finally { 2483 tp.kill(); 2484 } 2485 } catch (IOException e) { 2486 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2487 } catch (RemoteException e) { 2488 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2489 } 2490 needNL = true; 2491 } 2492 } 2493 return printed; 2494 } 2495 2496 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2497 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2498 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2499 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2500 } 2501 2502 final void scheduleIdleLocked() { 2503 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2504 } 2505 2506 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2507 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2508 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2509 } 2510 2511 final void scheduleResumeTopActivities() { 2512 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2513 } 2514 2515 void removeSleepTimeouts() { 2516 mSleepTimeout = false; 2517 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2518 } 2519 2520 final void scheduleSleepTimeout() { 2521 removeSleepTimeouts(); 2522 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2523 } 2524 2525 private final class ActivityStackSupervisorHandler extends Handler { 2526 2527 public ActivityStackSupervisorHandler(Looper looper) { 2528 super(looper); 2529 } 2530 2531 void activityIdleInternal(ActivityRecord r) { 2532 synchronized (mService) { 2533 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2534 } 2535 } 2536 2537 @Override 2538 public void handleMessage(Message msg) { 2539 switch (msg.what) { 2540 case IDLE_TIMEOUT_MSG: { 2541 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2542 if (mService.mDidDexOpt) { 2543 mService.mDidDexOpt = false; 2544 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2545 nmsg.obj = msg.obj; 2546 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2547 return; 2548 } 2549 // We don't at this point know if the activity is fullscreen, 2550 // so we need to be conservative and assume it isn't. 2551 activityIdleInternal((ActivityRecord)msg.obj); 2552 } break; 2553 case IDLE_NOW_MSG: { 2554 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2555 activityIdleInternal((ActivityRecord)msg.obj); 2556 } break; 2557 case RESUME_TOP_ACTIVITY_MSG: { 2558 synchronized (mService) { 2559 resumeTopActivitiesLocked(); 2560 } 2561 } break; 2562 case SLEEP_TIMEOUT_MSG: { 2563 synchronized (mService) { 2564 if (mService.isSleepingOrShuttingDown()) { 2565 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2566 mSleepTimeout = true; 2567 checkReadyForSleepLocked(); 2568 } 2569 } 2570 } break; 2571 case LAUNCH_TIMEOUT_MSG: { 2572 if (mService.mDidDexOpt) { 2573 mService.mDidDexOpt = false; 2574 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2575 return; 2576 } 2577 synchronized (mService) { 2578 if (mLaunchingActivity.isHeld()) { 2579 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2580 if (VALIDATE_WAKE_LOCK_CALLER 2581 && Binder.getCallingUid() != Process.myUid()) { 2582 throw new IllegalStateException("Calling must be system uid"); 2583 } 2584 mLaunchingActivity.release(); 2585 } 2586 } 2587 } break; 2588 } 2589 } 2590 } 2591 2592 String getHomePackageName() { 2593 return mHomePackageNames.get(mCurrentUser); 2594 } 2595 2596 void setHomePackageName(int userId, String homePackageName) { 2597 if (DEBUG_SWITCH) Slog.d(TAG, "setHomePackageName: user=" + userId + " package=" 2598 + homePackageName); 2599 mHomePackageNames.put(userId, homePackageName); 2600 } 2601} 2602