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