1 /* 2 * Copyright (C) 2006-2008 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 17 package com.android.server.am; 18 19 import com.android.internal.os.BatteryStatsImpl; 20 import com.android.server.AttributeCache; 21 import com.android.server.IntentResolver; 22 import com.android.server.ProcessMap; 23 import com.android.server.ProcessStats; 24 import com.android.server.SystemServer; 25 import com.android.server.Watchdog; 26 import com.android.server.WindowManagerService; 27 28 import android.app.Activity; 29 import android.app.ActivityManager; 30 import android.app.ActivityManagerNative; 31 import android.app.ActivityThread; 32 import android.app.AlertDialog; 33 import android.app.ApplicationErrorReport; 34 import android.app.Dialog; 35 import android.app.IActivityController; 36 import android.app.IActivityWatcher; 37 import android.app.IApplicationThread; 38 import android.app.IInstrumentationWatcher; 39 import android.app.IServiceConnection; 40 import android.app.IThumbnailReceiver; 41 import android.app.Instrumentation; 42 import android.app.Notification; 43 import android.app.PendingIntent; 44 import android.app.ResultInfo; 45 import android.app.Service; 46 import android.backup.IBackupManager; 47 import android.content.ActivityNotFoundException; 48 import android.content.ComponentName; 49 import android.content.ContentResolver; 50 import android.content.Context; 51 import android.content.Intent; 52 import android.content.IntentFilter; 53 import android.content.IIntentReceiver; 54 import android.content.IIntentSender; 55 import android.content.IntentSender; 56 import android.content.pm.ActivityInfo; 57 import android.content.pm.ApplicationInfo; 58 import android.content.pm.ConfigurationInfo; 59 import android.content.pm.IPackageDataObserver; 60 import android.content.pm.IPackageManager; 61 import android.content.pm.InstrumentationInfo; 62 import android.content.pm.PackageManager; 63 import android.content.pm.PathPermission; 64 import android.content.pm.ProviderInfo; 65 import android.content.pm.ResolveInfo; 66 import android.content.pm.ServiceInfo; 67 import android.content.res.Configuration; 68 import android.graphics.Bitmap; 69 import android.net.Uri; 70 import android.os.Binder; 71 import android.os.Bundle; 72 import android.os.Debug; 73 import android.os.Environment; 74 import android.os.FileUtils; 75 import android.os.Handler; 76 import android.os.IBinder; 77 import android.os.IPermissionController; 78 import android.os.Looper; 79 import android.os.Message; 80 import android.os.Parcel; 81 import android.os.ParcelFileDescriptor; 82 import android.os.PowerManager; 83 import android.os.Process; 84 import android.os.RemoteCallbackList; 85 import android.os.RemoteException; 86 import android.os.ServiceManager; 87 import android.os.SystemClock; 88 import android.os.SystemProperties; 89 import android.provider.Checkin; 90 import android.provider.Settings; 91 import android.server.data.CrashData; 92 import android.server.data.StackTraceElementData; 93 import android.server.data.ThrowableData; 94 import android.text.TextUtils; 95 import android.util.Config; 96 import android.util.EventLog; 97 import android.util.Log; 98 import android.util.PrintWriterPrinter; 99 import android.util.SparseArray; 100 import android.view.Gravity; 101 import android.view.LayoutInflater; 102 import android.view.View; 103 import android.view.WindowManager; 104 import android.view.WindowManagerPolicy; 105 106 import dalvik.system.Zygote; 107 108 import java.io.ByteArrayInputStream; 109 import java.io.DataInputStream; 110 import java.io.File; 111 import java.io.FileDescriptor; 112 import java.io.FileInputStream; 113 import java.io.FileNotFoundException; 114 import java.io.IOException; 115 import java.io.PrintWriter; 116 import java.lang.IllegalStateException; 117 import java.lang.ref.WeakReference; 118 import java.util.ArrayList; 119 import java.util.HashMap; 120 import java.util.HashSet; 121 import java.util.Iterator; 122 import java.util.List; 123 import java.util.Locale; 124 import java.util.Map; 125 126 public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { 127 static final String TAG = "ActivityManager"; 128 static final boolean DEBUG = false; 129 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 130 static final boolean DEBUG_SWITCH = localLOGV || false; 131 static final boolean DEBUG_TASKS = localLOGV || false; 132 static final boolean DEBUG_PAUSE = localLOGV || false; 133 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 134 static final boolean DEBUG_TRANSITION = localLOGV || false; 135 static final boolean DEBUG_BROADCAST = localLOGV || false; 136 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 137 static final boolean DEBUG_SERVICE = localLOGV || false; 138 static final boolean DEBUG_VISBILITY = localLOGV || false; 139 static final boolean DEBUG_PROCESSES = localLOGV || false; 140 static final boolean DEBUG_PROVIDER = localLOGV || false; 141 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 142 static final boolean DEBUG_RESULTS = localLOGV || false; 143 static final boolean DEBUG_BACKUP = localLOGV || false; 144 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 145 static final boolean VALIDATE_TOKENS = false; 146 static final boolean SHOW_ACTIVITY_START_TIME = true; 147 148 // Control over CPU and battery monitoring. 149 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 150 static final boolean MONITOR_CPU_USAGE = true; 151 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 152 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 153 static final boolean MONITOR_THREAD_CPU_USAGE = false; 154 155 // Event log tags 156 static final int LOG_CONFIGURATION_CHANGED = 2719; 157 static final int LOG_CPU = 2721; 158 static final int LOG_AM_FINISH_ACTIVITY = 30001; 159 static final int LOG_TASK_TO_FRONT = 30002; 160 static final int LOG_AM_NEW_INTENT = 30003; 161 static final int LOG_AM_CREATE_TASK = 30004; 162 static final int LOG_AM_CREATE_ACTIVITY = 30005; 163 static final int LOG_AM_RESTART_ACTIVITY = 30006; 164 static final int LOG_AM_RESUME_ACTIVITY = 30007; 165 static final int LOG_ANR = 30008; 166 static final int LOG_ACTIVITY_LAUNCH_TIME = 30009; 167 static final int LOG_AM_PROCESS_BOUND = 30010; 168 static final int LOG_AM_PROCESS_DIED = 30011; 169 static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012; 170 static final int LOG_AM_PAUSE_ACTIVITY = 30013; 171 static final int LOG_AM_PROCESS_START = 30014; 172 static final int LOG_AM_PROCESS_BAD = 30015; 173 static final int LOG_AM_PROCESS_GOOD = 30016; 174 static final int LOG_AM_LOW_MEMORY = 30017; 175 static final int LOG_AM_DESTROY_ACTIVITY = 30018; 176 static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019; 177 static final int LOG_AM_RELAUNCH_ACTIVITY = 30020; 178 static final int LOG_AM_KILL_FOR_MEMORY = 30023; 179 static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024; 180 static final int LOG_AM_BROADCAST_DISCARD_APP = 30025; 181 static final int LOG_AM_CREATE_SERVICE = 30030; 182 static final int LOG_AM_DESTROY_SERVICE = 30031; 183 static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032; 184 static final int LOG_AM_DROP_PROCESS = 30033; 185 static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034; 186 static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035; 187 static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036; 188 static final int LOG_AM_PROCESS_START_TIMEOUT = 30037; 189 190 static final int LOG_BOOT_PROGRESS_AMS_READY = 3040; 191 static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050; 192 193 // The flags that are set for all calls we make to the package manager. 194 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 195 196 private static final String SYSTEM_SECURE = "ro.secure"; 197 198 // This is the maximum number of application processes we would like 199 // to have running. Due to the asynchronous nature of things, we can 200 // temporarily go beyond this limit. 201 static final int MAX_PROCESSES = 2; 202 203 // Set to false to leave processes running indefinitely, relying on 204 // the kernel killing them as resources are required. 205 static final boolean ENFORCE_PROCESS_LIMIT = false; 206 207 // This is the maximum number of activities that we would like to have 208 // running at a given time. 209 static final int MAX_ACTIVITIES = 20; 210 211 // Maximum number of recent tasks that we can remember. 212 static final int MAX_RECENT_TASKS = 20; 213 214 // Amount of time after a call to stopAppSwitches() during which we will 215 // prevent further untrusted switches from happening. 216 static final long APP_SWITCH_DELAY_TIME = 5*1000; 217 218 // How long until we reset a task when the user returns to it. Currently 219 // 30 minutes. 220 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30; 221 222 // Set to true to disable the icon that is shown while a new activity 223 // is being started. 224 static final boolean SHOW_APP_STARTING_ICON = true; 225 226 // How long we wait until giving up on the last activity to pause. This 227 // is short because it directly impacts the responsiveness of starting the 228 // next activity. 229 static final int PAUSE_TIMEOUT = 500; 230 231 /** 232 * How long we can hold the launch wake lock before giving up. 233 */ 234 static final int LAUNCH_TIMEOUT = 10*1000; 235 236 // How long we wait for a launched process to attach to the activity manager 237 // before we decide it's never going to come up for real. 238 static final int PROC_START_TIMEOUT = 10*1000; 239 240 // How long we wait until giving up on the last activity telling us it 241 // is idle. 242 static final int IDLE_TIMEOUT = 10*1000; 243 244 // How long to wait after going idle before forcing apps to GC. 245 static final int GC_TIMEOUT = 5*1000; 246 247 // The minimum amount of time between successive GC requests for a process. 248 static final int GC_MIN_INTERVAL = 60*1000; 249 250 // How long we wait until giving up on an activity telling us it has 251 // finished destroying itself. 252 static final int DESTROY_TIMEOUT = 10*1000; 253 254 // How long we allow a receiver to run before giving up on it. 255 static final int BROADCAST_TIMEOUT = 10*1000; 256 257 // How long we wait for a service to finish executing. 258 static final int SERVICE_TIMEOUT = 20*1000; 259 260 // How long a service needs to be running until restarting its process 261 // is no longer considered to be a relaunch of the service. 262 static final int SERVICE_RESTART_DURATION = 5*1000; 263 264 // How long a service needs to be running until it will start back at 265 // SERVICE_RESTART_DURATION after being killed. 266 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 267 268 // Multiplying factor to increase restart duration time by, for each time 269 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 270 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 271 272 // The minimum amount of time between restarting services that we allow. 273 // That is, when multiple services are restarting, we won't allow each 274 // to restart less than this amount of time from the last one. 275 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 276 277 // Maximum amount of time for there to be no activity on a service before 278 // we consider it non-essential and allow its process to go on the 279 // LRU background list. 280 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 281 282 // How long we wait until we timeout on key dispatching. 283 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 284 285 // The minimum time we allow between crashes, for us to consider this 286 // application to be bad and stop and its services and reject broadcasts. 287 static final int MIN_CRASH_INTERVAL = 60*1000; 288 289 // How long we wait until we timeout on key dispatching during instrumentation. 290 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 291 292 // OOM adjustments for processes in various states: 293 294 // This is a process without anything currently running in it. Definitely 295 // the first to go! Value set in system/rootdir/init.rc on startup. 296 // This value is initalized in the constructor, careful when refering to 297 // this static variable externally. 298 static int EMPTY_APP_ADJ; 299 300 // This is a process with a content provider that does not have any clients 301 // attached to it. If it did have any clients, its adjustment would be the 302 // one for the highest-priority of those processes. 303 static int CONTENT_PROVIDER_ADJ; 304 305 // This is a process only hosting activities that are not visible, 306 // so it can be killed without any disruption. Value set in 307 // system/rootdir/init.rc on startup. 308 final int HIDDEN_APP_MAX_ADJ; 309 static int HIDDEN_APP_MIN_ADJ; 310 311 // This is a process holding the home application -- we want to try 312 // avoiding killing it, even if it would normally be in the background, 313 // because the user interacts with it so much. 314 final int HOME_APP_ADJ; 315 316 // This is a process currently hosting a backup operation. Killing it 317 // is not entirely fatal but is generally a bad idea. 318 final int BACKUP_APP_ADJ; 319 320 // This is a process holding a secondary server -- killing it will not 321 // have much of an impact as far as the user is concerned. Value set in 322 // system/rootdir/init.rc on startup. 323 final int SECONDARY_SERVER_ADJ; 324 325 // This is a process only hosting activities that are visible to the 326 // user, so we'd prefer they don't disappear. Value set in 327 // system/rootdir/init.rc on startup. 328 final int VISIBLE_APP_ADJ; 329 330 // This is the process running the current foreground app. We'd really 331 // rather not kill it! Value set in system/rootdir/init.rc on startup. 332 final int FOREGROUND_APP_ADJ; 333 334 // This is a process running a core server, such as telephony. Definitely 335 // don't want to kill it, but doing so is not completely fatal. 336 static final int CORE_SERVER_ADJ = -12; 337 338 // The system process runs at the default adjustment. 339 static final int SYSTEM_ADJ = -16; 340 341 // Memory pages are 4K. 342 static final int PAGE_SIZE = 4*1024; 343 344 // System property defining error report receiver for system apps 345 static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps"; 346 347 // System property defining default error report receiver 348 static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default"; 349 350 // Corresponding memory levels for above adjustments. 351 final int EMPTY_APP_MEM; 352 final int HIDDEN_APP_MEM; 353 final int HOME_APP_MEM; 354 final int BACKUP_APP_MEM; 355 final int SECONDARY_SERVER_MEM; 356 final int VISIBLE_APP_MEM; 357 final int FOREGROUND_APP_MEM; 358 359 final int MY_PID; 360 361 static final String[] EMPTY_STRING_ARRAY = new String[0]; 362 363 enum ActivityState { 364 INITIALIZING, 365 RESUMED, 366 PAUSING, 367 PAUSED, 368 STOPPING, 369 STOPPED, 370 FINISHING, 371 DESTROYING, 372 DESTROYED 373 } 374 375 /** 376 * The back history of all previous (and possibly still 377 * running) activities. It contains HistoryRecord objects. 378 */ 379 final ArrayList mHistory = new ArrayList(); 380 381 /** 382 * Description of a request to start a new activity, which has been held 383 * due to app switches being disabled. 384 */ 385 class PendingActivityLaunch { 386 HistoryRecord r; 387 HistoryRecord sourceRecord; 388 Uri[] grantedUriPermissions; 389 int grantedMode; 390 boolean onlyIfNeeded; 391 } 392 393 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 394 = new ArrayList<PendingActivityLaunch>(); 395 396 /** 397 * List of all active broadcasts that are to be executed immediately 398 * (without waiting for another broadcast to finish). Currently this only 399 * contains broadcasts to registered receivers, to avoid spinning up 400 * a bunch of processes to execute IntentReceiver components. 401 */ 402 final ArrayList<BroadcastRecord> mParallelBroadcasts 403 = new ArrayList<BroadcastRecord>(); 404 405 /** 406 * List of all active broadcasts that are to be executed one at a time. 407 * The object at the top of the list is the currently activity broadcasts; 408 * those after it are waiting for the top to finish.. 409 */ 410 final ArrayList<BroadcastRecord> mOrderedBroadcasts 411 = new ArrayList<BroadcastRecord>(); 412 413 /** 414 * Historical data of past broadcasts, for debugging. 415 */ 416 static final int MAX_BROADCAST_HISTORY = 100; 417 final BroadcastRecord[] mBroadcastHistory 418 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 419 420 /** 421 * Set when we current have a BROADCAST_INTENT_MSG in flight. 422 */ 423 boolean mBroadcastsScheduled = false; 424 425 /** 426 * Set to indicate whether to issue an onUserLeaving callback when a 427 * newly launched activity is being brought in front of us. 428 */ 429 boolean mUserLeaving = false; 430 431 /** 432 * When we are in the process of pausing an activity, before starting the 433 * next one, this variable holds the activity that is currently being paused. 434 */ 435 HistoryRecord mPausingActivity = null; 436 437 /** 438 * Current activity that is resumed, or null if there is none. 439 */ 440 HistoryRecord mResumedActivity = null; 441 442 /** 443 * Activity we have told the window manager to have key focus. 444 */ 445 HistoryRecord mFocusedActivity = null; 446 447 /** 448 * This is the last activity that we put into the paused state. This is 449 * used to determine if we need to do an activity transition while sleeping, 450 * when we normally hold the top activity paused. 451 */ 452 HistoryRecord mLastPausedActivity = null; 453 454 /** 455 * List of activities that are waiting for a new activity 456 * to become visible before completing whatever operation they are 457 * supposed to do. 458 */ 459 final ArrayList mWaitingVisibleActivities = new ArrayList(); 460 461 /** 462 * List of activities that are ready to be stopped, but waiting 463 * for the next activity to settle down before doing so. It contains 464 * HistoryRecord objects. 465 */ 466 final ArrayList<HistoryRecord> mStoppingActivities 467 = new ArrayList<HistoryRecord>(); 468 469 /** 470 * Animations that for the current transition have requested not to 471 * be considered for the transition animation. 472 */ 473 final ArrayList<HistoryRecord> mNoAnimActivities 474 = new ArrayList<HistoryRecord>(); 475 476 /** 477 * List of intents that were used to start the most recent tasks. 478 */ 479 final ArrayList<TaskRecord> mRecentTasks 480 = new ArrayList<TaskRecord>(); 481 482 /** 483 * List of activities that are ready to be finished, but waiting 484 * for the previous activity to settle down before doing so. It contains 485 * HistoryRecord objects. 486 */ 487 final ArrayList mFinishingActivities = new ArrayList(); 488 489 /** 490 * All of the applications we currently have running organized by name. 491 * The keys are strings of the application package name (as 492 * returned by the package manager), and the keys are ApplicationRecord 493 * objects. 494 */ 495 final ProcessMap<ProcessRecord> mProcessNames 496 = new ProcessMap<ProcessRecord>(); 497 498 /** 499 * The last time that various processes have crashed. 500 */ 501 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 502 503 /** 504 * Set of applications that we consider to be bad, and will reject 505 * incoming broadcasts from (which the user has no control over). 506 * Processes are added to this set when they have crashed twice within 507 * a minimum amount of time; they are removed from it when they are 508 * later restarted (hopefully due to some user action). The value is the 509 * time it was added to the list. 510 */ 511 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 512 513 /** 514 * All of the processes we currently have running organized by pid. 515 * The keys are the pid running the application. 516 * 517 * <p>NOTE: This object is protected by its own lock, NOT the global 518 * activity manager lock! 519 */ 520 final SparseArray<ProcessRecord> mPidsSelfLocked 521 = new SparseArray<ProcessRecord>(); 522 523 /** 524 * All of the processes that have been forced to be foreground. The key 525 * is the pid of the caller who requested it (we hold a death 526 * link on it). 527 */ 528 abstract class ForegroundToken implements IBinder.DeathRecipient { 529 int pid; 530 IBinder token; 531 } 532 final SparseArray<ForegroundToken> mForegroundProcesses 533 = new SparseArray<ForegroundToken>(); 534 535 /** 536 * List of records for processes that someone had tried to start before the 537 * system was ready. We don't start them at that point, but ensure they 538 * are started by the time booting is complete. 539 */ 540 final ArrayList<ProcessRecord> mProcessesOnHold 541 = new ArrayList<ProcessRecord>(); 542 543 /** 544 * List of records for processes that we have started and are waiting 545 * for them to call back. This is really only needed when running in 546 * single processes mode, in which case we do not have a unique pid for 547 * each process. 548 */ 549 final ArrayList<ProcessRecord> mStartingProcesses 550 = new ArrayList<ProcessRecord>(); 551 552 /** 553 * List of persistent applications that are in the process 554 * of being started. 555 */ 556 final ArrayList<ProcessRecord> mPersistentStartingProcesses 557 = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Processes that are being forcibly torn down. 561 */ 562 final ArrayList<ProcessRecord> mRemovedProcesses 563 = new ArrayList<ProcessRecord>(); 564 565 /** 566 * List of running applications, sorted by recent usage. 567 * The first entry in the list is the least recently used. 568 * It contains ApplicationRecord objects. This list does NOT include 569 * any persistent application records (since we never want to exit them). 570 */ 571 final ArrayList<ProcessRecord> mLRUProcesses 572 = new ArrayList<ProcessRecord>(); 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc 578 = new ArrayList<ProcessRecord>(); 579 580 /** 581 * This is the process holding what we currently consider to be 582 * the "home" activity. 583 */ 584 private ProcessRecord mHomeProcess; 585 586 /** 587 * List of running activities, sorted by recent usage. 588 * The first entry in the list is the least recently used. 589 * It contains HistoryRecord objects. 590 */ 591 private final ArrayList mLRUActivities = new ArrayList(); 592 593 /** 594 * Set of PendingResultRecord objects that are currently active. 595 */ 596 final HashSet mPendingResultRecords = new HashSet(); 597 598 /** 599 * Set of IntentSenderRecord objects that are currently active. 600 */ 601 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 602 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 603 604 /** 605 * Intent broadcast that we have tried to start, but are 606 * waiting for its application's process to be created. We only 607 * need one (instead of a list) because we always process broadcasts 608 * one at a time, so no others can be started while waiting for this 609 * one. 610 */ 611 BroadcastRecord mPendingBroadcast = null; 612 613 /** 614 * Keeps track of all IIntentReceivers that have been registered for 615 * broadcasts. Hash keys are the receiver IBinder, hash value is 616 * a ReceiverList. 617 */ 618 final HashMap mRegisteredReceivers = new HashMap(); 619 620 /** 621 * Resolver for broadcast intents to registered receivers. 622 * Holds BroadcastFilter (subclass of IntentFilter). 623 */ 624 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 625 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 626 @Override 627 protected boolean allowFilterResult( 628 BroadcastFilter filter, List<BroadcastFilter> dest) { 629 IBinder target = filter.receiverList.receiver.asBinder(); 630 for (int i=dest.size()-1; i>=0; i--) { 631 if (dest.get(i).receiverList.receiver.asBinder() == target) { 632 return false; 633 } 634 } 635 return true; 636 } 637 }; 638 639 /** 640 * State of all active sticky broadcasts. Keys are the action of the 641 * sticky Intent, values are an ArrayList of all broadcasted intents with 642 * that action (which should usually be one). 643 */ 644 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 645 new HashMap<String, ArrayList<Intent>>(); 646 647 /** 648 * All currently running services. 649 */ 650 final HashMap<ComponentName, ServiceRecord> mServices = 651 new HashMap<ComponentName, ServiceRecord>(); 652 653 /** 654 * All currently running services indexed by the Intent used to start them. 655 */ 656 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 657 new HashMap<Intent.FilterComparison, ServiceRecord>(); 658 659 /** 660 * All currently bound service connections. Keys are the IBinder of 661 * the client's IServiceConnection. 662 */ 663 final HashMap<IBinder, ConnectionRecord> mServiceConnections 664 = new HashMap<IBinder, ConnectionRecord>(); 665 666 /** 667 * List of services that we have been asked to start, 668 * but haven't yet been able to. It is used to hold start requests 669 * while waiting for their corresponding application thread to get 670 * going. 671 */ 672 final ArrayList<ServiceRecord> mPendingServices 673 = new ArrayList<ServiceRecord>(); 674 675 /** 676 * List of services that are scheduled to restart following a crash. 677 */ 678 final ArrayList<ServiceRecord> mRestartingServices 679 = new ArrayList<ServiceRecord>(); 680 681 /** 682 * List of services that are in the process of being stopped. 683 */ 684 final ArrayList<ServiceRecord> mStoppingServices 685 = new ArrayList<ServiceRecord>(); 686 687 /** 688 * Backup/restore process management 689 */ 690 String mBackupAppName = null; 691 BackupRecord mBackupTarget = null; 692 693 /** 694 * List of PendingThumbnailsRecord objects of clients who are still 695 * waiting to receive all of the thumbnails for a task. 696 */ 697 final ArrayList mPendingThumbnails = new ArrayList(); 698 699 /** 700 * List of HistoryRecord objects that have been finished and must 701 * still report back to a pending thumbnail receiver. 702 */ 703 final ArrayList mCancelledThumbnails = new ArrayList(); 704 705 /** 706 * All of the currently running global content providers. Keys are a 707 * string containing the provider name and values are a 708 * ContentProviderRecord object containing the data about it. Note 709 * that a single provider may be published under multiple names, so 710 * there may be multiple entries here for a single one in mProvidersByClass. 711 */ 712 final HashMap mProvidersByName = new HashMap(); 713 714 /** 715 * All of the currently running global content providers. Keys are a 716 * string containing the provider's implementation class and values are a 717 * ContentProviderRecord object containing the data about it. 718 */ 719 final HashMap mProvidersByClass = new HashMap(); 720 721 /** 722 * List of content providers who have clients waiting for them. The 723 * application is currently being launched and the provider will be 724 * removed from this list once it is published. 725 */ 726 final ArrayList mLaunchingProviders = new ArrayList(); 727 728 /** 729 * Global set of specific Uri permissions that have been granted. 730 */ 731 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 732 = new SparseArray<HashMap<Uri, UriPermission>>(); 733 734 /** 735 * Thread-local storage used to carry caller permissions over through 736 * indirect content-provider access. 737 * @see #ActivityManagerService.openContentUri() 738 */ 739 private class Identity { 740 public int pid; 741 public int uid; 742 Identity(int _pid, int _uid)743 Identity(int _pid, int _uid) { 744 pid = _pid; 745 uid = _uid; 746 } 747 } 748 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 749 750 /** 751 * All information we have collected about the runtime performance of 752 * any user id that can impact battery performance. 753 */ 754 final BatteryStatsService mBatteryStatsService; 755 756 /** 757 * information about component usage 758 */ 759 final UsageStatsService mUsageStatsService; 760 761 /** 762 * Current configuration information. HistoryRecord objects are given 763 * a reference to this object to indicate which configuration they are 764 * currently running in, so this object must be kept immutable. 765 */ 766 Configuration mConfiguration = new Configuration(); 767 768 /** 769 * Hardware-reported OpenGLES version. 770 */ 771 final int GL_ES_VERSION; 772 773 /** 774 * List of initialization arguments to pass to all processes when binding applications to them. 775 * For example, references to the commonly used services. 776 */ 777 HashMap<String, IBinder> mAppBindArgs; 778 779 /** 780 * Temporary to avoid allocations. Protected by main lock. 781 */ 782 final StringBuilder mStringBuilder = new StringBuilder(256); 783 784 /** 785 * Used to control how we initialize the service. 786 */ 787 boolean mStartRunning = false; 788 ComponentName mTopComponent; 789 String mTopAction; 790 String mTopData; 791 boolean mSystemReady = false; 792 boolean mBooting = false; 793 boolean mWaitingUpdate = false; 794 boolean mDidUpdate = false; 795 796 Context mContext; 797 798 int mFactoryTest; 799 800 boolean mCheckedForSetup; 801 802 /** 803 * The time at which we will allow normal application switches again, 804 * after a call to {@link #stopAppSwitches()}. 805 */ 806 long mAppSwitchesAllowedTime; 807 808 /** 809 * This is set to true after the first switch after mAppSwitchesAllowedTime 810 * is set; any switches after that will clear the time. 811 */ 812 boolean mDidAppSwitch; 813 814 /** 815 * Set while we are wanting to sleep, to prevent any 816 * activities from being started/resumed. 817 */ 818 boolean mSleeping = false; 819 820 /** 821 * Set if we are shutting down the system, similar to sleeping. 822 */ 823 boolean mShuttingDown = false; 824 825 /** 826 * Set when the system is going to sleep, until we have 827 * successfully paused the current activity and released our wake lock. 828 * At that point the system is allowed to actually sleep. 829 */ 830 PowerManager.WakeLock mGoingToSleep; 831 832 /** 833 * We don't want to allow the device to go to sleep while in the process 834 * of launching an activity. This is primarily to allow alarm intent 835 * receivers to launch an activity and get that to run before the device 836 * goes back to sleep. 837 */ 838 PowerManager.WakeLock mLaunchingActivity; 839 840 /** 841 * Task identifier that activities are currently being started 842 * in. Incremented each time a new task is created. 843 * todo: Replace this with a TokenSpace class that generates non-repeating 844 * integers that won't wrap. 845 */ 846 int mCurTask = 1; 847 848 /** 849 * Current sequence id for oom_adj computation traversal. 850 */ 851 int mAdjSeq = 0; 852 853 /** 854 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar 855 * is set, indicating the user wants processes started in such a way 856 * that they can use ANDROID_PROCESS_WRAPPER and know what will be 857 * running in each process (thus no pre-initialized process, etc). 858 */ 859 boolean mSimpleProcessManagement = false; 860 861 /** 862 * System monitoring: number of processes that died since the last 863 * N procs were started. 864 */ 865 int[] mProcDeaths = new int[20]; 866 867 /** 868 * This is set if we had to do a delayed dexopt of an app before launching 869 * it, to increasing the ANR timeouts in that case. 870 */ 871 boolean mDidDexOpt; 872 873 String mDebugApp = null; 874 boolean mWaitForDebugger = false; 875 boolean mDebugTransient = false; 876 String mOrigDebugApp = null; 877 boolean mOrigWaitForDebugger = false; 878 boolean mAlwaysFinishActivities = false; 879 IActivityController mController = null; 880 881 final RemoteCallbackList<IActivityWatcher> mWatchers 882 = new RemoteCallbackList<IActivityWatcher>(); 883 884 /** 885 * Callback of last caller to {@link #requestPss}. 886 */ 887 Runnable mRequestPssCallback; 888 889 /** 890 * Remaining processes for which we are waiting results from the last 891 * call to {@link #requestPss}. 892 */ 893 final ArrayList<ProcessRecord> mRequestPssList 894 = new ArrayList<ProcessRecord>(); 895 896 /** 897 * Runtime statistics collection thread. This object's lock is used to 898 * protect all related state. 899 */ 900 final Thread mProcessStatsThread; 901 902 /** 903 * Used to collect process stats when showing not responding dialog. 904 * Protected by mProcessStatsThread. 905 */ 906 final ProcessStats mProcessStats = new ProcessStats( 907 MONITOR_THREAD_CPU_USAGE); 908 long mLastCpuTime = 0; 909 long mLastWriteTime = 0; 910 911 long mInitialStartTime = 0; 912 913 /** 914 * Set to true after the system has finished booting. 915 */ 916 boolean mBooted = false; 917 918 int mProcessLimit = 0; 919 920 WindowManagerService mWindowManager; 921 922 static ActivityManagerService mSelf; 923 static ActivityThread mSystemThread; 924 925 private final class AppDeathRecipient implements IBinder.DeathRecipient { 926 final ProcessRecord mApp; 927 final int mPid; 928 final IApplicationThread mAppThread; 929 AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)930 AppDeathRecipient(ProcessRecord app, int pid, 931 IApplicationThread thread) { 932 if (localLOGV) Log.v( 933 TAG, "New death recipient " + this 934 + " for thread " + thread.asBinder()); 935 mApp = app; 936 mPid = pid; 937 mAppThread = thread; 938 } 939 binderDied()940 public void binderDied() { 941 if (localLOGV) Log.v( 942 TAG, "Death received in " + this 943 + " for thread " + mAppThread.asBinder()); 944 removeRequestedPss(mApp); 945 synchronized(ActivityManagerService.this) { 946 appDiedLocked(mApp, mPid, mAppThread); 947 } 948 } 949 } 950 951 static final int SHOW_ERROR_MSG = 1; 952 static final int SHOW_NOT_RESPONDING_MSG = 2; 953 static final int SHOW_FACTORY_ERROR_MSG = 3; 954 static final int UPDATE_CONFIGURATION_MSG = 4; 955 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 956 static final int WAIT_FOR_DEBUGGER_MSG = 6; 957 static final int BROADCAST_INTENT_MSG = 7; 958 static final int BROADCAST_TIMEOUT_MSG = 8; 959 static final int PAUSE_TIMEOUT_MSG = 9; 960 static final int IDLE_TIMEOUT_MSG = 10; 961 static final int IDLE_NOW_MSG = 11; 962 static final int SERVICE_TIMEOUT_MSG = 12; 963 static final int UPDATE_TIME_ZONE = 13; 964 static final int SHOW_UID_ERROR_MSG = 14; 965 static final int IM_FEELING_LUCKY_MSG = 15; 966 static final int LAUNCH_TIMEOUT_MSG = 16; 967 static final int DESTROY_TIMEOUT_MSG = 17; 968 static final int SERVICE_ERROR_MSG = 18; 969 static final int RESUME_TOP_ACTIVITY_MSG = 19; 970 static final int PROC_START_TIMEOUT_MSG = 20; 971 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 972 static final int KILL_APPLICATION_MSG = 22; 973 974 AlertDialog mUidAlert; 975 976 final Handler mHandler = new Handler() { 977 //public Handler() { 978 // if (localLOGV) Log.v(TAG, "Handler started!"); 979 //} 980 981 public void handleMessage(Message msg) { 982 switch (msg.what) { 983 case SHOW_ERROR_MSG: { 984 HashMap data = (HashMap) msg.obj; 985 byte[] crashData = (byte[])data.get("crashData"); 986 if (crashData != null) { 987 // This needs to be *un*synchronized to avoid deadlock. 988 ContentResolver resolver = mContext.getContentResolver(); 989 Checkin.reportCrash(resolver, crashData); 990 } 991 synchronized (ActivityManagerService.this) { 992 ProcessRecord proc = (ProcessRecord)data.get("app"); 993 if (proc != null && proc.crashDialog != null) { 994 Log.e(TAG, "App already has crash dialog: " + proc); 995 return; 996 } 997 AppErrorResult res = (AppErrorResult) data.get("result"); 998 if (!mSleeping && !mShuttingDown) { 999 Dialog d = new AppErrorDialog( 1000 mContext, res, proc, 1001 (Integer)data.get("flags"), 1002 (String)data.get("shortMsg"), 1003 (String)data.get("longMsg")); 1004 d.show(); 1005 proc.crashDialog = d; 1006 } else { 1007 // The device is asleep, so just pretend that the user 1008 // saw a crash dialog and hit "force quit". 1009 res.set(0); 1010 } 1011 } 1012 1013 ensureBootCompleted(); 1014 } break; 1015 case SHOW_NOT_RESPONDING_MSG: { 1016 synchronized (ActivityManagerService.this) { 1017 HashMap data = (HashMap) msg.obj; 1018 ProcessRecord proc = (ProcessRecord)data.get("app"); 1019 if (proc != null && proc.anrDialog != null) { 1020 Log.e(TAG, "App already has anr dialog: " + proc); 1021 return; 1022 } 1023 1024 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), 1025 null, null, 0, null, null, null, 1026 false, false, MY_PID, Process.SYSTEM_UID); 1027 1028 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1029 mContext, proc, (HistoryRecord)data.get("activity")); 1030 d.show(); 1031 proc.anrDialog = d; 1032 } 1033 1034 ensureBootCompleted(); 1035 } break; 1036 case SHOW_FACTORY_ERROR_MSG: { 1037 Dialog d = new FactoryErrorDialog( 1038 mContext, msg.getData().getCharSequence("msg")); 1039 d.show(); 1040 ensureBootCompleted(); 1041 } break; 1042 case UPDATE_CONFIGURATION_MSG: { 1043 final ContentResolver resolver = mContext.getContentResolver(); 1044 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1045 } break; 1046 case GC_BACKGROUND_PROCESSES_MSG: { 1047 synchronized (ActivityManagerService.this) { 1048 performAppGcsIfAppropriateLocked(); 1049 } 1050 } break; 1051 case WAIT_FOR_DEBUGGER_MSG: { 1052 synchronized (ActivityManagerService.this) { 1053 ProcessRecord app = (ProcessRecord)msg.obj; 1054 if (msg.arg1 != 0) { 1055 if (!app.waitedForDebugger) { 1056 Dialog d = new AppWaitingForDebuggerDialog( 1057 ActivityManagerService.this, 1058 mContext, app); 1059 app.waitDialog = d; 1060 app.waitedForDebugger = true; 1061 d.show(); 1062 } 1063 } else { 1064 if (app.waitDialog != null) { 1065 app.waitDialog.dismiss(); 1066 app.waitDialog = null; 1067 } 1068 } 1069 } 1070 } break; 1071 case BROADCAST_INTENT_MSG: { 1072 if (DEBUG_BROADCAST) Log.v( 1073 TAG, "Received BROADCAST_INTENT_MSG"); 1074 processNextBroadcast(true); 1075 } break; 1076 case BROADCAST_TIMEOUT_MSG: { 1077 if (mDidDexOpt) { 1078 mDidDexOpt = false; 1079 Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 1080 mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT); 1081 return; 1082 } 1083 broadcastTimeout(); 1084 } break; 1085 case PAUSE_TIMEOUT_MSG: { 1086 IBinder token = (IBinder)msg.obj; 1087 // We don't at this point know if the activity is fullscreen, 1088 // so we need to be conservative and assume it isn't. 1089 Log.w(TAG, "Activity pause timeout for " + token); 1090 activityPaused(token, null, true); 1091 } break; 1092 case IDLE_TIMEOUT_MSG: { 1093 if (mDidDexOpt) { 1094 mDidDexOpt = false; 1095 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 1096 nmsg.obj = msg.obj; 1097 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 1098 return; 1099 } 1100 // We don't at this point know if the activity is fullscreen, 1101 // so we need to be conservative and assume it isn't. 1102 IBinder token = (IBinder)msg.obj; 1103 Log.w(TAG, "Activity idle timeout for " + token); 1104 activityIdleInternal(token, true, null); 1105 } break; 1106 case DESTROY_TIMEOUT_MSG: { 1107 IBinder token = (IBinder)msg.obj; 1108 // We don't at this point know if the activity is fullscreen, 1109 // so we need to be conservative and assume it isn't. 1110 Log.w(TAG, "Activity destroy timeout for " + token); 1111 activityDestroyed(token); 1112 } break; 1113 case IDLE_NOW_MSG: { 1114 IBinder token = (IBinder)msg.obj; 1115 activityIdle(token, null); 1116 } break; 1117 case SERVICE_TIMEOUT_MSG: { 1118 if (mDidDexOpt) { 1119 mDidDexOpt = false; 1120 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1121 nmsg.obj = msg.obj; 1122 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1123 return; 1124 } 1125 serviceTimeout((ProcessRecord)msg.obj); 1126 } break; 1127 case UPDATE_TIME_ZONE: { 1128 synchronized (ActivityManagerService.this) { 1129 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 1130 ProcessRecord r = mLRUProcesses.get(i); 1131 if (r.thread != null) { 1132 try { 1133 r.thread.updateTimeZone(); 1134 } catch (RemoteException ex) { 1135 Log.w(TAG, "Failed to update time zone for: " + r.info.processName); 1136 } 1137 } 1138 } 1139 } 1140 } break; 1141 case SHOW_UID_ERROR_MSG: { 1142 // XXX This is a temporary dialog, no need to localize. 1143 AlertDialog d = new BaseErrorDialog(mContext); 1144 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1145 d.setCancelable(false); 1146 d.setTitle("System UIDs Inconsistent"); 1147 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1148 d.setButton("I'm Feeling Lucky", 1149 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1150 mUidAlert = d; 1151 d.show(); 1152 } break; 1153 case IM_FEELING_LUCKY_MSG: { 1154 if (mUidAlert != null) { 1155 mUidAlert.dismiss(); 1156 mUidAlert = null; 1157 } 1158 } break; 1159 case LAUNCH_TIMEOUT_MSG: { 1160 if (mDidDexOpt) { 1161 mDidDexOpt = false; 1162 Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 1163 mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT); 1164 return; 1165 } 1166 synchronized (ActivityManagerService.this) { 1167 if (mLaunchingActivity.isHeld()) { 1168 Log.w(TAG, "Launch timeout has expired, giving up wake lock!"); 1169 mLaunchingActivity.release(); 1170 } 1171 } 1172 } break; 1173 case SERVICE_ERROR_MSG: { 1174 ServiceRecord srv = (ServiceRecord)msg.obj; 1175 // This needs to be *un*synchronized to avoid deadlock. 1176 Checkin.logEvent(mContext.getContentResolver(), 1177 Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING, 1178 srv.name.toShortString()); 1179 } break; 1180 case RESUME_TOP_ACTIVITY_MSG: { 1181 synchronized (ActivityManagerService.this) { 1182 resumeTopActivityLocked(null); 1183 } 1184 } break; 1185 case PROC_START_TIMEOUT_MSG: { 1186 if (mDidDexOpt) { 1187 mDidDexOpt = false; 1188 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1189 nmsg.obj = msg.obj; 1190 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1191 return; 1192 } 1193 ProcessRecord app = (ProcessRecord)msg.obj; 1194 synchronized (ActivityManagerService.this) { 1195 processStartTimedOutLocked(app); 1196 } 1197 } break; 1198 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1199 synchronized (ActivityManagerService.this) { 1200 doPendingActivityLaunchesLocked(true); 1201 } 1202 } break; 1203 case KILL_APPLICATION_MSG: { 1204 synchronized (ActivityManagerService.this) { 1205 int uid = msg.arg1; 1206 boolean restart = (msg.arg2 == 1); 1207 String pkg = (String) msg.obj; 1208 uninstallPackageLocked(pkg, uid, restart); 1209 } 1210 } break; 1211 } 1212 } 1213 }; 1214 setSystemProcess()1215 public static void setSystemProcess() { 1216 try { 1217 ActivityManagerService m = mSelf; 1218 1219 ServiceManager.addService("activity", m); 1220 ServiceManager.addService("meminfo", new MemBinder(m)); 1221 if (MONITOR_CPU_USAGE) { 1222 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1223 } 1224 ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m)); 1225 ServiceManager.addService("activity.services", new ServicesBinder(m)); 1226 ServiceManager.addService("activity.senders", new SendersBinder(m)); 1227 ServiceManager.addService("activity.providers", new ProvidersBinder(m)); 1228 ServiceManager.addService("permission", new PermissionController(m)); 1229 1230 ApplicationInfo info = 1231 mSelf.mContext.getPackageManager().getApplicationInfo( 1232 "android", STOCK_PM_FLAGS); 1233 mSystemThread.installSystemApplicationInfo(info); 1234 1235 synchronized (mSelf) { 1236 ProcessRecord app = mSelf.newProcessRecordLocked( 1237 mSystemThread.getApplicationThread(), info, 1238 info.processName); 1239 app.persistent = true; 1240 app.pid = Process.myPid(); 1241 app.maxAdj = SYSTEM_ADJ; 1242 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1243 synchronized (mSelf.mPidsSelfLocked) { 1244 mSelf.mPidsSelfLocked.put(app.pid, app); 1245 } 1246 mSelf.updateLRUListLocked(app, true); 1247 } 1248 } catch (PackageManager.NameNotFoundException e) { 1249 throw new RuntimeException( 1250 "Unable to find android system package", e); 1251 } 1252 } 1253 setWindowManager(WindowManagerService wm)1254 public void setWindowManager(WindowManagerService wm) { 1255 mWindowManager = wm; 1256 } 1257 main(int factoryTest)1258 public static final Context main(int factoryTest) { 1259 AThread thr = new AThread(); 1260 thr.start(); 1261 1262 synchronized (thr) { 1263 while (thr.mService == null) { 1264 try { 1265 thr.wait(); 1266 } catch (InterruptedException e) { 1267 } 1268 } 1269 } 1270 1271 ActivityManagerService m = thr.mService; 1272 mSelf = m; 1273 ActivityThread at = ActivityThread.systemMain(); 1274 mSystemThread = at; 1275 Context context = at.getSystemContext(); 1276 m.mContext = context; 1277 m.mFactoryTest = factoryTest; 1278 PowerManager pm = 1279 (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1280 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 1281 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 1282 m.mLaunchingActivity.setReferenceCounted(false); 1283 1284 m.mBatteryStatsService.publish(context); 1285 m.mUsageStatsService.publish(context); 1286 1287 synchronized (thr) { 1288 thr.mReady = true; 1289 thr.notifyAll(); 1290 } 1291 1292 m.startRunning(null, null, null, null); 1293 1294 return context; 1295 } 1296 self()1297 public static ActivityManagerService self() { 1298 return mSelf; 1299 } 1300 1301 static class AThread extends Thread { 1302 ActivityManagerService mService; 1303 boolean mReady = false; 1304 AThread()1305 public AThread() { 1306 super("ActivityManager"); 1307 } 1308 run()1309 public void run() { 1310 Looper.prepare(); 1311 1312 android.os.Process.setThreadPriority( 1313 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1314 1315 ActivityManagerService m = new ActivityManagerService(); 1316 1317 synchronized (this) { 1318 mService = m; 1319 notifyAll(); 1320 } 1321 1322 synchronized (this) { 1323 while (!mReady) { 1324 try { 1325 wait(); 1326 } catch (InterruptedException e) { 1327 } 1328 } 1329 } 1330 1331 Looper.loop(); 1332 } 1333 } 1334 1335 static class BroadcastsBinder extends Binder { 1336 ActivityManagerService mActivityManagerService; BroadcastsBinder(ActivityManagerService activityManagerService)1337 BroadcastsBinder(ActivityManagerService activityManagerService) { 1338 mActivityManagerService = activityManagerService; 1339 } 1340 1341 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1342 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1343 mActivityManagerService.dumpBroadcasts(pw); 1344 } 1345 } 1346 1347 static class ServicesBinder extends Binder { 1348 ActivityManagerService mActivityManagerService; ServicesBinder(ActivityManagerService activityManagerService)1349 ServicesBinder(ActivityManagerService activityManagerService) { 1350 mActivityManagerService = activityManagerService; 1351 } 1352 1353 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1354 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1355 mActivityManagerService.dumpServices(pw); 1356 } 1357 } 1358 1359 static class SendersBinder extends Binder { 1360 ActivityManagerService mActivityManagerService; SendersBinder(ActivityManagerService activityManagerService)1361 SendersBinder(ActivityManagerService activityManagerService) { 1362 mActivityManagerService = activityManagerService; 1363 } 1364 1365 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1366 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1367 mActivityManagerService.dumpSenders(pw); 1368 } 1369 } 1370 1371 static class ProvidersBinder extends Binder { 1372 ActivityManagerService mActivityManagerService; ProvidersBinder(ActivityManagerService activityManagerService)1373 ProvidersBinder(ActivityManagerService activityManagerService) { 1374 mActivityManagerService = activityManagerService; 1375 } 1376 1377 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1378 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1379 mActivityManagerService.dumpProviders(pw); 1380 } 1381 } 1382 1383 static class MemBinder extends Binder { 1384 ActivityManagerService mActivityManagerService; MemBinder(ActivityManagerService activityManagerService)1385 MemBinder(ActivityManagerService activityManagerService) { 1386 mActivityManagerService = activityManagerService; 1387 } 1388 1389 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1390 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1391 ActivityManagerService service = mActivityManagerService; 1392 ArrayList<ProcessRecord> procs; 1393 synchronized (mActivityManagerService) { 1394 if (args != null && args.length > 0 1395 && args[0].charAt(0) != '-') { 1396 procs = new ArrayList<ProcessRecord>(); 1397 int pid = -1; 1398 try { 1399 pid = Integer.parseInt(args[0]); 1400 } catch (NumberFormatException e) { 1401 1402 } 1403 for (int i=0; i<service.mLRUProcesses.size(); i++) { 1404 ProcessRecord proc = service.mLRUProcesses.get(i); 1405 if (proc.pid == pid) { 1406 procs.add(proc); 1407 } else if (proc.processName.equals(args[0])) { 1408 procs.add(proc); 1409 } 1410 } 1411 if (procs.size() <= 0) { 1412 pw.println("No process found for: " + args[0]); 1413 return; 1414 } 1415 } else { 1416 procs = service.mLRUProcesses; 1417 } 1418 } 1419 dumpApplicationMemoryUsage(fd, pw, procs, " ", args); 1420 } 1421 } 1422 1423 static class CpuBinder extends Binder { 1424 ActivityManagerService mActivityManagerService; CpuBinder(ActivityManagerService activityManagerService)1425 CpuBinder(ActivityManagerService activityManagerService) { 1426 mActivityManagerService = activityManagerService; 1427 } 1428 1429 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1430 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1431 synchronized (mActivityManagerService.mProcessStatsThread) { 1432 pw.print(mActivityManagerService.mProcessStats.printCurrentState()); 1433 } 1434 } 1435 } 1436 ActivityManagerService()1437 private ActivityManagerService() { 1438 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT"); 1439 if (v != null && Integer.getInteger(v) != 0) { 1440 mSimpleProcessManagement = true; 1441 } 1442 v = System.getenv("ANDROID_DEBUG_APP"); 1443 if (v != null) { 1444 mSimpleProcessManagement = true; 1445 } 1446 1447 Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1448 1449 MY_PID = Process.myPid(); 1450 1451 File dataDir = Environment.getDataDirectory(); 1452 File systemDir = new File(dataDir, "system"); 1453 systemDir.mkdirs(); 1454 mBatteryStatsService = new BatteryStatsService(new File( 1455 systemDir, "batterystats.bin").toString()); 1456 mBatteryStatsService.getActiveStatistics().readLocked(); 1457 mBatteryStatsService.getActiveStatistics().writeLocked(); 1458 1459 mUsageStatsService = new UsageStatsService( new File( 1460 systemDir, "usagestats").toString()); 1461 1462 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1463 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1464 1465 mConfiguration.makeDefault(); 1466 mProcessStats.init(); 1467 1468 // Add ourself to the Watchdog monitors. 1469 Watchdog.getInstance().addMonitor(this); 1470 1471 // These values are set in system/rootdir/init.rc on startup. 1472 FOREGROUND_APP_ADJ = 1473 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 1474 VISIBLE_APP_ADJ = 1475 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 1476 SECONDARY_SERVER_ADJ = 1477 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 1478 BACKUP_APP_ADJ = 1479 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 1480 HOME_APP_ADJ = 1481 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 1482 HIDDEN_APP_MIN_ADJ = 1483 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 1484 CONTENT_PROVIDER_ADJ = 1485 Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ")); 1486 HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1; 1487 EMPTY_APP_ADJ = 1488 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 1489 FOREGROUND_APP_MEM = 1490 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 1491 VISIBLE_APP_MEM = 1492 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 1493 SECONDARY_SERVER_MEM = 1494 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 1495 BACKUP_APP_MEM = 1496 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 1497 HOME_APP_MEM = 1498 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 1499 HIDDEN_APP_MEM = 1500 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 1501 EMPTY_APP_MEM = 1502 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 1503 1504 mProcessStatsThread = new Thread("ProcessStats") { 1505 public void run() { 1506 while (true) { 1507 try { 1508 try { 1509 synchronized(this) { 1510 final long now = SystemClock.uptimeMillis(); 1511 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now; 1512 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1513 //Log.i(TAG, "Cpu delay=" + nextCpuDelay 1514 // + ", write delay=" + nextWriteDelay); 1515 if (nextWriteDelay < nextCpuDelay) { 1516 nextCpuDelay = nextWriteDelay; 1517 } 1518 if (nextCpuDelay > 0) { 1519 this.wait(nextCpuDelay); 1520 } 1521 } 1522 } catch (InterruptedException e) { 1523 } 1524 1525 updateCpuStatsNow(); 1526 } catch (Exception e) { 1527 Log.e(TAG, "Unexpected exception collecting process stats", e); 1528 } 1529 } 1530 } 1531 }; 1532 mProcessStatsThread.start(); 1533 } 1534 1535 @Override onTransact(int code, Parcel data, Parcel reply, int flags)1536 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1537 throws RemoteException { 1538 try { 1539 return super.onTransact(code, data, reply, flags); 1540 } catch (RuntimeException e) { 1541 // The activity manager only throws security exceptions, so let's 1542 // log all others. 1543 if (!(e instanceof SecurityException)) { 1544 Log.e(TAG, "Activity Manager Crash", e); 1545 } 1546 throw e; 1547 } 1548 } 1549 updateCpuStats()1550 void updateCpuStats() { 1551 synchronized (mProcessStatsThread) { 1552 final long now = SystemClock.uptimeMillis(); 1553 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1554 mProcessStatsThread.notify(); 1555 } 1556 } 1557 } 1558 updateCpuStatsNow()1559 void updateCpuStatsNow() { 1560 synchronized (mProcessStatsThread) { 1561 final long now = SystemClock.uptimeMillis(); 1562 boolean haveNewCpuStats = false; 1563 1564 if (MONITOR_CPU_USAGE && 1565 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1566 mLastCpuTime = now; 1567 haveNewCpuStats = true; 1568 mProcessStats.update(); 1569 //Log.i(TAG, mProcessStats.printCurrentState()); 1570 //Log.i(TAG, "Total CPU usage: " 1571 // + mProcessStats.getTotalCpuPercent() + "%"); 1572 1573 // Log the cpu usage if the property is set. 1574 if ("true".equals(SystemProperties.get("events.cpu"))) { 1575 int user = mProcessStats.getLastUserTime(); 1576 int system = mProcessStats.getLastSystemTime(); 1577 int iowait = mProcessStats.getLastIoWaitTime(); 1578 int irq = mProcessStats.getLastIrqTime(); 1579 int softIrq = mProcessStats.getLastSoftIrqTime(); 1580 int idle = mProcessStats.getLastIdleTime(); 1581 1582 int total = user + system + iowait + irq + softIrq + idle; 1583 if (total == 0) total = 1; 1584 1585 EventLog.writeEvent(LOG_CPU, 1586 ((user+system+iowait+irq+softIrq) * 100) / total, 1587 (user * 100) / total, 1588 (system * 100) / total, 1589 (iowait * 100) / total, 1590 (irq * 100) / total, 1591 (softIrq * 100) / total); 1592 } 1593 } 1594 1595 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1596 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1597 synchronized(bstats) { 1598 synchronized(mPidsSelfLocked) { 1599 if (haveNewCpuStats) { 1600 if (mBatteryStatsService.isOnBattery()) { 1601 final int N = mProcessStats.countWorkingStats(); 1602 for (int i=0; i<N; i++) { 1603 ProcessStats.Stats st 1604 = mProcessStats.getWorkingStats(i); 1605 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1606 if (pr != null) { 1607 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1608 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1609 ps.addSpeedStepTimes(cpuSpeedTimes); 1610 } else { 1611 BatteryStatsImpl.Uid.Proc ps = 1612 bstats.getProcessStatsLocked(st.name, st.pid); 1613 if (ps != null) { 1614 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1615 ps.addSpeedStepTimes(cpuSpeedTimes); 1616 } 1617 } 1618 } 1619 } 1620 } 1621 } 1622 1623 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1624 mLastWriteTime = now; 1625 mBatteryStatsService.getActiveStatistics().writeLocked(); 1626 } 1627 } 1628 } 1629 } 1630 1631 /** 1632 * Initialize the application bind args. These are passed to each 1633 * process when the bindApplication() IPC is sent to the process. They're 1634 * lazily setup to make sure the services are running when they're asked for. 1635 */ getCommonServicesLocked()1636 private HashMap<String, IBinder> getCommonServicesLocked() { 1637 if (mAppBindArgs == null) { 1638 mAppBindArgs = new HashMap<String, IBinder>(); 1639 1640 // Setup the application init args 1641 mAppBindArgs.put("package", ServiceManager.getService("package")); 1642 mAppBindArgs.put("window", ServiceManager.getService("window")); 1643 mAppBindArgs.put(Context.ALARM_SERVICE, 1644 ServiceManager.getService(Context.ALARM_SERVICE)); 1645 } 1646 return mAppBindArgs; 1647 } 1648 setFocusedActivityLocked(HistoryRecord r)1649 private final void setFocusedActivityLocked(HistoryRecord r) { 1650 if (mFocusedActivity != r) { 1651 mFocusedActivity = r; 1652 mWindowManager.setFocusedApp(r, true); 1653 } 1654 } 1655 updateLRUListLocked(ProcessRecord app, boolean oomAdj)1656 private final void updateLRUListLocked(ProcessRecord app, 1657 boolean oomAdj) { 1658 // put it on the LRU to keep track of when it should be exited. 1659 int lrui = mLRUProcesses.indexOf(app); 1660 if (lrui >= 0) mLRUProcesses.remove(lrui); 1661 mLRUProcesses.add(app); 1662 //Log.i(TAG, "Putting proc to front: " + app.processName); 1663 if (oomAdj) { 1664 updateOomAdjLocked(); 1665 } 1666 } 1667 updateLRUListLocked(HistoryRecord r)1668 private final boolean updateLRUListLocked(HistoryRecord r) { 1669 final boolean hadit = mLRUActivities.remove(r); 1670 mLRUActivities.add(r); 1671 return hadit; 1672 } 1673 topRunningActivityLocked(HistoryRecord notTop)1674 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1675 int i = mHistory.size()-1; 1676 while (i >= 0) { 1677 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1678 if (!r.finishing && r != notTop) { 1679 return r; 1680 } 1681 i--; 1682 } 1683 return null; 1684 } 1685 topRunningNonDelayedActivityLocked(HistoryRecord notTop)1686 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1687 int i = mHistory.size()-1; 1688 while (i >= 0) { 1689 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1690 if (!r.finishing && !r.delayedResume && r != notTop) { 1691 return r; 1692 } 1693 i--; 1694 } 1695 return null; 1696 } 1697 1698 /** 1699 * This is a simplified version of topRunningActivityLocked that provides a number of 1700 * optional skip-over modes. It is intended for use with the ActivityController hook only. 1701 * 1702 * @param token If non-null, any history records matching this token will be skipped. 1703 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1704 * 1705 * @return Returns the HistoryRecord of the next activity on the stack. 1706 */ topRunningActivityLocked(IBinder token, int taskId)1707 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1708 int i = mHistory.size()-1; 1709 while (i >= 0) { 1710 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1711 // Note: the taskId check depends on real taskId fields being non-zero 1712 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1713 return r; 1714 } 1715 i--; 1716 } 1717 return null; 1718 } 1719 getProcessRecordLocked( String processName, int uid)1720 private final ProcessRecord getProcessRecordLocked( 1721 String processName, int uid) { 1722 if (uid == Process.SYSTEM_UID) { 1723 // The system gets to run in any process. If there are multiple 1724 // processes with the same uid, just pick the first (this 1725 // should never happen). 1726 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1727 processName); 1728 return procs != null ? procs.valueAt(0) : null; 1729 } 1730 ProcessRecord proc = mProcessNames.get(processName, uid); 1731 return proc; 1732 } 1733 ensurePackageDexOpt(String packageName)1734 private void ensurePackageDexOpt(String packageName) { 1735 IPackageManager pm = ActivityThread.getPackageManager(); 1736 try { 1737 if (pm.performDexOpt(packageName)) { 1738 mDidDexOpt = true; 1739 } 1740 } catch (RemoteException e) { 1741 } 1742 } 1743 isNextTransitionForward()1744 private boolean isNextTransitionForward() { 1745 int transit = mWindowManager.getPendingAppTransition(); 1746 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1747 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1748 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1749 } 1750 realStartActivityLocked(HistoryRecord r, ProcessRecord app, boolean andResume, boolean checkConfig)1751 private final boolean realStartActivityLocked(HistoryRecord r, 1752 ProcessRecord app, boolean andResume, boolean checkConfig) 1753 throws RemoteException { 1754 1755 r.startFreezingScreenLocked(app, 0); 1756 mWindowManager.setAppVisibility(r, true); 1757 1758 // Have the window manager re-evaluate the orientation of 1759 // the screen based on the new activity order. Note that 1760 // as a result of this, it can call back into the activity 1761 // manager with a new orientation. We don't care about that, 1762 // because the activity is not currently running so we are 1763 // just restarting it anyway. 1764 if (checkConfig) { 1765 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1766 mConfiguration, 1767 r.mayFreezeScreenLocked(app) ? r : null); 1768 updateConfigurationLocked(config, r); 1769 } 1770 1771 r.app = app; 1772 1773 if (localLOGV) Log.v(TAG, "Launching: " + r); 1774 1775 int idx = app.activities.indexOf(r); 1776 if (idx < 0) { 1777 app.activities.add(r); 1778 } 1779 updateLRUListLocked(app, true); 1780 1781 try { 1782 if (app.thread == null) { 1783 throw new RemoteException(); 1784 } 1785 List<ResultInfo> results = null; 1786 List<Intent> newIntents = null; 1787 if (andResume) { 1788 results = r.results; 1789 newIntents = r.newIntents; 1790 } 1791 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r 1792 + " icicle=" + r.icicle 1793 + " with results=" + results + " newIntents=" + newIntents 1794 + " andResume=" + andResume); 1795 if (andResume) { 1796 EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY, 1797 System.identityHashCode(r), 1798 r.task.taskId, r.shortComponentName); 1799 } 1800 if (r.isHomeActivity) { 1801 mHomeProcess = app; 1802 } 1803 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1804 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1805 System.identityHashCode(r), 1806 r.info, r.icicle, results, newIntents, !andResume, 1807 isNextTransitionForward()); 1808 } catch (RemoteException e) { 1809 if (r.launchFailed) { 1810 // This is the second time we failed -- finish activity 1811 // and give up. 1812 Log.e(TAG, "Second failure launching " 1813 + r.intent.getComponent().flattenToShortString() 1814 + ", giving up", e); 1815 appDiedLocked(app, app.pid, app.thread); 1816 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1817 "2nd-crash"); 1818 return false; 1819 } 1820 1821 // This is the first time we failed -- restart process and 1822 // retry. 1823 app.activities.remove(r); 1824 throw e; 1825 } 1826 1827 r.launchFailed = false; 1828 if (updateLRUListLocked(r)) { 1829 Log.w(TAG, "Activity " + r 1830 + " being launched, but already in LRU list"); 1831 } 1832 1833 if (andResume) { 1834 // As part of the process of launching, ActivityThread also performs 1835 // a resume. 1836 r.state = ActivityState.RESUMED; 1837 r.icicle = null; 1838 r.haveState = false; 1839 r.stopped = false; 1840 mResumedActivity = r; 1841 r.task.touchActiveTime(); 1842 completeResumeLocked(r); 1843 pauseIfSleepingLocked(); 1844 } else { 1845 // This activity is not starting in the resumed state... which 1846 // should look like we asked it to pause+stop (but remain visible), 1847 // and it has done so and reported back the current icicle and 1848 // other state. 1849 r.state = ActivityState.STOPPED; 1850 r.stopped = true; 1851 } 1852 1853 // Launch the new version setup screen if needed. We do this -after- 1854 // launching the initial activity (that is, home), so that it can have 1855 // a chance to initialize itself while in the background, making the 1856 // switch back to it faster and look better. 1857 startSetupActivityLocked(); 1858 1859 return true; 1860 } 1861 startSpecificActivityLocked(HistoryRecord r, boolean andResume, boolean checkConfig)1862 private final void startSpecificActivityLocked(HistoryRecord r, 1863 boolean andResume, boolean checkConfig) { 1864 // Is this activity's application already running? 1865 ProcessRecord app = getProcessRecordLocked(r.processName, 1866 r.info.applicationInfo.uid); 1867 1868 if (r.startTime == 0) { 1869 r.startTime = SystemClock.uptimeMillis(); 1870 if (mInitialStartTime == 0) { 1871 mInitialStartTime = r.startTime; 1872 } 1873 } else if (mInitialStartTime == 0) { 1874 mInitialStartTime = SystemClock.uptimeMillis(); 1875 } 1876 1877 if (app != null && app.thread != null) { 1878 try { 1879 realStartActivityLocked(r, app, andResume, checkConfig); 1880 return; 1881 } catch (RemoteException e) { 1882 Log.w(TAG, "Exception when starting activity " 1883 + r.intent.getComponent().flattenToShortString(), e); 1884 } 1885 1886 // If a dead object exception was thrown -- fall through to 1887 // restart the application. 1888 } 1889 1890 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1891 "activity", r.intent.getComponent(), false); 1892 } 1893 startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting)1894 private final ProcessRecord startProcessLocked(String processName, 1895 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1896 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1897 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1898 // We don't have to do anything more if: 1899 // (1) There is an existing application record; and 1900 // (2) The caller doesn't think it is dead, OR there is no thread 1901 // object attached to it so we know it couldn't have crashed; and 1902 // (3) There is a pid assigned to it, so it is either starting or 1903 // already running. 1904 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName 1905 + " app=" + app + " knownToBeDead=" + knownToBeDead 1906 + " thread=" + (app != null ? app.thread : null) 1907 + " pid=" + (app != null ? app.pid : -1)); 1908 if (app != null && 1909 (!knownToBeDead || app.thread == null) && app.pid > 0) { 1910 return app; 1911 } 1912 1913 String hostingNameStr = hostingName != null 1914 ? hostingName.flattenToShortString() : null; 1915 1916 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1917 // If we are in the background, then check to see if this process 1918 // is bad. If so, we will just silently fail. 1919 if (mBadProcesses.get(info.processName, info.uid) != null) { 1920 return null; 1921 } 1922 } else { 1923 // When the user is explicitly starting a process, then clear its 1924 // crash count so that we won't make it bad until they see at 1925 // least one crash dialog again, and make the process good again 1926 // if it had been bad. 1927 mProcessCrashTimes.remove(info.processName, info.uid); 1928 if (mBadProcesses.get(info.processName, info.uid) != null) { 1929 EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid, 1930 info.processName); 1931 mBadProcesses.remove(info.processName, info.uid); 1932 if (app != null) { 1933 app.bad = false; 1934 } 1935 } 1936 } 1937 1938 if (app == null) { 1939 app = newProcessRecordLocked(null, info, processName); 1940 mProcessNames.put(processName, info.uid, app); 1941 } else { 1942 // If this is a new package in the process, add the package to the list 1943 app.addPackage(info.packageName); 1944 } 1945 1946 // If the system is not ready yet, then hold off on starting this 1947 // process until it is. 1948 if (!mSystemReady 1949 && !isAllowedWhileBooting(info) 1950 && !allowWhileBooting) { 1951 if (!mProcessesOnHold.contains(app)) { 1952 mProcessesOnHold.add(app); 1953 } 1954 return app; 1955 } 1956 1957 startProcessLocked(app, hostingType, hostingNameStr); 1958 return (app.pid != 0) ? app : null; 1959 } 1960 isAllowedWhileBooting(ApplicationInfo ai)1961 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1962 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1963 } 1964 startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)1965 private final void startProcessLocked(ProcessRecord app, 1966 String hostingType, String hostingNameStr) { 1967 if (app.pid > 0 && app.pid != MY_PID) { 1968 synchronized (mPidsSelfLocked) { 1969 mPidsSelfLocked.remove(app.pid); 1970 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1971 } 1972 app.pid = 0; 1973 } 1974 1975 mProcessesOnHold.remove(app); 1976 1977 updateCpuStats(); 1978 1979 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1980 mProcDeaths[0] = 0; 1981 1982 try { 1983 int uid = app.info.uid; 1984 int[] gids = null; 1985 try { 1986 gids = mContext.getPackageManager().getPackageGids( 1987 app.info.packageName); 1988 } catch (PackageManager.NameNotFoundException e) { 1989 Log.w(TAG, "Unable to retrieve gids", e); 1990 } 1991 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1992 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1993 && mTopComponent != null 1994 && app.processName.equals(mTopComponent.getPackageName())) { 1995 uid = 0; 1996 } 1997 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1998 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1999 uid = 0; 2000 } 2001 } 2002 int debugFlags = 0; 2003 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2004 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2005 } 2006 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2007 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2008 } 2009 if ("1".equals(SystemProperties.get("debug.assert"))) { 2010 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2011 } 2012 int pid = Process.start("android.app.ActivityThread", 2013 mSimpleProcessManagement ? app.processName : null, uid, uid, 2014 gids, debugFlags, null); 2015 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2016 synchronized (bs) { 2017 if (bs.isOnBattery()) { 2018 app.batteryStats.incStartsLocked(); 2019 } 2020 } 2021 2022 EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid, 2023 app.processName, hostingType, 2024 hostingNameStr != null ? hostingNameStr : ""); 2025 2026 if (app.persistent) { 2027 Watchdog.getInstance().processStarted(app, app.processName, pid); 2028 } 2029 2030 StringBuilder buf = mStringBuilder; 2031 buf.setLength(0); 2032 buf.append("Start proc "); 2033 buf.append(app.processName); 2034 buf.append(" for "); 2035 buf.append(hostingType); 2036 if (hostingNameStr != null) { 2037 buf.append(" "); 2038 buf.append(hostingNameStr); 2039 } 2040 buf.append(": pid="); 2041 buf.append(pid); 2042 buf.append(" uid="); 2043 buf.append(uid); 2044 buf.append(" gids={"); 2045 if (gids != null) { 2046 for (int gi=0; gi<gids.length; gi++) { 2047 if (gi != 0) buf.append(", "); 2048 buf.append(gids[gi]); 2049 2050 } 2051 } 2052 buf.append("}"); 2053 Log.i(TAG, buf.toString()); 2054 if (pid == 0 || pid == MY_PID) { 2055 // Processes are being emulated with threads. 2056 app.pid = MY_PID; 2057 app.removed = false; 2058 mStartingProcesses.add(app); 2059 } else if (pid > 0) { 2060 app.pid = pid; 2061 app.removed = false; 2062 synchronized (mPidsSelfLocked) { 2063 this.mPidsSelfLocked.put(pid, app); 2064 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2065 msg.obj = app; 2066 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 2067 } 2068 } else { 2069 app.pid = 0; 2070 RuntimeException e = new RuntimeException( 2071 "Failure starting process " + app.processName 2072 + ": returned pid=" + pid); 2073 Log.e(TAG, e.getMessage(), e); 2074 } 2075 } catch (RuntimeException e) { 2076 // XXX do better error recovery. 2077 app.pid = 0; 2078 Log.e(TAG, "Failure starting process " + app.processName, e); 2079 } 2080 } 2081 startPausingLocked(boolean userLeaving, boolean uiSleeping)2082 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 2083 if (mPausingActivity != null) { 2084 RuntimeException e = new RuntimeException(); 2085 Log.e(TAG, "Trying to pause when pause is already pending for " 2086 + mPausingActivity, e); 2087 } 2088 HistoryRecord prev = mResumedActivity; 2089 if (prev == null) { 2090 RuntimeException e = new RuntimeException(); 2091 Log.e(TAG, "Trying to pause when nothing is resumed", e); 2092 resumeTopActivityLocked(null); 2093 return; 2094 } 2095 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev); 2096 mResumedActivity = null; 2097 mPausingActivity = prev; 2098 mLastPausedActivity = prev; 2099 prev.state = ActivityState.PAUSING; 2100 prev.task.touchActiveTime(); 2101 2102 updateCpuStats(); 2103 2104 if (prev.app != null && prev.app.thread != null) { 2105 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev); 2106 try { 2107 EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY, 2108 System.identityHashCode(prev), 2109 prev.shortComponentName); 2110 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 2111 prev.configChangeFlags); 2112 updateUsageStats(prev, false); 2113 } catch (Exception e) { 2114 // Ignore exception, if process died other code will cleanup. 2115 Log.w(TAG, "Exception thrown during pause", e); 2116 mPausingActivity = null; 2117 mLastPausedActivity = null; 2118 } 2119 } else { 2120 mPausingActivity = null; 2121 mLastPausedActivity = null; 2122 } 2123 2124 // If we are not going to sleep, we want to ensure the device is 2125 // awake until the next activity is started. 2126 if (!mSleeping && !mShuttingDown) { 2127 mLaunchingActivity.acquire(); 2128 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2129 // To be safe, don't allow the wake lock to be held for too long. 2130 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 2131 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 2132 } 2133 } 2134 2135 2136 if (mPausingActivity != null) { 2137 // Have the window manager pause its key dispatching until the new 2138 // activity has started. If we're pausing the activity just because 2139 // the screen is being turned off and the UI is sleeping, don't interrupt 2140 // key dispatch; the same activity will pick it up again on wakeup. 2141 if (!uiSleeping) { 2142 prev.pauseKeyDispatchingLocked(); 2143 } else { 2144 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off"); 2145 } 2146 2147 // Schedule a pause timeout in case the app doesn't respond. 2148 // We don't give it much time because this directly impacts the 2149 // responsiveness seen by the user. 2150 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2151 msg.obj = prev; 2152 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2153 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete..."); 2154 } else { 2155 // This activity failed to schedule the 2156 // pause, so just treat it as being paused now. 2157 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next."); 2158 resumeTopActivityLocked(null); 2159 } 2160 } 2161 completePauseLocked()2162 private final void completePauseLocked() { 2163 HistoryRecord prev = mPausingActivity; 2164 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev); 2165 2166 if (prev != null) { 2167 if (prev.finishing) { 2168 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev); 2169 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2170 } else if (prev.app != null) { 2171 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev); 2172 if (prev.waitingVisible) { 2173 prev.waitingVisible = false; 2174 mWaitingVisibleActivities.remove(prev); 2175 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v( 2176 TAG, "Complete pause, no longer waiting: " + prev); 2177 } 2178 if (prev.configDestroy) { 2179 // The previous is being paused because the configuration 2180 // is changing, which means it is actually stopping... 2181 // To juggle the fact that we are also starting a new 2182 // instance right now, we need to first completely stop 2183 // the current instance before starting the new one. 2184 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev); 2185 destroyActivityLocked(prev, true); 2186 } else { 2187 mStoppingActivities.add(prev); 2188 if (mStoppingActivities.size() > 3) { 2189 // If we already have a few activities waiting to stop, 2190 // then give up on things going idle and start clearing 2191 // them out. 2192 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle"); 2193 Message msg = Message.obtain(); 2194 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2195 mHandler.sendMessage(msg); 2196 } 2197 } 2198 } else { 2199 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev); 2200 prev = null; 2201 } 2202 mPausingActivity = null; 2203 } 2204 2205 if (!mSleeping && !mShuttingDown) { 2206 resumeTopActivityLocked(prev); 2207 } else { 2208 if (mGoingToSleep.isHeld()) { 2209 mGoingToSleep.release(); 2210 } 2211 if (mShuttingDown) { 2212 notifyAll(); 2213 } 2214 } 2215 2216 if (prev != null) { 2217 prev.resumeKeyDispatchingLocked(); 2218 } 2219 2220 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2221 long diff = 0; 2222 synchronized (mProcessStatsThread) { 2223 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2224 } 2225 if (diff > 0) { 2226 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2227 synchronized (bsi) { 2228 BatteryStatsImpl.Uid.Proc ps = 2229 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2230 prev.info.packageName); 2231 if (ps != null) { 2232 ps.addForegroundTimeLocked(diff); 2233 } 2234 } 2235 } 2236 } 2237 prev.cpuTimeAtResume = 0; // reset it 2238 } 2239 2240 /** 2241 * Once we know that we have asked an application to put an activity in 2242 * the resumed state (either by launching it or explicitly telling it), 2243 * this function updates the rest of our state to match that fact. 2244 */ completeResumeLocked(HistoryRecord next)2245 private final void completeResumeLocked(HistoryRecord next) { 2246 next.idle = false; 2247 next.results = null; 2248 next.newIntents = null; 2249 2250 // schedule an idle timeout in case the app doesn't do it for us. 2251 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2252 msg.obj = next; 2253 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2254 2255 if (false) { 2256 // The activity was never told to pause, so just keep 2257 // things going as-is. To maintain our own state, 2258 // we need to emulate it coming back and saying it is 2259 // idle. 2260 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2261 msg.obj = next; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 reportResumedActivityLocked(next); 2266 2267 next.thumbnail = null; 2268 setFocusedActivityLocked(next); 2269 next.resumeKeyDispatchingLocked(); 2270 ensureActivitiesVisibleLocked(null, 0); 2271 mWindowManager.executeAppTransition(); 2272 mNoAnimActivities.clear(); 2273 2274 // Mark the point when the activity is resuming 2275 // TODO: To be more accurate, the mark should be before the onCreate, 2276 // not after the onResume. But for subsequent starts, onResume is fine. 2277 if (next.app != null) { 2278 synchronized (mProcessStatsThread) { 2279 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2280 } 2281 } else { 2282 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2283 } 2284 } 2285 2286 /** 2287 * Make sure that all activities that need to be visible (that is, they 2288 * currently can be seen by the user) actually are. 2289 */ ensureActivitiesVisibleLocked(HistoryRecord top, HistoryRecord starting, String onlyThisProcess, int configChanges)2290 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2291 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2292 if (DEBUG_VISBILITY) Log.v( 2293 TAG, "ensureActivitiesVisible behind " + top 2294 + " configChanges=0x" + Integer.toHexString(configChanges)); 2295 2296 // If the top activity is not fullscreen, then we need to 2297 // make sure any activities under it are now visible. 2298 final int count = mHistory.size(); 2299 int i = count-1; 2300 while (mHistory.get(i) != top) { 2301 i--; 2302 } 2303 HistoryRecord r; 2304 boolean behindFullscreen = false; 2305 for (; i>=0; i--) { 2306 r = (HistoryRecord)mHistory.get(i); 2307 if (DEBUG_VISBILITY) Log.v( 2308 TAG, "Make visible? " + r + " finishing=" + r.finishing 2309 + " state=" + r.state); 2310 if (r.finishing) { 2311 continue; 2312 } 2313 2314 final boolean doThisProcess = onlyThisProcess == null 2315 || onlyThisProcess.equals(r.processName); 2316 2317 // First: if this is not the current activity being started, make 2318 // sure it matches the current configuration. 2319 if (r != starting && doThisProcess) { 2320 ensureActivityConfigurationLocked(r, 0); 2321 } 2322 2323 if (r.app == null || r.app.thread == null) { 2324 if (onlyThisProcess == null 2325 || onlyThisProcess.equals(r.processName)) { 2326 // This activity needs to be visible, but isn't even 2327 // running... get it started, but don't resume it 2328 // at this point. 2329 if (DEBUG_VISBILITY) Log.v( 2330 TAG, "Start and freeze screen for " + r); 2331 if (r != starting) { 2332 r.startFreezingScreenLocked(r.app, configChanges); 2333 } 2334 if (!r.visible) { 2335 if (DEBUG_VISBILITY) Log.v( 2336 TAG, "Starting and making visible: " + r); 2337 mWindowManager.setAppVisibility(r, true); 2338 } 2339 if (r != starting) { 2340 startSpecificActivityLocked(r, false, false); 2341 } 2342 } 2343 2344 } else if (r.visible) { 2345 // If this activity is already visible, then there is nothing 2346 // else to do here. 2347 if (DEBUG_VISBILITY) Log.v( 2348 TAG, "Skipping: already visible at " + r); 2349 r.stopFreezingScreenLocked(false); 2350 2351 } else if (onlyThisProcess == null) { 2352 // This activity is not currently visible, but is running. 2353 // Tell it to become visible. 2354 r.visible = true; 2355 if (r.state != ActivityState.RESUMED && r != starting) { 2356 // If this activity is paused, tell it 2357 // to now show its window. 2358 if (DEBUG_VISBILITY) Log.v( 2359 TAG, "Making visible and scheduling visibility: " + r); 2360 try { 2361 mWindowManager.setAppVisibility(r, true); 2362 r.app.thread.scheduleWindowVisibility(r, true); 2363 r.stopFreezingScreenLocked(false); 2364 } catch (Exception e) { 2365 // Just skip on any failure; we'll make it 2366 // visible when it next restarts. 2367 Log.w(TAG, "Exception thrown making visibile: " 2368 + r.intent.getComponent(), e); 2369 } 2370 } 2371 } 2372 2373 // Aggregate current change flags. 2374 configChanges |= r.configChangeFlags; 2375 2376 if (r.fullscreen) { 2377 // At this point, nothing else needs to be shown 2378 if (DEBUG_VISBILITY) Log.v( 2379 TAG, "Stopping: fullscreen at " + r); 2380 behindFullscreen = true; 2381 i--; 2382 break; 2383 } 2384 } 2385 2386 // Now for any activities that aren't visible to the user, make 2387 // sure they no longer are keeping the screen frozen. 2388 while (i >= 0) { 2389 r = (HistoryRecord)mHistory.get(i); 2390 if (DEBUG_VISBILITY) Log.v( 2391 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2392 + " state=" + r.state 2393 + " behindFullscreen=" + behindFullscreen); 2394 if (!r.finishing) { 2395 if (behindFullscreen) { 2396 if (r.visible) { 2397 if (DEBUG_VISBILITY) Log.v( 2398 TAG, "Making invisible: " + r); 2399 r.visible = false; 2400 try { 2401 mWindowManager.setAppVisibility(r, false); 2402 if ((r.state == ActivityState.STOPPING 2403 || r.state == ActivityState.STOPPED) 2404 && r.app != null && r.app.thread != null) { 2405 if (DEBUG_VISBILITY) Log.v( 2406 TAG, "Scheduling invisibility: " + r); 2407 r.app.thread.scheduleWindowVisibility(r, false); 2408 } 2409 } catch (Exception e) { 2410 // Just skip on any failure; we'll make it 2411 // visible when it next restarts. 2412 Log.w(TAG, "Exception thrown making hidden: " 2413 + r.intent.getComponent(), e); 2414 } 2415 } else { 2416 if (DEBUG_VISBILITY) Log.v( 2417 TAG, "Already invisible: " + r); 2418 } 2419 } else if (r.fullscreen) { 2420 if (DEBUG_VISBILITY) Log.v( 2421 TAG, "Now behindFullscreen: " + r); 2422 behindFullscreen = true; 2423 } 2424 } 2425 i--; 2426 } 2427 } 2428 2429 /** 2430 * Version of ensureActivitiesVisible that can easily be called anywhere. 2431 */ ensureActivitiesVisibleLocked(HistoryRecord starting, int configChanges)2432 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2433 int configChanges) { 2434 HistoryRecord r = topRunningActivityLocked(null); 2435 if (r != null) { 2436 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2437 } 2438 } 2439 updateUsageStats(HistoryRecord resumedComponent, boolean resumed)2440 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2441 if (resumed) { 2442 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2443 } else { 2444 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2445 } 2446 } 2447 startHomeActivityLocked()2448 private boolean startHomeActivityLocked() { 2449 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2450 && mTopAction == null) { 2451 // We are running in factory test mode, but unable to find 2452 // the factory test app, so just sit around displaying the 2453 // error message and don't try to start anything. 2454 return false; 2455 } 2456 Intent intent = new Intent( 2457 mTopAction, 2458 mTopData != null ? Uri.parse(mTopData) : null); 2459 intent.setComponent(mTopComponent); 2460 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2461 intent.addCategory(Intent.CATEGORY_HOME); 2462 } 2463 ActivityInfo aInfo = 2464 intent.resolveActivityInfo(mContext.getPackageManager(), 2465 STOCK_PM_FLAGS); 2466 if (aInfo != null) { 2467 intent.setComponent(new ComponentName( 2468 aInfo.applicationInfo.packageName, aInfo.name)); 2469 // Don't do this if the home app is currently being 2470 // instrumented. 2471 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2472 aInfo.applicationInfo.uid); 2473 if (app == null || app.instrumentationClass == null) { 2474 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2475 startActivityLocked(null, intent, null, null, 0, aInfo, 2476 null, null, 0, 0, 0, false, false); 2477 } 2478 } 2479 2480 2481 return true; 2482 } 2483 2484 /** 2485 * Starts the "new version setup screen" if appropriate. 2486 */ startSetupActivityLocked()2487 private void startSetupActivityLocked() { 2488 // Only do this once per boot. 2489 if (mCheckedForSetup) { 2490 return; 2491 } 2492 2493 // We will show this screen if the current one is a different 2494 // version than the last one shown, and we are not running in 2495 // low-level factory test mode. 2496 final ContentResolver resolver = mContext.getContentResolver(); 2497 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2498 Settings.Secure.getInt(resolver, 2499 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2500 mCheckedForSetup = true; 2501 2502 // See if we should be showing the platform update setup UI. 2503 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2504 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2505 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2506 2507 // We don't allow third party apps to replace this. 2508 ResolveInfo ri = null; 2509 for (int i=0; ris != null && i<ris.size(); i++) { 2510 if ((ris.get(i).activityInfo.applicationInfo.flags 2511 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2512 ri = ris.get(i); 2513 break; 2514 } 2515 } 2516 2517 if (ri != null) { 2518 String vers = ri.activityInfo.metaData != null 2519 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2520 : null; 2521 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2522 vers = ri.activityInfo.applicationInfo.metaData.getString( 2523 Intent.METADATA_SETUP_VERSION); 2524 } 2525 String lastVers = Settings.Secure.getString( 2526 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2527 if (vers != null && !vers.equals(lastVers)) { 2528 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2529 intent.setComponent(new ComponentName( 2530 ri.activityInfo.packageName, ri.activityInfo.name)); 2531 startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2532 null, null, 0, 0, 0, false, false); 2533 } 2534 } 2535 } 2536 } 2537 reportResumedActivityLocked(HistoryRecord r)2538 private void reportResumedActivityLocked(HistoryRecord r) { 2539 //Log.i(TAG, "**** REPORT RESUME: " + r); 2540 2541 final int identHash = System.identityHashCode(r); 2542 updateUsageStats(r, true); 2543 2544 int i = mWatchers.beginBroadcast(); 2545 while (i > 0) { 2546 i--; 2547 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2548 if (w != null) { 2549 try { 2550 w.activityResuming(identHash); 2551 } catch (RemoteException e) { 2552 } 2553 } 2554 } 2555 mWatchers.finishBroadcast(); 2556 } 2557 2558 /** 2559 * Ensure that the top activity in the stack is resumed. 2560 * 2561 * @param prev The previously resumed activity, for when in the process 2562 * of pausing; can be null to call from elsewhere. 2563 * 2564 * @return Returns true if something is being resumed, or false if 2565 * nothing happened. 2566 */ resumeTopActivityLocked(HistoryRecord prev)2567 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2568 // Find the first activity that is not finishing. 2569 HistoryRecord next = topRunningActivityLocked(null); 2570 2571 // Remember how we'll process this pause/resume situation, and ensure 2572 // that the state is reset however we wind up proceeding. 2573 final boolean userLeaving = mUserLeaving; 2574 mUserLeaving = false; 2575 2576 if (next == null) { 2577 // There are no more activities! Let's just start up the 2578 // Launcher... 2579 return startHomeActivityLocked(); 2580 } 2581 2582 next.delayedResume = false; 2583 2584 // If the top activity is the resumed one, nothing to do. 2585 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2586 // Make sure we have executed any pending transitions, since there 2587 // should be nothing left to do at this point. 2588 mWindowManager.executeAppTransition(); 2589 mNoAnimActivities.clear(); 2590 return false; 2591 } 2592 2593 // If we are sleeping, and there is no resumed activity, and the top 2594 // activity is paused, well that is the state we want. 2595 if ((mSleeping || mShuttingDown) 2596 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2597 // Make sure we have executed any pending transitions, since there 2598 // should be nothing left to do at this point. 2599 mWindowManager.executeAppTransition(); 2600 mNoAnimActivities.clear(); 2601 return false; 2602 } 2603 2604 // The activity may be waiting for stop, but that is no longer 2605 // appropriate for it. 2606 mStoppingActivities.remove(next); 2607 mWaitingVisibleActivities.remove(next); 2608 2609 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next); 2610 2611 // If we are currently pausing an activity, then don't do anything 2612 // until that is done. 2613 if (mPausingActivity != null) { 2614 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2615 return false; 2616 } 2617 2618 // We need to start pausing the current activity so the top one 2619 // can be resumed... 2620 if (mResumedActivity != null) { 2621 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing"); 2622 startPausingLocked(userLeaving, false); 2623 return true; 2624 } 2625 2626 if (prev != null && prev != next) { 2627 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2628 prev.waitingVisible = true; 2629 mWaitingVisibleActivities.add(prev); 2630 if (DEBUG_SWITCH) Log.v( 2631 TAG, "Resuming top, waiting visible to hide: " + prev); 2632 } else { 2633 // The next activity is already visible, so hide the previous 2634 // activity's windows right now so we can show the new one ASAP. 2635 // We only do this if the previous is finishing, which should mean 2636 // it is on top of the one being resumed so hiding it quickly 2637 // is good. Otherwise, we want to do the normal route of allowing 2638 // the resumed activity to be shown so we can decide if the 2639 // previous should actually be hidden depending on whether the 2640 // new one is found to be full-screen or not. 2641 if (prev.finishing) { 2642 mWindowManager.setAppVisibility(prev, false); 2643 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: " 2644 + prev + ", waitingVisible=" 2645 + (prev != null ? prev.waitingVisible : null) 2646 + ", nowVisible=" + next.nowVisible); 2647 } else { 2648 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: " 2649 + prev + ", waitingVisible=" 2650 + (prev != null ? prev.waitingVisible : null) 2651 + ", nowVisible=" + next.nowVisible); 2652 } 2653 } 2654 } 2655 2656 // We are starting up the next activity, so tell the window manager 2657 // that the previous one will be hidden soon. This way it can know 2658 // to ignore it when computing the desired screen orientation. 2659 if (prev != null) { 2660 if (prev.finishing) { 2661 if (DEBUG_TRANSITION) Log.v(TAG, 2662 "Prepare close transition: prev=" + prev); 2663 if (mNoAnimActivities.contains(prev)) { 2664 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2665 } else { 2666 mWindowManager.prepareAppTransition(prev.task == next.task 2667 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2668 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2669 } 2670 mWindowManager.setAppWillBeHidden(prev); 2671 mWindowManager.setAppVisibility(prev, false); 2672 } else { 2673 if (DEBUG_TRANSITION) Log.v(TAG, 2674 "Prepare open transition: prev=" + prev); 2675 if (mNoAnimActivities.contains(next)) { 2676 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2677 } else { 2678 mWindowManager.prepareAppTransition(prev.task == next.task 2679 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2680 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2681 } 2682 } 2683 if (false) { 2684 mWindowManager.setAppWillBeHidden(prev); 2685 mWindowManager.setAppVisibility(prev, false); 2686 } 2687 } else if (mHistory.size() > 1) { 2688 if (DEBUG_TRANSITION) Log.v(TAG, 2689 "Prepare open transition: no previous"); 2690 if (mNoAnimActivities.contains(next)) { 2691 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2692 } else { 2693 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2694 } 2695 } 2696 2697 if (next.app != null && next.app.thread != null) { 2698 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next); 2699 2700 // This activity is now becoming visible. 2701 mWindowManager.setAppVisibility(next, true); 2702 2703 HistoryRecord lastResumedActivity = mResumedActivity; 2704 ActivityState lastState = next.state; 2705 2706 updateCpuStats(); 2707 2708 next.state = ActivityState.RESUMED; 2709 mResumedActivity = next; 2710 next.task.touchActiveTime(); 2711 updateLRUListLocked(next.app, true); 2712 updateLRUListLocked(next); 2713 2714 // Have the window manager re-evaluate the orientation of 2715 // the screen based on the new activity order. 2716 boolean updated; 2717 synchronized (this) { 2718 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2719 mConfiguration, 2720 next.mayFreezeScreenLocked(next.app) ? next : null); 2721 if (config != null) { 2722 /* 2723 * Explicitly restore the locale to the one from the 2724 * old configuration, since the one that comes back from 2725 * the window manager has the default (boot) locale. 2726 * 2727 * It looks like previously the locale picker only worked 2728 * by coincidence: usually it would do its setting of 2729 * the locale after the activity transition, so it didn't 2730 * matter that this lost it. With the synchronized 2731 * block now keeping them from happening at the same time, 2732 * this one always would happen second and undo what the 2733 * locale picker had just done. 2734 */ 2735 config.locale = mConfiguration.locale; 2736 next.frozenBeforeDestroy = true; 2737 } 2738 updated = updateConfigurationLocked(config, next); 2739 } 2740 if (!updated) { 2741 // The configuration update wasn't able to keep the existing 2742 // instance of the activity, and instead started a new one. 2743 // We should be all done, but let's just make sure our activity 2744 // is still at the top and schedule another run if something 2745 // weird happened. 2746 HistoryRecord nextNext = topRunningActivityLocked(null); 2747 if (DEBUG_SWITCH) Log.i(TAG, 2748 "Activity config changed during resume: " + next 2749 + ", new next: " + nextNext); 2750 if (nextNext != next) { 2751 // Do over! 2752 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2753 } 2754 setFocusedActivityLocked(next); 2755 ensureActivitiesVisibleLocked(null, 0); 2756 mWindowManager.executeAppTransition(); 2757 mNoAnimActivities.clear(); 2758 return true; 2759 } 2760 2761 try { 2762 // Deliver all pending results. 2763 ArrayList a = next.results; 2764 if (a != null) { 2765 final int N = a.size(); 2766 if (!next.finishing && N > 0) { 2767 if (DEBUG_RESULTS) Log.v( 2768 TAG, "Delivering results to " + next 2769 + ": " + a); 2770 next.app.thread.scheduleSendResult(next, a); 2771 } 2772 } 2773 2774 if (next.newIntents != null) { 2775 next.app.thread.scheduleNewIntent(next.newIntents, next); 2776 } 2777 2778 EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY, 2779 System.identityHashCode(next), 2780 next.task.taskId, next.shortComponentName); 2781 2782 next.app.thread.scheduleResumeActivity(next, 2783 isNextTransitionForward()); 2784 2785 pauseIfSleepingLocked(); 2786 2787 } catch (Exception e) { 2788 // Whoops, need to restart this activity! 2789 next.state = lastState; 2790 mResumedActivity = lastResumedActivity; 2791 if (Config.LOGD) Log.d(TAG, 2792 "Restarting because process died: " + next); 2793 if (!next.hasBeenLaunched) { 2794 next.hasBeenLaunched = true; 2795 } else { 2796 if (SHOW_APP_STARTING_ICON) { 2797 mWindowManager.setAppStartingWindow( 2798 next, next.packageName, next.theme, 2799 next.nonLocalizedLabel, 2800 next.labelRes, next.icon, null, true); 2801 } 2802 } 2803 startSpecificActivityLocked(next, true, false); 2804 return true; 2805 } 2806 2807 // From this point on, if something goes wrong there is no way 2808 // to recover the activity. 2809 try { 2810 next.visible = true; 2811 completeResumeLocked(next); 2812 } catch (Exception e) { 2813 // If any exception gets thrown, toss away this 2814 // activity and try the next one. 2815 Log.w(TAG, "Exception thrown during resume of " + next, e); 2816 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2817 "resume-exception"); 2818 return true; 2819 } 2820 2821 // Didn't need to use the icicle, and it is now out of date. 2822 next.icicle = null; 2823 next.haveState = false; 2824 next.stopped = false; 2825 2826 } else { 2827 // Whoops, need to restart this activity! 2828 if (!next.hasBeenLaunched) { 2829 next.hasBeenLaunched = true; 2830 } else { 2831 if (SHOW_APP_STARTING_ICON) { 2832 mWindowManager.setAppStartingWindow( 2833 next, next.packageName, next.theme, 2834 next.nonLocalizedLabel, 2835 next.labelRes, next.icon, null, true); 2836 } 2837 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next); 2838 } 2839 startSpecificActivityLocked(next, true, true); 2840 } 2841 2842 return true; 2843 } 2844 startActivityLocked(HistoryRecord r, boolean newTask, boolean doResume)2845 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2846 boolean doResume) { 2847 final int NH = mHistory.size(); 2848 2849 int addPos = -1; 2850 2851 if (!newTask) { 2852 // If starting in an existing task, find where that is... 2853 HistoryRecord next = null; 2854 boolean startIt = true; 2855 for (int i = NH-1; i >= 0; i--) { 2856 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2857 if (p.finishing) { 2858 continue; 2859 } 2860 if (p.task == r.task) { 2861 // Here it is! Now, if this is not yet visible to the 2862 // user, then just add it without starting; it will 2863 // get started when the user navigates back to it. 2864 addPos = i+1; 2865 if (!startIt) { 2866 mHistory.add(addPos, r); 2867 r.inHistory = true; 2868 r.task.numActivities++; 2869 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2870 r.info.screenOrientation, r.fullscreen); 2871 if (VALIDATE_TOKENS) { 2872 mWindowManager.validateAppTokens(mHistory); 2873 } 2874 return; 2875 } 2876 break; 2877 } 2878 if (p.fullscreen) { 2879 startIt = false; 2880 } 2881 next = p; 2882 } 2883 } 2884 2885 // Place a new activity at top of stack, so it is next to interact 2886 // with the user. 2887 if (addPos < 0) { 2888 addPos = mHistory.size(); 2889 } 2890 2891 // If we are not placing the new activity frontmost, we do not want 2892 // to deliver the onUserLeaving callback to the actual frontmost 2893 // activity 2894 if (addPos < NH) { 2895 mUserLeaving = false; 2896 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2897 } 2898 2899 // Slot the activity into the history stack and proceed 2900 mHistory.add(addPos, r); 2901 r.inHistory = true; 2902 r.frontOfTask = newTask; 2903 r.task.numActivities++; 2904 if (NH > 0) { 2905 // We want to show the starting preview window if we are 2906 // switching to a new task, or the next activity's process is 2907 // not currently running. 2908 boolean showStartingIcon = newTask; 2909 ProcessRecord proc = r.app; 2910 if (proc == null) { 2911 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2912 } 2913 if (proc == null || proc.thread == null) { 2914 showStartingIcon = true; 2915 } 2916 if (DEBUG_TRANSITION) Log.v(TAG, 2917 "Prepare open transition: starting " + r); 2918 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2919 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2920 mNoAnimActivities.add(r); 2921 } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 2922 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN); 2923 mNoAnimActivities.remove(r); 2924 } else { 2925 mWindowManager.prepareAppTransition(newTask 2926 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2927 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2928 mNoAnimActivities.remove(r); 2929 } 2930 mWindowManager.addAppToken( 2931 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2932 boolean doShow = true; 2933 if (newTask) { 2934 // Even though this activity is starting fresh, we still need 2935 // to reset it to make sure we apply affinities to move any 2936 // existing activities from other tasks in to it. 2937 // If the caller has requested that the target task be 2938 // reset, then do so. 2939 if ((r.intent.getFlags() 2940 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2941 resetTaskIfNeededLocked(r, r); 2942 doShow = topRunningNonDelayedActivityLocked(null) == r; 2943 } 2944 } 2945 if (SHOW_APP_STARTING_ICON && doShow) { 2946 // Figure out if we are transitioning from another activity that is 2947 // "has the same starting icon" as the next one. This allows the 2948 // window manager to keep the previous window it had previously 2949 // created, if it still had one. 2950 HistoryRecord prev = mResumedActivity; 2951 if (prev != null) { 2952 // We don't want to reuse the previous starting preview if: 2953 // (1) The current activity is in a different task. 2954 if (prev.task != r.task) prev = null; 2955 // (2) The current activity is already displayed. 2956 else if (prev.nowVisible) prev = null; 2957 } 2958 mWindowManager.setAppStartingWindow( 2959 r, r.packageName, r.theme, r.nonLocalizedLabel, 2960 r.labelRes, r.icon, prev, showStartingIcon); 2961 } 2962 } else { 2963 // If this is the first activity, don't do any fancy animations, 2964 // because there is nothing for it to animate on top of. 2965 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2966 r.info.screenOrientation, r.fullscreen); 2967 } 2968 if (VALIDATE_TOKENS) { 2969 mWindowManager.validateAppTokens(mHistory); 2970 } 2971 2972 if (doResume) { 2973 resumeTopActivityLocked(null); 2974 } 2975 } 2976 2977 /** 2978 * Perform clear operation as requested by 2979 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2980 * stack to the given task, then look for 2981 * an instance of that activity in the stack and, if found, finish all 2982 * activities on top of it and return the instance. 2983 * 2984 * @param newR Description of the new activity being started. 2985 * @return Returns the old activity that should be continue to be used, 2986 * or null if none was found. 2987 */ performClearTaskLocked(int taskId, HistoryRecord newR, int launchFlags, boolean doClear)2988 private final HistoryRecord performClearTaskLocked(int taskId, 2989 HistoryRecord newR, int launchFlags, boolean doClear) { 2990 int i = mHistory.size(); 2991 2992 // First find the requested task. 2993 while (i > 0) { 2994 i--; 2995 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2996 if (r.task.taskId == taskId) { 2997 i++; 2998 break; 2999 } 3000 } 3001 3002 // Now clear it. 3003 while (i > 0) { 3004 i--; 3005 HistoryRecord r = (HistoryRecord)mHistory.get(i); 3006 if (r.finishing) { 3007 continue; 3008 } 3009 if (r.task.taskId != taskId) { 3010 return null; 3011 } 3012 if (r.realActivity.equals(newR.realActivity)) { 3013 // Here it is! Now finish everything in front... 3014 HistoryRecord ret = r; 3015 if (doClear) { 3016 while (i < (mHistory.size()-1)) { 3017 i++; 3018 r = (HistoryRecord)mHistory.get(i); 3019 if (r.finishing) { 3020 continue; 3021 } 3022 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3023 null, "clear")) { 3024 i--; 3025 } 3026 } 3027 } 3028 3029 // Finally, if this is a normal launch mode (that is, not 3030 // expecting onNewIntent()), then we will finish the current 3031 // instance of the activity so a new fresh one can be started. 3032 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE 3033 && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { 3034 if (!ret.finishing) { 3035 int index = indexOfTokenLocked(ret); 3036 if (index >= 0) { 3037 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED, 3038 null, "clear"); 3039 } 3040 return null; 3041 } 3042 } 3043 3044 return ret; 3045 } 3046 } 3047 3048 return null; 3049 } 3050 3051 /** 3052 * Find the activity in the history stack within the given task. Returns 3053 * the index within the history at which it's found, or < 0 if not found. 3054 */ findActivityInHistoryLocked(HistoryRecord r, int task)3055 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 3056 int i = mHistory.size(); 3057 while (i > 0) { 3058 i--; 3059 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 3060 if (candidate.task.taskId != task) { 3061 break; 3062 } 3063 if (candidate.realActivity.equals(r.realActivity)) { 3064 return i; 3065 } 3066 } 3067 3068 return -1; 3069 } 3070 3071 /** 3072 * Reorder the history stack so that the activity at the given index is 3073 * brought to the front. 3074 */ moveActivityToFrontLocked(int where)3075 private final HistoryRecord moveActivityToFrontLocked(int where) { 3076 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 3077 int top = mHistory.size(); 3078 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 3079 mHistory.add(top, newTop); 3080 oldTop.frontOfTask = false; 3081 newTop.frontOfTask = true; 3082 return newTop; 3083 } 3084 3085 /** 3086 * Deliver a new Intent to an existing activity, so that its onNewIntent() 3087 * method will be called at the proper time. 3088 */ deliverNewIntentLocked(HistoryRecord r, Intent intent)3089 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 3090 boolean sent = false; 3091 if (r.state == ActivityState.RESUMED 3092 && r.app != null && r.app.thread != null) { 3093 try { 3094 ArrayList<Intent> ar = new ArrayList<Intent>(); 3095 ar.add(new Intent(intent)); 3096 r.app.thread.scheduleNewIntent(ar, r); 3097 sent = true; 3098 } catch (Exception e) { 3099 Log.w(TAG, "Exception thrown sending new intent to " + r, e); 3100 } 3101 } 3102 if (!sent) { 3103 r.addNewIntentLocked(new Intent(intent)); 3104 } 3105 } 3106 logStartActivity(int tag, HistoryRecord r, TaskRecord task)3107 private final void logStartActivity(int tag, HistoryRecord r, 3108 TaskRecord task) { 3109 EventLog.writeEvent(tag, 3110 System.identityHashCode(r), task.taskId, 3111 r.shortComponentName, r.intent.getAction(), 3112 r.intent.getType(), r.intent.getDataString(), 3113 r.intent.getFlags()); 3114 } 3115 startActivityLocked(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, ActivityInfo aInfo, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, boolean onlyIfNeeded, boolean componentSpecified)3116 private final int startActivityLocked(IApplicationThread caller, 3117 Intent intent, String resolvedType, 3118 Uri[] grantedUriPermissions, 3119 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 3120 String resultWho, int requestCode, 3121 int callingPid, int callingUid, boolean onlyIfNeeded, 3122 boolean componentSpecified) { 3123 Log.i(TAG, "Starting activity: " + intent); 3124 3125 HistoryRecord sourceRecord = null; 3126 HistoryRecord resultRecord = null; 3127 if (resultTo != null) { 3128 int index = indexOfTokenLocked(resultTo); 3129 if (DEBUG_RESULTS) Log.v( 3130 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 3131 if (index >= 0) { 3132 sourceRecord = (HistoryRecord)mHistory.get(index); 3133 if (requestCode >= 0 && !sourceRecord.finishing) { 3134 resultRecord = sourceRecord; 3135 } 3136 } 3137 } 3138 3139 int launchFlags = intent.getFlags(); 3140 3141 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 3142 && sourceRecord != null) { 3143 // Transfer the result target from the source activity to the new 3144 // one being started, including any failures. 3145 if (requestCode >= 0) { 3146 return START_FORWARD_AND_REQUEST_CONFLICT; 3147 } 3148 resultRecord = sourceRecord.resultTo; 3149 resultWho = sourceRecord.resultWho; 3150 requestCode = sourceRecord.requestCode; 3151 sourceRecord.resultTo = null; 3152 if (resultRecord != null) { 3153 resultRecord.removeResultsLocked( 3154 sourceRecord, resultWho, requestCode); 3155 } 3156 } 3157 3158 int err = START_SUCCESS; 3159 3160 if (intent.getComponent() == null) { 3161 // We couldn't find a class that can handle the given Intent. 3162 // That's the end of that! 3163 err = START_INTENT_NOT_RESOLVED; 3164 } 3165 3166 if (err == START_SUCCESS && aInfo == null) { 3167 // We couldn't find the specific class specified in the Intent. 3168 // Also the end of the line. 3169 err = START_CLASS_NOT_FOUND; 3170 } 3171 3172 ProcessRecord callerApp = null; 3173 if (err == START_SUCCESS && caller != null) { 3174 callerApp = getRecordForAppLocked(caller); 3175 if (callerApp != null) { 3176 callingPid = callerApp.pid; 3177 callingUid = callerApp.info.uid; 3178 } else { 3179 Log.w(TAG, "Unable to find app for caller " + caller 3180 + " (pid=" + callingPid + ") when starting: " 3181 + intent.toString()); 3182 err = START_PERMISSION_DENIED; 3183 } 3184 } 3185 3186 if (err != START_SUCCESS) { 3187 if (resultRecord != null) { 3188 sendActivityResultLocked(-1, 3189 resultRecord, resultWho, requestCode, 3190 Activity.RESULT_CANCELED, null); 3191 } 3192 return err; 3193 } 3194 3195 final int perm = checkComponentPermission(aInfo.permission, callingPid, 3196 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 3197 if (perm != PackageManager.PERMISSION_GRANTED) { 3198 if (resultRecord != null) { 3199 sendActivityResultLocked(-1, 3200 resultRecord, resultWho, requestCode, 3201 Activity.RESULT_CANCELED, null); 3202 } 3203 String msg = "Permission Denial: starting " + intent.toString() 3204 + " from " + callerApp + " (pid=" + callingPid 3205 + ", uid=" + callingUid + ")" 3206 + " requires " + aInfo.permission; 3207 Log.w(TAG, msg); 3208 throw new SecurityException(msg); 3209 } 3210 3211 if (mController != null) { 3212 boolean abort = false; 3213 try { 3214 // The Intent we give to the watcher has the extra data 3215 // stripped off, since it can contain private information. 3216 Intent watchIntent = intent.cloneFilter(); 3217 abort = !mController.activityStarting(watchIntent, 3218 aInfo.applicationInfo.packageName); 3219 } catch (RemoteException e) { 3220 mController = null; 3221 } 3222 3223 if (abort) { 3224 if (resultRecord != null) { 3225 sendActivityResultLocked(-1, 3226 resultRecord, resultWho, requestCode, 3227 Activity.RESULT_CANCELED, null); 3228 } 3229 // We pretend to the caller that it was really started, but 3230 // they will just get a cancel result. 3231 return START_SUCCESS; 3232 } 3233 } 3234 3235 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 3236 intent, resolvedType, aInfo, mConfiguration, 3237 resultRecord, resultWho, requestCode, componentSpecified); 3238 3239 if (mResumedActivity == null 3240 || mResumedActivity.info.applicationInfo.uid != callingUid) { 3241 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 3242 PendingActivityLaunch pal = new PendingActivityLaunch(); 3243 pal.r = r; 3244 pal.sourceRecord = sourceRecord; 3245 pal.grantedUriPermissions = grantedUriPermissions; 3246 pal.grantedMode = grantedMode; 3247 pal.onlyIfNeeded = onlyIfNeeded; 3248 mPendingActivityLaunches.add(pal); 3249 return START_SWITCHES_CANCELED; 3250 } 3251 } 3252 3253 if (mDidAppSwitch) { 3254 // This is the second allowed switch since we stopped switches, 3255 // so now just generally allow switches. Use case: user presses 3256 // home (switches disabled, switch to home, mDidAppSwitch now true); 3257 // user taps a home icon (coming from home so allowed, we hit here 3258 // and now allow anyone to switch again). 3259 mAppSwitchesAllowedTime = 0; 3260 } else { 3261 mDidAppSwitch = true; 3262 } 3263 3264 doPendingActivityLaunchesLocked(false); 3265 3266 return startActivityUncheckedLocked(r, sourceRecord, 3267 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 3268 } 3269 doPendingActivityLaunchesLocked(boolean doResume)3270 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3271 final int N = mPendingActivityLaunches.size(); 3272 if (N <= 0) { 3273 return; 3274 } 3275 for (int i=0; i<N; i++) { 3276 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3277 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3278 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3279 doResume && i == (N-1)); 3280 } 3281 mPendingActivityLaunches.clear(); 3282 } 3283 startActivityUncheckedLocked(HistoryRecord r, HistoryRecord sourceRecord, Uri[] grantedUriPermissions, int grantedMode, boolean onlyIfNeeded, boolean doResume)3284 private final int startActivityUncheckedLocked(HistoryRecord r, 3285 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3286 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3287 final Intent intent = r.intent; 3288 final int callingUid = r.launchedFromUid; 3289 3290 int launchFlags = intent.getFlags(); 3291 3292 // We'll invoke onUserLeaving before onPause only if the launching 3293 // activity did not explicitly state that this is an automated launch. 3294 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3295 if (DEBUG_USER_LEAVING) Log.v(TAG, 3296 "startActivity() => mUserLeaving=" + mUserLeaving); 3297 3298 // If the caller has asked not to resume at this point, we make note 3299 // of this in the record so that we can skip it when trying to find 3300 // the top running activity. 3301 if (!doResume) { 3302 r.delayedResume = true; 3303 } 3304 3305 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3306 != 0 ? r : null; 3307 3308 // If the onlyIfNeeded flag is set, then we can do this if the activity 3309 // being launched is the same as the one making the call... or, as 3310 // a special case, if we do not know the caller then we count the 3311 // current top activity as the caller. 3312 if (onlyIfNeeded) { 3313 HistoryRecord checkedCaller = sourceRecord; 3314 if (checkedCaller == null) { 3315 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3316 } 3317 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3318 // Caller is not the same as launcher, so always needed. 3319 onlyIfNeeded = false; 3320 } 3321 } 3322 3323 if (grantedUriPermissions != null && callingUid > 0) { 3324 for (int i=0; i<grantedUriPermissions.length; i++) { 3325 grantUriPermissionLocked(callingUid, r.packageName, 3326 grantedUriPermissions[i], grantedMode, r); 3327 } 3328 } 3329 3330 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3331 intent, r); 3332 3333 if (sourceRecord == null) { 3334 // This activity is not being started from another... in this 3335 // case we -always- start a new task. 3336 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3337 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3338 + intent); 3339 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3340 } 3341 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3342 // The original activity who is starting us is running as a single 3343 // instance... this new activity it is starting must go on its 3344 // own task. 3345 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3346 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3347 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3348 // The activity being started is a single instance... it always 3349 // gets launched into its own task. 3350 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3351 } 3352 3353 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3354 // For whatever reason this activity is being launched into a new 3355 // task... yet the caller has requested a result back. Well, that 3356 // is pretty messed up, so instead immediately send back a cancel 3357 // and let the new task continue launched as normal without a 3358 // dependency on its originator. 3359 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3360 sendActivityResultLocked(-1, 3361 r.resultTo, r.resultWho, r.requestCode, 3362 Activity.RESULT_CANCELED, null); 3363 r.resultTo = null; 3364 } 3365 3366 boolean addingToTask = false; 3367 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3368 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3369 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3370 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3371 // If bring to front is requested, and no result is requested, and 3372 // we can find a task that was started with this same 3373 // component, then instead of launching bring that one to the front. 3374 if (r.resultTo == null) { 3375 // See if there is a task to bring to the front. If this is 3376 // a SINGLE_INSTANCE activity, there can be one and only one 3377 // instance of it in the history, and it is always in its own 3378 // unique task, so we do a special search. 3379 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3380 ? findTaskLocked(intent, r.info) 3381 : findActivityLocked(intent, r.info); 3382 if (taskTop != null) { 3383 if (taskTop.task.intent == null) { 3384 // This task was started because of movement of 3385 // the activity based on affinity... now that we 3386 // are actually launching it, we can assign the 3387 // base intent. 3388 taskTop.task.setIntent(intent, r.info); 3389 } 3390 // If the target task is not in the front, then we need 3391 // to bring it to the front... except... well, with 3392 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3393 // to have the same behavior as if a new instance was 3394 // being started, which means not bringing it to the front 3395 // if the caller is not itself in the front. 3396 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3397 if (curTop.task != taskTop.task) { 3398 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3399 boolean callerAtFront = sourceRecord == null 3400 || curTop.task == sourceRecord.task; 3401 if (callerAtFront) { 3402 // We really do want to push this one into the 3403 // user's face, right now. 3404 moveTaskToFrontLocked(taskTop.task, r); 3405 } 3406 } 3407 // If the caller has requested that the target task be 3408 // reset, then do so. 3409 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3410 taskTop = resetTaskIfNeededLocked(taskTop, r); 3411 } 3412 if (onlyIfNeeded) { 3413 // We don't need to start a new activity, and 3414 // the client said not to do anything if that 3415 // is the case, so this is it! And for paranoia, make 3416 // sure we have correctly resumed the top activity. 3417 if (doResume) { 3418 resumeTopActivityLocked(null); 3419 } 3420 return START_RETURN_INTENT_TO_CALLER; 3421 } 3422 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3423 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3424 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3425 // In this situation we want to remove all activities 3426 // from the task up to the one being started. In most 3427 // cases this means we are resetting the task to its 3428 // initial state. 3429 HistoryRecord top = performClearTaskLocked( 3430 taskTop.task.taskId, r, launchFlags, true); 3431 if (top != null) { 3432 if (top.frontOfTask) { 3433 // Activity aliases may mean we use different 3434 // intents for the top activity, so make sure 3435 // the task now has the identity of the new 3436 // intent. 3437 top.task.setIntent(r.intent, r.info); 3438 } 3439 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3440 deliverNewIntentLocked(top, r.intent); 3441 } else { 3442 // A special case: we need to 3443 // start the activity because it is not currently 3444 // running, and the caller has asked to clear the 3445 // current task to have this activity at the top. 3446 addingToTask = true; 3447 // Now pretend like this activity is being started 3448 // by the top of its task, so it is put in the 3449 // right place. 3450 sourceRecord = taskTop; 3451 } 3452 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3453 // In this case the top activity on the task is the 3454 // same as the one being launched, so we take that 3455 // as a request to bring the task to the foreground. 3456 // If the top activity in the task is the root 3457 // activity, deliver this new intent to it if it 3458 // desires. 3459 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3460 && taskTop.realActivity.equals(r.realActivity)) { 3461 logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task); 3462 if (taskTop.frontOfTask) { 3463 taskTop.task.setIntent(r.intent, r.info); 3464 } 3465 deliverNewIntentLocked(taskTop, r.intent); 3466 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3467 // In this case we are launching the root activity 3468 // of the task, but with a different intent. We 3469 // should start a new instance on top. 3470 addingToTask = true; 3471 sourceRecord = taskTop; 3472 } 3473 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3474 // In this case an activity is being launched in to an 3475 // existing task, without resetting that task. This 3476 // is typically the situation of launching an activity 3477 // from a notification or shortcut. We want to place 3478 // the new activity on top of the current task. 3479 addingToTask = true; 3480 sourceRecord = taskTop; 3481 } else if (!taskTop.task.rootWasReset) { 3482 // In this case we are launching in to an existing task 3483 // that has not yet been started from its front door. 3484 // The current task has been brought to the front. 3485 // Ideally, we'd probably like to place this new task 3486 // at the bottom of its stack, but that's a little hard 3487 // to do with the current organization of the code so 3488 // for now we'll just drop it. 3489 taskTop.task.setIntent(r.intent, r.info); 3490 } 3491 if (!addingToTask) { 3492 // We didn't do anything... but it was needed (a.k.a., client 3493 // don't use that intent!) And for paranoia, make 3494 // sure we have correctly resumed the top activity. 3495 if (doResume) { 3496 resumeTopActivityLocked(null); 3497 } 3498 return START_TASK_TO_FRONT; 3499 } 3500 } 3501 } 3502 } 3503 3504 //String uri = r.intent.toURI(); 3505 //Intent intent2 = new Intent(uri); 3506 //Log.i(TAG, "Given intent: " + r.intent); 3507 //Log.i(TAG, "URI is: " + uri); 3508 //Log.i(TAG, "To intent: " + intent2); 3509 3510 if (r.packageName != null) { 3511 // If the activity being launched is the same as the one currently 3512 // at the top, then we need to check if it should only be launched 3513 // once. 3514 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3515 if (top != null && r.resultTo == null) { 3516 if (top.realActivity.equals(r.realActivity)) { 3517 if (top.app != null && top.app.thread != null) { 3518 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3519 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3520 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3521 logStartActivity(LOG_AM_NEW_INTENT, top, top.task); 3522 // For paranoia, make sure we have correctly 3523 // resumed the top activity. 3524 if (doResume) { 3525 resumeTopActivityLocked(null); 3526 } 3527 if (onlyIfNeeded) { 3528 // We don't need to start a new activity, and 3529 // the client said not to do anything if that 3530 // is the case, so this is it! 3531 return START_RETURN_INTENT_TO_CALLER; 3532 } 3533 deliverNewIntentLocked(top, r.intent); 3534 return START_DELIVERED_TO_TOP; 3535 } 3536 } 3537 } 3538 } 3539 3540 } else { 3541 if (r.resultTo != null) { 3542 sendActivityResultLocked(-1, 3543 r.resultTo, r.resultWho, r.requestCode, 3544 Activity.RESULT_CANCELED, null); 3545 } 3546 return START_CLASS_NOT_FOUND; 3547 } 3548 3549 boolean newTask = false; 3550 3551 // Should this be considered a new task? 3552 if (r.resultTo == null && !addingToTask 3553 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3554 // todo: should do better management of integers. 3555 mCurTask++; 3556 if (mCurTask <= 0) { 3557 mCurTask = 1; 3558 } 3559 r.task = new TaskRecord(mCurTask, r.info, intent, 3560 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3561 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3562 + " in new task " + r.task); 3563 newTask = true; 3564 addRecentTask(r.task); 3565 3566 } else if (sourceRecord != null) { 3567 if (!addingToTask && 3568 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3569 // In this case, we are adding the activity to an existing 3570 // task, but the caller has asked to clear that task if the 3571 // activity is already running. 3572 HistoryRecord top = performClearTaskLocked( 3573 sourceRecord.task.taskId, r, launchFlags, true); 3574 if (top != null) { 3575 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3576 deliverNewIntentLocked(top, r.intent); 3577 // For paranoia, make sure we have correctly 3578 // resumed the top activity. 3579 if (doResume) { 3580 resumeTopActivityLocked(null); 3581 } 3582 return START_DELIVERED_TO_TOP; 3583 } 3584 } else if (!addingToTask && 3585 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3586 // In this case, we are launching an activity in our own task 3587 // that may already be running somewhere in the history, and 3588 // we want to shuffle it to the front of the stack if so. 3589 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3590 if (where >= 0) { 3591 HistoryRecord top = moveActivityToFrontLocked(where); 3592 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3593 deliverNewIntentLocked(top, r.intent); 3594 if (doResume) { 3595 resumeTopActivityLocked(null); 3596 } 3597 return START_DELIVERED_TO_TOP; 3598 } 3599 } 3600 // An existing activity is starting this new activity, so we want 3601 // to keep the new one in the same task as the one that is starting 3602 // it. 3603 r.task = sourceRecord.task; 3604 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3605 + " in existing task " + r.task); 3606 3607 } else { 3608 // This not being started from an existing activity, and not part 3609 // of a new task... just put it in the top task, though these days 3610 // this case should never happen. 3611 final int N = mHistory.size(); 3612 HistoryRecord prev = 3613 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3614 r.task = prev != null 3615 ? prev.task 3616 : new TaskRecord(mCurTask, r.info, intent, 3617 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3618 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3619 + " in new guessed " + r.task); 3620 } 3621 if (newTask) { 3622 EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId); 3623 } 3624 logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task); 3625 startActivityLocked(r, newTask, doResume); 3626 return START_SUCCESS; 3627 } 3628 startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug)3629 public final int startActivity(IApplicationThread caller, 3630 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3631 int grantedMode, IBinder resultTo, 3632 String resultWho, int requestCode, boolean onlyIfNeeded, 3633 boolean debug) { 3634 // Refuse possible leaked file descriptors 3635 if (intent != null && intent.hasFileDescriptors()) { 3636 throw new IllegalArgumentException("File descriptors passed in Intent"); 3637 } 3638 3639 final boolean componentSpecified = intent.getComponent() != null; 3640 3641 // Don't modify the client's object! 3642 intent = new Intent(intent); 3643 3644 // Collect information about the target of the Intent. 3645 ActivityInfo aInfo; 3646 try { 3647 ResolveInfo rInfo = 3648 ActivityThread.getPackageManager().resolveIntent( 3649 intent, resolvedType, 3650 PackageManager.MATCH_DEFAULT_ONLY 3651 | STOCK_PM_FLAGS); 3652 aInfo = rInfo != null ? rInfo.activityInfo : null; 3653 } catch (RemoteException e) { 3654 aInfo = null; 3655 } 3656 3657 if (aInfo != null) { 3658 // Store the found target back into the intent, because now that 3659 // we have it we never want to do this again. For example, if the 3660 // user navigates back to this point in the history, we should 3661 // always restart the exact same activity. 3662 intent.setComponent(new ComponentName( 3663 aInfo.applicationInfo.packageName, aInfo.name)); 3664 3665 // Don't debug things in the system process 3666 if (debug) { 3667 if (!aInfo.processName.equals("system")) { 3668 setDebugApp(aInfo.processName, true, false); 3669 } 3670 } 3671 } 3672 3673 synchronized(this) { 3674 final long origId = Binder.clearCallingIdentity(); 3675 int res = startActivityLocked(caller, intent, resolvedType, 3676 grantedUriPermissions, grantedMode, aInfo, 3677 resultTo, resultWho, requestCode, -1, -1, 3678 onlyIfNeeded, componentSpecified); 3679 Binder.restoreCallingIdentity(origId); 3680 return res; 3681 } 3682 } 3683 startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues)3684 public int startActivityIntentSender(IApplicationThread caller, 3685 IntentSender intent, Intent fillInIntent, String resolvedType, 3686 IBinder resultTo, String resultWho, int requestCode, 3687 int flagsMask, int flagsValues) { 3688 // Refuse possible leaked file descriptors 3689 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3690 throw new IllegalArgumentException("File descriptors passed in Intent"); 3691 } 3692 3693 IIntentSender sender = intent.getTarget(); 3694 if (!(sender instanceof PendingIntentRecord)) { 3695 throw new IllegalArgumentException("Bad PendingIntent object"); 3696 } 3697 3698 PendingIntentRecord pir = (PendingIntentRecord)sender; 3699 3700 synchronized (this) { 3701 // If this is coming from the currently resumed activity, it is 3702 // effectively saying that app switches are allowed at this point. 3703 if (mResumedActivity != null 3704 && mResumedActivity.info.applicationInfo.uid == 3705 Binder.getCallingUid()) { 3706 mAppSwitchesAllowedTime = 0; 3707 } 3708 } 3709 3710 return pir.sendInner(0, fillInIntent, resolvedType, 3711 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 3712 } 3713 startNextMatchingActivity(IBinder callingActivity, Intent intent)3714 public boolean startNextMatchingActivity(IBinder callingActivity, 3715 Intent intent) { 3716 // Refuse possible leaked file descriptors 3717 if (intent != null && intent.hasFileDescriptors() == true) { 3718 throw new IllegalArgumentException("File descriptors passed in Intent"); 3719 } 3720 3721 synchronized (this) { 3722 int index = indexOfTokenLocked(callingActivity); 3723 if (index < 0) { 3724 return false; 3725 } 3726 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3727 if (r.app == null || r.app.thread == null) { 3728 // The caller is not running... d'oh! 3729 return false; 3730 } 3731 intent = new Intent(intent); 3732 // The caller is not allowed to change the data. 3733 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3734 // And we are resetting to find the next component... 3735 intent.setComponent(null); 3736 3737 ActivityInfo aInfo = null; 3738 try { 3739 List<ResolveInfo> resolves = 3740 ActivityThread.getPackageManager().queryIntentActivities( 3741 intent, r.resolvedType, 3742 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3743 3744 // Look for the original activity in the list... 3745 final int N = resolves != null ? resolves.size() : 0; 3746 for (int i=0; i<N; i++) { 3747 ResolveInfo rInfo = resolves.get(i); 3748 if (rInfo.activityInfo.packageName.equals(r.packageName) 3749 && rInfo.activityInfo.name.equals(r.info.name)) { 3750 // We found the current one... the next matching is 3751 // after it. 3752 i++; 3753 if (i<N) { 3754 aInfo = resolves.get(i).activityInfo; 3755 } 3756 break; 3757 } 3758 } 3759 } catch (RemoteException e) { 3760 } 3761 3762 if (aInfo == null) { 3763 // Nobody who is next! 3764 return false; 3765 } 3766 3767 intent.setComponent(new ComponentName( 3768 aInfo.applicationInfo.packageName, aInfo.name)); 3769 intent.setFlags(intent.getFlags()&~( 3770 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3771 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3772 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3773 Intent.FLAG_ACTIVITY_NEW_TASK)); 3774 3775 // Okay now we need to start the new activity, replacing the 3776 // currently running activity. This is a little tricky because 3777 // we want to start the new one as if the current one is finished, 3778 // but not finish the current one first so that there is no flicker. 3779 // And thus... 3780 final boolean wasFinishing = r.finishing; 3781 r.finishing = true; 3782 3783 // Propagate reply information over to the new activity. 3784 final HistoryRecord resultTo = r.resultTo; 3785 final String resultWho = r.resultWho; 3786 final int requestCode = r.requestCode; 3787 r.resultTo = null; 3788 if (resultTo != null) { 3789 resultTo.removeResultsLocked(r, resultWho, requestCode); 3790 } 3791 3792 final long origId = Binder.clearCallingIdentity(); 3793 // XXX we are not dealing with propagating grantedUriPermissions... 3794 // those are not yet exposed to user code, so there is no need. 3795 int res = startActivityLocked(r.app.thread, intent, 3796 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3797 requestCode, -1, r.launchedFromUid, false, false); 3798 Binder.restoreCallingIdentity(origId); 3799 3800 r.finishing = wasFinishing; 3801 if (res != START_SUCCESS) { 3802 return false; 3803 } 3804 return true; 3805 } 3806 } 3807 startActivityInPackage(int uid, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded)3808 public final int startActivityInPackage(int uid, 3809 Intent intent, String resolvedType, IBinder resultTo, 3810 String resultWho, int requestCode, boolean onlyIfNeeded) { 3811 3812 // This is so super not safe, that only the system (or okay root) 3813 // can do it. 3814 final int callingUid = Binder.getCallingUid(); 3815 if (callingUid != 0 && callingUid != Process.myUid()) { 3816 throw new SecurityException( 3817 "startActivityInPackage only available to the system"); 3818 } 3819 3820 final boolean componentSpecified = intent.getComponent() != null; 3821 3822 // Don't modify the client's object! 3823 intent = new Intent(intent); 3824 3825 // Collect information about the target of the Intent. 3826 ActivityInfo aInfo; 3827 try { 3828 ResolveInfo rInfo = 3829 ActivityThread.getPackageManager().resolveIntent( 3830 intent, resolvedType, 3831 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3832 aInfo = rInfo != null ? rInfo.activityInfo : null; 3833 } catch (RemoteException e) { 3834 aInfo = null; 3835 } 3836 3837 if (aInfo != null) { 3838 // Store the found target back into the intent, because now that 3839 // we have it we never want to do this again. For example, if the 3840 // user navigates back to this point in the history, we should 3841 // always restart the exact same activity. 3842 intent.setComponent(new ComponentName( 3843 aInfo.applicationInfo.packageName, aInfo.name)); 3844 } 3845 3846 synchronized(this) { 3847 return startActivityLocked(null, intent, resolvedType, 3848 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3849 onlyIfNeeded, componentSpecified); 3850 } 3851 } 3852 addRecentTask(TaskRecord task)3853 private final void addRecentTask(TaskRecord task) { 3854 // Remove any existing entries that are the same kind of task. 3855 int N = mRecentTasks.size(); 3856 for (int i=0; i<N; i++) { 3857 TaskRecord tr = mRecentTasks.get(i); 3858 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3859 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3860 mRecentTasks.remove(i); 3861 i--; 3862 N--; 3863 if (task.intent == null) { 3864 // If the new recent task we are adding is not fully 3865 // specified, then replace it with the existing recent task. 3866 task = tr; 3867 } 3868 } 3869 } 3870 if (N >= MAX_RECENT_TASKS) { 3871 mRecentTasks.remove(N-1); 3872 } 3873 mRecentTasks.add(0, task); 3874 } 3875 setRequestedOrientation(IBinder token, int requestedOrientation)3876 public void setRequestedOrientation(IBinder token, 3877 int requestedOrientation) { 3878 synchronized (this) { 3879 int index = indexOfTokenLocked(token); 3880 if (index < 0) { 3881 return; 3882 } 3883 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3884 final long origId = Binder.clearCallingIdentity(); 3885 mWindowManager.setAppOrientation(r, requestedOrientation); 3886 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3887 mConfiguration, 3888 r.mayFreezeScreenLocked(r.app) ? r : null); 3889 if (config != null) { 3890 r.frozenBeforeDestroy = true; 3891 if (!updateConfigurationLocked(config, r)) { 3892 resumeTopActivityLocked(null); 3893 } 3894 } 3895 Binder.restoreCallingIdentity(origId); 3896 } 3897 } 3898 getRequestedOrientation(IBinder token)3899 public int getRequestedOrientation(IBinder token) { 3900 synchronized (this) { 3901 int index = indexOfTokenLocked(token); 3902 if (index < 0) { 3903 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3904 } 3905 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3906 return mWindowManager.getAppOrientation(r); 3907 } 3908 } 3909 stopActivityLocked(HistoryRecord r)3910 private final void stopActivityLocked(HistoryRecord r) { 3911 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r); 3912 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3913 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3914 if (!r.finishing) { 3915 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 3916 "no-history"); 3917 } 3918 } else if (r.app != null && r.app.thread != null) { 3919 if (mFocusedActivity == r) { 3920 setFocusedActivityLocked(topRunningActivityLocked(null)); 3921 } 3922 r.resumeKeyDispatchingLocked(); 3923 try { 3924 r.stopped = false; 3925 r.state = ActivityState.STOPPING; 3926 if (DEBUG_VISBILITY) Log.v( 3927 TAG, "Stopping visible=" + r.visible + " for " + r); 3928 if (!r.visible) { 3929 mWindowManager.setAppVisibility(r, false); 3930 } 3931 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 3932 } catch (Exception e) { 3933 // Maybe just ignore exceptions here... if the process 3934 // has crashed, our death notification will clean things 3935 // up. 3936 Log.w(TAG, "Exception thrown during pause", e); 3937 // Just in case, assume it to be stopped. 3938 r.stopped = true; 3939 r.state = ActivityState.STOPPED; 3940 if (r.configDestroy) { 3941 destroyActivityLocked(r, true); 3942 } 3943 } 3944 } 3945 } 3946 3947 /** 3948 * @return Returns true if the activity is being finished, false if for 3949 * some reason it is being left as-is. 3950 */ requestFinishActivityLocked(IBinder token, int resultCode, Intent resultData, String reason)3951 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3952 Intent resultData, String reason) { 3953 if (DEBUG_RESULTS) Log.v( 3954 TAG, "Finishing activity: token=" + token 3955 + ", result=" + resultCode + ", data=" + resultData); 3956 3957 int index = indexOfTokenLocked(token); 3958 if (index < 0) { 3959 return false; 3960 } 3961 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3962 3963 // Is this the last activity left? 3964 boolean lastActivity = true; 3965 for (int i=mHistory.size()-1; i>=0; i--) { 3966 HistoryRecord p = (HistoryRecord)mHistory.get(i); 3967 if (!p.finishing && p != r) { 3968 lastActivity = false; 3969 break; 3970 } 3971 } 3972 3973 // If this is the last activity, but it is the home activity, then 3974 // just don't finish it. 3975 if (lastActivity) { 3976 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 3977 return false; 3978 } 3979 } 3980 3981 finishActivityLocked(r, index, resultCode, resultData, reason); 3982 return true; 3983 } 3984 3985 /** 3986 * @return Returns true if this activity has been removed from the history 3987 * list, or false if it is still in the list and will be removed later. 3988 */ finishActivityLocked(HistoryRecord r, int index, int resultCode, Intent resultData, String reason)3989 private final boolean finishActivityLocked(HistoryRecord r, int index, 3990 int resultCode, Intent resultData, String reason) { 3991 if (r.finishing) { 3992 Log.w(TAG, "Duplicate finish request for " + r); 3993 return false; 3994 } 3995 3996 r.finishing = true; 3997 EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY, 3998 System.identityHashCode(r), 3999 r.task.taskId, r.shortComponentName, reason); 4000 r.task.numActivities--; 4001 if (r.frontOfTask && index < (mHistory.size()-1)) { 4002 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 4003 if (next.task == r.task) { 4004 next.frontOfTask = true; 4005 } 4006 } 4007 4008 r.pauseKeyDispatchingLocked(); 4009 if (mFocusedActivity == r) { 4010 setFocusedActivityLocked(topRunningActivityLocked(null)); 4011 } 4012 4013 // send the result 4014 HistoryRecord resultTo = r.resultTo; 4015 if (resultTo != null) { 4016 if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo 4017 + " who=" + r.resultWho + " req=" + r.requestCode 4018 + " res=" + resultCode + " data=" + resultData); 4019 if (r.info.applicationInfo.uid > 0) { 4020 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 4021 r.packageName, resultData, r); 4022 } 4023 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 4024 resultData); 4025 r.resultTo = null; 4026 } 4027 else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r); 4028 4029 // Make sure this HistoryRecord is not holding on to other resources, 4030 // because clients have remote IPC references to this object so we 4031 // can't assume that will go away and want to avoid circular IPC refs. 4032 r.results = null; 4033 r.pendingResults = null; 4034 r.newIntents = null; 4035 r.icicle = null; 4036 4037 if (mPendingThumbnails.size() > 0) { 4038 // There are clients waiting to receive thumbnails so, in case 4039 // this is an activity that someone is waiting for, add it 4040 // to the pending list so we can correctly update the clients. 4041 mCancelledThumbnails.add(r); 4042 } 4043 4044 if (mResumedActivity == r) { 4045 boolean endTask = index <= 0 4046 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 4047 if (DEBUG_TRANSITION) Log.v(TAG, 4048 "Prepare close transition: finishing " + r); 4049 mWindowManager.prepareAppTransition(endTask 4050 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 4051 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 4052 4053 // Tell window manager to prepare for this one to be removed. 4054 mWindowManager.setAppVisibility(r, false); 4055 4056 if (mPausingActivity == null) { 4057 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r); 4058 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false"); 4059 startPausingLocked(false, false); 4060 } 4061 4062 } else if (r.state != ActivityState.PAUSING) { 4063 // If the activity is PAUSING, we will complete the finish once 4064 // it is done pausing; else we can just directly finish it here. 4065 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r); 4066 return finishCurrentActivityLocked(r, index, 4067 FINISH_AFTER_PAUSE) == null; 4068 } else { 4069 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r); 4070 } 4071 4072 return false; 4073 } 4074 4075 private static final int FINISH_IMMEDIATELY = 0; 4076 private static final int FINISH_AFTER_PAUSE = 1; 4077 private static final int FINISH_AFTER_VISIBLE = 2; 4078 finishCurrentActivityLocked(HistoryRecord r, int mode)4079 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4080 int mode) { 4081 final int index = indexOfTokenLocked(r); 4082 if (index < 0) { 4083 return null; 4084 } 4085 4086 return finishCurrentActivityLocked(r, index, mode); 4087 } 4088 finishCurrentActivityLocked(HistoryRecord r, int index, int mode)4089 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4090 int index, int mode) { 4091 // First things first: if this activity is currently visible, 4092 // and the resumed activity is not yet visible, then hold off on 4093 // finishing until the resumed one becomes visible. 4094 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 4095 if (!mStoppingActivities.contains(r)) { 4096 mStoppingActivities.add(r); 4097 if (mStoppingActivities.size() > 3) { 4098 // If we already have a few activities waiting to stop, 4099 // then give up on things going idle and start clearing 4100 // them out. 4101 Message msg = Message.obtain(); 4102 msg.what = ActivityManagerService.IDLE_NOW_MSG; 4103 mHandler.sendMessage(msg); 4104 } 4105 } 4106 r.state = ActivityState.STOPPING; 4107 updateOomAdjLocked(); 4108 return r; 4109 } 4110 4111 // make sure the record is cleaned out of other places. 4112 mStoppingActivities.remove(r); 4113 mWaitingVisibleActivities.remove(r); 4114 if (mResumedActivity == r) { 4115 mResumedActivity = null; 4116 } 4117 final ActivityState prevState = r.state; 4118 r.state = ActivityState.FINISHING; 4119 4120 if (mode == FINISH_IMMEDIATELY 4121 || prevState == ActivityState.STOPPED 4122 || prevState == ActivityState.INITIALIZING) { 4123 // If this activity is already stopped, we can just finish 4124 // it right now. 4125 return destroyActivityLocked(r, true) ? null : r; 4126 } else { 4127 // Need to go through the full pause cycle to get this 4128 // activity into the stopped state and then finish it. 4129 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r); 4130 mFinishingActivities.add(r); 4131 resumeTopActivityLocked(null); 4132 } 4133 return r; 4134 } 4135 4136 /** 4137 * This is the internal entry point for handling Activity.finish(). 4138 * 4139 * @param token The Binder token referencing the Activity we want to finish. 4140 * @param resultCode Result code, if any, from this Activity. 4141 * @param resultData Result data (Intent), if any, from this Activity. 4142 * 4143 * @result Returns true if the activity successfully finished, or false if it is still running. 4144 */ finishActivity(IBinder token, int resultCode, Intent resultData)4145 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 4146 // Refuse possible leaked file descriptors 4147 if (resultData != null && resultData.hasFileDescriptors() == true) { 4148 throw new IllegalArgumentException("File descriptors passed in Intent"); 4149 } 4150 4151 synchronized(this) { 4152 if (mController != null) { 4153 // Find the first activity that is not finishing. 4154 HistoryRecord next = topRunningActivityLocked(token, 0); 4155 if (next != null) { 4156 // ask watcher if this is allowed 4157 boolean resumeOK = true; 4158 try { 4159 resumeOK = mController.activityResuming(next.packageName); 4160 } catch (RemoteException e) { 4161 mController = null; 4162 } 4163 4164 if (!resumeOK) { 4165 return false; 4166 } 4167 } 4168 } 4169 final long origId = Binder.clearCallingIdentity(); 4170 boolean res = requestFinishActivityLocked(token, resultCode, 4171 resultData, "app-request"); 4172 Binder.restoreCallingIdentity(origId); 4173 return res; 4174 } 4175 } 4176 sendActivityResultLocked(int callingUid, HistoryRecord r, String resultWho, int requestCode, int resultCode, Intent data)4177 void sendActivityResultLocked(int callingUid, HistoryRecord r, 4178 String resultWho, int requestCode, int resultCode, Intent data) { 4179 4180 if (callingUid > 0) { 4181 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 4182 data, r); 4183 } 4184 4185 if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r 4186 + " : who=" + resultWho + " req=" + requestCode 4187 + " res=" + resultCode + " data=" + data); 4188 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 4189 try { 4190 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 4191 list.add(new ResultInfo(resultWho, requestCode, 4192 resultCode, data)); 4193 r.app.thread.scheduleSendResult(r, list); 4194 return; 4195 } catch (Exception e) { 4196 Log.w(TAG, "Exception thrown sending result to " + r, e); 4197 } 4198 } 4199 4200 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 4201 } 4202 finishSubActivity(IBinder token, String resultWho, int requestCode)4203 public final void finishSubActivity(IBinder token, String resultWho, 4204 int requestCode) { 4205 synchronized(this) { 4206 int index = indexOfTokenLocked(token); 4207 if (index < 0) { 4208 return; 4209 } 4210 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4211 4212 final long origId = Binder.clearCallingIdentity(); 4213 4214 int i; 4215 for (i=mHistory.size()-1; i>=0; i--) { 4216 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4217 if (r.resultTo == self && r.requestCode == requestCode) { 4218 if ((r.resultWho == null && resultWho == null) || 4219 (r.resultWho != null && r.resultWho.equals(resultWho))) { 4220 finishActivityLocked(r, i, 4221 Activity.RESULT_CANCELED, null, "request-sub"); 4222 } 4223 } 4224 } 4225 4226 Binder.restoreCallingIdentity(origId); 4227 } 4228 } 4229 overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)4230 public void overridePendingTransition(IBinder token, String packageName, 4231 int enterAnim, int exitAnim) { 4232 synchronized(this) { 4233 int index = indexOfTokenLocked(token); 4234 if (index < 0) { 4235 return; 4236 } 4237 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4238 4239 final long origId = Binder.clearCallingIdentity(); 4240 4241 if (self.state == ActivityState.RESUMED 4242 || self.state == ActivityState.PAUSING) { 4243 mWindowManager.overridePendingAppTransition(packageName, 4244 enterAnim, exitAnim); 4245 } 4246 4247 Binder.restoreCallingIdentity(origId); 4248 } 4249 } 4250 4251 /** 4252 * Perform clean-up of service connections in an activity record. 4253 */ cleanUpActivityServicesLocked(HistoryRecord r)4254 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 4255 // Throw away any services that have been bound by this activity. 4256 if (r.connections != null) { 4257 Iterator<ConnectionRecord> it = r.connections.iterator(); 4258 while (it.hasNext()) { 4259 ConnectionRecord c = it.next(); 4260 removeConnectionLocked(c, null, r); 4261 } 4262 r.connections = null; 4263 } 4264 } 4265 4266 /** 4267 * Perform the common clean-up of an activity record. This is called both 4268 * as part of destroyActivityLocked() (when destroying the client-side 4269 * representation) and cleaning things up as a result of its hosting 4270 * processing going away, in which case there is no remaining client-side 4271 * state to destroy so only the cleanup here is needed. 4272 */ cleanUpActivityLocked(HistoryRecord r, boolean cleanServices)4273 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 4274 if (mResumedActivity == r) { 4275 mResumedActivity = null; 4276 } 4277 if (mFocusedActivity == r) { 4278 mFocusedActivity = null; 4279 } 4280 4281 r.configDestroy = false; 4282 r.frozenBeforeDestroy = false; 4283 4284 // Make sure this record is no longer in the pending finishes list. 4285 // This could happen, for example, if we are trimming activities 4286 // down to the max limit while they are still waiting to finish. 4287 mFinishingActivities.remove(r); 4288 mWaitingVisibleActivities.remove(r); 4289 4290 // Remove any pending results. 4291 if (r.finishing && r.pendingResults != null) { 4292 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 4293 PendingIntentRecord rec = apr.get(); 4294 if (rec != null) { 4295 cancelIntentSenderLocked(rec, false); 4296 } 4297 } 4298 r.pendingResults = null; 4299 } 4300 4301 if (cleanServices) { 4302 cleanUpActivityServicesLocked(r); 4303 } 4304 4305 if (mPendingThumbnails.size() > 0) { 4306 // There are clients waiting to receive thumbnails so, in case 4307 // this is an activity that someone is waiting for, add it 4308 // to the pending list so we can correctly update the clients. 4309 mCancelledThumbnails.add(r); 4310 } 4311 4312 // Get rid of any pending idle timeouts. 4313 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4314 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4315 } 4316 removeActivityFromHistoryLocked(HistoryRecord r)4317 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 4318 if (r.state != ActivityState.DESTROYED) { 4319 mHistory.remove(r); 4320 r.inHistory = false; 4321 r.state = ActivityState.DESTROYED; 4322 mWindowManager.removeAppToken(r); 4323 if (VALIDATE_TOKENS) { 4324 mWindowManager.validateAppTokens(mHistory); 4325 } 4326 cleanUpActivityServicesLocked(r); 4327 removeActivityUriPermissionsLocked(r); 4328 } 4329 } 4330 4331 /** 4332 * Destroy the current CLIENT SIDE instance of an activity. This may be 4333 * called both when actually finishing an activity, or when performing 4334 * a configuration switch where we destroy the current client-side object 4335 * but then create a new client-side object for this same HistoryRecord. 4336 */ destroyActivityLocked(HistoryRecord r, boolean removeFromApp)4337 private final boolean destroyActivityLocked(HistoryRecord r, 4338 boolean removeFromApp) { 4339 if (DEBUG_SWITCH) Log.v( 4340 TAG, "Removing activity: token=" + r 4341 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4342 EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY, 4343 System.identityHashCode(r), 4344 r.task.taskId, r.shortComponentName); 4345 4346 boolean removedFromHistory = false; 4347 4348 cleanUpActivityLocked(r, false); 4349 4350 if (r.app != null) { 4351 if (removeFromApp) { 4352 int idx = r.app.activities.indexOf(r); 4353 if (idx >= 0) { 4354 r.app.activities.remove(idx); 4355 } 4356 if (r.persistent) { 4357 decPersistentCountLocked(r.app); 4358 } 4359 } 4360 4361 boolean skipDestroy = false; 4362 4363 try { 4364 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r); 4365 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4366 r.configChangeFlags); 4367 } catch (Exception e) { 4368 // We can just ignore exceptions here... if the process 4369 // has crashed, our death notification will clean things 4370 // up. 4371 //Log.w(TAG, "Exception thrown during finish", e); 4372 if (r.finishing) { 4373 removeActivityFromHistoryLocked(r); 4374 removedFromHistory = true; 4375 skipDestroy = true; 4376 } 4377 } 4378 4379 r.app = null; 4380 r.nowVisible = false; 4381 4382 if (r.finishing && !skipDestroy) { 4383 r.state = ActivityState.DESTROYING; 4384 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4385 msg.obj = r; 4386 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4387 } else { 4388 r.state = ActivityState.DESTROYED; 4389 } 4390 } else { 4391 // remove this record from the history. 4392 if (r.finishing) { 4393 removeActivityFromHistoryLocked(r); 4394 removedFromHistory = true; 4395 } else { 4396 r.state = ActivityState.DESTROYED; 4397 } 4398 } 4399 4400 r.configChangeFlags = 0; 4401 4402 if (!mLRUActivities.remove(r)) { 4403 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4404 } 4405 4406 return removedFromHistory; 4407 } 4408 removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app)4409 private static void removeHistoryRecordsForAppLocked(ArrayList list, 4410 ProcessRecord app) 4411 { 4412 int i = list.size(); 4413 if (localLOGV) Log.v( 4414 TAG, "Removing app " + app + " from list " + list 4415 + " with " + i + " entries"); 4416 while (i > 0) { 4417 i--; 4418 HistoryRecord r = (HistoryRecord)list.get(i); 4419 if (localLOGV) Log.v( 4420 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4421 if (r.app == app) { 4422 if (localLOGV) Log.v(TAG, "Removing this entry!"); 4423 list.remove(i); 4424 } 4425 } 4426 } 4427 4428 /** 4429 * Main function for removing an existing process from the activity manager 4430 * as a result of that process going away. Clears out all connections 4431 * to the process. 4432 */ handleAppDiedLocked(ProcessRecord app, boolean restarting)4433 private final void handleAppDiedLocked(ProcessRecord app, 4434 boolean restarting) { 4435 cleanUpApplicationRecordLocked(app, restarting, -1); 4436 if (!restarting) { 4437 mLRUProcesses.remove(app); 4438 } 4439 4440 // Just in case... 4441 if (mPausingActivity != null && mPausingActivity.app == app) { 4442 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity); 4443 mPausingActivity = null; 4444 } 4445 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4446 mLastPausedActivity = null; 4447 } 4448 4449 // Remove this application's activities from active lists. 4450 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4451 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4452 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4453 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4454 4455 boolean atTop = true; 4456 boolean hasVisibleActivities = false; 4457 4458 // Clean out the history list. 4459 int i = mHistory.size(); 4460 if (localLOGV) Log.v( 4461 TAG, "Removing app " + app + " from history with " + i + " entries"); 4462 while (i > 0) { 4463 i--; 4464 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4465 if (localLOGV) Log.v( 4466 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4467 if (r.app == app) { 4468 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4469 if (localLOGV) Log.v( 4470 TAG, "Removing this entry! frozen=" + r.haveState 4471 + " finishing=" + r.finishing); 4472 mHistory.remove(i); 4473 4474 r.inHistory = false; 4475 mWindowManager.removeAppToken(r); 4476 if (VALIDATE_TOKENS) { 4477 mWindowManager.validateAppTokens(mHistory); 4478 } 4479 removeActivityUriPermissionsLocked(r); 4480 4481 } else { 4482 // We have the current state for this activity, so 4483 // it can be restarted later when needed. 4484 if (localLOGV) Log.v( 4485 TAG, "Keeping entry, setting app to null"); 4486 if (r.visible) { 4487 hasVisibleActivities = true; 4488 } 4489 r.app = null; 4490 r.nowVisible = false; 4491 if (!r.haveState) { 4492 r.icicle = null; 4493 } 4494 } 4495 4496 cleanUpActivityLocked(r, true); 4497 r.state = ActivityState.STOPPED; 4498 } 4499 atTop = false; 4500 } 4501 4502 app.activities.clear(); 4503 4504 if (app.instrumentationClass != null) { 4505 Log.w(TAG, "Crash of app " + app.processName 4506 + " running instrumentation " + app.instrumentationClass); 4507 Bundle info = new Bundle(); 4508 info.putString("shortMsg", "Process crashed."); 4509 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4510 } 4511 4512 if (!restarting) { 4513 if (!resumeTopActivityLocked(null)) { 4514 // If there was nothing to resume, and we are not already 4515 // restarting this process, but there is a visible activity that 4516 // is hosted by the process... then make sure all visible 4517 // activities are running, taking care of restarting this 4518 // process. 4519 if (hasVisibleActivities) { 4520 ensureActivitiesVisibleLocked(null, 0); 4521 } 4522 } 4523 } 4524 } 4525 getLRURecordIndexForAppLocked(IApplicationThread thread)4526 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4527 IBinder threadBinder = thread.asBinder(); 4528 4529 // Find the application record. 4530 int count = mLRUProcesses.size(); 4531 int i; 4532 for (i=0; i<count; i++) { 4533 ProcessRecord rec = mLRUProcesses.get(i); 4534 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4535 return i; 4536 } 4537 } 4538 return -1; 4539 } 4540 getRecordForAppLocked( IApplicationThread thread)4541 private final ProcessRecord getRecordForAppLocked( 4542 IApplicationThread thread) { 4543 if (thread == null) { 4544 return null; 4545 } 4546 4547 int appIndex = getLRURecordIndexForAppLocked(thread); 4548 return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null; 4549 } 4550 appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread)4551 private final void appDiedLocked(ProcessRecord app, int pid, 4552 IApplicationThread thread) { 4553 4554 mProcDeaths[0]++; 4555 4556 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) { 4557 Log.i(TAG, "Process " + app.processName + " (pid " + pid 4558 + ") has died."); 4559 EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName); 4560 if (localLOGV) Log.v( 4561 TAG, "Dying app: " + app + ", pid: " + pid 4562 + ", thread: " + thread.asBinder()); 4563 boolean doLowMem = app.instrumentationClass == null; 4564 handleAppDiedLocked(app, false); 4565 4566 if (doLowMem) { 4567 // If there are no longer any background processes running, 4568 // and the app that died was not running instrumentation, 4569 // then tell everyone we are now low on memory. 4570 boolean haveBg = false; 4571 int count = mLRUProcesses.size(); 4572 int i; 4573 for (i=0; i<count; i++) { 4574 ProcessRecord rec = mLRUProcesses.get(i); 4575 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4576 haveBg = true; 4577 break; 4578 } 4579 } 4580 4581 if (!haveBg) { 4582 Log.i(TAG, "Low Memory: No more background processes."); 4583 EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size()); 4584 long now = SystemClock.uptimeMillis(); 4585 for (i=0; i<count; i++) { 4586 ProcessRecord rec = mLRUProcesses.get(i); 4587 if (rec != app && rec.thread != null && 4588 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4589 // The low memory report is overriding any current 4590 // state for a GC request. Make sure to do 4591 // visible/foreground processes first. 4592 if (rec.setAdj <= VISIBLE_APP_ADJ) { 4593 rec.lastRequestedGc = 0; 4594 } else { 4595 rec.lastRequestedGc = rec.lastLowMemory; 4596 } 4597 rec.reportLowMemory = true; 4598 rec.lastLowMemory = now; 4599 mProcessesToGc.remove(rec); 4600 addProcessToGcListLocked(rec); 4601 } 4602 } 4603 scheduleAppGcsLocked(); 4604 } 4605 } 4606 } else if (Config.LOGD) { 4607 Log.d(TAG, "Received spurious death notification for thread " 4608 + thread.asBinder()); 4609 } 4610 } 4611 readFile(String filename)4612 final String readFile(String filename) { 4613 try { 4614 FileInputStream fs = new FileInputStream(filename); 4615 byte[] inp = new byte[8192]; 4616 int size = fs.read(inp); 4617 fs.close(); 4618 return new String(inp, 0, 0, size); 4619 } catch (java.io.IOException e) { 4620 } 4621 return ""; 4622 } 4623 appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, HistoryRecord reportedActivity, final String annotation)4624 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, 4625 HistoryRecord reportedActivity, final String annotation) { 4626 if (app.notResponding || app.crashing) { 4627 return; 4628 } 4629 4630 // Log the ANR to the event log. 4631 EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation); 4632 4633 // If we are on a secure build and the application is not interesting to the user (it is 4634 // not visible or in the background), just kill it instead of displaying a dialog. 4635 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 4636 if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) { 4637 Process.killProcess(app.pid); 4638 return; 4639 } 4640 4641 // DeviceMonitor.start(); 4642 4643 String processInfo = null; 4644 if (MONITOR_CPU_USAGE) { 4645 updateCpuStatsNow(); 4646 synchronized (mProcessStatsThread) { 4647 processInfo = mProcessStats.printCurrentState(); 4648 } 4649 } 4650 4651 StringBuilder info = mStringBuilder; 4652 info.setLength(0); 4653 info.append("ANR in process: "); 4654 info.append(app.processName); 4655 if (reportedActivity != null && reportedActivity.app != null) { 4656 info.append(" (last in "); 4657 info.append(reportedActivity.app.processName); 4658 info.append(")"); 4659 } 4660 if (annotation != null) { 4661 info.append("\nAnnotation: "); 4662 info.append(annotation); 4663 } 4664 if (MONITOR_CPU_USAGE) { 4665 info.append("\nCPU usage:\n"); 4666 info.append(processInfo); 4667 } 4668 Log.i(TAG, info.toString()); 4669 4670 // The application is not responding. Dump as many thread traces as we can. 4671 boolean fileDump = prepareTraceFile(true); 4672 if (!fileDump) { 4673 // Dumping traces to the log, just dump the process that isn't responding so 4674 // we don't overflow the log 4675 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4676 } else { 4677 // Dumping traces to a file so dump all active processes we know about 4678 synchronized (this) { 4679 // First, these are the most important processes. 4680 final int[] imppids = new int[3]; 4681 int i=0; 4682 imppids[0] = app.pid; 4683 i++; 4684 if (reportedActivity != null && reportedActivity.app != null 4685 && reportedActivity.app.thread != null 4686 && reportedActivity.app.pid != app.pid) { 4687 imppids[i] = reportedActivity.app.pid; 4688 i++; 4689 } 4690 imppids[i] = Process.myPid(); 4691 for (i=0; i<imppids.length && imppids[i] != 0; i++) { 4692 Process.sendSignal(imppids[i], Process.SIGNAL_QUIT); 4693 synchronized (this) { 4694 try { 4695 wait(200); 4696 } catch (InterruptedException e) { 4697 } 4698 } 4699 } 4700 for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 4701 ProcessRecord r = mLRUProcesses.get(i); 4702 boolean done = false; 4703 for (int j=0; j<imppids.length && imppids[j] != 0; j++) { 4704 if (imppids[j] == r.pid) { 4705 done = true; 4706 break; 4707 } 4708 } 4709 if (!done && r.thread != null) { 4710 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 4711 synchronized (this) { 4712 try { 4713 wait(200); 4714 } catch (InterruptedException e) { 4715 } 4716 } 4717 } 4718 } 4719 } 4720 } 4721 4722 if (mController != null) { 4723 try { 4724 int res = mController.appNotResponding(app.processName, 4725 app.pid, info.toString()); 4726 if (res != 0) { 4727 if (res < 0) { 4728 // wait until the SIGQUIT has had a chance to process before killing the 4729 // process. 4730 try { 4731 wait(2000); 4732 } catch (InterruptedException e) { 4733 } 4734 4735 Process.killProcess(app.pid); 4736 return; 4737 } 4738 } 4739 } catch (RemoteException e) { 4740 mController = null; 4741 } 4742 } 4743 4744 makeAppNotRespondingLocked(app, 4745 activity != null ? activity.shortComponentName : null, 4746 annotation != null ? "ANR " + annotation : "ANR", 4747 info.toString(), null); 4748 Message msg = Message.obtain(); 4749 HashMap map = new HashMap(); 4750 msg.what = SHOW_NOT_RESPONDING_MSG; 4751 msg.obj = map; 4752 map.put("app", app); 4753 if (activity != null) { 4754 map.put("activity", activity); 4755 } 4756 4757 mHandler.sendMessage(msg); 4758 return; 4759 } 4760 4761 /** 4762 * If a stack trace file has been configured, prepare the filesystem 4763 * by creating the directory if it doesn't exist and optionally 4764 * removing the old trace file. 4765 * 4766 * @param removeExisting If set, the existing trace file will be removed. 4767 * @return Returns true if the trace file preparations succeeded 4768 */ prepareTraceFile(boolean removeExisting)4769 public static boolean prepareTraceFile(boolean removeExisting) { 4770 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4771 boolean fileReady = false; 4772 if (!TextUtils.isEmpty(tracesPath)) { 4773 File f = new File(tracesPath); 4774 if (!f.exists()) { 4775 // Ensure the enclosing directory exists 4776 File dir = f.getParentFile(); 4777 if (!dir.exists()) { 4778 fileReady = dir.mkdirs(); 4779 FileUtils.setPermissions(dir.getAbsolutePath(), 4780 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1); 4781 } else if (dir.isDirectory()) { 4782 fileReady = true; 4783 } 4784 } else if (removeExisting) { 4785 // Remove the previous traces file, so we don't fill the disk. 4786 // The VM will recreate it 4787 Log.i(TAG, "Removing old ANR trace file from " + tracesPath); 4788 fileReady = f.delete(); 4789 } 4790 4791 if (removeExisting) { 4792 try { 4793 f.createNewFile(); 4794 FileUtils.setPermissions(f.getAbsolutePath(), 4795 FileUtils.S_IRWXU | FileUtils.S_IRWXG 4796 | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1); 4797 fileReady = true; 4798 } catch (IOException e) { 4799 Log.w(TAG, "Unable to make ANR traces file", e); 4800 } 4801 } 4802 } 4803 4804 return fileReady; 4805 } 4806 4807 decPersistentCountLocked(ProcessRecord app)4808 private final void decPersistentCountLocked(ProcessRecord app) 4809 { 4810 app.persistentActivities--; 4811 if (app.persistentActivities > 0) { 4812 // Still more of 'em... 4813 return; 4814 } 4815 if (app.persistent) { 4816 // Ah, but the application itself is persistent. Whatever! 4817 return; 4818 } 4819 4820 // App is no longer persistent... make sure it and the ones 4821 // following it in the LRU list have the correc oom_adj. 4822 updateOomAdjLocked(); 4823 } 4824 setPersistent(IBinder token, boolean isPersistent)4825 public void setPersistent(IBinder token, boolean isPersistent) { 4826 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4827 != PackageManager.PERMISSION_GRANTED) { 4828 String msg = "Permission Denial: setPersistent() from pid=" 4829 + Binder.getCallingPid() 4830 + ", uid=" + Binder.getCallingUid() 4831 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4832 Log.w(TAG, msg); 4833 throw new SecurityException(msg); 4834 } 4835 4836 synchronized(this) { 4837 int index = indexOfTokenLocked(token); 4838 if (index < 0) { 4839 return; 4840 } 4841 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4842 ProcessRecord app = r.app; 4843 4844 if (localLOGV) Log.v( 4845 TAG, "Setting persistence " + isPersistent + ": " + r); 4846 4847 if (isPersistent) { 4848 if (r.persistent) { 4849 // Okay okay, I heard you already! 4850 if (localLOGV) Log.v(TAG, "Already persistent!"); 4851 return; 4852 } 4853 r.persistent = true; 4854 app.persistentActivities++; 4855 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities); 4856 if (app.persistentActivities > 1) { 4857 // We aren't the first... 4858 if (localLOGV) Log.v(TAG, "Not the first!"); 4859 return; 4860 } 4861 if (app.persistent) { 4862 // This would be redundant. 4863 if (localLOGV) Log.v(TAG, "App is persistent!"); 4864 return; 4865 } 4866 4867 // App is now persistent... make sure it and the ones 4868 // following it now have the correct oom_adj. 4869 final long origId = Binder.clearCallingIdentity(); 4870 updateOomAdjLocked(); 4871 Binder.restoreCallingIdentity(origId); 4872 4873 } else { 4874 if (!r.persistent) { 4875 // Okay okay, I heard you already! 4876 return; 4877 } 4878 r.persistent = false; 4879 final long origId = Binder.clearCallingIdentity(); 4880 decPersistentCountLocked(app); 4881 Binder.restoreCallingIdentity(origId); 4882 4883 } 4884 } 4885 } 4886 clearApplicationUserData(final String packageName, final IPackageDataObserver observer)4887 public boolean clearApplicationUserData(final String packageName, 4888 final IPackageDataObserver observer) { 4889 int uid = Binder.getCallingUid(); 4890 int pid = Binder.getCallingPid(); 4891 long callingId = Binder.clearCallingIdentity(); 4892 try { 4893 IPackageManager pm = ActivityThread.getPackageManager(); 4894 int pkgUid = -1; 4895 synchronized(this) { 4896 try { 4897 pkgUid = pm.getPackageUid(packageName); 4898 } catch (RemoteException e) { 4899 } 4900 if (pkgUid == -1) { 4901 Log.w(TAG, "Invalid packageName:" + packageName); 4902 return false; 4903 } 4904 if (uid == pkgUid || checkComponentPermission( 4905 android.Manifest.permission.CLEAR_APP_USER_DATA, 4906 pid, uid, -1) 4907 == PackageManager.PERMISSION_GRANTED) { 4908 restartPackageLocked(packageName, pkgUid); 4909 } else { 4910 throw new SecurityException(pid+" does not have permission:"+ 4911 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4912 "for process:"+packageName); 4913 } 4914 } 4915 4916 try { 4917 //clear application user data 4918 pm.clearApplicationUserData(packageName, observer); 4919 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4920 Uri.fromParts("package", packageName, null)); 4921 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4922 broadcastIntentLocked(null, null, intent, 4923 null, null, 0, null, null, null, 4924 false, false, MY_PID, Process.SYSTEM_UID); 4925 } catch (RemoteException e) { 4926 } 4927 } finally { 4928 Binder.restoreCallingIdentity(callingId); 4929 } 4930 return true; 4931 } 4932 restartPackage(final String packageName)4933 public void restartPackage(final String packageName) { 4934 if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4935 != PackageManager.PERMISSION_GRANTED) { 4936 String msg = "Permission Denial: restartPackage() from pid=" 4937 + Binder.getCallingPid() 4938 + ", uid=" + Binder.getCallingUid() 4939 + " requires " + android.Manifest.permission.RESTART_PACKAGES; 4940 Log.w(TAG, msg); 4941 throw new SecurityException(msg); 4942 } 4943 4944 long callingId = Binder.clearCallingIdentity(); 4945 try { 4946 IPackageManager pm = ActivityThread.getPackageManager(); 4947 int pkgUid = -1; 4948 synchronized(this) { 4949 try { 4950 pkgUid = pm.getPackageUid(packageName); 4951 } catch (RemoteException e) { 4952 } 4953 if (pkgUid == -1) { 4954 Log.w(TAG, "Invalid packageName: " + packageName); 4955 return; 4956 } 4957 restartPackageLocked(packageName, pkgUid); 4958 } 4959 } finally { 4960 Binder.restoreCallingIdentity(callingId); 4961 } 4962 } 4963 4964 /* 4965 * The pkg name and uid have to be specified. 4966 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 4967 */ killApplicationWithUid(String pkg, int uid)4968 public void killApplicationWithUid(String pkg, int uid) { 4969 if (pkg == null) { 4970 return; 4971 } 4972 // Make sure the uid is valid. 4973 if (uid < 0) { 4974 Log.w(TAG, "Invalid uid specified for pkg : " + pkg); 4975 return; 4976 } 4977 int callerUid = Binder.getCallingUid(); 4978 // Only the system server can kill an application 4979 if (callerUid == Process.SYSTEM_UID) { 4980 // Post an aysnc message to kill the application 4981 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4982 msg.arg1 = uid; 4983 msg.arg2 = 0; 4984 msg.obj = pkg; 4985 mHandler.sendMessage(msg); 4986 } else { 4987 throw new SecurityException(callerUid + " cannot kill pkg: " + 4988 pkg); 4989 } 4990 } 4991 closeSystemDialogs(String reason)4992 public void closeSystemDialogs(String reason) { 4993 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4994 if (reason != null) { 4995 intent.putExtra("reason", reason); 4996 } 4997 4998 final int uid = Binder.getCallingUid(); 4999 final long origId = Binder.clearCallingIdentity(); 5000 synchronized (this) { 5001 int i = mWatchers.beginBroadcast(); 5002 while (i > 0) { 5003 i--; 5004 IActivityWatcher w = mWatchers.getBroadcastItem(i); 5005 if (w != null) { 5006 try { 5007 w.closingSystemDialogs(reason); 5008 } catch (RemoteException e) { 5009 } 5010 } 5011 } 5012 mWatchers.finishBroadcast(); 5013 5014 mWindowManager.closeSystemDialogs(reason); 5015 5016 for (i=mHistory.size()-1; i>=0; i--) { 5017 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5018 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 5019 finishActivityLocked(r, i, 5020 Activity.RESULT_CANCELED, null, "close-sys"); 5021 } 5022 } 5023 5024 broadcastIntentLocked(null, null, intent, null, 5025 null, 0, null, null, null, false, false, -1, uid); 5026 } 5027 Binder.restoreCallingIdentity(origId); 5028 } 5029 getProcessMemoryInfo(int[] pids)5030 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 5031 throws RemoteException { 5032 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5033 for (int i=pids.length-1; i>=0; i--) { 5034 infos[i] = new Debug.MemoryInfo(); 5035 Debug.getMemoryInfo(pids[i], infos[i]); 5036 } 5037 return infos; 5038 } 5039 killApplicationProcess(String processName, int uid)5040 public void killApplicationProcess(String processName, int uid) { 5041 if (processName == null) { 5042 return; 5043 } 5044 5045 int callerUid = Binder.getCallingUid(); 5046 // Only the system server can kill an application 5047 if (callerUid == Process.SYSTEM_UID) { 5048 synchronized (this) { 5049 ProcessRecord app = getProcessRecordLocked(processName, uid); 5050 if (app != null) { 5051 try { 5052 app.thread.scheduleSuicide(); 5053 } catch (RemoteException e) { 5054 // If the other end already died, then our work here is done. 5055 } 5056 } else { 5057 Log.w(TAG, "Process/uid not found attempting kill of " 5058 + processName + " / " + uid); 5059 } 5060 } 5061 } else { 5062 throw new SecurityException(callerUid + " cannot kill app process: " + 5063 processName); 5064 } 5065 } 5066 restartPackageLocked(final String packageName, int uid)5067 private void restartPackageLocked(final String packageName, int uid) { 5068 uninstallPackageLocked(packageName, uid, false); 5069 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5070 Uri.fromParts("package", packageName, null)); 5071 intent.putExtra(Intent.EXTRA_UID, uid); 5072 broadcastIntentLocked(null, null, intent, 5073 null, null, 0, null, null, null, 5074 false, false, MY_PID, Process.SYSTEM_UID); 5075 } 5076 uninstallPackageLocked(String name, int uid, boolean callerWillRestart)5077 private final void uninstallPackageLocked(String name, int uid, 5078 boolean callerWillRestart) { 5079 if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name); 5080 5081 int i, N; 5082 5083 final String procNamePrefix = name + ":"; 5084 if (uid < 0) { 5085 try { 5086 uid = ActivityThread.getPackageManager().getPackageUid(name); 5087 } catch (RemoteException e) { 5088 } 5089 } 5090 5091 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 5092 while (badApps.hasNext()) { 5093 SparseArray<Long> ba = badApps.next(); 5094 if (ba.get(uid) != null) { 5095 badApps.remove(); 5096 } 5097 } 5098 5099 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5100 5101 // Remove all processes this package may have touched: all with the 5102 // same UID (except for the system or root user), and all whose name 5103 // matches the package name. 5104 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 5105 final int NA = apps.size(); 5106 for (int ia=0; ia<NA; ia++) { 5107 ProcessRecord app = apps.valueAt(ia); 5108 if (app.removed) { 5109 procs.add(app); 5110 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 5111 || app.processName.equals(name) 5112 || app.processName.startsWith(procNamePrefix)) { 5113 app.removed = true; 5114 procs.add(app); 5115 } 5116 } 5117 } 5118 5119 N = procs.size(); 5120 for (i=0; i<N; i++) { 5121 removeProcessLocked(procs.get(i), callerWillRestart); 5122 } 5123 5124 for (i=mHistory.size()-1; i>=0; i--) { 5125 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5126 if (r.packageName.equals(name)) { 5127 if (Config.LOGD) Log.d( 5128 TAG, " Force finishing activity " 5129 + r.intent.getComponent().flattenToShortString()); 5130 if (r.app != null) { 5131 r.app.removed = true; 5132 } 5133 r.app = null; 5134 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 5135 } 5136 } 5137 5138 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5139 for (ServiceRecord service : mServices.values()) { 5140 if (service.packageName.equals(name)) { 5141 if (service.app != null) { 5142 service.app.removed = true; 5143 } 5144 service.app = null; 5145 services.add(service); 5146 } 5147 } 5148 5149 N = services.size(); 5150 for (i=0; i<N; i++) { 5151 bringDownServiceLocked(services.get(i), true); 5152 } 5153 5154 resumeTopActivityLocked(null); 5155 } 5156 removeProcessLocked(ProcessRecord app, boolean callerWillRestart)5157 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 5158 final String name = app.processName; 5159 final int uid = app.info.uid; 5160 if (Config.LOGD) Log.d( 5161 TAG, "Force removing process " + app + " (" + name 5162 + "/" + uid + ")"); 5163 5164 mProcessNames.remove(name, uid); 5165 boolean needRestart = false; 5166 if (app.pid > 0 && app.pid != MY_PID) { 5167 int pid = app.pid; 5168 synchronized (mPidsSelfLocked) { 5169 mPidsSelfLocked.remove(pid); 5170 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5171 } 5172 handleAppDiedLocked(app, true); 5173 mLRUProcesses.remove(app); 5174 Process.killProcess(pid); 5175 5176 if (app.persistent) { 5177 if (!callerWillRestart) { 5178 addAppLocked(app.info); 5179 } else { 5180 needRestart = true; 5181 } 5182 } 5183 } else { 5184 mRemovedProcesses.add(app); 5185 } 5186 5187 return needRestart; 5188 } 5189 processStartTimedOutLocked(ProcessRecord app)5190 private final void processStartTimedOutLocked(ProcessRecord app) { 5191 final int pid = app.pid; 5192 boolean gone = false; 5193 synchronized (mPidsSelfLocked) { 5194 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5195 if (knownApp != null && knownApp.thread == null) { 5196 mPidsSelfLocked.remove(pid); 5197 gone = true; 5198 } 5199 } 5200 5201 if (gone) { 5202 Log.w(TAG, "Process " + app + " failed to attach"); 5203 EventLog.writeEvent(LOG_AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 5204 app.processName); 5205 mProcessNames.remove(app.processName, app.info.uid); 5206 // Take care of any launching providers waiting for this process. 5207 checkAppInLaunchingProvidersLocked(app, true); 5208 // Take care of any services that are waiting for the process. 5209 for (int i=0; i<mPendingServices.size(); i++) { 5210 ServiceRecord sr = mPendingServices.get(i); 5211 if (app.info.uid == sr.appInfo.uid 5212 && app.processName.equals(sr.processName)) { 5213 Log.w(TAG, "Forcing bringing down service: " + sr); 5214 mPendingServices.remove(i); 5215 i--; 5216 bringDownServiceLocked(sr, true); 5217 } 5218 } 5219 Process.killProcess(pid); 5220 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5221 Log.w(TAG, "Unattached app died before backup, skipping"); 5222 try { 5223 IBackupManager bm = IBackupManager.Stub.asInterface( 5224 ServiceManager.getService(Context.BACKUP_SERVICE)); 5225 bm.agentDisconnected(app.info.packageName); 5226 } catch (RemoteException e) { 5227 // Can't happen; the backup manager is local 5228 } 5229 } 5230 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 5231 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5232 mPendingBroadcast = null; 5233 scheduleBroadcastsLocked(); 5234 } 5235 } else { 5236 Log.w(TAG, "Spurious process start timeout - pid not known for " + app); 5237 } 5238 } 5239 attachApplicationLocked(IApplicationThread thread, int pid)5240 private final boolean attachApplicationLocked(IApplicationThread thread, 5241 int pid) { 5242 5243 // Find the application record that is being attached... either via 5244 // the pid if we are running in multiple processes, or just pull the 5245 // next app record if we are emulating process with anonymous threads. 5246 ProcessRecord app; 5247 if (pid != MY_PID && pid >= 0) { 5248 synchronized (mPidsSelfLocked) { 5249 app = mPidsSelfLocked.get(pid); 5250 } 5251 } else if (mStartingProcesses.size() > 0) { 5252 app = mStartingProcesses.remove(0); 5253 app.setPid(pid); 5254 } else { 5255 app = null; 5256 } 5257 5258 if (app == null) { 5259 Log.w(TAG, "No pending application record for pid " + pid 5260 + " (IApplicationThread " + thread + "); dropping process"); 5261 EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid); 5262 if (pid > 0 && pid != MY_PID) { 5263 Process.killProcess(pid); 5264 } else { 5265 try { 5266 thread.scheduleExit(); 5267 } catch (Exception e) { 5268 // Ignore exceptions. 5269 } 5270 } 5271 return false; 5272 } 5273 5274 // If this application record is still attached to a previous 5275 // process, clean it up now. 5276 if (app.thread != null) { 5277 handleAppDiedLocked(app, true); 5278 } 5279 5280 // Tell the process all about itself. 5281 5282 if (localLOGV) Log.v( 5283 TAG, "Binding process pid " + pid + " to record " + app); 5284 5285 String processName = app.processName; 5286 try { 5287 thread.asBinder().linkToDeath(new AppDeathRecipient( 5288 app, pid, thread), 0); 5289 } catch (RemoteException e) { 5290 app.resetPackageList(); 5291 startProcessLocked(app, "link fail", processName); 5292 return false; 5293 } 5294 5295 EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName); 5296 5297 app.thread = thread; 5298 app.curAdj = app.setAdj = -100; 5299 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5300 app.forcingToForeground = null; 5301 app.foregroundServices = false; 5302 app.debugging = false; 5303 5304 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5305 5306 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); 5307 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5308 5309 if (!normalMode) { 5310 Log.i(TAG, "Launching preboot mode app: " + app); 5311 } 5312 5313 if (localLOGV) Log.v( 5314 TAG, "New app record " + app 5315 + " thread=" + thread.asBinder() + " pid=" + pid); 5316 try { 5317 int testMode = IApplicationThread.DEBUG_OFF; 5318 if (mDebugApp != null && mDebugApp.equals(processName)) { 5319 testMode = mWaitForDebugger 5320 ? IApplicationThread.DEBUG_WAIT 5321 : IApplicationThread.DEBUG_ON; 5322 app.debugging = true; 5323 if (mDebugTransient) { 5324 mDebugApp = mOrigDebugApp; 5325 mWaitForDebugger = mOrigWaitForDebugger; 5326 } 5327 } 5328 5329 // If the app is being launched for restore or full backup, set it up specially 5330 boolean isRestrictedBackupMode = false; 5331 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5332 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5333 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5334 } 5335 5336 ensurePackageDexOpt(app.instrumentationInfo != null 5337 ? app.instrumentationInfo.packageName 5338 : app.info.packageName); 5339 if (app.instrumentationClass != null) { 5340 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5341 } 5342 if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc " 5343 + processName + " with config " + mConfiguration); 5344 thread.bindApplication(processName, app.instrumentationInfo != null 5345 ? app.instrumentationInfo : app.info, providers, 5346 app.instrumentationClass, app.instrumentationProfileFile, 5347 app.instrumentationArguments, app.instrumentationWatcher, testMode, 5348 isRestrictedBackupMode || !normalMode, 5349 mConfiguration, getCommonServicesLocked()); 5350 updateLRUListLocked(app, false); 5351 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5352 } catch (Exception e) { 5353 // todo: Yikes! What should we do? For now we will try to 5354 // start another process, but that could easily get us in 5355 // an infinite loop of restarting processes... 5356 Log.w(TAG, "Exception thrown during bind!", e); 5357 5358 app.resetPackageList(); 5359 startProcessLocked(app, "bind fail", processName); 5360 return false; 5361 } 5362 5363 // Remove this record from the list of starting applications. 5364 mPersistentStartingProcesses.remove(app); 5365 mProcessesOnHold.remove(app); 5366 5367 boolean badApp = false; 5368 boolean didSomething = false; 5369 5370 // See if the top visible activity is waiting to run in this process... 5371 HistoryRecord hr = topRunningActivityLocked(null); 5372 if (hr != null) { 5373 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 5374 && processName.equals(hr.processName)) { 5375 try { 5376 if (realStartActivityLocked(hr, app, true, true)) { 5377 didSomething = true; 5378 } 5379 } catch (Exception e) { 5380 Log.w(TAG, "Exception in new application when starting activity " 5381 + hr.intent.getComponent().flattenToShortString(), e); 5382 badApp = true; 5383 } 5384 } else { 5385 ensureActivitiesVisibleLocked(hr, null, processName, 0); 5386 } 5387 } 5388 5389 // Find any services that should be running in this process... 5390 if (!badApp && mPendingServices.size() > 0) { 5391 ServiceRecord sr = null; 5392 try { 5393 for (int i=0; i<mPendingServices.size(); i++) { 5394 sr = mPendingServices.get(i); 5395 if (app.info.uid != sr.appInfo.uid 5396 || !processName.equals(sr.processName)) { 5397 continue; 5398 } 5399 5400 mPendingServices.remove(i); 5401 i--; 5402 realStartServiceLocked(sr, app); 5403 didSomething = true; 5404 } 5405 } catch (Exception e) { 5406 Log.w(TAG, "Exception in new application when starting service " 5407 + sr.shortName, e); 5408 badApp = true; 5409 } 5410 } 5411 5412 // Check if the next broadcast receiver is in this process... 5413 BroadcastRecord br = mPendingBroadcast; 5414 if (!badApp && br != null && br.curApp == app) { 5415 try { 5416 mPendingBroadcast = null; 5417 processCurBroadcastLocked(br, app); 5418 didSomething = true; 5419 } catch (Exception e) { 5420 Log.w(TAG, "Exception in new application when starting receiver " 5421 + br.curComponent.flattenToShortString(), e); 5422 badApp = true; 5423 logBroadcastReceiverDiscard(br); 5424 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 5425 br.resultExtras, br.resultAbort, true); 5426 scheduleBroadcastsLocked(); 5427 } 5428 } 5429 5430 // Check whether the next backup agent is in this process... 5431 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 5432 if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); 5433 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5434 try { 5435 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 5436 } catch (Exception e) { 5437 Log.w(TAG, "Exception scheduling backup agent creation: "); 5438 e.printStackTrace(); 5439 } 5440 } 5441 5442 if (badApp) { 5443 // todo: Also need to kill application to deal with all 5444 // kinds of exceptions. 5445 handleAppDiedLocked(app, false); 5446 return false; 5447 } 5448 5449 if (!didSomething) { 5450 updateOomAdjLocked(); 5451 } 5452 5453 return true; 5454 } 5455 attachApplication(IApplicationThread thread)5456 public final void attachApplication(IApplicationThread thread) { 5457 synchronized (this) { 5458 int callingPid = Binder.getCallingPid(); 5459 final long origId = Binder.clearCallingIdentity(); 5460 attachApplicationLocked(thread, callingPid); 5461 Binder.restoreCallingIdentity(origId); 5462 } 5463 } 5464 activityIdle(IBinder token, Configuration config)5465 public final void activityIdle(IBinder token, Configuration config) { 5466 final long origId = Binder.clearCallingIdentity(); 5467 activityIdleInternal(token, false, config); 5468 Binder.restoreCallingIdentity(origId); 5469 } 5470 processStoppingActivitiesLocked( boolean remove)5471 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 5472 boolean remove) { 5473 int N = mStoppingActivities.size(); 5474 if (N <= 0) return null; 5475 5476 ArrayList<HistoryRecord> stops = null; 5477 5478 final boolean nowVisible = mResumedActivity != null 5479 && mResumedActivity.nowVisible 5480 && !mResumedActivity.waitingVisible; 5481 for (int i=0; i<N; i++) { 5482 HistoryRecord s = mStoppingActivities.get(i); 5483 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible=" 5484 + nowVisible + " waitingVisible=" + s.waitingVisible 5485 + " finishing=" + s.finishing); 5486 if (s.waitingVisible && nowVisible) { 5487 mWaitingVisibleActivities.remove(s); 5488 s.waitingVisible = false; 5489 if (s.finishing) { 5490 // If this activity is finishing, it is sitting on top of 5491 // everyone else but we now know it is no longer needed... 5492 // so get rid of it. Otherwise, we need to go through the 5493 // normal flow and hide it once we determine that it is 5494 // hidden by the activities in front of it. 5495 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s); 5496 mWindowManager.setAppVisibility(s, false); 5497 } 5498 } 5499 if (!s.waitingVisible && remove) { 5500 if (localLOGV) Log.v(TAG, "Ready to stop: " + s); 5501 if (stops == null) { 5502 stops = new ArrayList<HistoryRecord>(); 5503 } 5504 stops.add(s); 5505 mStoppingActivities.remove(i); 5506 N--; 5507 i--; 5508 } 5509 } 5510 5511 return stops; 5512 } 5513 enableScreenAfterBoot()5514 void enableScreenAfterBoot() { 5515 EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN, 5516 SystemClock.uptimeMillis()); 5517 mWindowManager.enableScreenAfterBoot(); 5518 } 5519 activityIdleInternal(IBinder token, boolean fromTimeout, Configuration config)5520 final void activityIdleInternal(IBinder token, boolean fromTimeout, 5521 Configuration config) { 5522 if (localLOGV) Log.v(TAG, "Activity idle: " + token); 5523 5524 ArrayList<HistoryRecord> stops = null; 5525 ArrayList<HistoryRecord> finishes = null; 5526 ArrayList<HistoryRecord> thumbnails = null; 5527 int NS = 0; 5528 int NF = 0; 5529 int NT = 0; 5530 IApplicationThread sendThumbnail = null; 5531 boolean booting = false; 5532 boolean enableScreen = false; 5533 5534 synchronized (this) { 5535 if (token != null) { 5536 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5537 } 5538 5539 // Get the activity record. 5540 int index = indexOfTokenLocked(token); 5541 if (index >= 0) { 5542 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5543 5544 // This is a hack to semi-deal with a race condition 5545 // in the client where it can be constructed with a 5546 // newer configuration from when we asked it to launch. 5547 // We'll update with whatever configuration it now says 5548 // it used to launch. 5549 if (config != null) { 5550 r.configuration = config; 5551 } 5552 5553 // No longer need to keep the device awake. 5554 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5555 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5556 mLaunchingActivity.release(); 5557 } 5558 5559 // We are now idle. If someone is waiting for a thumbnail from 5560 // us, we can now deliver. 5561 r.idle = true; 5562 scheduleAppGcsLocked(); 5563 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5564 sendThumbnail = r.app.thread; 5565 r.thumbnailNeeded = false; 5566 } 5567 5568 // If this activity is fullscreen, set up to hide those under it. 5569 5570 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r); 5571 ensureActivitiesVisibleLocked(null, 0); 5572 5573 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5574 if (!mBooted && !fromTimeout) { 5575 mBooted = true; 5576 enableScreen = true; 5577 } 5578 } 5579 5580 // Atomically retrieve all of the other things to do. 5581 stops = processStoppingActivitiesLocked(true); 5582 NS = stops != null ? stops.size() : 0; 5583 if ((NF=mFinishingActivities.size()) > 0) { 5584 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5585 mFinishingActivities.clear(); 5586 } 5587 if ((NT=mCancelledThumbnails.size()) > 0) { 5588 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5589 mCancelledThumbnails.clear(); 5590 } 5591 5592 booting = mBooting; 5593 mBooting = false; 5594 } 5595 5596 int i; 5597 5598 // Send thumbnail if requested. 5599 if (sendThumbnail != null) { 5600 try { 5601 sendThumbnail.requestThumbnail(token); 5602 } catch (Exception e) { 5603 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 5604 sendPendingThumbnail(null, token, null, null, true); 5605 } 5606 } 5607 5608 // Stop any activities that are scheduled to do so but have been 5609 // waiting for the next one to start. 5610 for (i=0; i<NS; i++) { 5611 HistoryRecord r = (HistoryRecord)stops.get(i); 5612 synchronized (this) { 5613 if (r.finishing) { 5614 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5615 } else { 5616 stopActivityLocked(r); 5617 } 5618 } 5619 } 5620 5621 // Finish any activities that are scheduled to do so but have been 5622 // waiting for the next one to start. 5623 for (i=0; i<NF; i++) { 5624 HistoryRecord r = (HistoryRecord)finishes.get(i); 5625 synchronized (this) { 5626 destroyActivityLocked(r, true); 5627 } 5628 } 5629 5630 // Report back to any thumbnail receivers. 5631 for (i=0; i<NT; i++) { 5632 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5633 sendPendingThumbnail(r, null, null, null, true); 5634 } 5635 5636 if (booting) { 5637 finishBooting(); 5638 } 5639 5640 trimApplications(); 5641 //dump(); 5642 //mWindowManager.dump(); 5643 5644 if (enableScreen) { 5645 enableScreenAfterBoot(); 5646 } 5647 } 5648 finishBooting()5649 final void finishBooting() { 5650 // Ensure that any processes we had put on hold are now started 5651 // up. 5652 final int NP = mProcessesOnHold.size(); 5653 if (NP > 0) { 5654 ArrayList<ProcessRecord> procs = 5655 new ArrayList<ProcessRecord>(mProcessesOnHold); 5656 for (int ip=0; ip<NP; ip++) { 5657 this.startProcessLocked(procs.get(ip), "on-hold", null); 5658 } 5659 } 5660 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5661 // Tell anyone interested that we are done booting! 5662 synchronized (this) { 5663 broadcastIntentLocked(null, null, 5664 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5665 null, null, 0, null, null, 5666 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5667 false, false, MY_PID, Process.SYSTEM_UID); 5668 } 5669 } 5670 } 5671 ensureBootCompleted()5672 final void ensureBootCompleted() { 5673 boolean booting; 5674 boolean enableScreen; 5675 synchronized (this) { 5676 booting = mBooting; 5677 mBooting = false; 5678 enableScreen = !mBooted; 5679 mBooted = true; 5680 } 5681 5682 if (booting) { 5683 finishBooting(); 5684 } 5685 5686 if (enableScreen) { 5687 enableScreenAfterBoot(); 5688 } 5689 } 5690 activityPaused(IBinder token, Bundle icicle)5691 public final void activityPaused(IBinder token, Bundle icicle) { 5692 // Refuse possible leaked file descriptors 5693 if (icicle != null && icicle.hasFileDescriptors()) { 5694 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5695 } 5696 5697 final long origId = Binder.clearCallingIdentity(); 5698 activityPaused(token, icicle, false); 5699 Binder.restoreCallingIdentity(origId); 5700 } 5701 activityPaused(IBinder token, Bundle icicle, boolean timeout)5702 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5703 if (DEBUG_PAUSE) Log.v( 5704 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5705 + ", timeout=" + timeout); 5706 5707 HistoryRecord r = null; 5708 5709 synchronized (this) { 5710 int index = indexOfTokenLocked(token); 5711 if (index >= 0) { 5712 r = (HistoryRecord)mHistory.get(index); 5713 if (!timeout) { 5714 r.icicle = icicle; 5715 r.haveState = true; 5716 } 5717 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5718 if (mPausingActivity == r) { 5719 r.state = ActivityState.PAUSED; 5720 completePauseLocked(); 5721 } else { 5722 EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY, 5723 System.identityHashCode(r), r.shortComponentName, 5724 mPausingActivity != null 5725 ? mPausingActivity.shortComponentName : "(none)"); 5726 } 5727 } 5728 } 5729 } 5730 activityStopped(IBinder token, Bitmap thumbnail, CharSequence description)5731 public final void activityStopped(IBinder token, Bitmap thumbnail, 5732 CharSequence description) { 5733 if (localLOGV) Log.v( 5734 TAG, "Activity stopped: token=" + token); 5735 5736 HistoryRecord r = null; 5737 5738 final long origId = Binder.clearCallingIdentity(); 5739 5740 synchronized (this) { 5741 int index = indexOfTokenLocked(token); 5742 if (index >= 0) { 5743 r = (HistoryRecord)mHistory.get(index); 5744 r.thumbnail = thumbnail; 5745 r.description = description; 5746 r.stopped = true; 5747 r.state = ActivityState.STOPPED; 5748 if (!r.finishing) { 5749 if (r.configDestroy) { 5750 destroyActivityLocked(r, true); 5751 resumeTopActivityLocked(null); 5752 } 5753 } 5754 } 5755 } 5756 5757 if (r != null) { 5758 sendPendingThumbnail(r, null, null, null, false); 5759 } 5760 5761 trimApplications(); 5762 5763 Binder.restoreCallingIdentity(origId); 5764 } 5765 activityDestroyed(IBinder token)5766 public final void activityDestroyed(IBinder token) { 5767 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token); 5768 synchronized (this) { 5769 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 5770 5771 int index = indexOfTokenLocked(token); 5772 if (index >= 0) { 5773 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5774 if (r.state == ActivityState.DESTROYING) { 5775 final long origId = Binder.clearCallingIdentity(); 5776 removeActivityFromHistoryLocked(r); 5777 Binder.restoreCallingIdentity(origId); 5778 } 5779 } 5780 } 5781 } 5782 getCallingPackage(IBinder token)5783 public String getCallingPackage(IBinder token) { 5784 synchronized (this) { 5785 HistoryRecord r = getCallingRecordLocked(token); 5786 return r != null && r.app != null ? r.info.packageName : null; 5787 } 5788 } 5789 getCallingActivity(IBinder token)5790 public ComponentName getCallingActivity(IBinder token) { 5791 synchronized (this) { 5792 HistoryRecord r = getCallingRecordLocked(token); 5793 return r != null ? r.intent.getComponent() : null; 5794 } 5795 } 5796 getCallingRecordLocked(IBinder token)5797 private HistoryRecord getCallingRecordLocked(IBinder token) { 5798 int index = indexOfTokenLocked(token); 5799 if (index >= 0) { 5800 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5801 if (r != null) { 5802 return r.resultTo; 5803 } 5804 } 5805 return null; 5806 } 5807 getActivityClassForToken(IBinder token)5808 public ComponentName getActivityClassForToken(IBinder token) { 5809 synchronized(this) { 5810 int index = indexOfTokenLocked(token); 5811 if (index >= 0) { 5812 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5813 return r.intent.getComponent(); 5814 } 5815 return null; 5816 } 5817 } 5818 getPackageForToken(IBinder token)5819 public String getPackageForToken(IBinder token) { 5820 synchronized(this) { 5821 int index = indexOfTokenLocked(token); 5822 if (index >= 0) { 5823 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5824 return r.packageName; 5825 } 5826 return null; 5827 } 5828 } 5829 getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent intent, String resolvedType, int flags)5830 public IIntentSender getIntentSender(int type, 5831 String packageName, IBinder token, String resultWho, 5832 int requestCode, Intent intent, String resolvedType, int flags) { 5833 // Refuse possible leaked file descriptors 5834 if (intent != null && intent.hasFileDescriptors() == true) { 5835 throw new IllegalArgumentException("File descriptors passed in Intent"); 5836 } 5837 5838 if (type == INTENT_SENDER_BROADCAST) { 5839 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5840 throw new IllegalArgumentException( 5841 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5842 } 5843 } 5844 5845 synchronized(this) { 5846 int callingUid = Binder.getCallingUid(); 5847 try { 5848 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 5849 Process.supportsProcesses()) { 5850 int uid = ActivityThread.getPackageManager() 5851 .getPackageUid(packageName); 5852 if (uid != Binder.getCallingUid()) { 5853 String msg = "Permission Denial: getIntentSender() from pid=" 5854 + Binder.getCallingPid() 5855 + ", uid=" + Binder.getCallingUid() 5856 + ", (need uid=" + uid + ")" 5857 + " is not allowed to send as package " + packageName; 5858 Log.w(TAG, msg); 5859 throw new SecurityException(msg); 5860 } 5861 } 5862 } catch (RemoteException e) { 5863 throw new SecurityException(e); 5864 } 5865 HistoryRecord activity = null; 5866 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5867 int index = indexOfTokenLocked(token); 5868 if (index < 0) { 5869 return null; 5870 } 5871 activity = (HistoryRecord)mHistory.get(index); 5872 if (activity.finishing) { 5873 return null; 5874 } 5875 } 5876 5877 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5878 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5879 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5880 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5881 |PendingIntent.FLAG_UPDATE_CURRENT); 5882 5883 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5884 type, packageName, activity, resultWho, 5885 requestCode, intent, resolvedType, flags); 5886 WeakReference<PendingIntentRecord> ref; 5887 ref = mIntentSenderRecords.get(key); 5888 PendingIntentRecord rec = ref != null ? ref.get() : null; 5889 if (rec != null) { 5890 if (!cancelCurrent) { 5891 if (updateCurrent) { 5892 rec.key.requestIntent.replaceExtras(intent); 5893 } 5894 return rec; 5895 } 5896 rec.canceled = true; 5897 mIntentSenderRecords.remove(key); 5898 } 5899 if (noCreate) { 5900 return rec; 5901 } 5902 rec = new PendingIntentRecord(this, key, callingUid); 5903 mIntentSenderRecords.put(key, rec.ref); 5904 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5905 if (activity.pendingResults == null) { 5906 activity.pendingResults 5907 = new HashSet<WeakReference<PendingIntentRecord>>(); 5908 } 5909 activity.pendingResults.add(rec.ref); 5910 } 5911 return rec; 5912 } 5913 } 5914 cancelIntentSender(IIntentSender sender)5915 public void cancelIntentSender(IIntentSender sender) { 5916 if (!(sender instanceof PendingIntentRecord)) { 5917 return; 5918 } 5919 synchronized(this) { 5920 PendingIntentRecord rec = (PendingIntentRecord)sender; 5921 try { 5922 int uid = ActivityThread.getPackageManager() 5923 .getPackageUid(rec.key.packageName); 5924 if (uid != Binder.getCallingUid()) { 5925 String msg = "Permission Denial: cancelIntentSender() from pid=" 5926 + Binder.getCallingPid() 5927 + ", uid=" + Binder.getCallingUid() 5928 + " is not allowed to cancel packges " 5929 + rec.key.packageName; 5930 Log.w(TAG, msg); 5931 throw new SecurityException(msg); 5932 } 5933 } catch (RemoteException e) { 5934 throw new SecurityException(e); 5935 } 5936 cancelIntentSenderLocked(rec, true); 5937 } 5938 } 5939 cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)5940 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5941 rec.canceled = true; 5942 mIntentSenderRecords.remove(rec.key); 5943 if (cleanActivity && rec.key.activity != null) { 5944 rec.key.activity.pendingResults.remove(rec.ref); 5945 } 5946 } 5947 getPackageForIntentSender(IIntentSender pendingResult)5948 public String getPackageForIntentSender(IIntentSender pendingResult) { 5949 if (!(pendingResult instanceof PendingIntentRecord)) { 5950 return null; 5951 } 5952 synchronized(this) { 5953 try { 5954 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5955 return res.key.packageName; 5956 } catch (ClassCastException e) { 5957 } 5958 } 5959 return null; 5960 } 5961 setProcessLimit(int max)5962 public void setProcessLimit(int max) { 5963 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5964 "setProcessLimit()"); 5965 mProcessLimit = max; 5966 } 5967 getProcessLimit()5968 public int getProcessLimit() { 5969 return mProcessLimit; 5970 } 5971 foregroundTokenDied(ForegroundToken token)5972 void foregroundTokenDied(ForegroundToken token) { 5973 synchronized (ActivityManagerService.this) { 5974 synchronized (mPidsSelfLocked) { 5975 ForegroundToken cur 5976 = mForegroundProcesses.get(token.pid); 5977 if (cur != token) { 5978 return; 5979 } 5980 mForegroundProcesses.remove(token.pid); 5981 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5982 if (pr == null) { 5983 return; 5984 } 5985 pr.forcingToForeground = null; 5986 pr.foregroundServices = false; 5987 } 5988 updateOomAdjLocked(); 5989 } 5990 } 5991 setProcessForeground(IBinder token, int pid, boolean isForeground)5992 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5993 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5994 "setProcessForeground()"); 5995 synchronized(this) { 5996 boolean changed = false; 5997 5998 synchronized (mPidsSelfLocked) { 5999 ProcessRecord pr = mPidsSelfLocked.get(pid); 6000 if (pr == null) { 6001 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6002 return; 6003 } 6004 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6005 if (oldToken != null) { 6006 oldToken.token.unlinkToDeath(oldToken, 0); 6007 mForegroundProcesses.remove(pid); 6008 pr.forcingToForeground = null; 6009 changed = true; 6010 } 6011 if (isForeground && token != null) { 6012 ForegroundToken newToken = new ForegroundToken() { 6013 public void binderDied() { 6014 foregroundTokenDied(this); 6015 } 6016 }; 6017 newToken.pid = pid; 6018 newToken.token = token; 6019 try { 6020 token.linkToDeath(newToken, 0); 6021 mForegroundProcesses.put(pid, newToken); 6022 pr.forcingToForeground = token; 6023 changed = true; 6024 } catch (RemoteException e) { 6025 // If the process died while doing this, we will later 6026 // do the cleanup with the process death link. 6027 } 6028 } 6029 } 6030 6031 if (changed) { 6032 updateOomAdjLocked(); 6033 } 6034 } 6035 } 6036 6037 // ========================================================= 6038 // PERMISSIONS 6039 // ========================================================= 6040 6041 static class PermissionController extends IPermissionController.Stub { 6042 ActivityManagerService mActivityManagerService; PermissionController(ActivityManagerService activityManagerService)6043 PermissionController(ActivityManagerService activityManagerService) { 6044 mActivityManagerService = activityManagerService; 6045 } 6046 checkPermission(String permission, int pid, int uid)6047 public boolean checkPermission(String permission, int pid, int uid) { 6048 return mActivityManagerService.checkPermission(permission, pid, 6049 uid) == PackageManager.PERMISSION_GRANTED; 6050 } 6051 } 6052 6053 /** 6054 * This can be called with or without the global lock held. 6055 */ checkComponentPermission(String permission, int pid, int uid, int reqUid)6056 int checkComponentPermission(String permission, int pid, int uid, 6057 int reqUid) { 6058 // We might be performing an operation on behalf of an indirect binder 6059 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6060 // client identity accordingly before proceeding. 6061 Identity tlsIdentity = sCallerIdentity.get(); 6062 if (tlsIdentity != null) { 6063 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6064 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6065 uid = tlsIdentity.uid; 6066 pid = tlsIdentity.pid; 6067 } 6068 6069 // Root, system server and our own process get to do everything. 6070 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 6071 !Process.supportsProcesses()) { 6072 return PackageManager.PERMISSION_GRANTED; 6073 } 6074 // If the target requires a specific UID, always fail for others. 6075 if (reqUid >= 0 && uid != reqUid) { 6076 return PackageManager.PERMISSION_DENIED; 6077 } 6078 if (permission == null) { 6079 return PackageManager.PERMISSION_GRANTED; 6080 } 6081 try { 6082 return ActivityThread.getPackageManager() 6083 .checkUidPermission(permission, uid); 6084 } catch (RemoteException e) { 6085 // Should never happen, but if it does... deny! 6086 Log.e(TAG, "PackageManager is dead?!?", e); 6087 } 6088 return PackageManager.PERMISSION_DENIED; 6089 } 6090 6091 /** 6092 * As the only public entry point for permissions checking, this method 6093 * can enforce the semantic that requesting a check on a null global 6094 * permission is automatically denied. (Internally a null permission 6095 * string is used when calling {@link #checkComponentPermission} in cases 6096 * when only uid-based security is needed.) 6097 * 6098 * This can be called with or without the global lock held. 6099 */ checkPermission(String permission, int pid, int uid)6100 public int checkPermission(String permission, int pid, int uid) { 6101 if (permission == null) { 6102 return PackageManager.PERMISSION_DENIED; 6103 } 6104 return checkComponentPermission(permission, pid, uid, -1); 6105 } 6106 6107 /** 6108 * Binder IPC calls go through the public entry point. 6109 * This can be called with or without the global lock held. 6110 */ checkCallingPermission(String permission)6111 int checkCallingPermission(String permission) { 6112 return checkPermission(permission, 6113 Binder.getCallingPid(), 6114 Binder.getCallingUid()); 6115 } 6116 6117 /** 6118 * This can be called with or without the global lock held. 6119 */ enforceCallingPermission(String permission, String func)6120 void enforceCallingPermission(String permission, String func) { 6121 if (checkCallingPermission(permission) 6122 == PackageManager.PERMISSION_GRANTED) { 6123 return; 6124 } 6125 6126 String msg = "Permission Denial: " + func + " from pid=" 6127 + Binder.getCallingPid() 6128 + ", uid=" + Binder.getCallingUid() 6129 + " requires " + permission; 6130 Log.w(TAG, msg); 6131 throw new SecurityException(msg); 6132 } 6133 checkHoldingPermissionsLocked(IPackageManager pm, ProviderInfo pi, int uid, int modeFlags)6134 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 6135 ProviderInfo pi, int uid, int modeFlags) { 6136 try { 6137 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6138 if ((pi.readPermission != null) && 6139 (pm.checkUidPermission(pi.readPermission, uid) 6140 != PackageManager.PERMISSION_GRANTED)) { 6141 return false; 6142 } 6143 } 6144 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6145 if ((pi.writePermission != null) && 6146 (pm.checkUidPermission(pi.writePermission, uid) 6147 != PackageManager.PERMISSION_GRANTED)) { 6148 return false; 6149 } 6150 } 6151 return true; 6152 } catch (RemoteException e) { 6153 return false; 6154 } 6155 } 6156 checkUriPermissionLocked(Uri uri, int uid, int modeFlags)6157 private final boolean checkUriPermissionLocked(Uri uri, int uid, 6158 int modeFlags) { 6159 // Root gets to do everything. 6160 if (uid == 0 || !Process.supportsProcesses()) { 6161 return true; 6162 } 6163 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6164 if (perms == null) return false; 6165 UriPermission perm = perms.get(uri); 6166 if (perm == null) return false; 6167 return (modeFlags&perm.modeFlags) == modeFlags; 6168 } 6169 checkUriPermission(Uri uri, int pid, int uid, int modeFlags)6170 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 6171 // Another redirected-binder-call permissions check as in 6172 // {@link checkComponentPermission}. 6173 Identity tlsIdentity = sCallerIdentity.get(); 6174 if (tlsIdentity != null) { 6175 uid = tlsIdentity.uid; 6176 pid = tlsIdentity.pid; 6177 } 6178 6179 // Our own process gets to do everything. 6180 if (pid == MY_PID) { 6181 return PackageManager.PERMISSION_GRANTED; 6182 } 6183 synchronized(this) { 6184 return checkUriPermissionLocked(uri, uid, modeFlags) 6185 ? PackageManager.PERMISSION_GRANTED 6186 : PackageManager.PERMISSION_DENIED; 6187 } 6188 } 6189 grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, HistoryRecord activity)6190 private void grantUriPermissionLocked(int callingUid, 6191 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 6192 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6193 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6194 if (modeFlags == 0) { 6195 return; 6196 } 6197 6198 final IPackageManager pm = ActivityThread.getPackageManager(); 6199 6200 // If this is not a content: uri, we can't do anything with it. 6201 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6202 return; 6203 } 6204 6205 String name = uri.getAuthority(); 6206 ProviderInfo pi = null; 6207 ContentProviderRecord cpr 6208 = (ContentProviderRecord)mProvidersByName.get(name); 6209 if (cpr != null) { 6210 pi = cpr.info; 6211 } else { 6212 try { 6213 pi = pm.resolveContentProvider(name, 6214 PackageManager.GET_URI_PERMISSION_PATTERNS); 6215 } catch (RemoteException ex) { 6216 } 6217 } 6218 if (pi == null) { 6219 Log.w(TAG, "No content provider found for: " + name); 6220 return; 6221 } 6222 6223 int targetUid; 6224 try { 6225 targetUid = pm.getPackageUid(targetPkg); 6226 if (targetUid < 0) { 6227 return; 6228 } 6229 } catch (RemoteException ex) { 6230 return; 6231 } 6232 6233 // First... does the target actually need this permission? 6234 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 6235 // No need to grant the target this permission. 6236 return; 6237 } 6238 6239 // Second... maybe someone else has already granted the 6240 // permission? 6241 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) { 6242 // No need to grant the target this permission. 6243 return; 6244 } 6245 6246 // Third... is the provider allowing granting of URI permissions? 6247 if (!pi.grantUriPermissions) { 6248 throw new SecurityException("Provider " + pi.packageName 6249 + "/" + pi.name 6250 + " does not allow granting of Uri permissions (uri " 6251 + uri + ")"); 6252 } 6253 if (pi.uriPermissionPatterns != null) { 6254 final int N = pi.uriPermissionPatterns.length; 6255 boolean allowed = false; 6256 for (int i=0; i<N; i++) { 6257 if (pi.uriPermissionPatterns[i] != null 6258 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6259 allowed = true; 6260 break; 6261 } 6262 } 6263 if (!allowed) { 6264 throw new SecurityException("Provider " + pi.packageName 6265 + "/" + pi.name 6266 + " does not allow granting of permission to path of Uri " 6267 + uri); 6268 } 6269 } 6270 6271 // Fourth... does the caller itself have permission to access 6272 // this uri? 6273 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6274 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6275 throw new SecurityException("Uid " + callingUid 6276 + " does not have permission to uri " + uri); 6277 } 6278 } 6279 6280 // Okay! So here we are: the caller has the assumed permission 6281 // to the uri, and the target doesn't. Let's now give this to 6282 // the target. 6283 6284 HashMap<Uri, UriPermission> targetUris 6285 = mGrantedUriPermissions.get(targetUid); 6286 if (targetUris == null) { 6287 targetUris = new HashMap<Uri, UriPermission>(); 6288 mGrantedUriPermissions.put(targetUid, targetUris); 6289 } 6290 6291 UriPermission perm = targetUris.get(uri); 6292 if (perm == null) { 6293 perm = new UriPermission(targetUid, uri); 6294 targetUris.put(uri, perm); 6295 6296 } 6297 perm.modeFlags |= modeFlags; 6298 if (activity == null) { 6299 perm.globalModeFlags |= modeFlags; 6300 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6301 perm.readActivities.add(activity); 6302 if (activity.readUriPermissions == null) { 6303 activity.readUriPermissions = new HashSet<UriPermission>(); 6304 } 6305 activity.readUriPermissions.add(perm); 6306 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6307 perm.writeActivities.add(activity); 6308 if (activity.writeUriPermissions == null) { 6309 activity.writeUriPermissions = new HashSet<UriPermission>(); 6310 } 6311 activity.writeUriPermissions.add(perm); 6312 } 6313 } 6314 grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, HistoryRecord activity)6315 private void grantUriPermissionFromIntentLocked(int callingUid, 6316 String targetPkg, Intent intent, HistoryRecord activity) { 6317 if (intent == null) { 6318 return; 6319 } 6320 Uri data = intent.getData(); 6321 if (data == null) { 6322 return; 6323 } 6324 grantUriPermissionLocked(callingUid, targetPkg, data, 6325 intent.getFlags(), activity); 6326 } 6327 grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, int modeFlags)6328 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6329 Uri uri, int modeFlags) { 6330 synchronized(this) { 6331 final ProcessRecord r = getRecordForAppLocked(caller); 6332 if (r == null) { 6333 throw new SecurityException("Unable to find app for caller " 6334 + caller 6335 + " when granting permission to uri " + uri); 6336 } 6337 if (targetPkg == null) { 6338 Log.w(TAG, "grantUriPermission: null target"); 6339 return; 6340 } 6341 if (uri == null) { 6342 Log.w(TAG, "grantUriPermission: null uri"); 6343 return; 6344 } 6345 6346 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 6347 null); 6348 } 6349 } 6350 removeUriPermissionIfNeededLocked(UriPermission perm)6351 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 6352 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6353 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6354 HashMap<Uri, UriPermission> perms 6355 = mGrantedUriPermissions.get(perm.uid); 6356 if (perms != null) { 6357 perms.remove(perm.uri); 6358 if (perms.size() == 0) { 6359 mGrantedUriPermissions.remove(perm.uid); 6360 } 6361 } 6362 } 6363 } 6364 removeActivityUriPermissionsLocked(HistoryRecord activity)6365 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 6366 if (activity.readUriPermissions != null) { 6367 for (UriPermission perm : activity.readUriPermissions) { 6368 perm.readActivities.remove(activity); 6369 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 6370 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 6371 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 6372 removeUriPermissionIfNeededLocked(perm); 6373 } 6374 } 6375 } 6376 if (activity.writeUriPermissions != null) { 6377 for (UriPermission perm : activity.writeUriPermissions) { 6378 perm.writeActivities.remove(activity); 6379 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 6380 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 6381 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 6382 removeUriPermissionIfNeededLocked(perm); 6383 } 6384 } 6385 } 6386 } 6387 revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags)6388 private void revokeUriPermissionLocked(int callingUid, Uri uri, 6389 int modeFlags) { 6390 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6391 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6392 if (modeFlags == 0) { 6393 return; 6394 } 6395 6396 final IPackageManager pm = ActivityThread.getPackageManager(); 6397 6398 final String authority = uri.getAuthority(); 6399 ProviderInfo pi = null; 6400 ContentProviderRecord cpr 6401 = (ContentProviderRecord)mProvidersByName.get(authority); 6402 if (cpr != null) { 6403 pi = cpr.info; 6404 } else { 6405 try { 6406 pi = pm.resolveContentProvider(authority, 6407 PackageManager.GET_URI_PERMISSION_PATTERNS); 6408 } catch (RemoteException ex) { 6409 } 6410 } 6411 if (pi == null) { 6412 Log.w(TAG, "No content provider found for: " + authority); 6413 return; 6414 } 6415 6416 // Does the caller have this permission on the URI? 6417 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6418 // Right now, if you are not the original owner of the permission, 6419 // you are not allowed to revoke it. 6420 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6421 throw new SecurityException("Uid " + callingUid 6422 + " does not have permission to uri " + uri); 6423 //} 6424 } 6425 6426 // Go through all of the permissions and remove any that match. 6427 final List<String> SEGMENTS = uri.getPathSegments(); 6428 if (SEGMENTS != null) { 6429 final int NS = SEGMENTS.size(); 6430 int N = mGrantedUriPermissions.size(); 6431 for (int i=0; i<N; i++) { 6432 HashMap<Uri, UriPermission> perms 6433 = mGrantedUriPermissions.valueAt(i); 6434 Iterator<UriPermission> it = perms.values().iterator(); 6435 toploop: 6436 while (it.hasNext()) { 6437 UriPermission perm = it.next(); 6438 Uri targetUri = perm.uri; 6439 if (!authority.equals(targetUri.getAuthority())) { 6440 continue; 6441 } 6442 List<String> targetSegments = targetUri.getPathSegments(); 6443 if (targetSegments == null) { 6444 continue; 6445 } 6446 if (targetSegments.size() < NS) { 6447 continue; 6448 } 6449 for (int j=0; j<NS; j++) { 6450 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6451 continue toploop; 6452 } 6453 } 6454 perm.clearModes(modeFlags); 6455 if (perm.modeFlags == 0) { 6456 it.remove(); 6457 } 6458 } 6459 if (perms.size() == 0) { 6460 mGrantedUriPermissions.remove( 6461 mGrantedUriPermissions.keyAt(i)); 6462 N--; 6463 i--; 6464 } 6465 } 6466 } 6467 } 6468 revokeUriPermission(IApplicationThread caller, Uri uri, int modeFlags)6469 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6470 int modeFlags) { 6471 synchronized(this) { 6472 final ProcessRecord r = getRecordForAppLocked(caller); 6473 if (r == null) { 6474 throw new SecurityException("Unable to find app for caller " 6475 + caller 6476 + " when revoking permission to uri " + uri); 6477 } 6478 if (uri == null) { 6479 Log.w(TAG, "revokeUriPermission: null uri"); 6480 return; 6481 } 6482 6483 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6484 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6485 if (modeFlags == 0) { 6486 return; 6487 } 6488 6489 final IPackageManager pm = ActivityThread.getPackageManager(); 6490 6491 final String authority = uri.getAuthority(); 6492 ProviderInfo pi = null; 6493 ContentProviderRecord cpr 6494 = (ContentProviderRecord)mProvidersByName.get(authority); 6495 if (cpr != null) { 6496 pi = cpr.info; 6497 } else { 6498 try { 6499 pi = pm.resolveContentProvider(authority, 6500 PackageManager.GET_URI_PERMISSION_PATTERNS); 6501 } catch (RemoteException ex) { 6502 } 6503 } 6504 if (pi == null) { 6505 Log.w(TAG, "No content provider found for: " + authority); 6506 return; 6507 } 6508 6509 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 6510 } 6511 } 6512 showWaitingForDebugger(IApplicationThread who, boolean waiting)6513 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6514 synchronized (this) { 6515 ProcessRecord app = 6516 who != null ? getRecordForAppLocked(who) : null; 6517 if (app == null) return; 6518 6519 Message msg = Message.obtain(); 6520 msg.what = WAIT_FOR_DEBUGGER_MSG; 6521 msg.obj = app; 6522 msg.arg1 = waiting ? 1 : 0; 6523 mHandler.sendMessage(msg); 6524 } 6525 } 6526 getMemoryInfo(ActivityManager.MemoryInfo outInfo)6527 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6528 outInfo.availMem = Process.getFreeMemory(); 6529 outInfo.threshold = HOME_APP_MEM; 6530 outInfo.lowMemory = outInfo.availMem < 6531 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 6532 } 6533 6534 // ========================================================= 6535 // TASK MANAGEMENT 6536 // ========================================================= 6537 6538 public List getTasks(int maxNum, int flags, 6539 IThumbnailReceiver receiver) { 6540 ArrayList list = new ArrayList(); 6541 6542 PendingThumbnailsRecord pending = null; 6543 IApplicationThread topThumbnail = null; 6544 HistoryRecord topRecord = null; 6545 6546 synchronized(this) { 6547 if (localLOGV) Log.v( 6548 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6549 + ", receiver=" + receiver); 6550 6551 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6552 != PackageManager.PERMISSION_GRANTED) { 6553 if (receiver != null) { 6554 // If the caller wants to wait for pending thumbnails, 6555 // it ain't gonna get them. 6556 try { 6557 receiver.finished(); 6558 } catch (RemoteException ex) { 6559 } 6560 } 6561 String msg = "Permission Denial: getTasks() from pid=" 6562 + Binder.getCallingPid() 6563 + ", uid=" + Binder.getCallingUid() 6564 + " requires " + android.Manifest.permission.GET_TASKS; 6565 Log.w(TAG, msg); 6566 throw new SecurityException(msg); 6567 } 6568 6569 int pos = mHistory.size()-1; 6570 HistoryRecord next = 6571 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6572 HistoryRecord top = null; 6573 CharSequence topDescription = null; 6574 TaskRecord curTask = null; 6575 int numActivities = 0; 6576 int numRunning = 0; 6577 while (pos >= 0 && maxNum > 0) { 6578 final HistoryRecord r = next; 6579 pos--; 6580 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6581 6582 // Initialize state for next task if needed. 6583 if (top == null || 6584 (top.state == ActivityState.INITIALIZING 6585 && top.task == r.task)) { 6586 top = r; 6587 topDescription = r.description; 6588 curTask = r.task; 6589 numActivities = numRunning = 0; 6590 } 6591 6592 // Add 'r' into the current task. 6593 numActivities++; 6594 if (r.app != null && r.app.thread != null) { 6595 numRunning++; 6596 } 6597 if (topDescription == null) { 6598 topDescription = r.description; 6599 } 6600 6601 if (localLOGV) Log.v( 6602 TAG, r.intent.getComponent().flattenToShortString() 6603 + ": task=" + r.task); 6604 6605 // If the next one is a different task, generate a new 6606 // TaskInfo entry for what we have. 6607 if (next == null || next.task != curTask) { 6608 ActivityManager.RunningTaskInfo ci 6609 = new ActivityManager.RunningTaskInfo(); 6610 ci.id = curTask.taskId; 6611 ci.baseActivity = r.intent.getComponent(); 6612 ci.topActivity = top.intent.getComponent(); 6613 ci.thumbnail = top.thumbnail; 6614 ci.description = topDescription; 6615 ci.numActivities = numActivities; 6616 ci.numRunning = numRunning; 6617 //System.out.println( 6618 // "#" + maxNum + ": " + " descr=" + ci.description); 6619 if (ci.thumbnail == null && receiver != null) { 6620 if (localLOGV) Log.v( 6621 TAG, "State=" + top.state + "Idle=" + top.idle 6622 + " app=" + top.app 6623 + " thr=" + (top.app != null ? top.app.thread : null)); 6624 if (top.state == ActivityState.RESUMED 6625 || top.state == ActivityState.PAUSING) { 6626 if (top.idle && top.app != null 6627 && top.app.thread != null) { 6628 topRecord = top; 6629 topThumbnail = top.app.thread; 6630 } else { 6631 top.thumbnailNeeded = true; 6632 } 6633 } 6634 if (pending == null) { 6635 pending = new PendingThumbnailsRecord(receiver); 6636 } 6637 pending.pendingRecords.add(top); 6638 } 6639 list.add(ci); 6640 maxNum--; 6641 top = null; 6642 } 6643 } 6644 6645 if (pending != null) { 6646 mPendingThumbnails.add(pending); 6647 } 6648 } 6649 Log.v(TAG, "We have pending thumbnails: " + pending)6650 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending); 6651 6652 if (topThumbnail != null) { Log.v(TAG, "Requesting top thumbnail")6653 if (localLOGV) Log.v(TAG, "Requesting top thumbnail"); 6654 try { 6655 topThumbnail.requestThumbnail(topRecord); 6656 } catch (Exception e) { 6657 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 6658 sendPendingThumbnail(null, topRecord, null, null, true); 6659 } 6660 } 6661 6662 if (pending == null && receiver != null) { 6663 // In this case all thumbnails were available and the client 6664 // is being asked to be told when the remaining ones come in... 6665 // which is unusually, since the top-most currently running 6666 // activity should never have a canned thumbnail! Oh well. 6667 try { receiver.finished()6668 receiver.finished(); 6669 } catch (RemoteException ex) { 6670 } 6671 } 6672 6673 return list; 6674 } 6675 getRecentTasks(int maxNum, int flags)6676 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6677 int flags) { 6678 synchronized (this) { 6679 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6680 "getRecentTasks()"); 6681 6682 final int N = mRecentTasks.size(); 6683 ArrayList<ActivityManager.RecentTaskInfo> res 6684 = new ArrayList<ActivityManager.RecentTaskInfo>( 6685 maxNum < N ? maxNum : N); 6686 for (int i=0; i<N && maxNum > 0; i++) { 6687 TaskRecord tr = mRecentTasks.get(i); 6688 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6689 || (tr.intent == null) 6690 || ((tr.intent.getFlags() 6691 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6692 ActivityManager.RecentTaskInfo rti 6693 = new ActivityManager.RecentTaskInfo(); 6694 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6695 rti.baseIntent = new Intent( 6696 tr.intent != null ? tr.intent : tr.affinityIntent); 6697 rti.origActivity = tr.origActivity; 6698 res.add(rti); 6699 maxNum--; 6700 } 6701 } 6702 return res; 6703 } 6704 } 6705 findAffinityTaskTopLocked(int startIndex, String affinity)6706 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6707 int j; 6708 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6709 TaskRecord jt = startTask; 6710 6711 // First look backwards 6712 for (j=startIndex-1; j>=0; j--) { 6713 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6714 if (r.task != jt) { 6715 jt = r.task; 6716 if (affinity.equals(jt.affinity)) { 6717 return j; 6718 } 6719 } 6720 } 6721 6722 // Now look forwards 6723 final int N = mHistory.size(); 6724 jt = startTask; 6725 for (j=startIndex+1; j<N; j++) { 6726 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6727 if (r.task != jt) { 6728 if (affinity.equals(jt.affinity)) { 6729 return j; 6730 } 6731 jt = r.task; 6732 } 6733 } 6734 6735 // Might it be at the top? 6736 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 6737 return N-1; 6738 } 6739 6740 return -1; 6741 } 6742 6743 /** 6744 * Perform a reset of the given task, if needed as part of launching it. 6745 * Returns the new HistoryRecord at the top of the task. 6746 */ resetTaskIfNeededLocked(HistoryRecord taskTop, HistoryRecord newActivity)6747 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 6748 HistoryRecord newActivity) { 6749 boolean forceReset = (newActivity.info.flags 6750 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 6751 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 6752 if ((newActivity.info.flags 6753 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 6754 forceReset = true; 6755 } 6756 } 6757 6758 final TaskRecord task = taskTop.task; 6759 6760 // We are going to move through the history list so that we can look 6761 // at each activity 'target' with 'below' either the interesting 6762 // activity immediately below it in the stack or null. 6763 HistoryRecord target = null; 6764 int targetI = 0; 6765 int taskTopI = -1; 6766 int replyChainEnd = -1; 6767 int lastReparentPos = -1; 6768 for (int i=mHistory.size()-1; i>=-1; i--) { 6769 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 6770 6771 if (below != null && below.finishing) { 6772 continue; 6773 } 6774 if (target == null) { 6775 target = below; 6776 targetI = i; 6777 // If we were in the middle of a reply chain before this 6778 // task, it doesn't appear like the root of the chain wants 6779 // anything interesting, so drop it. 6780 replyChainEnd = -1; 6781 continue; 6782 } 6783 6784 final int flags = target.info.flags; 6785 6786 final boolean finishOnTaskLaunch = 6787 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 6788 final boolean allowTaskReparenting = 6789 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 6790 6791 if (target.task == task) { 6792 // We are inside of the task being reset... we'll either 6793 // finish this activity, push it out for another task, 6794 // or leave it as-is. We only do this 6795 // for activities that are not the root of the task (since 6796 // if we finish the root, we may no longer have the task!). 6797 if (taskTopI < 0) { 6798 taskTopI = targetI; 6799 } 6800 if (below != null && below.task == task) { 6801 final boolean clearWhenTaskReset = 6802 (target.intent.getFlags() 6803 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 6804 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 6805 // If this activity is sending a reply to a previous 6806 // activity, we can't do anything with it now until 6807 // we reach the start of the reply chain. 6808 // XXX note that we are assuming the result is always 6809 // to the previous activity, which is almost always 6810 // the case but we really shouldn't count on. 6811 if (replyChainEnd < 0) { 6812 replyChainEnd = targetI; 6813 } 6814 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 6815 && target.taskAffinity != null 6816 && !target.taskAffinity.equals(task.affinity)) { 6817 // If this activity has an affinity for another 6818 // task, then we need to move it out of here. We will 6819 // move it as far out of the way as possible, to the 6820 // bottom of the activity stack. This also keeps it 6821 // correctly ordered with any activities we previously 6822 // moved. 6823 HistoryRecord p = (HistoryRecord)mHistory.get(0); 6824 if (target.taskAffinity != null 6825 && target.taskAffinity.equals(p.task.affinity)) { 6826 // If the activity currently at the bottom has the 6827 // same task affinity as the one we are moving, 6828 // then merge it into the same task. 6829 target.task = p.task; 6830 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6831 + " out to bottom task " + p.task); 6832 } else { 6833 mCurTask++; 6834 if (mCurTask <= 0) { 6835 mCurTask = 1; 6836 } 6837 target.task = new TaskRecord(mCurTask, target.info, null, 6838 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 6839 target.task.affinityIntent = target.intent; 6840 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6841 + " out to new task " + target.task); 6842 } 6843 mWindowManager.setAppGroupId(target, task.taskId); 6844 if (replyChainEnd < 0) { 6845 replyChainEnd = targetI; 6846 } 6847 int dstPos = 0; 6848 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6849 p = (HistoryRecord)mHistory.get(srcPos); 6850 if (p.finishing) { 6851 continue; 6852 } 6853 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p 6854 + " out to target's task " + target.task); 6855 task.numActivities--; 6856 p.task = target.task; 6857 target.task.numActivities++; 6858 mHistory.remove(srcPos); 6859 mHistory.add(dstPos, p); 6860 mWindowManager.moveAppToken(dstPos, p); 6861 mWindowManager.setAppGroupId(p, p.task.taskId); 6862 dstPos++; 6863 if (VALIDATE_TOKENS) { 6864 mWindowManager.validateAppTokens(mHistory); 6865 } 6866 i++; 6867 } 6868 if (taskTop == p) { 6869 taskTop = below; 6870 } 6871 if (taskTopI == replyChainEnd) { 6872 taskTopI = -1; 6873 } 6874 replyChainEnd = -1; 6875 addRecentTask(target.task); 6876 } else if (forceReset || finishOnTaskLaunch 6877 || clearWhenTaskReset) { 6878 // If the activity should just be removed -- either 6879 // because it asks for it, or the task should be 6880 // cleared -- then finish it and anything that is 6881 // part of its reply chain. 6882 if (clearWhenTaskReset) { 6883 // In this case, we want to finish this activity 6884 // and everything above it, so be sneaky and pretend 6885 // like these are all in the reply chain. 6886 replyChainEnd = targetI+1; 6887 while (replyChainEnd < mHistory.size() && 6888 ((HistoryRecord)mHistory.get( 6889 replyChainEnd)).task == task) { 6890 replyChainEnd++; 6891 } 6892 replyChainEnd--; 6893 } else if (replyChainEnd < 0) { 6894 replyChainEnd = targetI; 6895 } 6896 HistoryRecord p = null; 6897 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6898 p = (HistoryRecord)mHistory.get(srcPos); 6899 if (p.finishing) { 6900 continue; 6901 } 6902 if (finishActivityLocked(p, srcPos, 6903 Activity.RESULT_CANCELED, null, "reset")) { 6904 replyChainEnd--; 6905 srcPos--; 6906 } 6907 } 6908 if (taskTop == p) { 6909 taskTop = below; 6910 } 6911 if (taskTopI == replyChainEnd) { 6912 taskTopI = -1; 6913 } 6914 replyChainEnd = -1; 6915 } else { 6916 // If we were in the middle of a chain, well the 6917 // activity that started it all doesn't want anything 6918 // special, so leave it all as-is. 6919 replyChainEnd = -1; 6920 } 6921 } else { 6922 // Reached the bottom of the task -- any reply chain 6923 // should be left as-is. 6924 replyChainEnd = -1; 6925 } 6926 6927 } else if (target.resultTo != null) { 6928 // If this activity is sending a reply to a previous 6929 // activity, we can't do anything with it now until 6930 // we reach the start of the reply chain. 6931 // XXX note that we are assuming the result is always 6932 // to the previous activity, which is almost always 6933 // the case but we really shouldn't count on. 6934 if (replyChainEnd < 0) { 6935 replyChainEnd = targetI; 6936 } 6937 6938 } else if (taskTopI >= 0 && allowTaskReparenting 6939 && task.affinity != null 6940 && task.affinity.equals(target.taskAffinity)) { 6941 // We are inside of another task... if this activity has 6942 // an affinity for our task, then either remove it if we are 6943 // clearing or move it over to our task. Note that 6944 // we currently punt on the case where we are resetting a 6945 // task that is not at the top but who has activities above 6946 // with an affinity to it... this is really not a normal 6947 // case, and we will need to later pull that task to the front 6948 // and usually at that point we will do the reset and pick 6949 // up those remaining activities. (This only happens if 6950 // someone starts an activity in a new task from an activity 6951 // in a task that is not currently on top.) 6952 if (forceReset || finishOnTaskLaunch) { 6953 if (replyChainEnd < 0) { 6954 replyChainEnd = targetI; 6955 } 6956 HistoryRecord p = null; 6957 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6958 p = (HistoryRecord)mHistory.get(srcPos); 6959 if (p.finishing) { 6960 continue; 6961 } 6962 if (finishActivityLocked(p, srcPos, 6963 Activity.RESULT_CANCELED, null, "reset")) { 6964 taskTopI--; 6965 lastReparentPos--; 6966 replyChainEnd--; 6967 srcPos--; 6968 } 6969 } 6970 replyChainEnd = -1; 6971 } else { 6972 if (replyChainEnd < 0) { 6973 replyChainEnd = targetI; 6974 } 6975 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 6976 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 6977 if (p.finishing) { 6978 continue; 6979 } 6980 if (lastReparentPos < 0) { 6981 lastReparentPos = taskTopI; 6982 taskTop = p; 6983 } else { 6984 lastReparentPos--; 6985 } 6986 mHistory.remove(srcPos); 6987 p.task.numActivities--; 6988 p.task = task; 6989 mHistory.add(lastReparentPos, p); 6990 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p 6991 + " in to resetting task " + task); 6992 task.numActivities++; 6993 mWindowManager.moveAppToken(lastReparentPos, p); 6994 mWindowManager.setAppGroupId(p, p.task.taskId); 6995 if (VALIDATE_TOKENS) { 6996 mWindowManager.validateAppTokens(mHistory); 6997 } 6998 } 6999 replyChainEnd = -1; 7000 7001 // Now we've moved it in to place... but what if this is 7002 // a singleTop activity and we have put it on top of another 7003 // instance of the same activity? Then we drop the instance 7004 // below so it remains singleTop. 7005 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 7006 for (int j=lastReparentPos-1; j>=0; j--) { 7007 HistoryRecord p = (HistoryRecord)mHistory.get(j); 7008 if (p.finishing) { 7009 continue; 7010 } 7011 if (p.intent.getComponent().equals(target.intent.getComponent())) { 7012 if (finishActivityLocked(p, j, 7013 Activity.RESULT_CANCELED, null, "replace")) { 7014 taskTopI--; 7015 lastReparentPos--; 7016 } 7017 } 7018 } 7019 } 7020 } 7021 } 7022 7023 target = below; 7024 targetI = i; 7025 } 7026 7027 return taskTop; 7028 } 7029 7030 /** 7031 * TODO: Add mController hook 7032 */ moveTaskToFront(int task)7033 public void moveTaskToFront(int task) { 7034 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7035 "moveTaskToFront()"); 7036 7037 synchronized(this) { 7038 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7039 Binder.getCallingUid(), "Task to front")) { 7040 return; 7041 } 7042 final long origId = Binder.clearCallingIdentity(); 7043 try { 7044 int N = mRecentTasks.size(); 7045 for (int i=0; i<N; i++) { 7046 TaskRecord tr = mRecentTasks.get(i); 7047 if (tr.taskId == task) { 7048 moveTaskToFrontLocked(tr, null); 7049 return; 7050 } 7051 } 7052 for (int i=mHistory.size()-1; i>=0; i--) { 7053 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 7054 if (hr.task.taskId == task) { 7055 moveTaskToFrontLocked(hr.task, null); 7056 return; 7057 } 7058 } 7059 } finally { 7060 Binder.restoreCallingIdentity(origId); 7061 } 7062 } 7063 } 7064 moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason)7065 private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) { 7066 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr); 7067 7068 final int task = tr.taskId; 7069 int top = mHistory.size()-1; 7070 7071 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 7072 // nothing to do! 7073 return; 7074 } 7075 7076 ArrayList moved = new ArrayList(); 7077 7078 // Applying the affinities may have removed entries from the history, 7079 // so get the size again. 7080 top = mHistory.size()-1; 7081 int pos = top; 7082 7083 // Shift all activities with this task up to the top 7084 // of the stack, keeping them in the same internal order. 7085 while (pos >= 0) { 7086 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7087 if (localLOGV) Log.v( 7088 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7089 boolean first = true; 7090 if (r.task.taskId == task) { 7091 if (localLOGV) Log.v(TAG, "Removing and adding at " + top); 7092 mHistory.remove(pos); 7093 mHistory.add(top, r); 7094 moved.add(0, r); 7095 top--; 7096 if (first) { 7097 addRecentTask(r.task); 7098 first = false; 7099 } 7100 } 7101 pos--; 7102 } 7103 7104 if (DEBUG_TRANSITION) Log.v(TAG, 7105 "Prepare to front transition: task=" + tr); 7106 if (reason != null && 7107 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7108 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7109 HistoryRecord r = topRunningActivityLocked(null); 7110 if (r != null) { 7111 mNoAnimActivities.add(r); 7112 } 7113 } else { 7114 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7115 } 7116 7117 mWindowManager.moveAppTokensToTop(moved); 7118 if (VALIDATE_TOKENS) { 7119 mWindowManager.validateAppTokens(mHistory); 7120 } 7121 7122 finishTaskMove(task); 7123 EventLog.writeEvent(LOG_TASK_TO_FRONT, task); 7124 } 7125 finishTaskMove(int task)7126 private final void finishTaskMove(int task) { 7127 resumeTopActivityLocked(null); 7128 } 7129 moveTaskToBack(int task)7130 public void moveTaskToBack(int task) { 7131 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7132 "moveTaskToBack()"); 7133 7134 synchronized(this) { 7135 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 7136 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7137 Binder.getCallingUid(), "Task to back")) { 7138 return; 7139 } 7140 } 7141 final long origId = Binder.clearCallingIdentity(); 7142 moveTaskToBackLocked(task, null); 7143 Binder.restoreCallingIdentity(origId); 7144 } 7145 } 7146 7147 /** 7148 * Moves an activity, and all of the other activities within the same task, to the bottom 7149 * of the history stack. The activity's order within the task is unchanged. 7150 * 7151 * @param token A reference to the activity we wish to move 7152 * @param nonRoot If false then this only works if the activity is the root 7153 * of a task; if true it will work for any activity in a task. 7154 * @return Returns true if the move completed, false if not. 7155 */ moveActivityTaskToBack(IBinder token, boolean nonRoot)7156 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7157 synchronized(this) { 7158 final long origId = Binder.clearCallingIdentity(); 7159 int taskId = getTaskForActivityLocked(token, !nonRoot); 7160 if (taskId >= 0) { 7161 return moveTaskToBackLocked(taskId, null); 7162 } 7163 Binder.restoreCallingIdentity(origId); 7164 } 7165 return false; 7166 } 7167 7168 /** 7169 * Worker method for rearranging history stack. Implements the function of moving all 7170 * activities for a specific task (gathering them if disjoint) into a single group at the 7171 * bottom of the stack. 7172 * 7173 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 7174 * to premeptively cancel the move. 7175 * 7176 * @param task The taskId to collect and move to the bottom. 7177 * @return Returns true if the move completed, false if not. 7178 */ moveTaskToBackLocked(int task, HistoryRecord reason)7179 private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) { 7180 Log.i(TAG, "moveTaskToBack: " + task); 7181 7182 // If we have a watcher, preflight the move before committing to it. First check 7183 // for *other* available tasks, but if none are available, then try again allowing the 7184 // current task to be selected. 7185 if (mController != null) { 7186 HistoryRecord next = topRunningActivityLocked(null, task); 7187 if (next == null) { 7188 next = topRunningActivityLocked(null, 0); 7189 } 7190 if (next != null) { 7191 // ask watcher if this is allowed 7192 boolean moveOK = true; 7193 try { 7194 moveOK = mController.activityResuming(next.packageName); 7195 } catch (RemoteException e) { 7196 mController = null; 7197 } 7198 if (!moveOK) { 7199 return false; 7200 } 7201 } 7202 } 7203 7204 ArrayList moved = new ArrayList(); 7205 7206 if (DEBUG_TRANSITION) Log.v(TAG, 7207 "Prepare to back transition: task=" + task); 7208 7209 final int N = mHistory.size(); 7210 int bottom = 0; 7211 int pos = 0; 7212 7213 // Shift all activities with this task down to the bottom 7214 // of the stack, keeping them in the same internal order. 7215 while (pos < N) { 7216 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7217 if (localLOGV) Log.v( 7218 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7219 if (r.task.taskId == task) { 7220 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1)); 7221 mHistory.remove(pos); 7222 mHistory.add(bottom, r); 7223 moved.add(r); 7224 bottom++; 7225 } 7226 pos++; 7227 } 7228 7229 if (reason != null && 7230 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7231 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7232 HistoryRecord r = topRunningActivityLocked(null); 7233 if (r != null) { 7234 mNoAnimActivities.add(r); 7235 } 7236 } else { 7237 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 7238 } 7239 mWindowManager.moveAppTokensToBottom(moved); 7240 if (VALIDATE_TOKENS) { 7241 mWindowManager.validateAppTokens(mHistory); 7242 } 7243 7244 finishTaskMove(task); 7245 return true; 7246 } 7247 moveTaskBackwards(int task)7248 public void moveTaskBackwards(int task) { 7249 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7250 "moveTaskBackwards()"); 7251 7252 synchronized(this) { 7253 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7254 Binder.getCallingUid(), "Task backwards")) { 7255 return; 7256 } 7257 final long origId = Binder.clearCallingIdentity(); 7258 moveTaskBackwardsLocked(task); 7259 Binder.restoreCallingIdentity(origId); 7260 } 7261 } 7262 moveTaskBackwardsLocked(int task)7263 private final void moveTaskBackwardsLocked(int task) { 7264 Log.e(TAG, "moveTaskBackwards not yet implemented!"); 7265 } 7266 getTaskForActivity(IBinder token, boolean onlyRoot)7267 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7268 synchronized(this) { 7269 return getTaskForActivityLocked(token, onlyRoot); 7270 } 7271 } 7272 getTaskForActivityLocked(IBinder token, boolean onlyRoot)7273 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 7274 final int N = mHistory.size(); 7275 TaskRecord lastTask = null; 7276 for (int i=0; i<N; i++) { 7277 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7278 if (r == token) { 7279 if (!onlyRoot || lastTask != r.task) { 7280 return r.task.taskId; 7281 } 7282 return -1; 7283 } 7284 lastTask = r.task; 7285 } 7286 7287 return -1; 7288 } 7289 7290 /** 7291 * Returns the top activity in any existing task matching the given 7292 * Intent. Returns null if no such task is found. 7293 */ findTaskLocked(Intent intent, ActivityInfo info)7294 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 7295 ComponentName cls = intent.getComponent(); 7296 if (info.targetActivity != null) { 7297 cls = new ComponentName(info.packageName, info.targetActivity); 7298 } 7299 7300 TaskRecord cp = null; 7301 7302 final int N = mHistory.size(); 7303 for (int i=(N-1); i>=0; i--) { 7304 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7305 if (!r.finishing && r.task != cp 7306 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 7307 cp = r.task; 7308 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 7309 // + "/aff=" + r.task.affinity + " to new cls=" 7310 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 7311 if (r.task.affinity != null) { 7312 if (r.task.affinity.equals(info.taskAffinity)) { 7313 //Log.i(TAG, "Found matching affinity!"); 7314 return r; 7315 } 7316 } else if (r.task.intent != null 7317 && r.task.intent.getComponent().equals(cls)) { 7318 //Log.i(TAG, "Found matching class!"); 7319 //dump(); 7320 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7321 return r; 7322 } else if (r.task.affinityIntent != null 7323 && r.task.affinityIntent.getComponent().equals(cls)) { 7324 //Log.i(TAG, "Found matching class!"); 7325 //dump(); 7326 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7327 return r; 7328 } 7329 } 7330 } 7331 7332 return null; 7333 } 7334 7335 /** 7336 * Returns the first activity (starting from the top of the stack) that 7337 * is the same as the given activity. Returns null if no such activity 7338 * is found. 7339 */ findActivityLocked(Intent intent, ActivityInfo info)7340 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 7341 ComponentName cls = intent.getComponent(); 7342 if (info.targetActivity != null) { 7343 cls = new ComponentName(info.packageName, info.targetActivity); 7344 } 7345 7346 final int N = mHistory.size(); 7347 for (int i=(N-1); i>=0; i--) { 7348 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7349 if (!r.finishing) { 7350 if (r.intent.getComponent().equals(cls)) { 7351 //Log.i(TAG, "Found matching class!"); 7352 //dump(); 7353 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7354 return r; 7355 } 7356 } 7357 } 7358 7359 return null; 7360 } 7361 finishOtherInstances(IBinder token, ComponentName className)7362 public void finishOtherInstances(IBinder token, ComponentName className) { 7363 synchronized(this) { 7364 final long origId = Binder.clearCallingIdentity(); 7365 7366 int N = mHistory.size(); 7367 TaskRecord lastTask = null; 7368 for (int i=0; i<N; i++) { 7369 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7370 if (r.realActivity.equals(className) 7371 && r != token && lastTask != r.task) { 7372 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7373 null, "others")) { 7374 i--; 7375 N--; 7376 } 7377 } 7378 lastTask = r.task; 7379 } 7380 7381 Binder.restoreCallingIdentity(origId); 7382 } 7383 } 7384 7385 // ========================================================= 7386 // THUMBNAILS 7387 // ========================================================= 7388 reportThumbnail(IBinder token, Bitmap thumbnail, CharSequence description)7389 public void reportThumbnail(IBinder token, 7390 Bitmap thumbnail, CharSequence description) { 7391 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7392 final long origId = Binder.clearCallingIdentity(); 7393 sendPendingThumbnail(null, token, thumbnail, description, true); 7394 Binder.restoreCallingIdentity(origId); 7395 } 7396 sendPendingThumbnail(HistoryRecord r, IBinder token, Bitmap thumbnail, CharSequence description, boolean always)7397 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 7398 Bitmap thumbnail, CharSequence description, boolean always) { 7399 TaskRecord task = null; 7400 ArrayList receivers = null; 7401 7402 //System.out.println("Send pending thumbnail: " + r); 7403 7404 synchronized(this) { 7405 if (r == null) { 7406 int index = indexOfTokenLocked(token); 7407 if (index < 0) { 7408 return; 7409 } 7410 r = (HistoryRecord)mHistory.get(index); 7411 } 7412 if (thumbnail == null) { 7413 thumbnail = r.thumbnail; 7414 description = r.description; 7415 } 7416 if (thumbnail == null && !always) { 7417 // If there is no thumbnail, and this entry is not actually 7418 // going away, then abort for now and pick up the next 7419 // thumbnail we get. 7420 return; 7421 } 7422 task = r.task; 7423 7424 int N = mPendingThumbnails.size(); 7425 int i=0; 7426 while (i<N) { 7427 PendingThumbnailsRecord pr = 7428 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 7429 //System.out.println("Looking in " + pr.pendingRecords); 7430 if (pr.pendingRecords.remove(r)) { 7431 if (receivers == null) { 7432 receivers = new ArrayList(); 7433 } 7434 receivers.add(pr); 7435 if (pr.pendingRecords.size() == 0) { 7436 pr.finished = true; 7437 mPendingThumbnails.remove(i); 7438 N--; 7439 continue; 7440 } 7441 } 7442 i++; 7443 } 7444 } 7445 7446 if (receivers != null) { 7447 final int N = receivers.size(); 7448 for (int i=0; i<N; i++) { 7449 try { 7450 PendingThumbnailsRecord pr = 7451 (PendingThumbnailsRecord)receivers.get(i); 7452 pr.receiver.newThumbnail( 7453 task != null ? task.taskId : -1, thumbnail, description); 7454 if (pr.finished) { 7455 pr.receiver.finished(); 7456 } 7457 } catch (Exception e) { 7458 Log.w(TAG, "Exception thrown when sending thumbnail", e); 7459 } 7460 } 7461 } 7462 } 7463 7464 // ========================================================= 7465 // CONTENT PROVIDERS 7466 // ========================================================= 7467 generateApplicationProvidersLocked(ProcessRecord app)7468 private final List generateApplicationProvidersLocked(ProcessRecord app) { 7469 List providers = null; 7470 try { 7471 providers = ActivityThread.getPackageManager(). 7472 queryContentProviders(app.processName, app.info.uid, 7473 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7474 } catch (RemoteException ex) { 7475 } 7476 if (providers != null) { 7477 final int N = providers.size(); 7478 for (int i=0; i<N; i++) { 7479 ProviderInfo cpi = 7480 (ProviderInfo)providers.get(i); 7481 ContentProviderRecord cpr = 7482 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7483 if (cpr == null) { 7484 cpr = new ContentProviderRecord(cpi, app.info); 7485 mProvidersByClass.put(cpi.name, cpr); 7486 } 7487 app.pubProviders.put(cpi.name, cpr); 7488 app.addPackage(cpi.applicationInfo.packageName); 7489 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7490 } 7491 } 7492 return providers; 7493 } 7494 checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r, int mode)7495 private final String checkContentProviderPermissionLocked( 7496 ProviderInfo cpi, ProcessRecord r, int mode) { 7497 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7498 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 7499 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7500 cpi.exported ? -1 : cpi.applicationInfo.uid) 7501 == PackageManager.PERMISSION_GRANTED 7502 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7503 return null; 7504 } 7505 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7506 cpi.exported ? -1 : cpi.applicationInfo.uid) 7507 == PackageManager.PERMISSION_GRANTED) { 7508 return null; 7509 } 7510 7511 PathPermission[] pps = cpi.pathPermissions; 7512 if (pps != null) { 7513 int i = pps.length; 7514 while (i > 0) { 7515 i--; 7516 PathPermission pp = pps[i]; 7517 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7518 cpi.exported ? -1 : cpi.applicationInfo.uid) 7519 == PackageManager.PERMISSION_GRANTED 7520 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7521 return null; 7522 } 7523 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7524 cpi.exported ? -1 : cpi.applicationInfo.uid) 7525 == PackageManager.PERMISSION_GRANTED) { 7526 return null; 7527 } 7528 } 7529 } 7530 7531 String msg = "Permission Denial: opening provider " + cpi.name 7532 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7533 + ", uid=" + callingUid + ") requires " 7534 + cpi.readPermission + " or " + cpi.writePermission; 7535 Log.w(TAG, msg); 7536 return msg; 7537 } 7538 getContentProviderImpl( IApplicationThread caller, String name)7539 private final ContentProviderHolder getContentProviderImpl( 7540 IApplicationThread caller, String name) { 7541 ContentProviderRecord cpr; 7542 ProviderInfo cpi = null; 7543 7544 synchronized(this) { 7545 ProcessRecord r = null; 7546 if (caller != null) { 7547 r = getRecordForAppLocked(caller); 7548 if (r == null) { 7549 throw new SecurityException( 7550 "Unable to find app for caller " + caller 7551 + " (pid=" + Binder.getCallingPid() 7552 + ") when getting content provider " + name); 7553 } 7554 } 7555 7556 // First check if this content provider has been published... 7557 cpr = (ContentProviderRecord)mProvidersByName.get(name); 7558 if (cpr != null) { 7559 cpi = cpr.info; 7560 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7561 return new ContentProviderHolder(cpi, 7562 cpi.readPermission != null 7563 ? cpi.readPermission : cpi.writePermission); 7564 } 7565 7566 if (r != null && cpr.canRunHere(r)) { 7567 // This provider has been published or is in the process 7568 // of being published... but it is also allowed to run 7569 // in the caller's process, so don't make a connection 7570 // and just let the caller instantiate its own instance. 7571 if (cpr.provider != null) { 7572 // don't give caller the provider object, it needs 7573 // to make its own. 7574 cpr = new ContentProviderRecord(cpr); 7575 } 7576 return cpr; 7577 } 7578 7579 final long origId = Binder.clearCallingIdentity(); 7580 7581 // In this case the provider instance already exists, so we can 7582 // return it right away. 7583 if (r != null) { 7584 if (DEBUG_PROVIDER) Log.v(TAG, 7585 "Adding provider requested by " 7586 + r.processName + " from process " 7587 + cpr.info.processName); 7588 Integer cnt = r.conProviders.get(cpr); 7589 if (cnt == null) { 7590 r.conProviders.put(cpr, new Integer(1)); 7591 } else { 7592 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7593 } 7594 cpr.clients.add(r); 7595 } else { 7596 cpr.externals++; 7597 } 7598 7599 if (cpr.app != null) { 7600 updateOomAdjLocked(cpr.app); 7601 } 7602 7603 Binder.restoreCallingIdentity(origId); 7604 7605 } else { 7606 try { 7607 cpi = ActivityThread.getPackageManager(). 7608 resolveContentProvider(name, 7609 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7610 } catch (RemoteException ex) { 7611 } 7612 if (cpi == null) { 7613 return null; 7614 } 7615 7616 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7617 return new ContentProviderHolder(cpi, 7618 cpi.readPermission != null 7619 ? cpi.readPermission : cpi.writePermission); 7620 } 7621 7622 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7623 final boolean firstClass = cpr == null; 7624 if (firstClass) { 7625 try { 7626 ApplicationInfo ai = 7627 ActivityThread.getPackageManager(). 7628 getApplicationInfo( 7629 cpi.applicationInfo.packageName, 7630 STOCK_PM_FLAGS); 7631 if (ai == null) { 7632 Log.w(TAG, "No package info for content provider " 7633 + cpi.name); 7634 return null; 7635 } 7636 cpr = new ContentProviderRecord(cpi, ai); 7637 } catch (RemoteException ex) { 7638 // pm is in same process, this will never happen. 7639 } 7640 } 7641 7642 if (r != null && cpr.canRunHere(r)) { 7643 // If this is a multiprocess provider, then just return its 7644 // info and allow the caller to instantiate it. Only do 7645 // this if the provider is the same user as the caller's 7646 // process, or can run as root (so can be in any process). 7647 return cpr; 7648 } 7649 7650 if (DEBUG_PROVIDER) { 7651 RuntimeException e = new RuntimeException("here"); 7652 Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7653 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7654 } 7655 7656 // This is single process, and our app is now connecting to it. 7657 // See if we are already in the process of launching this 7658 // provider. 7659 final int N = mLaunchingProviders.size(); 7660 int i; 7661 for (i=0; i<N; i++) { 7662 if (mLaunchingProviders.get(i) == cpr) { 7663 break; 7664 } 7665 } 7666 7667 // If the provider is not already being launched, then get it 7668 // started. 7669 if (i >= N) { 7670 final long origId = Binder.clearCallingIdentity(); 7671 ProcessRecord proc = startProcessLocked(cpi.processName, 7672 cpr.appInfo, false, 0, "content provider", 7673 new ComponentName(cpi.applicationInfo.packageName, 7674 cpi.name), false); 7675 if (proc == null) { 7676 Log.w(TAG, "Unable to launch app " 7677 + cpi.applicationInfo.packageName + "/" 7678 + cpi.applicationInfo.uid + " for provider " 7679 + name + ": process is bad"); 7680 return null; 7681 } 7682 cpr.launchingApp = proc; 7683 mLaunchingProviders.add(cpr); 7684 Binder.restoreCallingIdentity(origId); 7685 } 7686 7687 // Make sure the provider is published (the same provider class 7688 // may be published under multiple names). 7689 if (firstClass) { 7690 mProvidersByClass.put(cpi.name, cpr); 7691 } 7692 mProvidersByName.put(name, cpr); 7693 7694 if (r != null) { 7695 if (DEBUG_PROVIDER) Log.v(TAG, 7696 "Adding provider requested by " 7697 + r.processName + " from process " 7698 + cpr.info.processName); 7699 Integer cnt = r.conProviders.get(cpr); 7700 if (cnt == null) { 7701 r.conProviders.put(cpr, new Integer(1)); 7702 } else { 7703 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7704 } 7705 cpr.clients.add(r); 7706 } else { 7707 cpr.externals++; 7708 } 7709 } 7710 } 7711 7712 // Wait for the provider to be published... 7713 synchronized (cpr) { 7714 while (cpr.provider == null) { 7715 if (cpr.launchingApp == null) { 7716 Log.w(TAG, "Unable to launch app " 7717 + cpi.applicationInfo.packageName + "/" 7718 + cpi.applicationInfo.uid + " for provider " 7719 + name + ": launching app became null"); 7720 EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS, 7721 cpi.applicationInfo.packageName, 7722 cpi.applicationInfo.uid, name); 7723 return null; 7724 } 7725 try { 7726 cpr.wait(); 7727 } catch (InterruptedException ex) { 7728 } 7729 } 7730 } 7731 return cpr; 7732 } 7733 getContentProvider( IApplicationThread caller, String name)7734 public final ContentProviderHolder getContentProvider( 7735 IApplicationThread caller, String name) { 7736 if (caller == null) { 7737 String msg = "null IApplicationThread when getting content provider " 7738 + name; 7739 Log.w(TAG, msg); 7740 throw new SecurityException(msg); 7741 } 7742 7743 return getContentProviderImpl(caller, name); 7744 } 7745 getContentProviderExternal(String name)7746 private ContentProviderHolder getContentProviderExternal(String name) { 7747 return getContentProviderImpl(null, name); 7748 } 7749 7750 /** 7751 * Drop a content provider from a ProcessRecord's bookkeeping 7752 * @param cpr 7753 */ removeContentProvider(IApplicationThread caller, String name)7754 public void removeContentProvider(IApplicationThread caller, String name) { 7755 synchronized (this) { 7756 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7757 if(cpr == null) { 7758 // remove from mProvidersByClass 7759 if (DEBUG_PROVIDER) Log.v(TAG, name + 7760 " provider not found in providers list"); 7761 return; 7762 } 7763 final ProcessRecord r = getRecordForAppLocked(caller); 7764 if (r == null) { 7765 throw new SecurityException( 7766 "Unable to find app for caller " + caller + 7767 " when removing content provider " + name); 7768 } 7769 //update content provider record entry info 7770 ContentProviderRecord localCpr = (ContentProviderRecord) 7771 mProvidersByClass.get(cpr.info.name); 7772 if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by " 7773 + r.info.processName + " from process " 7774 + localCpr.appInfo.processName); 7775 if (localCpr.app == r) { 7776 //should not happen. taken care of as a local provider 7777 Log.w(TAG, "removeContentProvider called on local provider: " 7778 + cpr.info.name + " in process " + r.processName); 7779 return; 7780 } else { 7781 Integer cnt = r.conProviders.get(localCpr); 7782 if (cnt == null || cnt.intValue() <= 1) { 7783 localCpr.clients.remove(r); 7784 r.conProviders.remove(localCpr); 7785 } else { 7786 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1)); 7787 } 7788 } 7789 updateOomAdjLocked(); 7790 } 7791 } 7792 removeContentProviderExternal(String name)7793 private void removeContentProviderExternal(String name) { 7794 synchronized (this) { 7795 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7796 if(cpr == null) { 7797 //remove from mProvidersByClass 7798 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7799 return; 7800 } 7801 7802 //update content provider record entry info 7803 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7804 localCpr.externals--; 7805 if (localCpr.externals < 0) { 7806 Log.e(TAG, "Externals < 0 for content provider " + localCpr); 7807 } 7808 updateOomAdjLocked(); 7809 } 7810 } 7811 publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers)7812 public final void publishContentProviders(IApplicationThread caller, 7813 List<ContentProviderHolder> providers) { 7814 if (providers == null) { 7815 return; 7816 } 7817 7818 synchronized(this) { 7819 final ProcessRecord r = getRecordForAppLocked(caller); 7820 if (r == null) { 7821 throw new SecurityException( 7822 "Unable to find app for caller " + caller 7823 + " (pid=" + Binder.getCallingPid() 7824 + ") when publishing content providers"); 7825 } 7826 7827 final long origId = Binder.clearCallingIdentity(); 7828 7829 final int N = providers.size(); 7830 for (int i=0; i<N; i++) { 7831 ContentProviderHolder src = providers.get(i); 7832 if (src == null || src.info == null || src.provider == null) { 7833 continue; 7834 } 7835 ContentProviderRecord dst = 7836 (ContentProviderRecord)r.pubProviders.get(src.info.name); 7837 if (dst != null) { 7838 mProvidersByClass.put(dst.info.name, dst); 7839 String names[] = dst.info.authority.split(";"); 7840 for (int j = 0; j < names.length; j++) { 7841 mProvidersByName.put(names[j], dst); 7842 } 7843 7844 int NL = mLaunchingProviders.size(); 7845 int j; 7846 for (j=0; j<NL; j++) { 7847 if (mLaunchingProviders.get(j) == dst) { 7848 mLaunchingProviders.remove(j); 7849 j--; 7850 NL--; 7851 } 7852 } 7853 synchronized (dst) { 7854 dst.provider = src.provider; 7855 dst.app = r; 7856 dst.notifyAll(); 7857 } 7858 updateOomAdjLocked(r); 7859 } 7860 } 7861 7862 Binder.restoreCallingIdentity(origId); 7863 } 7864 } 7865 installSystemProviders()7866 public static final void installSystemProviders() { 7867 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7868 List providers = mSelf.generateApplicationProvidersLocked(app); 7869 mSystemThread.installSystemProviders(providers); 7870 } 7871 7872 // ========================================================= 7873 // GLOBAL MANAGEMENT 7874 // ========================================================= 7875 newProcessRecordLocked(IApplicationThread thread, ApplicationInfo info, String customProcess)7876 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7877 ApplicationInfo info, String customProcess) { 7878 String proc = customProcess != null ? customProcess : info.processName; 7879 BatteryStatsImpl.Uid.Proc ps = null; 7880 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7881 synchronized (stats) { 7882 ps = stats.getProcessStatsLocked(info.uid, proc); 7883 } 7884 return new ProcessRecord(ps, thread, info, proc); 7885 } 7886 addAppLocked(ApplicationInfo info)7887 final ProcessRecord addAppLocked(ApplicationInfo info) { 7888 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 7889 7890 if (app == null) { 7891 app = newProcessRecordLocked(null, info, null); 7892 mProcessNames.put(info.processName, info.uid, app); 7893 updateLRUListLocked(app, true); 7894 } 7895 7896 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7897 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7898 app.persistent = true; 7899 app.maxAdj = CORE_SERVER_ADJ; 7900 } 7901 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7902 mPersistentStartingProcesses.add(app); 7903 startProcessLocked(app, "added application", app.processName); 7904 } 7905 7906 return app; 7907 } 7908 unhandledBack()7909 public void unhandledBack() { 7910 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7911 "unhandledBack()"); 7912 7913 synchronized(this) { 7914 int count = mHistory.size(); 7915 if (Config.LOGD) Log.d( 7916 TAG, "Performing unhandledBack(): stack size = " + count); 7917 if (count > 1) { 7918 final long origId = Binder.clearCallingIdentity(); 7919 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 7920 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 7921 Binder.restoreCallingIdentity(origId); 7922 } 7923 } 7924 } 7925 openContentUri(Uri uri)7926 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7927 String name = uri.getAuthority(); 7928 ContentProviderHolder cph = getContentProviderExternal(name); 7929 ParcelFileDescriptor pfd = null; 7930 if (cph != null) { 7931 // We record the binder invoker's uid in thread-local storage before 7932 // going to the content provider to open the file. Later, in the code 7933 // that handles all permissions checks, we look for this uid and use 7934 // that rather than the Activity Manager's own uid. The effect is that 7935 // we do the check against the caller's permissions even though it looks 7936 // to the content provider like the Activity Manager itself is making 7937 // the request. 7938 sCallerIdentity.set(new Identity( 7939 Binder.getCallingPid(), Binder.getCallingUid())); 7940 try { 7941 pfd = cph.provider.openFile(uri, "r"); 7942 } catch (FileNotFoundException e) { 7943 // do nothing; pfd will be returned null 7944 } finally { 7945 // Ensure that whatever happens, we clean up the identity state 7946 sCallerIdentity.remove(); 7947 } 7948 7949 // We've got the fd now, so we're done with the provider. 7950 removeContentProviderExternal(name); 7951 } else { 7952 Log.d(TAG, "Failed to get provider for authority '" + name + "'"); 7953 } 7954 return pfd; 7955 } 7956 goingToSleep()7957 public void goingToSleep() { 7958 synchronized(this) { 7959 mSleeping = true; 7960 mWindowManager.setEventDispatching(false); 7961 7962 if (mResumedActivity != null) { 7963 pauseIfSleepingLocked(); 7964 } else { 7965 Log.w(TAG, "goingToSleep with no resumed activity!"); 7966 } 7967 } 7968 } 7969 shutdown(int timeout)7970 public boolean shutdown(int timeout) { 7971 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7972 != PackageManager.PERMISSION_GRANTED) { 7973 throw new SecurityException("Requires permission " 7974 + android.Manifest.permission.SHUTDOWN); 7975 } 7976 7977 boolean timedout = false; 7978 7979 synchronized(this) { 7980 mShuttingDown = true; 7981 mWindowManager.setEventDispatching(false); 7982 7983 if (mResumedActivity != null) { 7984 pauseIfSleepingLocked(); 7985 final long endTime = System.currentTimeMillis() + timeout; 7986 while (mResumedActivity != null || mPausingActivity != null) { 7987 long delay = endTime - System.currentTimeMillis(); 7988 if (delay <= 0) { 7989 Log.w(TAG, "Activity manager shutdown timed out"); 7990 timedout = true; 7991 break; 7992 } 7993 try { 7994 this.wait(); 7995 } catch (InterruptedException e) { 7996 } 7997 } 7998 } 7999 } 8000 8001 mUsageStatsService.shutdown(); 8002 mBatteryStatsService.shutdown(); 8003 8004 return timedout; 8005 } 8006 pauseIfSleepingLocked()8007 void pauseIfSleepingLocked() { 8008 if (mSleeping || mShuttingDown) { 8009 if (!mGoingToSleep.isHeld()) { 8010 mGoingToSleep.acquire(); 8011 if (mLaunchingActivity.isHeld()) { 8012 mLaunchingActivity.release(); 8013 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 8014 } 8015 } 8016 8017 // If we are not currently pausing an activity, get the current 8018 // one to pause. If we are pausing one, we will just let that stuff 8019 // run and release the wake lock when all done. 8020 if (mPausingActivity == null) { 8021 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause..."); 8022 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false"); 8023 startPausingLocked(false, true); 8024 } 8025 } 8026 } 8027 wakingUp()8028 public void wakingUp() { 8029 synchronized(this) { 8030 if (mGoingToSleep.isHeld()) { 8031 mGoingToSleep.release(); 8032 } 8033 mWindowManager.setEventDispatching(true); 8034 mSleeping = false; 8035 resumeTopActivityLocked(null); 8036 } 8037 } 8038 stopAppSwitches()8039 public void stopAppSwitches() { 8040 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8041 != PackageManager.PERMISSION_GRANTED) { 8042 throw new SecurityException("Requires permission " 8043 + android.Manifest.permission.STOP_APP_SWITCHES); 8044 } 8045 8046 synchronized(this) { 8047 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8048 + APP_SWITCH_DELAY_TIME; 8049 mDidAppSwitch = false; 8050 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8051 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8052 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8053 } 8054 } 8055 resumeAppSwitches()8056 public void resumeAppSwitches() { 8057 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8058 != PackageManager.PERMISSION_GRANTED) { 8059 throw new SecurityException("Requires permission " 8060 + android.Manifest.permission.STOP_APP_SWITCHES); 8061 } 8062 8063 synchronized(this) { 8064 // Note that we don't execute any pending app switches... we will 8065 // let those wait until either the timeout, or the next start 8066 // activity request. 8067 mAppSwitchesAllowedTime = 0; 8068 } 8069 } 8070 checkAppSwitchAllowedLocked(int callingPid, int callingUid, String name)8071 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8072 String name) { 8073 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8074 return true; 8075 } 8076 8077 final int perm = checkComponentPermission( 8078 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8079 callingUid, -1); 8080 if (perm == PackageManager.PERMISSION_GRANTED) { 8081 return true; 8082 } 8083 8084 Log.w(TAG, name + " request from " + callingUid + " stopped"); 8085 return false; 8086 } 8087 setDebugApp(String packageName, boolean waitForDebugger, boolean persistent)8088 public void setDebugApp(String packageName, boolean waitForDebugger, 8089 boolean persistent) { 8090 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8091 "setDebugApp()"); 8092 8093 // Note that this is not really thread safe if there are multiple 8094 // callers into it at the same time, but that's not a situation we 8095 // care about. 8096 if (persistent) { 8097 final ContentResolver resolver = mContext.getContentResolver(); 8098 Settings.System.putString( 8099 resolver, Settings.System.DEBUG_APP, 8100 packageName); 8101 Settings.System.putInt( 8102 resolver, Settings.System.WAIT_FOR_DEBUGGER, 8103 waitForDebugger ? 1 : 0); 8104 } 8105 8106 synchronized (this) { 8107 if (!persistent) { 8108 mOrigDebugApp = mDebugApp; 8109 mOrigWaitForDebugger = mWaitForDebugger; 8110 } 8111 mDebugApp = packageName; 8112 mWaitForDebugger = waitForDebugger; 8113 mDebugTransient = !persistent; 8114 if (packageName != null) { 8115 final long origId = Binder.clearCallingIdentity(); 8116 uninstallPackageLocked(packageName, -1, false); 8117 Binder.restoreCallingIdentity(origId); 8118 } 8119 } 8120 } 8121 setAlwaysFinish(boolean enabled)8122 public void setAlwaysFinish(boolean enabled) { 8123 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8124 "setAlwaysFinish()"); 8125 8126 Settings.System.putInt( 8127 mContext.getContentResolver(), 8128 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8129 8130 synchronized (this) { 8131 mAlwaysFinishActivities = enabled; 8132 } 8133 } 8134 setActivityController(IActivityController controller)8135 public void setActivityController(IActivityController controller) { 8136 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8137 "setActivityController()"); 8138 synchronized (this) { 8139 mController = controller; 8140 } 8141 } 8142 registerActivityWatcher(IActivityWatcher watcher)8143 public void registerActivityWatcher(IActivityWatcher watcher) { 8144 mWatchers.register(watcher); 8145 } 8146 unregisterActivityWatcher(IActivityWatcher watcher)8147 public void unregisterActivityWatcher(IActivityWatcher watcher) { 8148 mWatchers.unregister(watcher); 8149 } 8150 enterSafeMode()8151 public final void enterSafeMode() { 8152 synchronized(this) { 8153 // It only makes sense to do this before the system is ready 8154 // and started launching other packages. 8155 if (!mSystemReady) { 8156 try { 8157 ActivityThread.getPackageManager().enterSafeMode(); 8158 } catch (RemoteException e) { 8159 } 8160 8161 View v = LayoutInflater.from(mContext).inflate( 8162 com.android.internal.R.layout.safe_mode, null); 8163 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8164 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 8165 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8166 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8167 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 8168 lp.format = v.getBackground().getOpacity(); 8169 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8170 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8171 ((WindowManager)mContext.getSystemService( 8172 Context.WINDOW_SERVICE)).addView(v, lp); 8173 } 8174 } 8175 } 8176 noteWakeupAlarm(IIntentSender sender)8177 public void noteWakeupAlarm(IIntentSender sender) { 8178 if (!(sender instanceof PendingIntentRecord)) { 8179 return; 8180 } 8181 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8182 synchronized (stats) { 8183 if (mBatteryStatsService.isOnBattery()) { 8184 mBatteryStatsService.enforceCallingPermission(); 8185 PendingIntentRecord rec = (PendingIntentRecord)sender; 8186 int MY_UID = Binder.getCallingUid(); 8187 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8188 BatteryStatsImpl.Uid.Pkg pkg = 8189 stats.getPackageStatsLocked(uid, rec.key.packageName); 8190 pkg.incWakeupsLocked(); 8191 } 8192 } 8193 } 8194 killPidsForMemory(int[] pids)8195 public boolean killPidsForMemory(int[] pids) { 8196 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8197 throw new SecurityException("killPidsForMemory only available to the system"); 8198 } 8199 8200 // XXX Note: don't acquire main activity lock here, because the window 8201 // manager calls in with its locks held. 8202 8203 boolean killed = false; 8204 synchronized (mPidsSelfLocked) { 8205 int[] types = new int[pids.length]; 8206 int worstType = 0; 8207 for (int i=0; i<pids.length; i++) { 8208 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8209 if (proc != null) { 8210 int type = proc.setAdj; 8211 types[i] = type; 8212 if (type > worstType) { 8213 worstType = type; 8214 } 8215 } 8216 } 8217 8218 // If the worse oom_adj is somewhere in the hidden proc LRU range, 8219 // then constrain it so we will kill all hidden procs. 8220 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 8221 worstType = HIDDEN_APP_MIN_ADJ; 8222 } 8223 Log.w(TAG, "Killing processes for memory at adjustment " + worstType); 8224 for (int i=0; i<pids.length; i++) { 8225 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8226 if (proc == null) { 8227 continue; 8228 } 8229 int adj = proc.setAdj; 8230 if (adj >= worstType) { 8231 Log.w(TAG, "Killing for memory: " + proc + " (adj " 8232 + adj + ")"); 8233 EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid, 8234 proc.processName, adj); 8235 killed = true; 8236 Process.killProcess(pids[i]); 8237 } 8238 } 8239 } 8240 return killed; 8241 } 8242 reportPss(IApplicationThread caller, int pss)8243 public void reportPss(IApplicationThread caller, int pss) { 8244 Watchdog.PssRequestor req; 8245 String name; 8246 ProcessRecord callerApp; 8247 synchronized (this) { 8248 if (caller == null) { 8249 return; 8250 } 8251 callerApp = getRecordForAppLocked(caller); 8252 if (callerApp == null) { 8253 return; 8254 } 8255 callerApp.lastPss = pss; 8256 req = callerApp; 8257 name = callerApp.processName; 8258 } 8259 Watchdog.getInstance().reportPss(req, name, pss); 8260 if (!callerApp.persistent) { 8261 removeRequestedPss(callerApp); 8262 } 8263 } 8264 requestPss(Runnable completeCallback)8265 public void requestPss(Runnable completeCallback) { 8266 ArrayList<ProcessRecord> procs; 8267 synchronized (this) { 8268 mRequestPssCallback = completeCallback; 8269 mRequestPssList.clear(); 8270 for (int i=mLRUProcesses.size()-1; i>=0; i--) { 8271 ProcessRecord proc = mLRUProcesses.get(i); 8272 if (!proc.persistent) { 8273 mRequestPssList.add(proc); 8274 } 8275 } 8276 procs = new ArrayList<ProcessRecord>(mRequestPssList); 8277 } 8278 8279 int oldPri = Process.getThreadPriority(Process.myTid()); 8280 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8281 for (int i=procs.size()-1; i>=0; i--) { 8282 ProcessRecord proc = procs.get(i); 8283 proc.lastPss = 0; 8284 proc.requestPss(); 8285 } 8286 Process.setThreadPriority(oldPri); 8287 } 8288 removeRequestedPss(ProcessRecord proc)8289 void removeRequestedPss(ProcessRecord proc) { 8290 Runnable callback = null; 8291 synchronized (this) { 8292 if (mRequestPssList.remove(proc)) { 8293 if (mRequestPssList.size() == 0) { 8294 callback = mRequestPssCallback; 8295 mRequestPssCallback = null; 8296 } 8297 } 8298 } 8299 8300 if (callback != null) { 8301 callback.run(); 8302 } 8303 } 8304 collectPss(Watchdog.PssStats stats)8305 public void collectPss(Watchdog.PssStats stats) { 8306 stats.mEmptyPss = 0; 8307 stats.mEmptyCount = 0; 8308 stats.mBackgroundPss = 0; 8309 stats.mBackgroundCount = 0; 8310 stats.mServicePss = 0; 8311 stats.mServiceCount = 0; 8312 stats.mVisiblePss = 0; 8313 stats.mVisibleCount = 0; 8314 stats.mForegroundPss = 0; 8315 stats.mForegroundCount = 0; 8316 stats.mNoPssCount = 0; 8317 synchronized (this) { 8318 int i; 8319 int NPD = mProcDeaths.length < stats.mProcDeaths.length 8320 ? mProcDeaths.length : stats.mProcDeaths.length; 8321 int aggr = 0; 8322 for (i=0; i<NPD; i++) { 8323 aggr += mProcDeaths[i]; 8324 stats.mProcDeaths[i] = aggr; 8325 } 8326 while (i<stats.mProcDeaths.length) { 8327 stats.mProcDeaths[i] = 0; 8328 i++; 8329 } 8330 8331 for (i=mLRUProcesses.size()-1; i>=0; i--) { 8332 ProcessRecord proc = mLRUProcesses.get(i); 8333 if (proc.persistent) { 8334 continue; 8335 } 8336 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 8337 if (proc.lastPss == 0) { 8338 stats.mNoPssCount++; 8339 continue; 8340 } 8341 if (proc.setAdj == EMPTY_APP_ADJ) { 8342 stats.mEmptyPss += proc.lastPss; 8343 stats.mEmptyCount++; 8344 } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) { 8345 stats.mEmptyPss += proc.lastPss; 8346 stats.mEmptyCount++; 8347 } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 8348 stats.mBackgroundPss += proc.lastPss; 8349 stats.mBackgroundCount++; 8350 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 8351 stats.mVisiblePss += proc.lastPss; 8352 stats.mVisibleCount++; 8353 } else { 8354 stats.mForegroundPss += proc.lastPss; 8355 stats.mForegroundCount++; 8356 } 8357 } 8358 } 8359 } 8360 8361 public final void startRunning(String pkg, String cls, String action, 8362 String data) { 8363 synchronized(this) { 8364 if (mStartRunning) { 8365 return; 8366 } 8367 mStartRunning = true; 8368 mTopComponent = pkg != null && cls != null 8369 ? new ComponentName(pkg, cls) : null; 8370 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8371 mTopData = data; 8372 if (!mSystemReady) { 8373 return; 8374 } 8375 } 8376 8377 systemReady(null); 8378 } 8379 8380 private void retrieveSettings() { 8381 final ContentResolver resolver = mContext.getContentResolver(); 8382 String debugApp = Settings.System.getString( 8383 resolver, Settings.System.DEBUG_APP); 8384 boolean waitForDebugger = Settings.System.getInt( 8385 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 8386 boolean alwaysFinishActivities = Settings.System.getInt( 8387 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8388 8389 Configuration configuration = new Configuration(); 8390 Settings.System.getConfiguration(resolver, configuration); 8391 8392 synchronized (this) { 8393 mDebugApp = mOrigDebugApp = debugApp; 8394 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8395 mAlwaysFinishActivities = alwaysFinishActivities; 8396 // This happens before any activities are started, so we can 8397 // change mConfiguration in-place. 8398 mConfiguration.updateFrom(configuration); 8399 if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration); 8400 } 8401 } 8402 8403 public boolean testIsSystemReady() { 8404 // no need to synchronize(this) just to read & return the value 8405 return mSystemReady; 8406 } 8407 8408 public void systemReady(final Runnable goingCallback) { 8409 // In the simulator, startRunning will never have been called, which 8410 // normally sets a few crucial variables. Do it here instead. 8411 if (!Process.supportsProcesses()) { 8412 mStartRunning = true; 8413 mTopAction = Intent.ACTION_MAIN; 8414 } 8415 8416 synchronized(this) { 8417 if (mSystemReady) { 8418 if (goingCallback != null) goingCallback.run(); 8419 return; 8420 } 8421 8422 // Check to see if there are any update receivers to run. 8423 if (!mDidUpdate) { 8424 if (mWaitingUpdate) { 8425 return; 8426 } 8427 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 8428 List<ResolveInfo> ris = null; 8429 try { 8430 ris = ActivityThread.getPackageManager().queryIntentReceivers( 8431 intent, null, 0); 8432 } catch (RemoteException e) { 8433 } 8434 if (ris != null) { 8435 for (int i=ris.size()-1; i>=0; i--) { 8436 if ((ris.get(i).activityInfo.applicationInfo.flags 8437 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8438 ris.remove(i); 8439 } 8440 } 8441 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8442 for (int i=0; i<ris.size(); i++) { 8443 ActivityInfo ai = ris.get(i).activityInfo; 8444 intent.setComponent(new ComponentName(ai.packageName, ai.name)); 8445 IIntentReceiver finisher = null; 8446 if (i == 0) { 8447 finisher = new IIntentReceiver.Stub() { 8448 public void performReceive(Intent intent, int resultCode, 8449 String data, Bundle extras, boolean ordered, 8450 boolean sticky) 8451 throws RemoteException { 8452 synchronized (ActivityManagerService.this) { 8453 mDidUpdate = true; 8454 } 8455 systemReady(goingCallback); 8456 } 8457 }; 8458 } 8459 Log.i(TAG, "Sending system update to: " + intent.getComponent()); 8460 broadcastIntentLocked(null, null, intent, null, finisher, 8461 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 8462 if (i == 0) { 8463 mWaitingUpdate = true; 8464 } 8465 } 8466 } 8467 if (mWaitingUpdate) { 8468 return; 8469 } 8470 mDidUpdate = true; 8471 } 8472 8473 mSystemReady = true; 8474 if (!mStartRunning) { 8475 return; 8476 } 8477 } 8478 8479 ArrayList<ProcessRecord> procsToKill = null; 8480 synchronized(mPidsSelfLocked) { 8481 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8482 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8483 if (!isAllowedWhileBooting(proc.info)){ 8484 if (procsToKill == null) { 8485 procsToKill = new ArrayList<ProcessRecord>(); 8486 } 8487 procsToKill.add(proc); 8488 } 8489 } 8490 } 8491 8492 if (procsToKill != null) { 8493 synchronized(this) { 8494 for (int i=procsToKill.size()-1; i>=0; i--) { 8495 ProcessRecord proc = procsToKill.get(i); 8496 Log.i(TAG, "Removing system update proc: " + proc); 8497 removeProcessLocked(proc, true); 8498 } 8499 } 8500 } 8501 8502 Log.i(TAG, "System now ready"); 8503 EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY, 8504 SystemClock.uptimeMillis()); 8505 8506 synchronized(this) { 8507 // Make sure we have no pre-ready processes sitting around. 8508 8509 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8510 ResolveInfo ri = mContext.getPackageManager() 8511 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8512 STOCK_PM_FLAGS); 8513 CharSequence errorMsg = null; 8514 if (ri != null) { 8515 ActivityInfo ai = ri.activityInfo; 8516 ApplicationInfo app = ai.applicationInfo; 8517 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8518 mTopAction = Intent.ACTION_FACTORY_TEST; 8519 mTopData = null; 8520 mTopComponent = new ComponentName(app.packageName, 8521 ai.name); 8522 } else { 8523 errorMsg = mContext.getResources().getText( 8524 com.android.internal.R.string.factorytest_not_system); 8525 } 8526 } else { 8527 errorMsg = mContext.getResources().getText( 8528 com.android.internal.R.string.factorytest_no_action); 8529 } 8530 if (errorMsg != null) { 8531 mTopAction = null; 8532 mTopData = null; 8533 mTopComponent = null; 8534 Message msg = Message.obtain(); 8535 msg.what = SHOW_FACTORY_ERROR_MSG; 8536 msg.getData().putCharSequence("msg", errorMsg); 8537 mHandler.sendMessage(msg); 8538 } 8539 } 8540 } 8541 8542 retrieveSettings(); 8543 8544 if (goingCallback != null) goingCallback.run(); 8545 8546 synchronized (this) { 8547 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8548 try { 8549 List apps = ActivityThread.getPackageManager(). 8550 getPersistentApplications(STOCK_PM_FLAGS); 8551 if (apps != null) { 8552 int N = apps.size(); 8553 int i; 8554 for (i=0; i<N; i++) { 8555 ApplicationInfo info 8556 = (ApplicationInfo)apps.get(i); 8557 if (info != null && 8558 !info.packageName.equals("android")) { 8559 addAppLocked(info); 8560 } 8561 } 8562 } 8563 } catch (RemoteException ex) { 8564 // pm is in same process, this will never happen. 8565 } 8566 } 8567 8568 // Start up initial activity. 8569 mBooting = true; 8570 8571 try { 8572 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 8573 Message msg = Message.obtain(); 8574 msg.what = SHOW_UID_ERROR_MSG; 8575 mHandler.sendMessage(msg); 8576 } 8577 } catch (RemoteException e) { 8578 } 8579 8580 resumeTopActivityLocked(null); 8581 } 8582 } 8583 8584 boolean makeAppCrashingLocked(ProcessRecord app, 8585 String tag, String shortMsg, String longMsg, byte[] crashData) { 8586 app.crashing = true; 8587 app.crashingReport = generateProcessError(app, 8588 ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData); 8589 startAppProblemLocked(app); 8590 app.stopFreezingAllLocked(); 8591 return handleAppCrashLocked(app); 8592 } 8593 8594 private ComponentName getErrorReportReceiver(ProcessRecord app) { 8595 // check if error reporting is enabled in Gservices 8596 int enabled = Settings.Gservices.getInt(mContext.getContentResolver(), 8597 Settings.Gservices.SEND_ACTION_APP_ERROR, 0); 8598 if (enabled == 0) { 8599 return null; 8600 } 8601 8602 IPackageManager pm = ActivityThread.getPackageManager(); 8603 8604 try { 8605 // look for receiver in the installer package 8606 String candidate = pm.getInstallerPackageName(app.info.packageName); 8607 ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8608 if (result != null) { 8609 return result; 8610 } 8611 8612 // if the error app is on the system image, look for system apps 8613 // error receiver 8614 if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8615 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY); 8616 result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8617 if (result != null) { 8618 return result; 8619 } 8620 } 8621 8622 // if there is a default receiver, try that 8623 candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY); 8624 return getErrorReportReceiver(pm, app.info.packageName, candidate); 8625 } catch (RemoteException e) { 8626 // should not happen 8627 Log.e(TAG, "error talking to PackageManager", e); 8628 return null; 8629 } 8630 } 8631 8632 /** 8633 * Return activity in receiverPackage that handles ACTION_APP_ERROR. 8634 * 8635 * @param pm PackageManager isntance 8636 * @param errorPackage package which caused the error 8637 * @param receiverPackage candidate package to receive the error 8638 * @return activity component within receiverPackage which handles 8639 * ACTION_APP_ERROR, or null if not found 8640 */ 8641 private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage, 8642 String receiverPackage) throws RemoteException { 8643 if (receiverPackage == null || receiverPackage.length() == 0) { 8644 return null; 8645 } 8646 8647 // break the loop if it's the error report receiver package that crashed 8648 if (receiverPackage.equals(errorPackage)) { 8649 return null; 8650 } 8651 8652 Intent intent = new Intent(Intent.ACTION_APP_ERROR); 8653 intent.setPackage(receiverPackage); 8654 ResolveInfo info = pm.resolveIntent(intent, null, 0); 8655 if (info == null || info.activityInfo == null) { 8656 return null; 8657 } 8658 return new ComponentName(receiverPackage, info.activityInfo.name); 8659 } 8660 8661 void makeAppNotRespondingLocked(ProcessRecord app, 8662 String tag, String shortMsg, String longMsg, byte[] crashData) { 8663 app.notResponding = true; 8664 app.notRespondingReport = generateProcessError(app, 8665 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg, 8666 crashData); 8667 startAppProblemLocked(app); 8668 app.stopFreezingAllLocked(); 8669 } 8670 8671 /** 8672 * Generate a process error record, suitable for attachment to a ProcessRecord. 8673 * 8674 * @param app The ProcessRecord in which the error occurred. 8675 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8676 * ActivityManager.AppErrorStateInfo 8677 * @param tag The tag that was passed into handleApplicationError(). Typically the classname. 8678 * @param shortMsg Short message describing the crash. 8679 * @param longMsg Long message describing the crash. 8680 * @param crashData Raw data passed into handleApplicationError(). Typically a stack trace. 8681 * 8682 * @return Returns a fully-formed AppErrorStateInfo record. 8683 */ 8684 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8685 int condition, String tag, String shortMsg, String longMsg, byte[] crashData) { 8686 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8687 8688 report.condition = condition; 8689 report.processName = app.processName; 8690 report.pid = app.pid; 8691 report.uid = app.info.uid; 8692 report.tag = tag; 8693 report.shortMsg = shortMsg; 8694 report.longMsg = longMsg; 8695 report.crashData = crashData; 8696 8697 return report; 8698 } 8699 8700 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog, 8701 boolean crashed) { 8702 synchronized (this) { 8703 app.crashing = false; 8704 app.crashingReport = null; 8705 app.notResponding = false; 8706 app.notRespondingReport = null; 8707 if (app.anrDialog == fromDialog) { 8708 app.anrDialog = null; 8709 } 8710 if (app.waitDialog == fromDialog) { 8711 app.waitDialog = null; 8712 } 8713 if (app.pid > 0 && app.pid != MY_PID) { 8714 if (crashed) { 8715 handleAppCrashLocked(app); 8716 } 8717 Log.i(ActivityManagerService.TAG, "Killing process " 8718 + app.processName 8719 + " (pid=" + app.pid + ") at user's request"); 8720 Process.killProcess(app.pid); 8721 } 8722 8723 } 8724 } 8725 8726 boolean handleAppCrashLocked(ProcessRecord app) { 8727 long now = SystemClock.uptimeMillis(); 8728 8729 Long crashTime = mProcessCrashTimes.get(app.info.processName, 8730 app.info.uid); 8731 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 8732 // This process loses! 8733 Log.w(TAG, "Process " + app.info.processName 8734 + " has crashed too many times: killing!"); 8735 EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH, 8736 app.info.processName, app.info.uid); 8737 killServicesLocked(app, false); 8738 for (int i=mHistory.size()-1; i>=0; i--) { 8739 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8740 if (r.app == app) { 8741 if (Config.LOGD) Log.d( 8742 TAG, " Force finishing activity " 8743 + r.intent.getComponent().flattenToShortString()); 8744 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8745 } 8746 } 8747 if (!app.persistent) { 8748 // We don't want to start this process again until the user 8749 // explicitly does so... but for persistent process, we really 8750 // need to keep it running. If a persistent process is actually 8751 // repeatedly crashing, then badness for everyone. 8752 EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid, 8753 app.info.processName); 8754 mBadProcesses.put(app.info.processName, app.info.uid, now); 8755 app.bad = true; 8756 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 8757 app.removed = true; 8758 removeProcessLocked(app, false); 8759 return false; 8760 } 8761 } 8762 8763 // Bump up the crash count of any services currently running in the proc. 8764 if (app.services.size() != 0) { 8765 // Any services running in the application need to be placed 8766 // back in the pending list. 8767 Iterator it = app.services.iterator(); 8768 while (it.hasNext()) { 8769 ServiceRecord sr = (ServiceRecord)it.next(); 8770 sr.crashCount++; 8771 } 8772 } 8773 8774 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 8775 return true; 8776 } 8777 8778 void startAppProblemLocked(ProcessRecord app) { 8779 app.errorReportReceiver = getErrorReportReceiver(app); 8780 skipCurrentReceiverLocked(app); 8781 } 8782 8783 void skipCurrentReceiverLocked(ProcessRecord app) { 8784 boolean reschedule = false; 8785 BroadcastRecord r = app.curReceiver; 8786 if (r != null) { 8787 // The current broadcast is waiting for this app's receiver 8788 // to be finished. Looks like that's not going to happen, so 8789 // let the broadcast continue. 8790 logBroadcastReceiverDiscard(r); 8791 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8792 r.resultExtras, r.resultAbort, true); 8793 reschedule = true; 8794 } 8795 r = mPendingBroadcast; 8796 if (r != null && r.curApp == app) { 8797 if (DEBUG_BROADCAST) Log.v(TAG, 8798 "skip & discard pending app " + r); 8799 logBroadcastReceiverDiscard(r); 8800 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8801 r.resultExtras, r.resultAbort, true); 8802 reschedule = true; 8803 } 8804 if (reschedule) { 8805 scheduleBroadcastsLocked(); 8806 } 8807 } 8808 8809 public int handleApplicationError(IBinder app, int flags, 8810 String tag, String shortMsg, String longMsg, byte[] crashData) { 8811 AppErrorResult result = new AppErrorResult(); 8812 ProcessRecord r = null; 8813 synchronized (this) { 8814 if (app != null) { 8815 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8816 final int NA = apps.size(); 8817 for (int ia=0; ia<NA; ia++) { 8818 ProcessRecord p = apps.valueAt(ia); 8819 if (p.thread != null && p.thread.asBinder() == app) { 8820 r = p; 8821 break; 8822 } 8823 } 8824 } 8825 } 8826 8827 if (r != null) { 8828 // The application has crashed. Send the SIGQUIT to the process so 8829 // that it can dump its state. 8830 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 8831 //Log.i(TAG, "Current system threads:"); 8832 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT); 8833 } 8834 8835 if (mController != null) { 8836 try { 8837 String name = r != null ? r.processName : null; 8838 int pid = r != null ? r.pid : Binder.getCallingPid(); 8839 if (!mController.appCrashed(name, pid, 8840 shortMsg, longMsg, crashData)) { 8841 Log.w(TAG, "Force-killing crashed app " + name 8842 + " at watcher's request"); 8843 Process.killProcess(pid); 8844 return 0; 8845 } 8846 } catch (RemoteException e) { 8847 mController = null; 8848 } 8849 } 8850 8851 final long origId = Binder.clearCallingIdentity(); 8852 8853 // If this process is running instrumentation, finish it. 8854 if (r != null && r.instrumentationClass != null) { 8855 Log.w(TAG, "Error in app " + r.processName 8856 + " running instrumentation " + r.instrumentationClass + ":"); 8857 if (shortMsg != null) Log.w(TAG, " " + shortMsg); 8858 if (longMsg != null) Log.w(TAG, " " + longMsg); 8859 Bundle info = new Bundle(); 8860 info.putString("shortMsg", shortMsg); 8861 info.putString("longMsg", longMsg); 8862 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8863 Binder.restoreCallingIdentity(origId); 8864 return 0; 8865 } 8866 8867 if (r != null) { 8868 if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) { 8869 return 0; 8870 } 8871 } else { 8872 Log.w(TAG, "Some application object " + app + " tag " + tag 8873 + " has crashed, but I don't know who it is."); 8874 Log.w(TAG, "ShortMsg:" + shortMsg); 8875 Log.w(TAG, "LongMsg:" + longMsg); 8876 Binder.restoreCallingIdentity(origId); 8877 return 0; 8878 } 8879 8880 Message msg = Message.obtain(); 8881 msg.what = SHOW_ERROR_MSG; 8882 HashMap data = new HashMap(); 8883 data.put("result", result); 8884 data.put("app", r); 8885 data.put("flags", flags); 8886 data.put("shortMsg", shortMsg); 8887 data.put("longMsg", longMsg); 8888 if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8889 // For system processes, submit crash data to the server. 8890 data.put("crashData", crashData); 8891 } 8892 msg.obj = data; 8893 mHandler.sendMessage(msg); 8894 8895 Binder.restoreCallingIdentity(origId); 8896 } 8897 8898 int res = result.get(); 8899 8900 Intent appErrorIntent = null; 8901 synchronized (this) { 8902 if (r != null) { 8903 mProcessCrashTimes.put(r.info.processName, r.info.uid, 8904 SystemClock.uptimeMillis()); 8905 } 8906 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8907 appErrorIntent = createAppErrorIntentLocked(r); 8908 res = AppErrorDialog.FORCE_QUIT; 8909 } 8910 } 8911 8912 if (appErrorIntent != null) { 8913 try { 8914 mContext.startActivity(appErrorIntent); 8915 } catch (ActivityNotFoundException e) { 8916 Log.w(TAG, "bug report receiver dissappeared", e); 8917 } 8918 } 8919 8920 return res; 8921 } 8922 8923 Intent createAppErrorIntentLocked(ProcessRecord r) { 8924 ApplicationErrorReport report = createAppErrorReportLocked(r); 8925 if (report == null) { 8926 return null; 8927 } 8928 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8929 result.setComponent(r.errorReportReceiver); 8930 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8931 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8932 return result; 8933 } 8934 8935 ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) { 8936 if (r.errorReportReceiver == null) { 8937 return null; 8938 } 8939 8940 if (!r.crashing && !r.notResponding) { 8941 return null; 8942 } 8943 8944 try { 8945 ApplicationErrorReport report = new ApplicationErrorReport(); 8946 report.packageName = r.info.packageName; 8947 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8948 report.processName = r.processName; 8949 8950 if (r.crashing) { 8951 report.type = ApplicationErrorReport.TYPE_CRASH; 8952 report.crashInfo = new ApplicationErrorReport.CrashInfo(); 8953 8954 ByteArrayInputStream byteStream = new ByteArrayInputStream( 8955 r.crashingReport.crashData); 8956 DataInputStream dataStream = new DataInputStream(byteStream); 8957 CrashData crashData = new CrashData(dataStream); 8958 ThrowableData throwData = crashData.getThrowableData(); 8959 8960 report.time = crashData.getTime(); 8961 report.crashInfo.stackTrace = throwData.toString(); 8962 8963 // Extract the source of the exception, useful for report 8964 // clustering. Also extract the "deepest" non-null exception 8965 // message. 8966 String exceptionMessage = throwData.getMessage(); 8967 while (throwData.getCause() != null) { 8968 throwData = throwData.getCause(); 8969 String msg = throwData.getMessage(); 8970 if (msg != null && msg.length() > 0) { 8971 exceptionMessage = msg; 8972 } 8973 } 8974 StackTraceElementData trace = throwData.getStackTrace()[0]; 8975 report.crashInfo.exceptionMessage = exceptionMessage; 8976 report.crashInfo.exceptionClassName = throwData.getType(); 8977 report.crashInfo.throwFileName = trace.getFileName(); 8978 report.crashInfo.throwClassName = trace.getClassName(); 8979 report.crashInfo.throwMethodName = trace.getMethodName(); 8980 report.crashInfo.throwLineNumber = trace.getLineNumber(); 8981 } else if (r.notResponding) { 8982 report.type = ApplicationErrorReport.TYPE_ANR; 8983 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8984 8985 report.anrInfo.activity = r.notRespondingReport.tag; 8986 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8987 report.anrInfo.info = r.notRespondingReport.longMsg; 8988 } 8989 8990 return report; 8991 } catch (IOException e) { 8992 // we don't send it 8993 } 8994 8995 return null; 8996 } 8997 8998 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8999 // assume our apps are happy - lazy create the list 9000 List<ActivityManager.ProcessErrorStateInfo> errList = null; 9001 9002 synchronized (this) { 9003 9004 // iterate across all processes 9005 final int N = mLRUProcesses.size(); 9006 for (int i = 0; i < N; i++) { 9007 ProcessRecord app = mLRUProcesses.get(i); 9008 if ((app.thread != null) && (app.crashing || app.notResponding)) { 9009 // This one's in trouble, so we'll generate a report for it 9010 // crashes are higher priority (in case there's a crash *and* an anr) 9011 ActivityManager.ProcessErrorStateInfo report = null; 9012 if (app.crashing) { 9013 report = app.crashingReport; 9014 } else if (app.notResponding) { 9015 report = app.notRespondingReport; 9016 } 9017 9018 if (report != null) { 9019 if (errList == null) { 9020 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 9021 } 9022 errList.add(report); 9023 } else { 9024 Log.w(TAG, "Missing app error report, app = " + app.processName + 9025 " crashing = " + app.crashing + 9026 " notResponding = " + app.notResponding); 9027 } 9028 } 9029 } 9030 } 9031 9032 return errList; 9033 } 9034 9035 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 9036 // Lazy instantiation of list 9037 List<ActivityManager.RunningAppProcessInfo> runList = null; 9038 synchronized (this) { 9039 // Iterate across all processes 9040 final int N = mLRUProcesses.size(); 9041 for (int i = 0; i < N; i++) { 9042 ProcessRecord app = mLRUProcesses.get(i); 9043 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 9044 // Generate process state info for running application 9045 ActivityManager.RunningAppProcessInfo currApp = 9046 new ActivityManager.RunningAppProcessInfo(app.processName, 9047 app.pid, app.getPackageList()); 9048 currApp.uid = app.info.uid; 9049 int adj = app.curAdj; 9050 if (adj >= CONTENT_PROVIDER_ADJ) { 9051 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 9052 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 9053 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9054 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 9055 } else if (adj >= HOME_APP_ADJ) { 9056 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9057 currApp.lru = 0; 9058 } else if (adj >= SECONDARY_SERVER_ADJ) { 9059 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9060 } else if (adj >= VISIBLE_APP_ADJ) { 9061 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 9062 } else { 9063 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 9064 } 9065 currApp.importanceReasonCode = app.adjTypeCode; 9066 if (app.adjSource instanceof ProcessRecord) { 9067 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9068 } else if (app.adjSource instanceof HistoryRecord) { 9069 HistoryRecord r = (HistoryRecord)app.adjSource; 9070 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9071 } 9072 if (app.adjTarget instanceof ComponentName) { 9073 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9074 } 9075 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9076 // + " lru=" + currApp.lru); 9077 if (runList == null) { 9078 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9079 } 9080 runList.add(currApp); 9081 } 9082 } 9083 } 9084 return runList; 9085 } 9086 9087 @Override 9088 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9089 synchronized (this) { 9090 if (checkCallingPermission(android.Manifest.permission.DUMP) 9091 != PackageManager.PERMISSION_GRANTED) { 9092 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9093 + Binder.getCallingPid() 9094 + ", uid=" + Binder.getCallingUid() 9095 + " without permission " 9096 + android.Manifest.permission.DUMP); 9097 return; 9098 } 9099 if (args.length != 0 && "service".equals(args[0])) { 9100 dumpService(fd, pw, args); 9101 return; 9102 } 9103 pw.println("Activities in Current Activity Manager State:"); 9104 dumpHistoryList(pw, mHistory, " ", "Hist", true); 9105 pw.println(" "); 9106 pw.println(" Running activities (most recent first):"); 9107 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 9108 if (mWaitingVisibleActivities.size() > 0) { 9109 pw.println(" "); 9110 pw.println(" Activities waiting for another to become visible:"); 9111 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 9112 } 9113 if (mStoppingActivities.size() > 0) { 9114 pw.println(" "); 9115 pw.println(" Activities waiting to stop:"); 9116 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 9117 } 9118 if (mFinishingActivities.size() > 0) { 9119 pw.println(" "); 9120 pw.println(" Activities waiting to finish:"); 9121 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 9122 } 9123 9124 pw.println(" "); 9125 pw.println(" mPausingActivity: " + mPausingActivity); 9126 pw.println(" mResumedActivity: " + mResumedActivity); 9127 pw.println(" mFocusedActivity: " + mFocusedActivity); 9128 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 9129 9130 if (mRecentTasks.size() > 0) { 9131 pw.println(" "); 9132 pw.println("Recent tasks in Current Activity Manager State:"); 9133 9134 final int N = mRecentTasks.size(); 9135 for (int i=0; i<N; i++) { 9136 TaskRecord tr = mRecentTasks.get(i); 9137 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9138 pw.println(tr); 9139 mRecentTasks.get(i).dump(pw, " "); 9140 } 9141 } 9142 9143 pw.println(" "); 9144 pw.println(" mCurTask: " + mCurTask); 9145 9146 pw.println(" "); 9147 pw.println("Processes in Current Activity Manager State:"); 9148 9149 boolean needSep = false; 9150 int numPers = 0; 9151 9152 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9153 final int NA = procs.size(); 9154 for (int ia=0; ia<NA; ia++) { 9155 if (!needSep) { 9156 pw.println(" All known processes:"); 9157 needSep = true; 9158 } 9159 ProcessRecord r = procs.valueAt(ia); 9160 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9161 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9162 pw.print(" "); pw.println(r); 9163 r.dump(pw, " "); 9164 if (r.persistent) { 9165 numPers++; 9166 } 9167 } 9168 } 9169 9170 if (mLRUProcesses.size() > 0) { 9171 if (needSep) pw.println(" "); 9172 needSep = true; 9173 pw.println(" Running processes (most recent first):"); 9174 dumpProcessList(pw, mLRUProcesses, " ", 9175 "App ", "PERS", true); 9176 needSep = true; 9177 } 9178 9179 synchronized (mPidsSelfLocked) { 9180 if (mPidsSelfLocked.size() > 0) { 9181 if (needSep) pw.println(" "); 9182 needSep = true; 9183 pw.println(" PID mappings:"); 9184 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9185 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9186 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9187 } 9188 } 9189 } 9190 9191 if (mForegroundProcesses.size() > 0) { 9192 if (needSep) pw.println(" "); 9193 needSep = true; 9194 pw.println(" Foreground Processes:"); 9195 for (int i=0; i<mForegroundProcesses.size(); i++) { 9196 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9197 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9198 } 9199 } 9200 9201 if (mPersistentStartingProcesses.size() > 0) { 9202 if (needSep) pw.println(" "); 9203 needSep = true; 9204 pw.println(" Persisent processes that are starting:"); 9205 dumpProcessList(pw, mPersistentStartingProcesses, " ", 9206 "Starting Norm", "Restarting PERS", false); 9207 } 9208 9209 if (mStartingProcesses.size() > 0) { 9210 if (needSep) pw.println(" "); 9211 needSep = true; 9212 pw.println(" Processes that are starting:"); 9213 dumpProcessList(pw, mStartingProcesses, " ", 9214 "Starting Norm", "Starting PERS", false); 9215 } 9216 9217 if (mRemovedProcesses.size() > 0) { 9218 if (needSep) pw.println(" "); 9219 needSep = true; 9220 pw.println(" Processes that are being removed:"); 9221 dumpProcessList(pw, mRemovedProcesses, " ", 9222 "Removed Norm", "Removed PERS", false); 9223 } 9224 9225 if (mProcessesOnHold.size() > 0) { 9226 if (needSep) pw.println(" "); 9227 needSep = true; 9228 pw.println(" Processes that are on old until the system is ready:"); 9229 dumpProcessList(pw, mProcessesOnHold, " ", 9230 "OnHold Norm", "OnHold PERS", false); 9231 } 9232 9233 if (mProcessesToGc.size() > 0) { 9234 if (needSep) pw.println(" "); 9235 needSep = true; 9236 pw.println(" Processes that are waiting to GC:"); 9237 long now = SystemClock.uptimeMillis(); 9238 for (int i=0; i<mProcessesToGc.size(); i++) { 9239 ProcessRecord proc = mProcessesToGc.get(i); 9240 pw.print(" Process "); pw.println(proc); 9241 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9242 pw.print(", last gced="); 9243 pw.print(now-proc.lastRequestedGc); 9244 pw.print(" ms ago, last lowMem="); 9245 pw.print(now-proc.lastLowMemory); 9246 pw.println(" ms ago"); 9247 9248 } 9249 } 9250 9251 if (mProcessCrashTimes.getMap().size() > 0) { 9252 if (needSep) pw.println(" "); 9253 needSep = true; 9254 pw.println(" Time since processes crashed:"); 9255 long now = SystemClock.uptimeMillis(); 9256 for (Map.Entry<String, SparseArray<Long>> procs 9257 : mProcessCrashTimes.getMap().entrySet()) { 9258 SparseArray<Long> uids = procs.getValue(); 9259 final int N = uids.size(); 9260 for (int i=0; i<N; i++) { 9261 pw.print(" Process "); pw.print(procs.getKey()); 9262 pw.print(" uid "); pw.print(uids.keyAt(i)); 9263 pw.print(": last crashed "); 9264 pw.print((now-uids.valueAt(i))); 9265 pw.println(" ms ago"); 9266 } 9267 } 9268 } 9269 9270 if (mBadProcesses.getMap().size() > 0) { 9271 if (needSep) pw.println(" "); 9272 needSep = true; 9273 pw.println(" Bad processes:"); 9274 for (Map.Entry<String, SparseArray<Long>> procs 9275 : mBadProcesses.getMap().entrySet()) { 9276 SparseArray<Long> uids = procs.getValue(); 9277 final int N = uids.size(); 9278 for (int i=0; i<N; i++) { 9279 pw.print(" Bad process "); pw.print(procs.getKey()); 9280 pw.print(" uid "); pw.print(uids.keyAt(i)); 9281 pw.print(": crashed at time "); 9282 pw.println(uids.valueAt(i)); 9283 } 9284 } 9285 } 9286 9287 pw.println(" "); 9288 pw.println(" Total persistent processes: " + numPers); 9289 pw.println(" mHomeProcess: " + mHomeProcess); 9290 pw.println(" mConfiguration: " + mConfiguration); 9291 pw.println(" mStartRunning=" + mStartRunning 9292 + " mSystemReady=" + mSystemReady 9293 + " mBooting=" + mBooting 9294 + " mBooted=" + mBooted 9295 + " mFactoryTest=" + mFactoryTest); 9296 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 9297 pw.println(" mGoingToSleep=" + mGoingToSleep); 9298 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 9299 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9300 + " mDebugTransient=" + mDebugTransient 9301 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9302 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9303 + " mController=" + mController); 9304 } 9305 } 9306 9307 /** 9308 * There are three ways to call this: 9309 * - no service specified: dump all the services 9310 * - a flattened component name that matched an existing service was specified as the 9311 * first arg: dump that one service 9312 * - the first arg isn't the flattened component name of an existing service: 9313 * dump all services whose component contains the first arg as a substring 9314 */ 9315 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) { 9316 String[] newArgs; 9317 String componentNameString; 9318 ServiceRecord r; 9319 if (args.length == 1) { 9320 componentNameString = null; 9321 newArgs = EMPTY_STRING_ARRAY; 9322 r = null; 9323 } else { 9324 componentNameString = args[1]; 9325 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 9326 r = componentName != null ? mServices.get(componentName) : null; 9327 newArgs = new String[args.length - 2]; 9328 if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2); 9329 } 9330 9331 if (r != null) { 9332 dumpService(fd, pw, r, newArgs); 9333 } else { 9334 for (ServiceRecord r1 : mServices.values()) { 9335 if (componentNameString == null 9336 || r1.name.flattenToString().contains(componentNameString)) { 9337 dumpService(fd, pw, r1, newArgs); 9338 } 9339 } 9340 } 9341 } 9342 9343 /** 9344 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9345 * there is a thread associated with the service. 9346 */ 9347 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 9348 pw.println(" Service " + r.name.flattenToString()); 9349 if (r.app != null && r.app.thread != null) { 9350 try { 9351 // flush anything that is already in the PrintWriter since the thread is going 9352 // to write to the file descriptor directly 9353 pw.flush(); 9354 r.app.thread.dumpService(fd, r, args); 9355 pw.print("\n"); 9356 } catch (RemoteException e) { 9357 pw.println("got a RemoteException while dumping the service"); 9358 } 9359 } 9360 } 9361 9362 void dumpBroadcasts(PrintWriter pw) { 9363 synchronized (this) { 9364 if (checkCallingPermission(android.Manifest.permission.DUMP) 9365 != PackageManager.PERMISSION_GRANTED) { 9366 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9367 + Binder.getCallingPid() 9368 + ", uid=" + Binder.getCallingUid() 9369 + " without permission " 9370 + android.Manifest.permission.DUMP); 9371 return; 9372 } 9373 pw.println("Broadcasts in Current Activity Manager State:"); 9374 9375 if (mRegisteredReceivers.size() > 0) { 9376 pw.println(" "); 9377 pw.println(" Registered Receivers:"); 9378 Iterator it = mRegisteredReceivers.values().iterator(); 9379 while (it.hasNext()) { 9380 ReceiverList r = (ReceiverList)it.next(); 9381 pw.print(" * "); pw.println(r); 9382 r.dump(pw, " "); 9383 } 9384 } 9385 9386 pw.println(" "); 9387 pw.println("Receiver Resolver Table:"); 9388 mReceiverResolver.dump(pw, " "); 9389 9390 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 9391 || mPendingBroadcast != null) { 9392 if (mParallelBroadcasts.size() > 0) { 9393 pw.println(" "); 9394 pw.println(" Active broadcasts:"); 9395 } 9396 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 9397 pw.println(" Broadcast #" + i + ":"); 9398 mParallelBroadcasts.get(i).dump(pw, " "); 9399 } 9400 if (mOrderedBroadcasts.size() > 0) { 9401 pw.println(" "); 9402 pw.println(" Active serialized broadcasts:"); 9403 } 9404 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 9405 pw.println(" Serialized Broadcast #" + i + ":"); 9406 mOrderedBroadcasts.get(i).dump(pw, " "); 9407 } 9408 pw.println(" "); 9409 pw.println(" Pending broadcast:"); 9410 if (mPendingBroadcast != null) { 9411 mPendingBroadcast.dump(pw, " "); 9412 } else { 9413 pw.println(" (null)"); 9414 } 9415 } 9416 9417 pw.println(" "); 9418 pw.println(" Historical broadcasts:"); 9419 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 9420 BroadcastRecord r = mBroadcastHistory[i]; 9421 if (r == null) { 9422 break; 9423 } 9424 pw.println(" Historical Broadcast #" + i + ":"); 9425 r.dump(pw, " "); 9426 } 9427 9428 pw.println(" "); 9429 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 9430 if (mStickyBroadcasts != null) { 9431 pw.println(" "); 9432 pw.println(" Sticky broadcasts:"); 9433 StringBuilder sb = new StringBuilder(128); 9434 for (Map.Entry<String, ArrayList<Intent>> ent 9435 : mStickyBroadcasts.entrySet()) { 9436 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9437 pw.println(":"); 9438 ArrayList<Intent> intents = ent.getValue(); 9439 final int N = intents.size(); 9440 for (int i=0; i<N; i++) { 9441 sb.setLength(0); 9442 sb.append(" Intent: "); 9443 intents.get(i).toShortString(sb, true, false); 9444 pw.println(sb.toString()); 9445 Bundle bundle = intents.get(i).getExtras(); 9446 if (bundle != null) { 9447 pw.print(" "); 9448 pw.println(bundle.toString()); 9449 } 9450 } 9451 } 9452 } 9453 9454 pw.println(" "); 9455 pw.println(" mHandler:"); 9456 mHandler.dump(new PrintWriterPrinter(pw), " "); 9457 } 9458 } 9459 9460 void dumpServices(PrintWriter pw) { 9461 synchronized (this) { 9462 if (checkCallingPermission(android.Manifest.permission.DUMP) 9463 != PackageManager.PERMISSION_GRANTED) { 9464 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9465 + Binder.getCallingPid() 9466 + ", uid=" + Binder.getCallingUid() 9467 + " without permission " 9468 + android.Manifest.permission.DUMP); 9469 return; 9470 } 9471 pw.println("Services in Current Activity Manager State:"); 9472 9473 boolean needSep = false; 9474 9475 if (mServices.size() > 0) { 9476 pw.println(" Active services:"); 9477 Iterator<ServiceRecord> it = mServices.values().iterator(); 9478 while (it.hasNext()) { 9479 ServiceRecord r = it.next(); 9480 pw.print(" * "); pw.println(r); 9481 r.dump(pw, " "); 9482 } 9483 needSep = true; 9484 } 9485 9486 if (mPendingServices.size() > 0) { 9487 if (needSep) pw.println(" "); 9488 pw.println(" Pending services:"); 9489 for (int i=0; i<mPendingServices.size(); i++) { 9490 ServiceRecord r = mPendingServices.get(i); 9491 pw.print(" * Pending "); pw.println(r); 9492 r.dump(pw, " "); 9493 } 9494 needSep = true; 9495 } 9496 9497 if (mRestartingServices.size() > 0) { 9498 if (needSep) pw.println(" "); 9499 pw.println(" Restarting services:"); 9500 for (int i=0; i<mRestartingServices.size(); i++) { 9501 ServiceRecord r = mRestartingServices.get(i); 9502 pw.print(" * Restarting "); pw.println(r); 9503 r.dump(pw, " "); 9504 } 9505 needSep = true; 9506 } 9507 9508 if (mStoppingServices.size() > 0) { 9509 if (needSep) pw.println(" "); 9510 pw.println(" Stopping services:"); 9511 for (int i=0; i<mStoppingServices.size(); i++) { 9512 ServiceRecord r = mStoppingServices.get(i); 9513 pw.print(" * Stopping "); pw.println(r); 9514 r.dump(pw, " "); 9515 } 9516 needSep = true; 9517 } 9518 9519 if (mServiceConnections.size() > 0) { 9520 if (needSep) pw.println(" "); 9521 pw.println(" Connection bindings to services:"); 9522 Iterator<ConnectionRecord> it 9523 = mServiceConnections.values().iterator(); 9524 while (it.hasNext()) { 9525 ConnectionRecord r = it.next(); 9526 pw.print(" * "); pw.println(r); 9527 r.dump(pw, " "); 9528 } 9529 } 9530 } 9531 } 9532 9533 void dumpProviders(PrintWriter pw) { 9534 synchronized (this) { 9535 if (checkCallingPermission(android.Manifest.permission.DUMP) 9536 != PackageManager.PERMISSION_GRANTED) { 9537 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9538 + Binder.getCallingPid() 9539 + ", uid=" + Binder.getCallingUid() 9540 + " without permission " 9541 + android.Manifest.permission.DUMP); 9542 return; 9543 } 9544 9545 pw.println("Content Providers in Current Activity Manager State:"); 9546 9547 boolean needSep = false; 9548 9549 if (mProvidersByClass.size() > 0) { 9550 if (needSep) pw.println(" "); 9551 pw.println(" Published content providers (by class):"); 9552 Iterator it = mProvidersByClass.entrySet().iterator(); 9553 while (it.hasNext()) { 9554 Map.Entry e = (Map.Entry)it.next(); 9555 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9556 pw.print(" * "); pw.println(r); 9557 r.dump(pw, " "); 9558 } 9559 needSep = true; 9560 } 9561 9562 if (mProvidersByName.size() > 0) { 9563 pw.println(" "); 9564 pw.println(" Authority to provider mappings:"); 9565 Iterator it = mProvidersByName.entrySet().iterator(); 9566 while (it.hasNext()) { 9567 Map.Entry e = (Map.Entry)it.next(); 9568 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9569 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 9570 pw.println(r); 9571 } 9572 needSep = true; 9573 } 9574 9575 if (mLaunchingProviders.size() > 0) { 9576 if (needSep) pw.println(" "); 9577 pw.println(" Launching content providers:"); 9578 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9579 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9580 pw.println(mLaunchingProviders.get(i)); 9581 } 9582 needSep = true; 9583 } 9584 9585 if (mGrantedUriPermissions.size() > 0) { 9586 pw.println(); 9587 pw.println("Granted Uri Permissions:"); 9588 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9589 int uid = mGrantedUriPermissions.keyAt(i); 9590 HashMap<Uri, UriPermission> perms 9591 = mGrantedUriPermissions.valueAt(i); 9592 pw.print(" * UID "); pw.print(uid); 9593 pw.println(" holds:"); 9594 for (UriPermission perm : perms.values()) { 9595 pw.print(" "); pw.println(perm); 9596 perm.dump(pw, " "); 9597 } 9598 } 9599 } 9600 } 9601 } 9602 9603 void dumpSenders(PrintWriter pw) { 9604 synchronized (this) { 9605 if (checkCallingPermission(android.Manifest.permission.DUMP) 9606 != PackageManager.PERMISSION_GRANTED) { 9607 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9608 + Binder.getCallingPid() 9609 + ", uid=" + Binder.getCallingUid() 9610 + " without permission " 9611 + android.Manifest.permission.DUMP); 9612 return; 9613 } 9614 9615 pw.println("Pending Intents in Current Activity Manager State:"); 9616 9617 if (this.mIntentSenderRecords.size() > 0) { 9618 Iterator<WeakReference<PendingIntentRecord>> it 9619 = mIntentSenderRecords.values().iterator(); 9620 while (it.hasNext()) { 9621 WeakReference<PendingIntentRecord> ref = it.next(); 9622 PendingIntentRecord rec = ref != null ? ref.get(): null; 9623 if (rec != null) { 9624 pw.print(" * "); pw.println(rec); 9625 rec.dump(pw, " "); 9626 } else { 9627 pw.print(" * "); pw.print(ref); 9628 } 9629 } 9630 } 9631 } 9632 } 9633 9634 private static final void dumpHistoryList(PrintWriter pw, List list, 9635 String prefix, String label, boolean complete) { 9636 TaskRecord lastTask = null; 9637 for (int i=list.size()-1; i>=0; i--) { 9638 HistoryRecord r = (HistoryRecord)list.get(i); 9639 final boolean full = complete || !r.inHistory; 9640 if (lastTask != r.task) { 9641 lastTask = r.task; 9642 pw.print(prefix); 9643 pw.print(full ? "* " : " "); 9644 pw.println(lastTask); 9645 if (full) { 9646 lastTask.dump(pw, prefix + " "); 9647 } 9648 } 9649 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9650 pw.print(" #"); pw.print(i); pw.print(": "); 9651 pw.println(r); 9652 if (full) { 9653 r.dump(pw, prefix + " "); 9654 } 9655 } 9656 } 9657 9658 private static final int dumpProcessList(PrintWriter pw, List list, 9659 String prefix, String normalLabel, String persistentLabel, 9660 boolean inclOomAdj) { 9661 int numPers = 0; 9662 for (int i=list.size()-1; i>=0; i--) { 9663 ProcessRecord r = (ProcessRecord)list.get(i); 9664 if (false) { 9665 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 9666 + " #" + i + ":"); 9667 r.dump(pw, prefix + " "); 9668 } else if (inclOomAdj) { 9669 pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)", 9670 prefix, (r.persistent ? persistentLabel : normalLabel), 9671 i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType)); 9672 if (r.adjSource != null || r.adjTarget != null) { 9673 pw.println(prefix + " " + r.adjTarget 9674 + " used by " + r.adjSource); 9675 } 9676 } else { 9677 pw.println(String.format("%s%s #%2d: %s", 9678 prefix, (r.persistent ? persistentLabel : normalLabel), 9679 i, r.toString())); 9680 } 9681 if (r.persistent) { 9682 numPers++; 9683 } 9684 } 9685 return numPers; 9686 } 9687 9688 private static final void dumpApplicationMemoryUsage(FileDescriptor fd, 9689 PrintWriter pw, List list, String prefix, String[] args) { 9690 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9691 long uptime = SystemClock.uptimeMillis(); 9692 long realtime = SystemClock.elapsedRealtime(); 9693 9694 if (isCheckinRequest) { 9695 // short checkin version 9696 pw.println(uptime + "," + realtime); 9697 pw.flush(); 9698 } else { 9699 pw.println("Applications Memory Usage (kB):"); 9700 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9701 } 9702 for (int i = list.size() - 1 ; i >= 0 ; i--) { 9703 ProcessRecord r = (ProcessRecord)list.get(i); 9704 if (r.thread != null) { 9705 if (!isCheckinRequest) { 9706 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9707 pw.flush(); 9708 } 9709 try { 9710 r.thread.asBinder().dump(fd, args); 9711 } catch (RemoteException e) { 9712 if (!isCheckinRequest) { 9713 pw.println("Got RemoteException!"); 9714 pw.flush(); 9715 } 9716 } 9717 } 9718 } 9719 } 9720 9721 /** 9722 * Searches array of arguments for the specified string 9723 * @param args array of argument strings 9724 * @param value value to search for 9725 * @return true if the value is contained in the array 9726 */ 9727 private static boolean scanArgs(String[] args, String value) { 9728 if (args != null) { 9729 for (String arg : args) { 9730 if (value.equals(arg)) { 9731 return true; 9732 } 9733 } 9734 } 9735 return false; 9736 } 9737 9738 private final int indexOfTokenLocked(IBinder token) { 9739 int count = mHistory.size(); 9740 9741 // convert the token to an entry in the history. 9742 HistoryRecord r = null; 9743 int index = -1; 9744 for (int i=count-1; i>=0; i--) { 9745 Object o = mHistory.get(i); 9746 if (o == token) { 9747 r = (HistoryRecord)o; 9748 index = i; 9749 break; 9750 } 9751 } 9752 9753 return index; 9754 } 9755 9756 private final void killServicesLocked(ProcessRecord app, 9757 boolean allowRestart) { 9758 // Report disconnected services. 9759 if (false) { 9760 // XXX we are letting the client link to the service for 9761 // death notifications. 9762 if (app.services.size() > 0) { 9763 Iterator it = app.services.iterator(); 9764 while (it.hasNext()) { 9765 ServiceRecord r = (ServiceRecord)it.next(); 9766 if (r.connections.size() > 0) { 9767 Iterator<ConnectionRecord> jt 9768 = r.connections.values().iterator(); 9769 while (jt.hasNext()) { 9770 ConnectionRecord c = jt.next(); 9771 if (c.binding.client != app) { 9772 try { 9773 //c.conn.connected(r.className, null); 9774 } catch (Exception e) { 9775 // todo: this should be asynchronous! 9776 Log.w(TAG, "Exception thrown disconnected servce " 9777 + r.shortName 9778 + " from app " + app.processName, e); 9779 } 9780 } 9781 } 9782 } 9783 } 9784 } 9785 } 9786 9787 // Clean up any connections this application has to other services. 9788 if (app.connections.size() > 0) { 9789 Iterator<ConnectionRecord> it = app.connections.iterator(); 9790 while (it.hasNext()) { 9791 ConnectionRecord r = it.next(); 9792 removeConnectionLocked(r, app, null); 9793 } 9794 } 9795 app.connections.clear(); 9796 9797 if (app.services.size() != 0) { 9798 // Any services running in the application need to be placed 9799 // back in the pending list. 9800 Iterator it = app.services.iterator(); 9801 while (it.hasNext()) { 9802 ServiceRecord sr = (ServiceRecord)it.next(); 9803 synchronized (sr.stats.getBatteryStats()) { 9804 sr.stats.stopLaunchedLocked(); 9805 } 9806 sr.app = null; 9807 sr.executeNesting = 0; 9808 mStoppingServices.remove(sr); 9809 9810 boolean hasClients = sr.bindings.size() > 0; 9811 if (hasClients) { 9812 Iterator<IntentBindRecord> bindings 9813 = sr.bindings.values().iterator(); 9814 while (bindings.hasNext()) { 9815 IntentBindRecord b = bindings.next(); 9816 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b 9817 + ": shouldUnbind=" + b.hasBound); 9818 b.binder = null; 9819 b.requested = b.received = b.hasBound = false; 9820 } 9821 } 9822 9823 if (sr.crashCount >= 2) { 9824 Log.w(TAG, "Service crashed " + sr.crashCount 9825 + " times, stopping: " + sr); 9826 EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH, 9827 sr.crashCount, sr.shortName, app.pid); 9828 bringDownServiceLocked(sr, true); 9829 } else if (!allowRestart) { 9830 bringDownServiceLocked(sr, true); 9831 } else { 9832 boolean canceled = scheduleServiceRestartLocked(sr, true); 9833 9834 // Should the service remain running? Note that in the 9835 // extreme case of so many attempts to deliver a command 9836 // that it failed, that we also will stop it here. 9837 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 9838 if (sr.pendingStarts.size() == 0) { 9839 sr.startRequested = false; 9840 if (!hasClients) { 9841 // Whoops, no reason to restart! 9842 bringDownServiceLocked(sr, true); 9843 } 9844 } 9845 } 9846 } 9847 } 9848 9849 if (!allowRestart) { 9850 app.services.clear(); 9851 } 9852 } 9853 9854 // Make sure we have no more records on the stopping list. 9855 int i = mStoppingServices.size(); 9856 while (i > 0) { 9857 i--; 9858 ServiceRecord sr = mStoppingServices.get(i); 9859 if (sr.app == app) { 9860 mStoppingServices.remove(i); 9861 } 9862 } 9863 9864 app.executingServices.clear(); 9865 } 9866 9867 private final void removeDyingProviderLocked(ProcessRecord proc, 9868 ContentProviderRecord cpr) { 9869 synchronized (cpr) { 9870 cpr.launchingApp = null; 9871 cpr.notifyAll(); 9872 } 9873 9874 mProvidersByClass.remove(cpr.info.name); 9875 String names[] = cpr.info.authority.split(";"); 9876 for (int j = 0; j < names.length; j++) { 9877 mProvidersByName.remove(names[j]); 9878 } 9879 9880 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 9881 while (cit.hasNext()) { 9882 ProcessRecord capp = cit.next(); 9883 if (!capp.persistent && capp.thread != null 9884 && capp.pid != 0 9885 && capp.pid != MY_PID) { 9886 Log.i(TAG, "Killing app " + capp.processName 9887 + " (pid " + capp.pid 9888 + ") because provider " + cpr.info.name 9889 + " is in dying process " + proc.processName); 9890 Process.killProcess(capp.pid); 9891 } 9892 } 9893 9894 mLaunchingProviders.remove(cpr); 9895 } 9896 9897 /** 9898 * Main code for cleaning up a process when it has gone away. This is 9899 * called both as a result of the process dying, or directly when stopping 9900 * a process when running in single process mode. 9901 */ 9902 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 9903 boolean restarting, int index) { 9904 if (index >= 0) { 9905 mLRUProcesses.remove(index); 9906 } 9907 9908 mProcessesToGc.remove(app); 9909 9910 // Dismiss any open dialogs. 9911 if (app.crashDialog != null) { 9912 app.crashDialog.dismiss(); 9913 app.crashDialog = null; 9914 } 9915 if (app.anrDialog != null) { 9916 app.anrDialog.dismiss(); 9917 app.anrDialog = null; 9918 } 9919 if (app.waitDialog != null) { 9920 app.waitDialog.dismiss(); 9921 app.waitDialog = null; 9922 } 9923 9924 app.crashing = false; 9925 app.notResponding = false; 9926 9927 app.resetPackageList(); 9928 app.thread = null; 9929 app.forcingToForeground = null; 9930 app.foregroundServices = false; 9931 9932 killServicesLocked(app, true); 9933 9934 boolean restart = false; 9935 9936 int NL = mLaunchingProviders.size(); 9937 9938 // Remove published content providers. 9939 if (!app.pubProviders.isEmpty()) { 9940 Iterator it = app.pubProviders.values().iterator(); 9941 while (it.hasNext()) { 9942 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9943 cpr.provider = null; 9944 cpr.app = null; 9945 9946 // See if someone is waiting for this provider... in which 9947 // case we don't remove it, but just let it restart. 9948 int i = 0; 9949 if (!app.bad) { 9950 for (; i<NL; i++) { 9951 if (mLaunchingProviders.get(i) == cpr) { 9952 restart = true; 9953 break; 9954 } 9955 } 9956 } else { 9957 i = NL; 9958 } 9959 9960 if (i >= NL) { 9961 removeDyingProviderLocked(app, cpr); 9962 NL = mLaunchingProviders.size(); 9963 } 9964 } 9965 app.pubProviders.clear(); 9966 } 9967 9968 // Take care of any launching providers waiting for this process. 9969 if (checkAppInLaunchingProvidersLocked(app, false)) { 9970 restart = true; 9971 } 9972 9973 // Unregister from connected content providers. 9974 if (!app.conProviders.isEmpty()) { 9975 Iterator it = app.conProviders.keySet().iterator(); 9976 while (it.hasNext()) { 9977 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9978 cpr.clients.remove(app); 9979 } 9980 app.conProviders.clear(); 9981 } 9982 9983 // At this point there may be remaining entries in mLaunchingProviders 9984 // where we were the only one waiting, so they are no longer of use. 9985 // Look for these and clean up if found. 9986 // XXX Commented out for now. Trying to figure out a way to reproduce 9987 // the actual situation to identify what is actually going on. 9988 if (false) { 9989 for (int i=0; i<NL; i++) { 9990 ContentProviderRecord cpr = (ContentProviderRecord) 9991 mLaunchingProviders.get(i); 9992 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 9993 synchronized (cpr) { 9994 cpr.launchingApp = null; 9995 cpr.notifyAll(); 9996 } 9997 } 9998 } 9999 } 10000 10001 skipCurrentReceiverLocked(app); 10002 10003 // Unregister any receivers. 10004 if (app.receivers.size() > 0) { 10005 Iterator<ReceiverList> it = app.receivers.iterator(); 10006 while (it.hasNext()) { 10007 removeReceiverLocked(it.next()); 10008 } 10009 app.receivers.clear(); 10010 } 10011 10012 // If the app is undergoing backup, tell the backup manager about it 10013 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10014 if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10015 try { 10016 IBackupManager bm = IBackupManager.Stub.asInterface( 10017 ServiceManager.getService(Context.BACKUP_SERVICE)); 10018 bm.agentDisconnected(app.info.packageName); 10019 } catch (RemoteException e) { 10020 // can't happen; backup manager is local 10021 } 10022 } 10023 10024 // If the caller is restarting this app, then leave it in its 10025 // current lists and let the caller take care of it. 10026 if (restarting) { 10027 return; 10028 } 10029 10030 if (!app.persistent) { 10031 if (DEBUG_PROCESSES) Log.v(TAG, 10032 "Removing non-persistent process during cleanup: " + app); 10033 mProcessNames.remove(app.processName, app.info.uid); 10034 } else if (!app.removed) { 10035 // This app is persistent, so we need to keep its record around. 10036 // If it is not already on the pending app list, add it there 10037 // and start a new process for it. 10038 app.thread = null; 10039 app.forcingToForeground = null; 10040 app.foregroundServices = false; 10041 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10042 mPersistentStartingProcesses.add(app); 10043 restart = true; 10044 } 10045 } 10046 mProcessesOnHold.remove(app); 10047 10048 if (app == mHomeProcess) { 10049 mHomeProcess = null; 10050 } 10051 10052 if (restart) { 10053 // We have components that still need to be running in the 10054 // process, so re-launch it. 10055 mProcessNames.put(app.processName, app.info.uid, app); 10056 startProcessLocked(app, "restart", app.processName); 10057 } else if (app.pid > 0 && app.pid != MY_PID) { 10058 // Goodbye! 10059 synchronized (mPidsSelfLocked) { 10060 mPidsSelfLocked.remove(app.pid); 10061 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10062 } 10063 app.setPid(0); 10064 } 10065 } 10066 10067 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10068 // Look through the content providers we are waiting to have launched, 10069 // and if any run in this process then either schedule a restart of 10070 // the process or kill the client waiting for it if this process has 10071 // gone bad. 10072 int NL = mLaunchingProviders.size(); 10073 boolean restart = false; 10074 for (int i=0; i<NL; i++) { 10075 ContentProviderRecord cpr = (ContentProviderRecord) 10076 mLaunchingProviders.get(i); 10077 if (cpr.launchingApp == app) { 10078 if (!alwaysBad && !app.bad) { 10079 restart = true; 10080 } else { 10081 removeDyingProviderLocked(app, cpr); 10082 NL = mLaunchingProviders.size(); 10083 } 10084 } 10085 } 10086 return restart; 10087 } 10088 10089 // ========================================================= 10090 // SERVICES 10091 // ========================================================= 10092 10093 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10094 ActivityManager.RunningServiceInfo info = 10095 new ActivityManager.RunningServiceInfo(); 10096 info.service = r.name; 10097 if (r.app != null) { 10098 info.pid = r.app.pid; 10099 } 10100 info.uid = r.appInfo.uid; 10101 info.process = r.processName; 10102 info.foreground = r.isForeground; 10103 info.activeSince = r.createTime; 10104 info.started = r.startRequested; 10105 info.clientCount = r.connections.size(); 10106 info.crashCount = r.crashCount; 10107 info.lastActivityTime = r.lastActivity; 10108 if (r.isForeground) { 10109 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10110 } 10111 if (r.startRequested) { 10112 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10113 } 10114 if (r.app != null && r.app.pid == Process.myPid()) { 10115 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10116 } 10117 if (r.app != null && r.app.persistent) { 10118 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10119 } 10120 for (ConnectionRecord conn : r.connections.values()) { 10121 if (conn.clientLabel != 0) { 10122 info.clientPackage = conn.binding.client.info.packageName; 10123 info.clientLabel = conn.clientLabel; 10124 break; 10125 } 10126 } 10127 return info; 10128 } 10129 10130 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10131 int flags) { 10132 synchronized (this) { 10133 ArrayList<ActivityManager.RunningServiceInfo> res 10134 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10135 10136 if (mServices.size() > 0) { 10137 Iterator<ServiceRecord> it = mServices.values().iterator(); 10138 while (it.hasNext() && res.size() < maxNum) { 10139 res.add(makeRunningServiceInfoLocked(it.next())); 10140 } 10141 } 10142 10143 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10144 ServiceRecord r = mRestartingServices.get(i); 10145 ActivityManager.RunningServiceInfo info = 10146 makeRunningServiceInfoLocked(r); 10147 info.restarting = r.nextRestartTime; 10148 res.add(info); 10149 } 10150 10151 return res; 10152 } 10153 } 10154 10155 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10156 synchronized (this) { 10157 ServiceRecord r = mServices.get(name); 10158 if (r != null) { 10159 for (ConnectionRecord conn : r.connections.values()) { 10160 if (conn.clientIntent != null) { 10161 return conn.clientIntent; 10162 } 10163 } 10164 } 10165 } 10166 return null; 10167 } 10168 10169 private final ServiceRecord findServiceLocked(ComponentName name, 10170 IBinder token) { 10171 ServiceRecord r = mServices.get(name); 10172 return r == token ? r : null; 10173 } 10174 10175 private final class ServiceLookupResult { 10176 final ServiceRecord record; 10177 final String permission; 10178 10179 ServiceLookupResult(ServiceRecord _record, String _permission) { 10180 record = _record; 10181 permission = _permission; 10182 } 10183 }; 10184 findServiceLocked(Intent service, String resolvedType)10185 private ServiceLookupResult findServiceLocked(Intent service, 10186 String resolvedType) { 10187 ServiceRecord r = null; 10188 if (service.getComponent() != null) { 10189 r = mServices.get(service.getComponent()); 10190 } 10191 if (r == null) { 10192 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10193 r = mServicesByIntent.get(filter); 10194 } 10195 10196 if (r == null) { 10197 try { 10198 ResolveInfo rInfo = 10199 ActivityThread.getPackageManager().resolveService( 10200 service, resolvedType, 0); 10201 ServiceInfo sInfo = 10202 rInfo != null ? rInfo.serviceInfo : null; 10203 if (sInfo == null) { 10204 return null; 10205 } 10206 10207 ComponentName name = new ComponentName( 10208 sInfo.applicationInfo.packageName, sInfo.name); 10209 r = mServices.get(name); 10210 } catch (RemoteException ex) { 10211 // pm is in same process, this will never happen. 10212 } 10213 } 10214 if (r != null) { 10215 int callingPid = Binder.getCallingPid(); 10216 int callingUid = Binder.getCallingUid(); 10217 if (checkComponentPermission(r.permission, 10218 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10219 != PackageManager.PERMISSION_GRANTED) { 10220 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10221 + " from pid=" + callingPid 10222 + ", uid=" + callingUid 10223 + " requires " + r.permission); 10224 return new ServiceLookupResult(null, r.permission); 10225 } 10226 return new ServiceLookupResult(r, null); 10227 } 10228 return null; 10229 } 10230 10231 private class ServiceRestarter implements Runnable { 10232 private ServiceRecord mService; 10233 setService(ServiceRecord service)10234 void setService(ServiceRecord service) { 10235 mService = service; 10236 } 10237 run()10238 public void run() { 10239 synchronized(ActivityManagerService.this) { 10240 performServiceRestartLocked(mService); 10241 } 10242 } 10243 } 10244 retrieveServiceLocked(Intent service, String resolvedType, int callingPid, int callingUid)10245 private ServiceLookupResult retrieveServiceLocked(Intent service, 10246 String resolvedType, int callingPid, int callingUid) { 10247 ServiceRecord r = null; 10248 if (service.getComponent() != null) { 10249 r = mServices.get(service.getComponent()); 10250 } 10251 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10252 r = mServicesByIntent.get(filter); 10253 if (r == null) { 10254 try { 10255 ResolveInfo rInfo = 10256 ActivityThread.getPackageManager().resolveService( 10257 service, resolvedType, STOCK_PM_FLAGS); 10258 ServiceInfo sInfo = 10259 rInfo != null ? rInfo.serviceInfo : null; 10260 if (sInfo == null) { 10261 Log.w(TAG, "Unable to start service " + service + 10262 ": not found"); 10263 return null; 10264 } 10265 10266 ComponentName name = new ComponentName( 10267 sInfo.applicationInfo.packageName, sInfo.name); 10268 r = mServices.get(name); 10269 if (r == null) { 10270 filter = new Intent.FilterComparison(service.cloneFilter()); 10271 ServiceRestarter res = new ServiceRestarter(); 10272 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10273 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10274 synchronized (stats) { 10275 ss = stats.getServiceStatsLocked( 10276 sInfo.applicationInfo.uid, sInfo.packageName, 10277 sInfo.name); 10278 } 10279 r = new ServiceRecord(ss, name, filter, sInfo, res); 10280 res.setService(r); 10281 mServices.put(name, r); 10282 mServicesByIntent.put(filter, r); 10283 10284 // Make sure this component isn't in the pending list. 10285 int N = mPendingServices.size(); 10286 for (int i=0; i<N; i++) { 10287 ServiceRecord pr = mPendingServices.get(i); 10288 if (pr.name.equals(name)) { 10289 mPendingServices.remove(i); 10290 i--; 10291 N--; 10292 } 10293 } 10294 } 10295 } catch (RemoteException ex) { 10296 // pm is in same process, this will never happen. 10297 } 10298 } 10299 if (r != null) { 10300 if (checkComponentPermission(r.permission, 10301 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10302 != PackageManager.PERMISSION_GRANTED) { 10303 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10304 + " from pid=" + Binder.getCallingPid() 10305 + ", uid=" + Binder.getCallingUid() 10306 + " requires " + r.permission); 10307 return new ServiceLookupResult(null, r.permission); 10308 } 10309 return new ServiceLookupResult(r, null); 10310 } 10311 return null; 10312 } 10313 bumpServiceExecutingLocked(ServiceRecord r)10314 private final void bumpServiceExecutingLocked(ServiceRecord r) { 10315 long now = SystemClock.uptimeMillis(); 10316 if (r.executeNesting == 0 && r.app != null) { 10317 if (r.app.executingServices.size() == 0) { 10318 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10319 msg.obj = r.app; 10320 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10321 } 10322 r.app.executingServices.add(r); 10323 } 10324 r.executeNesting++; 10325 r.executingStart = now; 10326 } 10327 sendServiceArgsLocked(ServiceRecord r, boolean oomAdjusted)10328 private final void sendServiceArgsLocked(ServiceRecord r, 10329 boolean oomAdjusted) { 10330 final int N = r.pendingStarts.size(); 10331 if (N == 0) { 10332 return; 10333 } 10334 10335 int i = 0; 10336 while (i < N) { 10337 try { 10338 ServiceRecord.StartItem si = r.pendingStarts.get(i); 10339 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: " 10340 + r.name + " " + r.intent + " args=" + si.intent); 10341 if (si.intent == null && N > 1) { 10342 // If somehow we got a dummy start at the front, then 10343 // just drop it here. 10344 i++; 10345 continue; 10346 } 10347 bumpServiceExecutingLocked(r); 10348 if (!oomAdjusted) { 10349 oomAdjusted = true; 10350 updateOomAdjLocked(r.app); 10351 } 10352 int flags = 0; 10353 if (si.deliveryCount > 0) { 10354 flags |= Service.START_FLAG_RETRY; 10355 } 10356 if (si.doneExecutingCount > 0) { 10357 flags |= Service.START_FLAG_REDELIVERY; 10358 } 10359 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); 10360 si.deliveredTime = SystemClock.uptimeMillis(); 10361 r.deliveredStarts.add(si); 10362 si.deliveryCount++; 10363 i++; 10364 } catch (RemoteException e) { 10365 // Remote process gone... we'll let the normal cleanup take 10366 // care of this. 10367 break; 10368 } catch (Exception e) { 10369 Log.w(TAG, "Unexpected exception", e); 10370 break; 10371 } 10372 } 10373 if (i == N) { 10374 r.pendingStarts.clear(); 10375 } else { 10376 while (i > 0) { 10377 i--; 10378 r.pendingStarts.remove(i); 10379 } 10380 } 10381 } 10382 requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean rebind)10383 private final boolean requestServiceBindingLocked(ServiceRecord r, 10384 IntentBindRecord i, boolean rebind) { 10385 if (r.app == null || r.app.thread == null) { 10386 // If service is not currently running, can't yet bind. 10387 return false; 10388 } 10389 if ((!i.requested || rebind) && i.apps.size() > 0) { 10390 try { 10391 bumpServiceExecutingLocked(r); 10392 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i 10393 + ": shouldUnbind=" + i.hasBound); 10394 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10395 if (!rebind) { 10396 i.requested = true; 10397 } 10398 i.hasBound = true; 10399 i.doRebind = false; 10400 } catch (RemoteException e) { 10401 return false; 10402 } 10403 } 10404 return true; 10405 } 10406 requestServiceBindingsLocked(ServiceRecord r)10407 private final void requestServiceBindingsLocked(ServiceRecord r) { 10408 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10409 while (bindings.hasNext()) { 10410 IntentBindRecord i = bindings.next(); 10411 if (!requestServiceBindingLocked(r, i, false)) { 10412 break; 10413 } 10414 } 10415 } 10416 realStartServiceLocked(ServiceRecord r, ProcessRecord app)10417 private final void realStartServiceLocked(ServiceRecord r, 10418 ProcessRecord app) throws RemoteException { 10419 if (app.thread == null) { 10420 throw new RemoteException(); 10421 } 10422 10423 r.app = app; 10424 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10425 10426 app.services.add(r); 10427 bumpServiceExecutingLocked(r); 10428 updateLRUListLocked(app, true); 10429 10430 boolean created = false; 10431 try { 10432 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: " 10433 + r.name + " " + r.intent); 10434 mStringBuilder.setLength(0); 10435 r.intent.getIntent().toShortString(mStringBuilder, false, true); 10436 EventLog.writeEvent(LOG_AM_CREATE_SERVICE, 10437 System.identityHashCode(r), r.shortName, 10438 mStringBuilder.toString(), r.app.pid); 10439 synchronized (r.stats.getBatteryStats()) { 10440 r.stats.startLaunchedLocked(); 10441 } 10442 ensurePackageDexOpt(r.serviceInfo.packageName); 10443 app.thread.scheduleCreateService(r, r.serviceInfo); 10444 r.postNotification(); 10445 created = true; 10446 } finally { 10447 if (!created) { 10448 app.services.remove(r); 10449 scheduleServiceRestartLocked(r, false); 10450 } 10451 } 10452 10453 requestServiceBindingsLocked(r); 10454 10455 // If the service is in the started state, and there are no 10456 // pending arguments, then fake up one so its onStartCommand() will 10457 // be called. 10458 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10459 r.lastStartId++; 10460 if (r.lastStartId < 1) { 10461 r.lastStartId = 1; 10462 } 10463 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); 10464 } 10465 10466 sendServiceArgsLocked(r, true); 10467 } 10468 scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel)10469 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10470 boolean allowCancel) { 10471 boolean canceled = false; 10472 10473 final long now = SystemClock.uptimeMillis(); 10474 long minDuration = SERVICE_RESTART_DURATION; 10475 long resetTime = SERVICE_RESET_RUN_DURATION; 10476 10477 // Any delivered but not yet finished starts should be put back 10478 // on the pending list. 10479 final int N = r.deliveredStarts.size(); 10480 if (N > 0) { 10481 for (int i=N-1; i>=0; i--) { 10482 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10483 if (si.intent == null) { 10484 // We'll generate this again if needed. 10485 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10486 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10487 r.pendingStarts.add(0, si); 10488 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10489 dur *= 2; 10490 if (minDuration < dur) minDuration = dur; 10491 if (resetTime < dur) resetTime = dur; 10492 } else { 10493 Log.w(TAG, "Canceling start item " + si.intent + " in service " 10494 + r.name); 10495 canceled = true; 10496 } 10497 } 10498 r.deliveredStarts.clear(); 10499 } 10500 10501 r.totalRestartCount++; 10502 if (r.restartDelay == 0) { 10503 r.restartCount++; 10504 r.restartDelay = minDuration; 10505 } else { 10506 // If it has been a "reasonably long time" since the service 10507 // was started, then reset our restart duration back to 10508 // the beginning, so we don't infinitely increase the duration 10509 // on a service that just occasionally gets killed (which is 10510 // a normal case, due to process being killed to reclaim memory). 10511 if (now > (r.restartTime+resetTime)) { 10512 r.restartCount = 1; 10513 r.restartDelay = minDuration; 10514 } else { 10515 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10516 if (r.restartDelay < minDuration) { 10517 r.restartDelay = minDuration; 10518 } 10519 } 10520 } 10521 10522 r.nextRestartTime = now + r.restartDelay; 10523 10524 // Make sure that we don't end up restarting a bunch of services 10525 // all at the same time. 10526 boolean repeat; 10527 do { 10528 repeat = false; 10529 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10530 ServiceRecord r2 = mRestartingServices.get(i); 10531 if (r2 != r && r.nextRestartTime 10532 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10533 && r.nextRestartTime 10534 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10535 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10536 r.restartDelay = r.nextRestartTime - now; 10537 repeat = true; 10538 break; 10539 } 10540 } 10541 } while (repeat); 10542 10543 if (!mRestartingServices.contains(r)) { 10544 mRestartingServices.add(r); 10545 } 10546 10547 r.cancelNotification(); 10548 10549 mHandler.removeCallbacks(r.restarter); 10550 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10551 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10552 Log.w(TAG, "Scheduling restart of crashed service " 10553 + r.shortName + " in " + r.restartDelay + "ms"); 10554 EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART, 10555 r.shortName, r.restartDelay); 10556 10557 Message msg = Message.obtain(); 10558 msg.what = SERVICE_ERROR_MSG; 10559 msg.obj = r; 10560 mHandler.sendMessage(msg); 10561 10562 return canceled; 10563 } 10564 performServiceRestartLocked(ServiceRecord r)10565 final void performServiceRestartLocked(ServiceRecord r) { 10566 if (!mRestartingServices.contains(r)) { 10567 return; 10568 } 10569 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10570 } 10571 unscheduleServiceRestartLocked(ServiceRecord r)10572 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10573 if (r.restartDelay == 0) { 10574 return false; 10575 } 10576 r.resetRestartCounter(); 10577 mRestartingServices.remove(r); 10578 mHandler.removeCallbacks(r.restarter); 10579 return true; 10580 } 10581 bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting)10582 private final boolean bringUpServiceLocked(ServiceRecord r, 10583 int intentFlags, boolean whileRestarting) { 10584 //Log.i(TAG, "Bring up service:"); 10585 //r.dump(" "); 10586 10587 if (r.app != null && r.app.thread != null) { 10588 sendServiceArgsLocked(r, false); 10589 return true; 10590 } 10591 10592 if (!whileRestarting && r.restartDelay > 0) { 10593 // If waiting for a restart, then do nothing. 10594 return true; 10595 } 10596 10597 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name 10598 + " " + r.intent); 10599 10600 // We are now bringing the service up, so no longer in the 10601 // restarting state. 10602 mRestartingServices.remove(r); 10603 10604 final String appName = r.processName; 10605 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10606 if (app != null && app.thread != null) { 10607 try { 10608 realStartServiceLocked(r, app); 10609 return true; 10610 } catch (RemoteException e) { 10611 Log.w(TAG, "Exception when starting service " + r.shortName, e); 10612 } 10613 10614 // If a dead object exception was thrown -- fall through to 10615 // restart the application. 10616 } 10617 10618 // Not running -- get it started, and enqueue this service record 10619 // to be executed when the app comes up. 10620 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10621 "service", r.name, false) == null) { 10622 Log.w(TAG, "Unable to launch app " 10623 + r.appInfo.packageName + "/" 10624 + r.appInfo.uid + " for service " 10625 + r.intent.getIntent() + ": process is bad"); 10626 bringDownServiceLocked(r, true); 10627 return false; 10628 } 10629 10630 if (!mPendingServices.contains(r)) { 10631 mPendingServices.add(r); 10632 } 10633 10634 return true; 10635 } 10636 bringDownServiceLocked(ServiceRecord r, boolean force)10637 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10638 //Log.i(TAG, "Bring down service:"); 10639 //r.dump(" "); 10640 10641 // Does it still need to run? 10642 if (!force && r.startRequested) { 10643 return; 10644 } 10645 if (r.connections.size() > 0) { 10646 if (!force) { 10647 // XXX should probably keep a count of the number of auto-create 10648 // connections directly in the service. 10649 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10650 while (it.hasNext()) { 10651 ConnectionRecord cr = it.next(); 10652 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 10653 return; 10654 } 10655 } 10656 } 10657 10658 // Report to all of the connections that the service is no longer 10659 // available. 10660 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10661 while (it.hasNext()) { 10662 ConnectionRecord c = it.next(); 10663 try { 10664 // todo: shouldn't be a synchronous call! 10665 c.conn.connected(r.name, null); 10666 } catch (Exception e) { 10667 Log.w(TAG, "Failure disconnecting service " + r.name + 10668 " to connection " + c.conn.asBinder() + 10669 " (in " + c.binding.client.processName + ")", e); 10670 } 10671 } 10672 } 10673 10674 // Tell the service that it has been unbound. 10675 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10676 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10677 while (it.hasNext()) { 10678 IntentBindRecord ibr = it.next(); 10679 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr 10680 + ": hasBound=" + ibr.hasBound); 10681 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10682 try { 10683 bumpServiceExecutingLocked(r); 10684 updateOomAdjLocked(r.app); 10685 ibr.hasBound = false; 10686 r.app.thread.scheduleUnbindService(r, 10687 ibr.intent.getIntent()); 10688 } catch (Exception e) { 10689 Log.w(TAG, "Exception when unbinding service " 10690 + r.shortName, e); 10691 serviceDoneExecutingLocked(r, true); 10692 } 10693 } 10694 } 10695 } 10696 10697 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name 10698 + " " + r.intent); 10699 EventLog.writeEvent(LOG_AM_DESTROY_SERVICE, 10700 System.identityHashCode(r), r.shortName, 10701 (r.app != null) ? r.app.pid : -1); 10702 10703 mServices.remove(r.name); 10704 mServicesByIntent.remove(r.intent); 10705 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 10706 r.totalRestartCount = 0; 10707 unscheduleServiceRestartLocked(r); 10708 10709 // Also make sure it is not on the pending list. 10710 int N = mPendingServices.size(); 10711 for (int i=0; i<N; i++) { 10712 if (mPendingServices.get(i) == r) { 10713 mPendingServices.remove(i); 10714 if (DEBUG_SERVICE) Log.v( 10715 TAG, "Removed pending service: " + r.shortName); 10716 i--; 10717 N--; 10718 } 10719 } 10720 10721 r.cancelNotification(); 10722 r.isForeground = false; 10723 r.foregroundId = 0; 10724 r.foregroundNoti = null; 10725 10726 // Clear start entries. 10727 r.deliveredStarts.clear(); 10728 r.pendingStarts.clear(); 10729 10730 if (r.app != null) { 10731 synchronized (r.stats.getBatteryStats()) { 10732 r.stats.stopLaunchedLocked(); 10733 } 10734 r.app.services.remove(r); 10735 if (r.app.thread != null) { 10736 try { 10737 if (DEBUG_SERVICE) Log.v(TAG, 10738 "Stopping service: " + r.shortName); 10739 bumpServiceExecutingLocked(r); 10740 mStoppingServices.add(r); 10741 updateOomAdjLocked(r.app); 10742 r.app.thread.scheduleStopService(r); 10743 } catch (Exception e) { 10744 Log.w(TAG, "Exception when stopping service " 10745 + r.shortName, e); 10746 serviceDoneExecutingLocked(r, true); 10747 } 10748 updateServiceForegroundLocked(r.app, false); 10749 } else { 10750 if (DEBUG_SERVICE) Log.v( 10751 TAG, "Removed service that has no process: " + r.shortName); 10752 } 10753 } else { 10754 if (DEBUG_SERVICE) Log.v( 10755 TAG, "Removed service that is not running: " + r.shortName); 10756 } 10757 } 10758 startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid)10759 ComponentName startServiceLocked(IApplicationThread caller, 10760 Intent service, String resolvedType, 10761 int callingPid, int callingUid) { 10762 synchronized(this) { 10763 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service 10764 + " type=" + resolvedType + " args=" + service.getExtras()); 10765 10766 if (caller != null) { 10767 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10768 if (callerApp == null) { 10769 throw new SecurityException( 10770 "Unable to find app for caller " + caller 10771 + " (pid=" + Binder.getCallingPid() 10772 + ") when starting service " + service); 10773 } 10774 } 10775 10776 ServiceLookupResult res = 10777 retrieveServiceLocked(service, resolvedType, 10778 callingPid, callingUid); 10779 if (res == null) { 10780 return null; 10781 } 10782 if (res.record == null) { 10783 return new ComponentName("!", res.permission != null 10784 ? res.permission : "private to package"); 10785 } 10786 ServiceRecord r = res.record; 10787 if (unscheduleServiceRestartLocked(r)) { 10788 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: " 10789 + r.shortName); 10790 } 10791 r.startRequested = true; 10792 r.callStart = false; 10793 r.lastStartId++; 10794 if (r.lastStartId < 1) { 10795 r.lastStartId = 1; 10796 } 10797 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); 10798 r.lastActivity = SystemClock.uptimeMillis(); 10799 synchronized (r.stats.getBatteryStats()) { 10800 r.stats.startRunningLocked(); 10801 } 10802 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 10803 return new ComponentName("!", "Service process is bad"); 10804 } 10805 return r.name; 10806 } 10807 } 10808 startService(IApplicationThread caller, Intent service, String resolvedType)10809 public ComponentName startService(IApplicationThread caller, Intent service, 10810 String resolvedType) { 10811 // Refuse possible leaked file descriptors 10812 if (service != null && service.hasFileDescriptors() == true) { 10813 throw new IllegalArgumentException("File descriptors passed in Intent"); 10814 } 10815 10816 synchronized(this) { 10817 final int callingPid = Binder.getCallingPid(); 10818 final int callingUid = Binder.getCallingUid(); 10819 final long origId = Binder.clearCallingIdentity(); 10820 ComponentName res = startServiceLocked(caller, service, 10821 resolvedType, callingPid, callingUid); 10822 Binder.restoreCallingIdentity(origId); 10823 return res; 10824 } 10825 } 10826 startServiceInPackage(int uid, Intent service, String resolvedType)10827 ComponentName startServiceInPackage(int uid, 10828 Intent service, String resolvedType) { 10829 synchronized(this) { 10830 final long origId = Binder.clearCallingIdentity(); 10831 ComponentName res = startServiceLocked(null, service, 10832 resolvedType, -1, uid); 10833 Binder.restoreCallingIdentity(origId); 10834 return res; 10835 } 10836 } 10837 stopService(IApplicationThread caller, Intent service, String resolvedType)10838 public int stopService(IApplicationThread caller, Intent service, 10839 String resolvedType) { 10840 // Refuse possible leaked file descriptors 10841 if (service != null && service.hasFileDescriptors() == true) { 10842 throw new IllegalArgumentException("File descriptors passed in Intent"); 10843 } 10844 10845 synchronized(this) { 10846 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service 10847 + " type=" + resolvedType); 10848 10849 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10850 if (caller != null && callerApp == null) { 10851 throw new SecurityException( 10852 "Unable to find app for caller " + caller 10853 + " (pid=" + Binder.getCallingPid() 10854 + ") when stopping service " + service); 10855 } 10856 10857 // If this service is active, make sure it is stopped. 10858 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10859 if (r != null) { 10860 if (r.record != null) { 10861 synchronized (r.record.stats.getBatteryStats()) { 10862 r.record.stats.stopRunningLocked(); 10863 } 10864 r.record.startRequested = false; 10865 r.record.callStart = false; 10866 final long origId = Binder.clearCallingIdentity(); 10867 bringDownServiceLocked(r.record, false); 10868 Binder.restoreCallingIdentity(origId); 10869 return 1; 10870 } 10871 return -1; 10872 } 10873 } 10874 10875 return 0; 10876 } 10877 peekService(Intent service, String resolvedType)10878 public IBinder peekService(Intent service, String resolvedType) { 10879 // Refuse possible leaked file descriptors 10880 if (service != null && service.hasFileDescriptors() == true) { 10881 throw new IllegalArgumentException("File descriptors passed in Intent"); 10882 } 10883 10884 IBinder ret = null; 10885 10886 synchronized(this) { 10887 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10888 10889 if (r != null) { 10890 // r.record is null if findServiceLocked() failed the caller permission check 10891 if (r.record == null) { 10892 throw new SecurityException( 10893 "Permission Denial: Accessing service " + r.record.name 10894 + " from pid=" + Binder.getCallingPid() 10895 + ", uid=" + Binder.getCallingUid() 10896 + " requires " + r.permission); 10897 } 10898 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 10899 if (ib != null) { 10900 ret = ib.binder; 10901 } 10902 } 10903 } 10904 10905 return ret; 10906 } 10907 stopServiceToken(ComponentName className, IBinder token, int startId)10908 public boolean stopServiceToken(ComponentName className, IBinder token, 10909 int startId) { 10910 synchronized(this) { 10911 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className 10912 + " " + token + " startId=" + startId); 10913 ServiceRecord r = findServiceLocked(className, token); 10914 if (r != null) { 10915 if (startId >= 0) { 10916 // Asked to only stop if done with all work. Note that 10917 // to avoid leaks, we will take this as dropping all 10918 // start items up to and including this one. 10919 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 10920 if (si != null) { 10921 while (r.deliveredStarts.size() > 0) { 10922 if (r.deliveredStarts.remove(0) == si) { 10923 break; 10924 } 10925 } 10926 } 10927 10928 if (r.lastStartId != startId) { 10929 return false; 10930 } 10931 10932 if (r.deliveredStarts.size() > 0) { 10933 Log.w(TAG, "stopServiceToken startId " + startId 10934 + " is last, but have " + r.deliveredStarts.size() 10935 + " remaining args"); 10936 } 10937 } 10938 10939 synchronized (r.stats.getBatteryStats()) { 10940 r.stats.stopRunningLocked(); 10941 r.startRequested = false; 10942 r.callStart = false; 10943 } 10944 final long origId = Binder.clearCallingIdentity(); 10945 bringDownServiceLocked(r, false); 10946 Binder.restoreCallingIdentity(origId); 10947 return true; 10948 } 10949 } 10950 return false; 10951 } 10952 setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)10953 public void setServiceForeground(ComponentName className, IBinder token, 10954 int id, Notification notification, boolean removeNotification) { 10955 final long origId = Binder.clearCallingIdentity(); 10956 try { 10957 synchronized(this) { 10958 ServiceRecord r = findServiceLocked(className, token); 10959 if (r != null) { 10960 if (id != 0) { 10961 if (notification == null) { 10962 throw new IllegalArgumentException("null notification"); 10963 } 10964 if (r.foregroundId != id) { 10965 r.cancelNotification(); 10966 r.foregroundId = id; 10967 } 10968 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 10969 r.foregroundNoti = notification; 10970 r.isForeground = true; 10971 r.postNotification(); 10972 if (r.app != null) { 10973 updateServiceForegroundLocked(r.app, true); 10974 } 10975 } else { 10976 if (r.isForeground) { 10977 r.isForeground = false; 10978 if (r.app != null) { 10979 updateServiceForegroundLocked(r.app, true); 10980 } 10981 } 10982 if (removeNotification) { 10983 r.cancelNotification(); 10984 r.foregroundId = 0; 10985 r.foregroundNoti = null; 10986 } 10987 } 10988 } 10989 } 10990 } finally { 10991 Binder.restoreCallingIdentity(origId); 10992 } 10993 } 10994 updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj)10995 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 10996 boolean anyForeground = false; 10997 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 10998 if (sr.isForeground) { 10999 anyForeground = true; 11000 break; 11001 } 11002 } 11003 if (anyForeground != proc.foregroundServices) { 11004 proc.foregroundServices = anyForeground; 11005 if (oomAdj) { 11006 updateOomAdjLocked(); 11007 } 11008 } 11009 } 11010 bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags)11011 public int bindService(IApplicationThread caller, IBinder token, 11012 Intent service, String resolvedType, 11013 IServiceConnection connection, int flags) { 11014 // Refuse possible leaked file descriptors 11015 if (service != null && service.hasFileDescriptors() == true) { 11016 throw new IllegalArgumentException("File descriptors passed in Intent"); 11017 } 11018 11019 synchronized(this) { 11020 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service 11021 + " type=" + resolvedType + " conn=" + connection.asBinder() 11022 + " flags=0x" + Integer.toHexString(flags)); 11023 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11024 if (callerApp == null) { 11025 throw new SecurityException( 11026 "Unable to find app for caller " + caller 11027 + " (pid=" + Binder.getCallingPid() 11028 + ") when binding service " + service); 11029 } 11030 11031 HistoryRecord activity = null; 11032 if (token != null) { 11033 int aindex = indexOfTokenLocked(token); 11034 if (aindex < 0) { 11035 Log.w(TAG, "Binding with unknown activity: " + token); 11036 return 0; 11037 } 11038 activity = (HistoryRecord)mHistory.get(aindex); 11039 } 11040 11041 int clientLabel = 0; 11042 PendingIntent clientIntent = null; 11043 11044 if (callerApp.info.uid == Process.SYSTEM_UID) { 11045 // Hacky kind of thing -- allow system stuff to tell us 11046 // what they are, so we can report this elsewhere for 11047 // others to know why certain services are running. 11048 try { 11049 clientIntent = (PendingIntent)service.getParcelableExtra( 11050 Intent.EXTRA_CLIENT_INTENT); 11051 } catch (RuntimeException e) { 11052 } 11053 if (clientIntent != null) { 11054 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11055 if (clientLabel != 0) { 11056 // There are no useful extras in the intent, trash them. 11057 // System code calling with this stuff just needs to know 11058 // this will happen. 11059 service = service.cloneFilter(); 11060 } 11061 } 11062 } 11063 11064 ServiceLookupResult res = 11065 retrieveServiceLocked(service, resolvedType, 11066 Binder.getCallingPid(), Binder.getCallingUid()); 11067 if (res == null) { 11068 return 0; 11069 } 11070 if (res.record == null) { 11071 return -1; 11072 } 11073 ServiceRecord s = res.record; 11074 11075 final long origId = Binder.clearCallingIdentity(); 11076 11077 if (unscheduleServiceRestartLocked(s)) { 11078 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11079 + s.shortName); 11080 } 11081 11082 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11083 ConnectionRecord c = new ConnectionRecord(b, activity, 11084 connection, flags, clientLabel, clientIntent); 11085 11086 IBinder binder = connection.asBinder(); 11087 s.connections.put(binder, c); 11088 b.connections.add(c); 11089 if (activity != null) { 11090 if (activity.connections == null) { 11091 activity.connections = new HashSet<ConnectionRecord>(); 11092 } 11093 activity.connections.add(c); 11094 } 11095 b.client.connections.add(c); 11096 mServiceConnections.put(binder, c); 11097 11098 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11099 s.lastActivity = SystemClock.uptimeMillis(); 11100 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11101 return 0; 11102 } 11103 } 11104 11105 if (s.app != null) { 11106 // This could have made the service more important. 11107 updateOomAdjLocked(s.app); 11108 } 11109 11110 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b 11111 + ": received=" + b.intent.received 11112 + " apps=" + b.intent.apps.size() 11113 + " doRebind=" + b.intent.doRebind); 11114 11115 if (s.app != null && b.intent.received) { 11116 // Service is already running, so we can immediately 11117 // publish the connection. 11118 try { 11119 c.conn.connected(s.name, b.intent.binder); 11120 } catch (Exception e) { 11121 Log.w(TAG, "Failure sending service " + s.shortName 11122 + " to connection " + c.conn.asBinder() 11123 + " (in " + c.binding.client.processName + ")", e); 11124 } 11125 11126 // If this is the first app connected back to this binding, 11127 // and the service had previously asked to be told when 11128 // rebound, then do so. 11129 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11130 requestServiceBindingLocked(s, b.intent, true); 11131 } 11132 } else if (!b.intent.requested) { 11133 requestServiceBindingLocked(s, b.intent, false); 11134 } 11135 11136 Binder.restoreCallingIdentity(origId); 11137 } 11138 11139 return 1; 11140 } 11141 removeConnectionLocked( ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct)11142 private void removeConnectionLocked( 11143 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 11144 IBinder binder = c.conn.asBinder(); 11145 AppBindRecord b = c.binding; 11146 ServiceRecord s = b.service; 11147 s.connections.remove(binder); 11148 b.connections.remove(c); 11149 if (c.activity != null && c.activity != skipAct) { 11150 if (c.activity.connections != null) { 11151 c.activity.connections.remove(c); 11152 } 11153 } 11154 if (b.client != skipApp) { 11155 b.client.connections.remove(c); 11156 } 11157 mServiceConnections.remove(binder); 11158 11159 if (b.connections.size() == 0) { 11160 b.intent.apps.remove(b.client); 11161 } 11162 11163 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent 11164 + ": shouldUnbind=" + b.intent.hasBound); 11165 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11166 && b.intent.hasBound) { 11167 try { 11168 bumpServiceExecutingLocked(s); 11169 updateOomAdjLocked(s.app); 11170 b.intent.hasBound = false; 11171 // Assume the client doesn't want to know about a rebind; 11172 // we will deal with that later if it asks for one. 11173 b.intent.doRebind = false; 11174 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11175 } catch (Exception e) { 11176 Log.w(TAG, "Exception when unbinding service " + s.shortName, e); 11177 serviceDoneExecutingLocked(s, true); 11178 } 11179 } 11180 11181 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11182 bringDownServiceLocked(s, false); 11183 } 11184 } 11185 unbindService(IServiceConnection connection)11186 public boolean unbindService(IServiceConnection connection) { 11187 synchronized (this) { 11188 IBinder binder = connection.asBinder(); 11189 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder); 11190 ConnectionRecord r = mServiceConnections.get(binder); 11191 if (r == null) { 11192 Log.w(TAG, "Unbind failed: could not find connection for " 11193 + connection.asBinder()); 11194 return false; 11195 } 11196 11197 final long origId = Binder.clearCallingIdentity(); 11198 11199 removeConnectionLocked(r, null, null); 11200 11201 if (r.binding.service.app != null) { 11202 // This could have made the service less important. 11203 updateOomAdjLocked(r.binding.service.app); 11204 } 11205 11206 Binder.restoreCallingIdentity(origId); 11207 } 11208 11209 return true; 11210 } 11211 publishService(IBinder token, Intent intent, IBinder service)11212 public void publishService(IBinder token, Intent intent, IBinder service) { 11213 // Refuse possible leaked file descriptors 11214 if (intent != null && intent.hasFileDescriptors() == true) { 11215 throw new IllegalArgumentException("File descriptors passed in Intent"); 11216 } 11217 11218 synchronized(this) { 11219 if (!(token instanceof ServiceRecord)) { 11220 throw new IllegalArgumentException("Invalid service token"); 11221 } 11222 ServiceRecord r = (ServiceRecord)token; 11223 11224 final long origId = Binder.clearCallingIdentity(); 11225 11226 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name 11227 + " " + intent + ": " + service); 11228 if (r != null) { 11229 Intent.FilterComparison filter 11230 = new Intent.FilterComparison(intent); 11231 IntentBindRecord b = r.bindings.get(filter); 11232 if (b != null && !b.received) { 11233 b.binder = service; 11234 b.requested = true; 11235 b.received = true; 11236 if (r.connections.size() > 0) { 11237 Iterator<ConnectionRecord> it 11238 = r.connections.values().iterator(); 11239 while (it.hasNext()) { 11240 ConnectionRecord c = it.next(); 11241 if (!filter.equals(c.binding.intent.intent)) { 11242 if (DEBUG_SERVICE) Log.v( 11243 TAG, "Not publishing to: " + c); 11244 if (DEBUG_SERVICE) Log.v( 11245 TAG, "Bound intent: " + c.binding.intent.intent); 11246 if (DEBUG_SERVICE) Log.v( 11247 TAG, "Published intent: " + intent); 11248 continue; 11249 } 11250 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c); 11251 try { 11252 c.conn.connected(r.name, service); 11253 } catch (Exception e) { 11254 Log.w(TAG, "Failure sending service " + r.name + 11255 " to connection " + c.conn.asBinder() + 11256 " (in " + c.binding.client.processName + ")", e); 11257 } 11258 } 11259 } 11260 } 11261 11262 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11263 11264 Binder.restoreCallingIdentity(origId); 11265 } 11266 } 11267 } 11268 unbindFinished(IBinder token, Intent intent, boolean doRebind)11269 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11270 // Refuse possible leaked file descriptors 11271 if (intent != null && intent.hasFileDescriptors() == true) { 11272 throw new IllegalArgumentException("File descriptors passed in Intent"); 11273 } 11274 11275 synchronized(this) { 11276 if (!(token instanceof ServiceRecord)) { 11277 throw new IllegalArgumentException("Invalid service token"); 11278 } 11279 ServiceRecord r = (ServiceRecord)token; 11280 11281 final long origId = Binder.clearCallingIdentity(); 11282 11283 if (r != null) { 11284 Intent.FilterComparison filter 11285 = new Intent.FilterComparison(intent); 11286 IntentBindRecord b = r.bindings.get(filter); 11287 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r 11288 + " at " + b + ": apps=" 11289 + (b != null ? b.apps.size() : 0)); 11290 if (b != null) { 11291 if (b.apps.size() > 0) { 11292 // Applications have already bound since the last 11293 // unbind, so just rebind right here. 11294 requestServiceBindingLocked(r, b, true); 11295 } else { 11296 // Note to tell the service the next time there is 11297 // a new client. 11298 b.doRebind = true; 11299 } 11300 } 11301 11302 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11303 11304 Binder.restoreCallingIdentity(origId); 11305 } 11306 } 11307 } 11308 serviceDoneExecuting(IBinder token, int type, int startId, int res)11309 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11310 synchronized(this) { 11311 if (!(token instanceof ServiceRecord)) { 11312 throw new IllegalArgumentException("Invalid service token"); 11313 } 11314 ServiceRecord r = (ServiceRecord)token; 11315 boolean inStopping = mStoppingServices.contains(token); 11316 if (r != null) { 11317 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name 11318 + ": nesting=" + r.executeNesting 11319 + ", inStopping=" + inStopping); 11320 if (r != token) { 11321 Log.w(TAG, "Done executing service " + r.name 11322 + " with incorrect token: given " + token 11323 + ", expected " + r); 11324 return; 11325 } 11326 11327 if (type == 1) { 11328 // This is a call from a service start... take care of 11329 // book-keeping. 11330 r.callStart = true; 11331 switch (res) { 11332 case Service.START_STICKY_COMPATIBILITY: 11333 case Service.START_STICKY: { 11334 // We are done with the associated start arguments. 11335 r.findDeliveredStart(startId, true); 11336 // Don't stop if killed. 11337 r.stopIfKilled = false; 11338 break; 11339 } 11340 case Service.START_NOT_STICKY: { 11341 // We are done with the associated start arguments. 11342 r.findDeliveredStart(startId, true); 11343 if (r.lastStartId == startId) { 11344 // There is no more work, and this service 11345 // doesn't want to hang around if killed. 11346 r.stopIfKilled = true; 11347 } 11348 break; 11349 } 11350 case Service.START_REDELIVER_INTENT: { 11351 // We'll keep this item until they explicitly 11352 // call stop for it, but keep track of the fact 11353 // that it was delivered. 11354 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11355 if (si != null) { 11356 si.deliveryCount = 0; 11357 si.doneExecutingCount++; 11358 // Don't stop if killed. 11359 r.stopIfKilled = true; 11360 } 11361 break; 11362 } 11363 default: 11364 throw new IllegalArgumentException( 11365 "Unknown service start result: " + res); 11366 } 11367 if (res == Service.START_STICKY_COMPATIBILITY) { 11368 r.callStart = false; 11369 } 11370 } 11371 11372 final long origId = Binder.clearCallingIdentity(); 11373 serviceDoneExecutingLocked(r, inStopping); 11374 Binder.restoreCallingIdentity(origId); 11375 } else { 11376 Log.w(TAG, "Done executing unknown service " + r.name 11377 + " with token " + token); 11378 } 11379 } 11380 } 11381 serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping)11382 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11383 r.executeNesting--; 11384 if (r.executeNesting <= 0 && r.app != null) { 11385 r.app.executingServices.remove(r); 11386 if (r.app.executingServices.size() == 0) { 11387 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11388 } 11389 if (inStopping) { 11390 mStoppingServices.remove(r); 11391 } 11392 updateOomAdjLocked(r.app); 11393 } 11394 } 11395 serviceTimeout(ProcessRecord proc)11396 void serviceTimeout(ProcessRecord proc) { 11397 synchronized(this) { 11398 if (proc.executingServices.size() == 0 || proc.thread == null) { 11399 return; 11400 } 11401 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11402 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11403 ServiceRecord timeout = null; 11404 long nextTime = 0; 11405 while (it.hasNext()) { 11406 ServiceRecord sr = it.next(); 11407 if (sr.executingStart < maxTime) { 11408 timeout = sr; 11409 break; 11410 } 11411 if (sr.executingStart > nextTime) { 11412 nextTime = sr.executingStart; 11413 } 11414 } 11415 if (timeout != null && mLRUProcesses.contains(proc)) { 11416 Log.w(TAG, "Timeout executing service: " + timeout); 11417 appNotRespondingLocked(proc, null, null, "Executing service " 11418 + timeout.name); 11419 } else { 11420 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11421 msg.obj = proc; 11422 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11423 } 11424 } 11425 } 11426 11427 // ========================================================= 11428 // BACKUP AND RESTORE 11429 // ========================================================= 11430 11431 // Cause the target app to be launched if necessary and its backup agent 11432 // instantiated. The backup agent will invoke backupAgentCreated() on the 11433 // activity manager to announce its creation. bindBackupAgent(ApplicationInfo app, int backupMode)11434 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11435 if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11436 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11437 11438 synchronized(this) { 11439 // !!! TODO: currently no check here that we're already bound 11440 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11441 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11442 synchronized (stats) { 11443 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11444 } 11445 11446 BackupRecord r = new BackupRecord(ss, app, backupMode); 11447 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 11448 // startProcessLocked() returns existing proc's record if it's already running 11449 ProcessRecord proc = startProcessLocked(app.processName, app, 11450 false, 0, "backup", hostingName, false); 11451 if (proc == null) { 11452 Log.e(TAG, "Unable to start backup agent process " + r); 11453 return false; 11454 } 11455 11456 r.app = proc; 11457 mBackupTarget = r; 11458 mBackupAppName = app.packageName; 11459 11460 // Try not to kill the process during backup 11461 updateOomAdjLocked(proc); 11462 11463 // If the process is already attached, schedule the creation of the backup agent now. 11464 // If it is not yet live, this will be done when it attaches to the framework. 11465 if (proc.thread != null) { 11466 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc); 11467 try { 11468 proc.thread.scheduleCreateBackupAgent(app, backupMode); 11469 } catch (RemoteException e) { 11470 // Will time out on the backup manager side 11471 } 11472 } else { 11473 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach"); 11474 } 11475 // Invariants: at this point, the target app process exists and the application 11476 // is either already running or in the process of coming up. mBackupTarget and 11477 // mBackupAppName describe the app, so that when it binds back to the AM we 11478 // know that it's scheduled for a backup-agent operation. 11479 } 11480 11481 return true; 11482 } 11483 11484 // A backup agent has just come up backupAgentCreated(String agentPackageName, IBinder agent)11485 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11486 if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName 11487 + " = " + agent); 11488 11489 synchronized(this) { 11490 if (!agentPackageName.equals(mBackupAppName)) { 11491 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11492 return; 11493 } 11494 11495 long oldIdent = Binder.clearCallingIdentity(); 11496 try { 11497 IBackupManager bm = IBackupManager.Stub.asInterface( 11498 ServiceManager.getService(Context.BACKUP_SERVICE)); 11499 bm.agentConnected(agentPackageName, agent); 11500 } catch (RemoteException e) { 11501 // can't happen; the backup manager service is local 11502 } catch (Exception e) { 11503 Log.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11504 e.printStackTrace(); 11505 } finally { 11506 Binder.restoreCallingIdentity(oldIdent); 11507 } 11508 } 11509 } 11510 11511 // done with this agent unbindBackupAgent(ApplicationInfo appInfo)11512 public void unbindBackupAgent(ApplicationInfo appInfo) { 11513 if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo); 11514 if (appInfo == null) { 11515 Log.w(TAG, "unbind backup agent for null app"); 11516 return; 11517 } 11518 11519 synchronized(this) { 11520 if (mBackupAppName == null) { 11521 Log.w(TAG, "Unbinding backup agent with no active backup"); 11522 return; 11523 } 11524 11525 if (!mBackupAppName.equals(appInfo.packageName)) { 11526 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11527 return; 11528 } 11529 11530 ProcessRecord proc = mBackupTarget.app; 11531 mBackupTarget = null; 11532 mBackupAppName = null; 11533 11534 // Not backing this app up any more; reset its OOM adjustment 11535 updateOomAdjLocked(proc); 11536 11537 // If the app crashed during backup, 'thread' will be null here 11538 if (proc.thread != null) { 11539 try { 11540 proc.thread.scheduleDestroyBackupAgent(appInfo); 11541 } catch (Exception e) { 11542 Log.e(TAG, "Exception when unbinding backup agent:"); 11543 e.printStackTrace(); 11544 } 11545 } 11546 } 11547 } 11548 // ========================================================= 11549 // BROADCASTS 11550 // ========================================================= 11551 getStickies(String action, IntentFilter filter, List cur)11552 private final List getStickies(String action, IntentFilter filter, 11553 List cur) { 11554 final ContentResolver resolver = mContext.getContentResolver(); 11555 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11556 if (list == null) { 11557 return cur; 11558 } 11559 int N = list.size(); 11560 for (int i=0; i<N; i++) { 11561 Intent intent = list.get(i); 11562 if (filter.match(resolver, intent, true, TAG) >= 0) { 11563 if (cur == null) { 11564 cur = new ArrayList<Intent>(); 11565 } 11566 cur.add(intent); 11567 } 11568 } 11569 return cur; 11570 } 11571 scheduleBroadcastsLocked()11572 private final void scheduleBroadcastsLocked() { 11573 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current=" 11574 + mBroadcastsScheduled); 11575 11576 if (mBroadcastsScheduled) { 11577 return; 11578 } 11579 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11580 mBroadcastsScheduled = true; 11581 } 11582 registerReceiver(IApplicationThread caller, IIntentReceiver receiver, IntentFilter filter, String permission)11583 public Intent registerReceiver(IApplicationThread caller, 11584 IIntentReceiver receiver, IntentFilter filter, String permission) { 11585 synchronized(this) { 11586 ProcessRecord callerApp = null; 11587 if (caller != null) { 11588 callerApp = getRecordForAppLocked(caller); 11589 if (callerApp == null) { 11590 throw new SecurityException( 11591 "Unable to find app for caller " + caller 11592 + " (pid=" + Binder.getCallingPid() 11593 + ") when registering receiver " + receiver); 11594 } 11595 } 11596 11597 List allSticky = null; 11598 11599 // Look for any matching sticky broadcasts... 11600 Iterator actions = filter.actionsIterator(); 11601 if (actions != null) { 11602 while (actions.hasNext()) { 11603 String action = (String)actions.next(); 11604 allSticky = getStickies(action, filter, allSticky); 11605 } 11606 } else { 11607 allSticky = getStickies(null, filter, allSticky); 11608 } 11609 11610 // The first sticky in the list is returned directly back to 11611 // the client. 11612 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11613 11614 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter 11615 + ": " + sticky); 11616 11617 if (receiver == null) { 11618 return sticky; 11619 } 11620 11621 ReceiverList rl 11622 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11623 if (rl == null) { 11624 rl = new ReceiverList(this, callerApp, 11625 Binder.getCallingPid(), 11626 Binder.getCallingUid(), receiver); 11627 if (rl.app != null) { 11628 rl.app.receivers.add(rl); 11629 } else { 11630 try { 11631 receiver.asBinder().linkToDeath(rl, 0); 11632 } catch (RemoteException e) { 11633 return sticky; 11634 } 11635 rl.linkedToDeath = true; 11636 } 11637 mRegisteredReceivers.put(receiver.asBinder(), rl); 11638 } 11639 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 11640 rl.add(bf); 11641 if (!bf.debugCheck()) { 11642 Log.w(TAG, "==> For Dynamic broadast"); 11643 } 11644 mReceiverResolver.addFilter(bf); 11645 11646 // Enqueue broadcasts for all existing stickies that match 11647 // this filter. 11648 if (allSticky != null) { 11649 ArrayList receivers = new ArrayList(); 11650 receivers.add(bf); 11651 11652 int N = allSticky.size(); 11653 for (int i=0; i<N; i++) { 11654 Intent intent = (Intent)allSticky.get(i); 11655 BroadcastRecord r = new BroadcastRecord(intent, null, 11656 null, -1, -1, null, receivers, null, 0, null, null, 11657 false, true, true); 11658 if (mParallelBroadcasts.size() == 0) { 11659 scheduleBroadcastsLocked(); 11660 } 11661 mParallelBroadcasts.add(r); 11662 } 11663 } 11664 11665 return sticky; 11666 } 11667 } 11668 unregisterReceiver(IIntentReceiver receiver)11669 public void unregisterReceiver(IIntentReceiver receiver) { 11670 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver); 11671 11672 boolean doNext = false; 11673 11674 synchronized(this) { 11675 ReceiverList rl 11676 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11677 if (rl != null) { 11678 if (rl.curBroadcast != null) { 11679 BroadcastRecord r = rl.curBroadcast; 11680 doNext = finishReceiverLocked( 11681 receiver.asBinder(), r.resultCode, r.resultData, 11682 r.resultExtras, r.resultAbort, true); 11683 } 11684 11685 if (rl.app != null) { 11686 rl.app.receivers.remove(rl); 11687 } 11688 removeReceiverLocked(rl); 11689 if (rl.linkedToDeath) { 11690 rl.linkedToDeath = false; 11691 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11692 } 11693 } 11694 } 11695 11696 if (!doNext) { 11697 return; 11698 } 11699 11700 final long origId = Binder.clearCallingIdentity(); 11701 processNextBroadcast(false); 11702 trimApplications(); 11703 Binder.restoreCallingIdentity(origId); 11704 } 11705 removeReceiverLocked(ReceiverList rl)11706 void removeReceiverLocked(ReceiverList rl) { 11707 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11708 int N = rl.size(); 11709 for (int i=0; i<N; i++) { 11710 mReceiverResolver.removeFilter(rl.get(i)); 11711 } 11712 } 11713 broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean ordered, boolean sticky, int callingPid, int callingUid)11714 private final int broadcastIntentLocked(ProcessRecord callerApp, 11715 String callerPackage, Intent intent, String resolvedType, 11716 IIntentReceiver resultTo, int resultCode, String resultData, 11717 Bundle map, String requiredPermission, 11718 boolean ordered, boolean sticky, int callingPid, int callingUid) { 11719 intent = new Intent(intent); 11720 11721 if (DEBUG_BROADCAST_LIGHT) Log.v( 11722 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11723 + " ordered=" + ordered); 11724 if ((resultTo != null) && !ordered) { 11725 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11726 } 11727 11728 // Handle special intents: if this broadcast is from the package 11729 // manager about a package being removed, we need to remove all of 11730 // its activities from the history stack. 11731 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 11732 intent.getAction()); 11733 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11734 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11735 || uidRemoved) { 11736 if (checkComponentPermission( 11737 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11738 callingPid, callingUid, -1) 11739 == PackageManager.PERMISSION_GRANTED) { 11740 if (uidRemoved) { 11741 final Bundle intentExtras = intent.getExtras(); 11742 final int uid = intentExtras != null 11743 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11744 if (uid >= 0) { 11745 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11746 synchronized (bs) { 11747 bs.removeUidStatsLocked(uid); 11748 } 11749 } 11750 } else { 11751 Uri data = intent.getData(); 11752 String ssp; 11753 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11754 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11755 uninstallPackageLocked(ssp, 11756 intent.getIntExtra(Intent.EXTRA_UID, -1), false); 11757 AttributeCache ac = AttributeCache.instance(); 11758 if (ac != null) { 11759 ac.removePackage(ssp); 11760 } 11761 } 11762 } 11763 } 11764 } else { 11765 String msg = "Permission Denial: " + intent.getAction() 11766 + " broadcast from " + callerPackage + " (pid=" + callingPid 11767 + ", uid=" + callingUid + ")" 11768 + " requires " 11769 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11770 Log.w(TAG, msg); 11771 throw new SecurityException(msg); 11772 } 11773 } 11774 11775 /* 11776 * If this is the time zone changed action, queue up a message that will reset the timezone 11777 * of all currently running processes. This message will get queued up before the broadcast 11778 * happens. 11779 */ 11780 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11781 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11782 } 11783 11784 /* 11785 * Prevent non-system code (defined here to be non-persistent 11786 * processes) from sending protected broadcasts. 11787 */ 11788 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11789 || callingUid == Process.SHELL_UID || callingUid == 0) { 11790 // Always okay. 11791 } else if (callerApp == null || !callerApp.persistent) { 11792 try { 11793 if (ActivityThread.getPackageManager().isProtectedBroadcast( 11794 intent.getAction())) { 11795 String msg = "Permission Denial: not allowed to send broadcast " 11796 + intent.getAction() + " from pid=" 11797 + callingPid + ", uid=" + callingUid; 11798 Log.w(TAG, msg); 11799 throw new SecurityException(msg); 11800 } 11801 } catch (RemoteException e) { 11802 Log.w(TAG, "Remote exception", e); 11803 return BROADCAST_SUCCESS; 11804 } 11805 } 11806 11807 // Add to the sticky list if requested. 11808 if (sticky) { 11809 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11810 callingPid, callingUid) 11811 != PackageManager.PERMISSION_GRANTED) { 11812 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11813 + callingPid + ", uid=" + callingUid 11814 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11815 Log.w(TAG, msg); 11816 throw new SecurityException(msg); 11817 } 11818 if (requiredPermission != null) { 11819 Log.w(TAG, "Can't broadcast sticky intent " + intent 11820 + " and enforce permission " + requiredPermission); 11821 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11822 } 11823 if (intent.getComponent() != null) { 11824 throw new SecurityException( 11825 "Sticky broadcasts can't target a specific component"); 11826 } 11827 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11828 if (list == null) { 11829 list = new ArrayList<Intent>(); 11830 mStickyBroadcasts.put(intent.getAction(), list); 11831 } 11832 int N = list.size(); 11833 int i; 11834 for (i=0; i<N; i++) { 11835 if (intent.filterEquals(list.get(i))) { 11836 // This sticky already exists, replace it. 11837 list.set(i, new Intent(intent)); 11838 break; 11839 } 11840 } 11841 if (i >= N) { 11842 list.add(new Intent(intent)); 11843 } 11844 } 11845 11846 // Figure out who all will receive this broadcast. 11847 List receivers = null; 11848 List<BroadcastFilter> registeredReceivers = null; 11849 try { 11850 if (intent.getComponent() != null) { 11851 // Broadcast is going to one specific receiver class... 11852 ActivityInfo ai = ActivityThread.getPackageManager(). 11853 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 11854 if (ai != null) { 11855 receivers = new ArrayList(); 11856 ResolveInfo ri = new ResolveInfo(); 11857 ri.activityInfo = ai; 11858 receivers.add(ri); 11859 } 11860 } else { 11861 // Need to resolve the intent to interested receivers... 11862 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11863 == 0) { 11864 receivers = 11865 ActivityThread.getPackageManager().queryIntentReceivers( 11866 intent, resolvedType, STOCK_PM_FLAGS); 11867 } 11868 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 11869 } 11870 } catch (RemoteException ex) { 11871 // pm is in same process, this will never happen. 11872 } 11873 11874 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11875 if (!ordered && NR > 0) { 11876 // If we are not serializing this broadcast, then send the 11877 // registered receivers separately so they don't wait for the 11878 // components to be launched. 11879 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11880 callerPackage, callingPid, callingUid, requiredPermission, 11881 registeredReceivers, resultTo, resultCode, resultData, map, 11882 ordered, sticky, false); 11883 if (DEBUG_BROADCAST) Log.v( 11884 TAG, "Enqueueing parallel broadcast " + r 11885 + ": prev had " + mParallelBroadcasts.size()); 11886 mParallelBroadcasts.add(r); 11887 scheduleBroadcastsLocked(); 11888 registeredReceivers = null; 11889 NR = 0; 11890 } 11891 11892 // Merge into one list. 11893 int ir = 0; 11894 if (receivers != null) { 11895 // A special case for PACKAGE_ADDED: do not allow the package 11896 // being added to see this broadcast. This prevents them from 11897 // using this as a back door to get run as soon as they are 11898 // installed. Maybe in the future we want to have a special install 11899 // broadcast or such for apps, but we'd like to deliberately make 11900 // this decision. 11901 boolean skip = false; 11902 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11903 skip = true; 11904 } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) { 11905 skip = true; 11906 } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11907 skip = true; 11908 } 11909 String skipPackage = (skip && intent.getData() != null) 11910 ? intent.getData().getSchemeSpecificPart() 11911 : null; 11912 if (skipPackage != null && receivers != null) { 11913 int NT = receivers.size(); 11914 for (int it=0; it<NT; it++) { 11915 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11916 if (curt.activityInfo.packageName.equals(skipPackage)) { 11917 receivers.remove(it); 11918 it--; 11919 NT--; 11920 } 11921 } 11922 } 11923 11924 int NT = receivers != null ? receivers.size() : 0; 11925 int it = 0; 11926 ResolveInfo curt = null; 11927 BroadcastFilter curr = null; 11928 while (it < NT && ir < NR) { 11929 if (curt == null) { 11930 curt = (ResolveInfo)receivers.get(it); 11931 } 11932 if (curr == null) { 11933 curr = registeredReceivers.get(ir); 11934 } 11935 if (curr.getPriority() >= curt.priority) { 11936 // Insert this broadcast record into the final list. 11937 receivers.add(it, curr); 11938 ir++; 11939 curr = null; 11940 it++; 11941 NT++; 11942 } else { 11943 // Skip to the next ResolveInfo in the final list. 11944 it++; 11945 curt = null; 11946 } 11947 } 11948 } 11949 while (ir < NR) { 11950 if (receivers == null) { 11951 receivers = new ArrayList(); 11952 } 11953 receivers.add(registeredReceivers.get(ir)); 11954 ir++; 11955 } 11956 11957 if ((receivers != null && receivers.size() > 0) 11958 || resultTo != null) { 11959 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11960 callerPackage, callingPid, callingUid, requiredPermission, 11961 receivers, resultTo, resultCode, resultData, map, ordered, 11962 sticky, false); 11963 if (DEBUG_BROADCAST) Log.v( 11964 TAG, "Enqueueing ordered broadcast " + r 11965 + ": prev had " + mOrderedBroadcasts.size()); 11966 if (DEBUG_BROADCAST) { 11967 int seq = r.intent.getIntExtra("seq", -1); 11968 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11969 } 11970 mOrderedBroadcasts.add(r); 11971 scheduleBroadcastsLocked(); 11972 } 11973 11974 return BROADCAST_SUCCESS; 11975 } 11976 broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky)11977 public final int broadcastIntent(IApplicationThread caller, 11978 Intent intent, String resolvedType, IIntentReceiver resultTo, 11979 int resultCode, String resultData, Bundle map, 11980 String requiredPermission, boolean serialized, boolean sticky) { 11981 // Refuse possible leaked file descriptors 11982 if (intent != null && intent.hasFileDescriptors() == true) { 11983 throw new IllegalArgumentException("File descriptors passed in Intent"); 11984 } 11985 11986 synchronized(this) { 11987 int flags = intent.getFlags(); 11988 11989 if (!mSystemReady) { 11990 // if the caller really truly claims to know what they're doing, go 11991 // ahead and allow the broadcast without launching any receivers 11992 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11993 intent = new Intent(intent); 11994 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11995 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 11996 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11997 + " before boot completion"); 11998 throw new IllegalStateException("Cannot broadcast before boot completed"); 11999 } 12000 } 12001 12002 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12003 throw new IllegalArgumentException( 12004 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12005 } 12006 12007 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12008 final int callingPid = Binder.getCallingPid(); 12009 final int callingUid = Binder.getCallingUid(); 12010 final long origId = Binder.clearCallingIdentity(); 12011 int res = broadcastIntentLocked(callerApp, 12012 callerApp != null ? callerApp.info.packageName : null, 12013 intent, resolvedType, resultTo, 12014 resultCode, resultData, map, requiredPermission, serialized, 12015 sticky, callingPid, callingUid); 12016 Binder.restoreCallingIdentity(origId); 12017 return res; 12018 } 12019 } 12020 broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky)12021 int broadcastIntentInPackage(String packageName, int uid, 12022 Intent intent, String resolvedType, IIntentReceiver resultTo, 12023 int resultCode, String resultData, Bundle map, 12024 String requiredPermission, boolean serialized, boolean sticky) { 12025 synchronized(this) { 12026 final long origId = Binder.clearCallingIdentity(); 12027 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12028 resultTo, resultCode, resultData, map, requiredPermission, 12029 serialized, sticky, -1, uid); 12030 Binder.restoreCallingIdentity(origId); 12031 return res; 12032 } 12033 } 12034 unbroadcastIntent(IApplicationThread caller, Intent intent)12035 public final void unbroadcastIntent(IApplicationThread caller, 12036 Intent intent) { 12037 // Refuse possible leaked file descriptors 12038 if (intent != null && intent.hasFileDescriptors() == true) { 12039 throw new IllegalArgumentException("File descriptors passed in Intent"); 12040 } 12041 12042 synchronized(this) { 12043 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12044 != PackageManager.PERMISSION_GRANTED) { 12045 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12046 + Binder.getCallingPid() 12047 + ", uid=" + Binder.getCallingUid() 12048 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12049 Log.w(TAG, msg); 12050 throw new SecurityException(msg); 12051 } 12052 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12053 if (list != null) { 12054 int N = list.size(); 12055 int i; 12056 for (i=0; i<N; i++) { 12057 if (intent.filterEquals(list.get(i))) { 12058 list.remove(i); 12059 break; 12060 } 12061 } 12062 } 12063 } 12064 } 12065 finishReceiverLocked(IBinder receiver, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort, boolean explicit)12066 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12067 String resultData, Bundle resultExtras, boolean resultAbort, 12068 boolean explicit) { 12069 if (mOrderedBroadcasts.size() == 0) { 12070 if (explicit) { 12071 Log.w(TAG, "finishReceiver called but no pending broadcasts"); 12072 } 12073 return false; 12074 } 12075 BroadcastRecord r = mOrderedBroadcasts.get(0); 12076 if (r.receiver == null) { 12077 if (explicit) { 12078 Log.w(TAG, "finishReceiver called but none active"); 12079 } 12080 return false; 12081 } 12082 if (r.receiver != receiver) { 12083 Log.w(TAG, "finishReceiver called but active receiver is different"); 12084 return false; 12085 } 12086 int state = r.state; 12087 r.state = r.IDLE; 12088 if (state == r.IDLE) { 12089 if (explicit) { 12090 Log.w(TAG, "finishReceiver called but state is IDLE"); 12091 } 12092 } 12093 r.receiver = null; 12094 r.intent.setComponent(null); 12095 if (r.curApp != null) { 12096 r.curApp.curReceiver = null; 12097 } 12098 if (r.curFilter != null) { 12099 r.curFilter.receiverList.curBroadcast = null; 12100 } 12101 r.curFilter = null; 12102 r.curApp = null; 12103 r.curComponent = null; 12104 r.curReceiver = null; 12105 mPendingBroadcast = null; 12106 12107 r.resultCode = resultCode; 12108 r.resultData = resultData; 12109 r.resultExtras = resultExtras; 12110 r.resultAbort = resultAbort; 12111 12112 // We will process the next receiver right now if this is finishing 12113 // an app receiver (which is always asynchronous) or after we have 12114 // come back from calling a receiver. 12115 return state == BroadcastRecord.APP_RECEIVE 12116 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12117 } 12118 finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)12119 public void finishReceiver(IBinder who, int resultCode, String resultData, 12120 Bundle resultExtras, boolean resultAbort) { 12121 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who); 12122 12123 // Refuse possible leaked file descriptors 12124 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12125 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12126 } 12127 12128 boolean doNext; 12129 12130 final long origId = Binder.clearCallingIdentity(); 12131 12132 synchronized(this) { 12133 doNext = finishReceiverLocked( 12134 who, resultCode, resultData, resultExtras, resultAbort, true); 12135 } 12136 12137 if (doNext) { 12138 processNextBroadcast(false); 12139 } 12140 trimApplications(); 12141 12142 Binder.restoreCallingIdentity(origId); 12143 } 12144 logBroadcastReceiverDiscard(BroadcastRecord r)12145 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 12146 if (r.nextReceiver > 0) { 12147 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12148 if (curReceiver instanceof BroadcastFilter) { 12149 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12150 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER, 12151 System.identityHashCode(r), 12152 r.intent.getAction(), 12153 r.nextReceiver - 1, 12154 System.identityHashCode(bf)); 12155 } else { 12156 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 12157 System.identityHashCode(r), 12158 r.intent.getAction(), 12159 r.nextReceiver - 1, 12160 ((ResolveInfo)curReceiver).toString()); 12161 } 12162 } else { 12163 Log.w(TAG, "Discarding broadcast before first receiver is invoked: " 12164 + r); 12165 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 12166 System.identityHashCode(r), 12167 r.intent.getAction(), 12168 r.nextReceiver, 12169 "NONE"); 12170 } 12171 } 12172 broadcastTimeout()12173 private final void broadcastTimeout() { 12174 synchronized (this) { 12175 if (mOrderedBroadcasts.size() == 0) { 12176 return; 12177 } 12178 long now = SystemClock.uptimeMillis(); 12179 BroadcastRecord r = mOrderedBroadcasts.get(0); 12180 if ((r.receiverTime+BROADCAST_TIMEOUT) > now) { 12181 if (DEBUG_BROADCAST) Log.v(TAG, 12182 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12183 + (r.receiverTime + BROADCAST_TIMEOUT)); 12184 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12185 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12186 return; 12187 } 12188 12189 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 12190 r.receiverTime = now; 12191 r.anrCount++; 12192 12193 // Current receiver has passed its expiration date. 12194 if (r.nextReceiver <= 0) { 12195 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12196 return; 12197 } 12198 12199 ProcessRecord app = null; 12200 12201 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12202 Log.w(TAG, "Receiver during timeout: " + curReceiver); 12203 logBroadcastReceiverDiscard(r); 12204 if (curReceiver instanceof BroadcastFilter) { 12205 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12206 if (bf.receiverList.pid != 0 12207 && bf.receiverList.pid != MY_PID) { 12208 synchronized (this.mPidsSelfLocked) { 12209 app = this.mPidsSelfLocked.get( 12210 bf.receiverList.pid); 12211 } 12212 } 12213 } else { 12214 app = r.curApp; 12215 } 12216 12217 if (app != null) { 12218 appNotRespondingLocked(app, null, null, 12219 "Broadcast of " + r.intent.toString()); 12220 } 12221 12222 if (mPendingBroadcast == r) { 12223 mPendingBroadcast = null; 12224 } 12225 12226 // Move on to the next receiver. 12227 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12228 r.resultExtras, r.resultAbort, true); 12229 scheduleBroadcastsLocked(); 12230 } 12231 } 12232 processCurBroadcastLocked(BroadcastRecord r, ProcessRecord app)12233 private final void processCurBroadcastLocked(BroadcastRecord r, 12234 ProcessRecord app) throws RemoteException { 12235 if (app.thread == null) { 12236 throw new RemoteException(); 12237 } 12238 r.receiver = app.thread.asBinder(); 12239 r.curApp = app; 12240 app.curReceiver = r; 12241 updateLRUListLocked(app, true); 12242 12243 // Tell the application to launch this receiver. 12244 r.intent.setComponent(r.curComponent); 12245 12246 boolean started = false; 12247 try { 12248 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, 12249 "Delivering to component " + r.curComponent 12250 + ": " + r); 12251 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12252 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12253 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12254 started = true; 12255 } finally { 12256 if (!started) { 12257 r.receiver = null; 12258 r.curApp = null; 12259 app.curReceiver = null; 12260 } 12261 } 12262 12263 } 12264 performReceive(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky)12265 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 12266 Intent intent, int resultCode, String data, Bundle extras, 12267 boolean ordered, boolean sticky) throws RemoteException { 12268 if (app != null && app.thread != null) { 12269 // If we have an app thread, do the call through that so it is 12270 // correctly ordered with other one-way calls. 12271 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12272 data, extras, ordered, sticky); 12273 } else { 12274 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12275 } 12276 } 12277 deliverToRegisteredReceiver(BroadcastRecord r, BroadcastFilter filter, boolean ordered)12278 private final void deliverToRegisteredReceiver(BroadcastRecord r, 12279 BroadcastFilter filter, boolean ordered) { 12280 boolean skip = false; 12281 if (filter.requiredPermission != null) { 12282 int perm = checkComponentPermission(filter.requiredPermission, 12283 r.callingPid, r.callingUid, -1); 12284 if (perm != PackageManager.PERMISSION_GRANTED) { 12285 Log.w(TAG, "Permission Denial: broadcasting " 12286 + r.intent.toString() 12287 + " from " + r.callerPackage + " (pid=" 12288 + r.callingPid + ", uid=" + r.callingUid + ")" 12289 + " requires " + filter.requiredPermission 12290 + " due to registered receiver " + filter); 12291 skip = true; 12292 } 12293 } 12294 if (r.requiredPermission != null) { 12295 int perm = checkComponentPermission(r.requiredPermission, 12296 filter.receiverList.pid, filter.receiverList.uid, -1); 12297 if (perm != PackageManager.PERMISSION_GRANTED) { 12298 Log.w(TAG, "Permission Denial: receiving " 12299 + r.intent.toString() 12300 + " to " + filter.receiverList.app 12301 + " (pid=" + filter.receiverList.pid 12302 + ", uid=" + filter.receiverList.uid + ")" 12303 + " requires " + r.requiredPermission 12304 + " due to sender " + r.callerPackage 12305 + " (uid " + r.callingUid + ")"); 12306 skip = true; 12307 } 12308 } 12309 12310 if (!skip) { 12311 // If this is not being sent as an ordered broadcast, then we 12312 // don't want to touch the fields that keep track of the current 12313 // state of ordered broadcasts. 12314 if (ordered) { 12315 r.receiver = filter.receiverList.receiver.asBinder(); 12316 r.curFilter = filter; 12317 filter.receiverList.curBroadcast = r; 12318 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12319 if (filter.receiverList.app != null) { 12320 // Bump hosting application to no longer be in background 12321 // scheduling class. Note that we can't do that if there 12322 // isn't an app... but we can only be in that case for 12323 // things that directly call the IActivityManager API, which 12324 // are already core system stuff so don't matter for this. 12325 r.curApp = filter.receiverList.app; 12326 filter.receiverList.app.curReceiver = r; 12327 updateOomAdjLocked(); 12328 } 12329 } 12330 try { 12331 if (DEBUG_BROADCAST_LIGHT) { 12332 int seq = r.intent.getIntExtra("seq", -1); 12333 Log.i(TAG, "Delivering to " + filter.receiverList.app 12334 + " (seq=" + seq + "): " + r); 12335 } 12336 performReceive(filter.receiverList.app, filter.receiverList.receiver, 12337 new Intent(r.intent), r.resultCode, 12338 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 12339 if (ordered) { 12340 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12341 } 12342 } catch (RemoteException e) { 12343 Log.w(TAG, "Failure sending broadcast " + r.intent, e); 12344 if (ordered) { 12345 r.receiver = null; 12346 r.curFilter = null; 12347 filter.receiverList.curBroadcast = null; 12348 if (filter.receiverList.app != null) { 12349 filter.receiverList.app.curReceiver = null; 12350 } 12351 } 12352 } 12353 } 12354 } 12355 addBroadcastToHistoryLocked(BroadcastRecord r)12356 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 12357 if (r.callingUid < 0) { 12358 // This was from a registerReceiver() call; ignore it. 12359 return; 12360 } 12361 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 12362 MAX_BROADCAST_HISTORY-1); 12363 r.finishTime = SystemClock.uptimeMillis(); 12364 mBroadcastHistory[0] = r; 12365 } 12366 processNextBroadcast(boolean fromMsg)12367 private final void processNextBroadcast(boolean fromMsg) { 12368 synchronized(this) { 12369 BroadcastRecord r; 12370 12371 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: " 12372 + mParallelBroadcasts.size() + " broadcasts, " 12373 + mOrderedBroadcasts.size() + " serialized broadcasts"); 12374 12375 updateCpuStats(); 12376 12377 if (fromMsg) { 12378 mBroadcastsScheduled = false; 12379 } 12380 12381 // First, deliver any non-serialized broadcasts right away. 12382 while (mParallelBroadcasts.size() > 0) { 12383 r = mParallelBroadcasts.remove(0); 12384 r.dispatchTime = SystemClock.uptimeMillis(); 12385 final int N = r.receivers.size(); 12386 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast " 12387 + r); 12388 for (int i=0; i<N; i++) { 12389 Object target = r.receivers.get(i); 12390 if (DEBUG_BROADCAST) Log.v(TAG, 12391 "Delivering non-serialized to registered " 12392 + target + ": " + r); 12393 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 12394 } 12395 addBroadcastToHistoryLocked(r); 12396 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast " 12397 + r); 12398 } 12399 12400 // Now take care of the next serialized one... 12401 12402 // If we are waiting for a process to come up to handle the next 12403 // broadcast, then do nothing at this point. Just in case, we 12404 // check that the process we're waiting for still exists. 12405 if (mPendingBroadcast != null) { 12406 if (DEBUG_BROADCAST_LIGHT) { 12407 Log.v(TAG, "processNextBroadcast: waiting for " 12408 + mPendingBroadcast.curApp); 12409 } 12410 12411 boolean isDead; 12412 synchronized (mPidsSelfLocked) { 12413 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12414 } 12415 if (!isDead) { 12416 // It's still alive, so keep waiting 12417 return; 12418 } else { 12419 Log.w(TAG, "pending app " + mPendingBroadcast.curApp 12420 + " died before responding to broadcast"); 12421 mPendingBroadcast = null; 12422 } 12423 } 12424 12425 boolean looped = false; 12426 12427 do { 12428 if (mOrderedBroadcasts.size() == 0) { 12429 // No more broadcasts pending, so all done! 12430 scheduleAppGcsLocked(); 12431 if (looped) { 12432 // If we had finished the last ordered broadcast, then 12433 // make sure all processes have correct oom and sched 12434 // adjustments. 12435 updateOomAdjLocked(); 12436 } 12437 return; 12438 } 12439 r = mOrderedBroadcasts.get(0); 12440 boolean forceReceive = false; 12441 12442 // Ensure that even if something goes awry with the timeout 12443 // detection, we catch "hung" broadcasts here, discard them, 12444 // and continue to make progress. 12445 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12446 long now = SystemClock.uptimeMillis(); 12447 if (r.dispatchTime > 0) { 12448 if ((numReceivers > 0) && 12449 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12450 Log.w(TAG, "Hung broadcast discarded after timeout failure:" 12451 + " now=" + now 12452 + " dispatchTime=" + r.dispatchTime 12453 + " startTime=" + r.receiverTime 12454 + " intent=" + r.intent 12455 + " numReceivers=" + numReceivers 12456 + " nextReceiver=" + r.nextReceiver 12457 + " state=" + r.state); 12458 broadcastTimeout(); // forcibly finish this broadcast 12459 forceReceive = true; 12460 r.state = BroadcastRecord.IDLE; 12461 } 12462 } 12463 12464 if (r.state != BroadcastRecord.IDLE) { 12465 if (DEBUG_BROADCAST) Log.d(TAG, 12466 "processNextBroadcast() called when not idle (state=" 12467 + r.state + ")"); 12468 return; 12469 } 12470 12471 if (r.receivers == null || r.nextReceiver >= numReceivers 12472 || r.resultAbort || forceReceive) { 12473 // No more receivers for this broadcast! Send the final 12474 // result if requested... 12475 if (r.resultTo != null) { 12476 try { 12477 if (DEBUG_BROADCAST) { 12478 int seq = r.intent.getIntExtra("seq", -1); 12479 Log.i(TAG, "Finishing broadcast " + r.intent.getAction() 12480 + " seq=" + seq + " app=" + r.callerApp); 12481 } 12482 performReceive(r.callerApp, r.resultTo, 12483 new Intent(r.intent), r.resultCode, 12484 r.resultData, r.resultExtras, false, false); 12485 } catch (RemoteException e) { 12486 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12487 } 12488 } 12489 12490 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12491 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12492 12493 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast " 12494 + r); 12495 12496 // ... and on to the next... 12497 addBroadcastToHistoryLocked(r); 12498 mOrderedBroadcasts.remove(0); 12499 r = null; 12500 looped = true; 12501 continue; 12502 } 12503 } while (r == null); 12504 12505 // Get the next receiver... 12506 int recIdx = r.nextReceiver++; 12507 12508 // Keep track of when this receiver started, and make sure there 12509 // is a timeout message pending to kill it if need be. 12510 r.receiverTime = SystemClock.uptimeMillis(); 12511 if (recIdx == 0) { 12512 r.dispatchTime = r.receiverTime; 12513 12514 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast " 12515 + r); 12516 if (DEBUG_BROADCAST) Log.v(TAG, 12517 "Submitting BROADCAST_TIMEOUT_MSG for " 12518 + (r.receiverTime + BROADCAST_TIMEOUT)); 12519 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12520 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12521 } 12522 12523 Object nextReceiver = r.receivers.get(recIdx); 12524 if (nextReceiver instanceof BroadcastFilter) { 12525 // Simple case: this is a registered receiver who gets 12526 // a direct call. 12527 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 12528 if (DEBUG_BROADCAST) Log.v(TAG, 12529 "Delivering serialized to registered " 12530 + filter + ": " + r); 12531 deliverToRegisteredReceiver(r, filter, r.ordered); 12532 if (r.receiver == null || !r.ordered) { 12533 // The receiver has already finished, so schedule to 12534 // process the next one. 12535 r.state = BroadcastRecord.IDLE; 12536 scheduleBroadcastsLocked(); 12537 } 12538 return; 12539 } 12540 12541 // Hard case: need to instantiate the receiver, possibly 12542 // starting its application process to host it. 12543 12544 ResolveInfo info = 12545 (ResolveInfo)nextReceiver; 12546 12547 boolean skip = false; 12548 int perm = checkComponentPermission(info.activityInfo.permission, 12549 r.callingPid, r.callingUid, 12550 info.activityInfo.exported 12551 ? -1 : info.activityInfo.applicationInfo.uid); 12552 if (perm != PackageManager.PERMISSION_GRANTED) { 12553 Log.w(TAG, "Permission Denial: broadcasting " 12554 + r.intent.toString() 12555 + " from " + r.callerPackage + " (pid=" + r.callingPid 12556 + ", uid=" + r.callingUid + ")" 12557 + " requires " + info.activityInfo.permission 12558 + " due to receiver " + info.activityInfo.packageName 12559 + "/" + info.activityInfo.name); 12560 skip = true; 12561 } 12562 if (r.callingUid != Process.SYSTEM_UID && 12563 r.requiredPermission != null) { 12564 try { 12565 perm = ActivityThread.getPackageManager(). 12566 checkPermission(r.requiredPermission, 12567 info.activityInfo.applicationInfo.packageName); 12568 } catch (RemoteException e) { 12569 perm = PackageManager.PERMISSION_DENIED; 12570 } 12571 if (perm != PackageManager.PERMISSION_GRANTED) { 12572 Log.w(TAG, "Permission Denial: receiving " 12573 + r.intent + " to " 12574 + info.activityInfo.applicationInfo.packageName 12575 + " requires " + r.requiredPermission 12576 + " due to sender " + r.callerPackage 12577 + " (uid " + r.callingUid + ")"); 12578 skip = true; 12579 } 12580 } 12581 if (r.curApp != null && r.curApp.crashing) { 12582 // If the target process is crashing, just skip it. 12583 skip = true; 12584 } 12585 12586 if (skip) { 12587 r.receiver = null; 12588 r.curFilter = null; 12589 r.state = BroadcastRecord.IDLE; 12590 scheduleBroadcastsLocked(); 12591 return; 12592 } 12593 12594 r.state = BroadcastRecord.APP_RECEIVE; 12595 String targetProcess = info.activityInfo.processName; 12596 r.curComponent = new ComponentName( 12597 info.activityInfo.applicationInfo.packageName, 12598 info.activityInfo.name); 12599 r.curReceiver = info.activityInfo; 12600 12601 // Is this receiver's application already running? 12602 ProcessRecord app = getProcessRecordLocked(targetProcess, 12603 info.activityInfo.applicationInfo.uid); 12604 if (app != null && app.thread != null) { 12605 try { 12606 processCurBroadcastLocked(r, app); 12607 return; 12608 } catch (RemoteException e) { 12609 Log.w(TAG, "Exception when sending broadcast to " 12610 + r.curComponent, e); 12611 } 12612 12613 // If a dead object exception was thrown -- fall through to 12614 // restart the application. 12615 } 12616 12617 // Not running -- get it started, to be executed when the app comes up. 12618 if ((r.curApp=startProcessLocked(targetProcess, 12619 info.activityInfo.applicationInfo, true, 12620 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 12621 "broadcast", r.curComponent, 12622 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 12623 == null) { 12624 // Ah, this recipient is unavailable. Finish it if necessary, 12625 // and mark the broadcast record as ready for the next. 12626 Log.w(TAG, "Unable to launch app " 12627 + info.activityInfo.applicationInfo.packageName + "/" 12628 + info.activityInfo.applicationInfo.uid + " for broadcast " 12629 + r.intent + ": process is bad"); 12630 logBroadcastReceiverDiscard(r); 12631 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12632 r.resultExtras, r.resultAbort, true); 12633 scheduleBroadcastsLocked(); 12634 r.state = BroadcastRecord.IDLE; 12635 return; 12636 } 12637 12638 mPendingBroadcast = r; 12639 } 12640 } 12641 12642 // ========================================================= 12643 // INSTRUMENTATION 12644 // ========================================================= 12645 startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher)12646 public boolean startInstrumentation(ComponentName className, 12647 String profileFile, int flags, Bundle arguments, 12648 IInstrumentationWatcher watcher) { 12649 // Refuse possible leaked file descriptors 12650 if (arguments != null && arguments.hasFileDescriptors()) { 12651 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12652 } 12653 12654 synchronized(this) { 12655 InstrumentationInfo ii = null; 12656 ApplicationInfo ai = null; 12657 try { 12658 ii = mContext.getPackageManager().getInstrumentationInfo( 12659 className, STOCK_PM_FLAGS); 12660 ai = mContext.getPackageManager().getApplicationInfo( 12661 ii.targetPackage, STOCK_PM_FLAGS); 12662 } catch (PackageManager.NameNotFoundException e) { 12663 } 12664 if (ii == null) { 12665 reportStartInstrumentationFailure(watcher, className, 12666 "Unable to find instrumentation info for: " + className); 12667 return false; 12668 } 12669 if (ai == null) { 12670 reportStartInstrumentationFailure(watcher, className, 12671 "Unable to find instrumentation target package: " + ii.targetPackage); 12672 return false; 12673 } 12674 12675 int match = mContext.getPackageManager().checkSignatures( 12676 ii.targetPackage, ii.packageName); 12677 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12678 String msg = "Permission Denial: starting instrumentation " 12679 + className + " from pid=" 12680 + Binder.getCallingPid() 12681 + ", uid=" + Binder.getCallingPid() 12682 + " not allowed because package " + ii.packageName 12683 + " does not have a signature matching the target " 12684 + ii.targetPackage; 12685 reportStartInstrumentationFailure(watcher, className, msg); 12686 throw new SecurityException(msg); 12687 } 12688 12689 final long origId = Binder.clearCallingIdentity(); 12690 uninstallPackageLocked(ii.targetPackage, -1, true); 12691 ProcessRecord app = addAppLocked(ai); 12692 app.instrumentationClass = className; 12693 app.instrumentationInfo = ai; 12694 app.instrumentationProfileFile = profileFile; 12695 app.instrumentationArguments = arguments; 12696 app.instrumentationWatcher = watcher; 12697 app.instrumentationResultClass = className; 12698 Binder.restoreCallingIdentity(origId); 12699 } 12700 12701 return true; 12702 } 12703 12704 /** 12705 * Report errors that occur while attempting to start Instrumentation. Always writes the 12706 * error to the logs, but if somebody is watching, send the report there too. This enables 12707 * the "am" command to report errors with more information. 12708 * 12709 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12710 * @param cn The component name of the instrumentation. 12711 * @param report The error report. 12712 */ reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report)12713 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12714 ComponentName cn, String report) { 12715 Log.w(TAG, report); 12716 try { 12717 if (watcher != null) { 12718 Bundle results = new Bundle(); 12719 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12720 results.putString("Error", report); 12721 watcher.instrumentationStatus(cn, -1, results); 12722 } 12723 } catch (RemoteException e) { 12724 Log.w(TAG, e); 12725 } 12726 } 12727 finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)12728 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12729 if (app.instrumentationWatcher != null) { 12730 try { 12731 // NOTE: IInstrumentationWatcher *must* be oneway here 12732 app.instrumentationWatcher.instrumentationFinished( 12733 app.instrumentationClass, 12734 resultCode, 12735 results); 12736 } catch (RemoteException e) { 12737 } 12738 } 12739 app.instrumentationWatcher = null; 12740 app.instrumentationClass = null; 12741 app.instrumentationInfo = null; 12742 app.instrumentationProfileFile = null; 12743 app.instrumentationArguments = null; 12744 12745 uninstallPackageLocked(app.processName, -1, false); 12746 } 12747 finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)12748 public void finishInstrumentation(IApplicationThread target, 12749 int resultCode, Bundle results) { 12750 // Refuse possible leaked file descriptors 12751 if (results != null && results.hasFileDescriptors()) { 12752 throw new IllegalArgumentException("File descriptors passed in Intent"); 12753 } 12754 12755 synchronized(this) { 12756 ProcessRecord app = getRecordForAppLocked(target); 12757 if (app == null) { 12758 Log.w(TAG, "finishInstrumentation: no app for " + target); 12759 return; 12760 } 12761 final long origId = Binder.clearCallingIdentity(); 12762 finishInstrumentationLocked(app, resultCode, results); 12763 Binder.restoreCallingIdentity(origId); 12764 } 12765 } 12766 12767 // ========================================================= 12768 // CONFIGURATION 12769 // ========================================================= 12770 getDeviceConfigurationInfo()12771 public ConfigurationInfo getDeviceConfigurationInfo() { 12772 ConfigurationInfo config = new ConfigurationInfo(); 12773 synchronized (this) { 12774 config.reqTouchScreen = mConfiguration.touchscreen; 12775 config.reqKeyboardType = mConfiguration.keyboard; 12776 config.reqNavigation = mConfiguration.navigation; 12777 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12778 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12779 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12780 } 12781 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12782 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12783 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12784 } 12785 config.reqGlEsVersion = GL_ES_VERSION; 12786 } 12787 return config; 12788 } 12789 getConfiguration()12790 public Configuration getConfiguration() { 12791 Configuration ci; 12792 synchronized(this) { 12793 ci = new Configuration(mConfiguration); 12794 } 12795 return ci; 12796 } 12797 updateConfiguration(Configuration values)12798 public void updateConfiguration(Configuration values) { 12799 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12800 "updateConfiguration()"); 12801 12802 synchronized(this) { 12803 if (values == null && mWindowManager != null) { 12804 // sentinel: fetch the current configuration from the window manager 12805 values = mWindowManager.computeNewConfiguration(); 12806 } 12807 12808 final long origId = Binder.clearCallingIdentity(); 12809 updateConfigurationLocked(values, null); 12810 Binder.restoreCallingIdentity(origId); 12811 } 12812 } 12813 12814 /** 12815 * Do either or both things: (1) change the current configuration, and (2) 12816 * make sure the given activity is running with the (now) current 12817 * configuration. Returns true if the activity has been left running, or 12818 * false if <var>starting</var> is being destroyed to match the new 12819 * configuration. 12820 */ updateConfigurationLocked(Configuration values, HistoryRecord starting)12821 public boolean updateConfigurationLocked(Configuration values, 12822 HistoryRecord starting) { 12823 int changes = 0; 12824 12825 boolean kept = true; 12826 12827 if (values != null) { 12828 Configuration newConfig = new Configuration(mConfiguration); 12829 changes = newConfig.updateFrom(values); 12830 if (changes != 0) { 12831 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12832 Log.i(TAG, "Updating configuration to: " + values); 12833 } 12834 12835 EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes); 12836 12837 if (values.locale != null) { 12838 saveLocaleLocked(values.locale, 12839 !values.locale.equals(mConfiguration.locale), 12840 values.userSetLocale); 12841 } 12842 12843 mConfiguration = newConfig; 12844 Log.i(TAG, "Config changed: " + newConfig); 12845 12846 AttributeCache ac = AttributeCache.instance(); 12847 if (ac != null) { 12848 ac.updateConfiguration(mConfiguration); 12849 } 12850 12851 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12852 msg.obj = new Configuration(mConfiguration); 12853 mHandler.sendMessage(msg); 12854 12855 final int N = mLRUProcesses.size(); 12856 for (int i=0; i<N; i++) { 12857 ProcessRecord app = mLRUProcesses.get(i); 12858 try { 12859 if (app.thread != null) { 12860 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc " 12861 + app.processName + " new config " + mConfiguration); 12862 app.thread.scheduleConfigurationChanged(mConfiguration); 12863 } 12864 } catch (Exception e) { 12865 } 12866 } 12867 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12868 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12869 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12870 null, false, false, MY_PID, Process.SYSTEM_UID); 12871 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12872 broadcastIntentLocked(null, null, 12873 new Intent(Intent.ACTION_LOCALE_CHANGED), 12874 null, null, 0, null, null, 12875 null, false, false, MY_PID, Process.SYSTEM_UID); 12876 } 12877 } 12878 } 12879 12880 if (changes != 0 && starting == null) { 12881 // If the configuration changed, and the caller is not already 12882 // in the process of starting an activity, then find the top 12883 // activity to check if its configuration needs to change. 12884 starting = topRunningActivityLocked(null); 12885 } 12886 12887 if (starting != null) { 12888 kept = ensureActivityConfigurationLocked(starting, changes); 12889 if (kept) { 12890 // If this didn't result in the starting activity being 12891 // destroyed, then we need to make sure at this point that all 12892 // other activities are made visible. 12893 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting 12894 + ", ensuring others are correct."); 12895 ensureActivitiesVisibleLocked(starting, changes); 12896 } 12897 } 12898 12899 return kept; 12900 } 12901 relaunchActivityLocked(HistoryRecord r, int changes, boolean andResume)12902 private final boolean relaunchActivityLocked(HistoryRecord r, 12903 int changes, boolean andResume) { 12904 List<ResultInfo> results = null; 12905 List<Intent> newIntents = null; 12906 if (andResume) { 12907 results = r.results; 12908 newIntents = r.newIntents; 12909 } 12910 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r 12911 + " with results=" + results + " newIntents=" + newIntents 12912 + " andResume=" + andResume); 12913 EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY 12914 : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 12915 r.task.taskId, r.shortComponentName); 12916 12917 r.startFreezingScreenLocked(r.app, 0); 12918 12919 try { 12920 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 12921 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 12922 changes, !andResume); 12923 // Note: don't need to call pauseIfSleepingLocked() here, because 12924 // the caller will only pass in 'andResume' if this activity is 12925 // currently resumed, which implies we aren't sleeping. 12926 } catch (RemoteException e) { 12927 return false; 12928 } 12929 12930 if (andResume) { 12931 r.results = null; 12932 r.newIntents = null; 12933 reportResumedActivityLocked(r); 12934 } 12935 12936 return true; 12937 } 12938 12939 /** 12940 * Make sure the given activity matches the current configuration. Returns 12941 * false if the activity had to be destroyed. Returns true if the 12942 * configuration is the same, or the activity will remain running as-is 12943 * for whatever reason. Ensures the HistoryRecord is updated with the 12944 * correct configuration and all other bookkeeping is handled. 12945 */ ensureActivityConfigurationLocked(HistoryRecord r, int globalChanges)12946 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 12947 int globalChanges) { 12948 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12949 "Ensuring correct configuration: " + r); 12950 12951 // Short circuit: if the two configurations are the exact same 12952 // object (the common case), then there is nothing to do. 12953 Configuration newConfig = mConfiguration; 12954 if (r.configuration == newConfig) { 12955 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12956 "Configuration unchanged in " + r); 12957 return true; 12958 } 12959 12960 // We don't worry about activities that are finishing. 12961 if (r.finishing) { 12962 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12963 "Configuration doesn't matter in finishing " + r); 12964 r.stopFreezingScreenLocked(false); 12965 return true; 12966 } 12967 12968 // Okay we now are going to make this activity have the new config. 12969 // But then we need to figure out how it needs to deal with that. 12970 Configuration oldConfig = r.configuration; 12971 r.configuration = newConfig; 12972 12973 // If the activity isn't currently running, just leave the new 12974 // configuration and it will pick that up next time it starts. 12975 if (r.app == null || r.app.thread == null) { 12976 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12977 "Configuration doesn't matter not running " + r); 12978 r.stopFreezingScreenLocked(false); 12979 return true; 12980 } 12981 12982 // If the activity isn't persistent, there is a chance we will 12983 // need to restart it. 12984 if (!r.persistent) { 12985 12986 // Figure out what has changed between the two configurations. 12987 int changes = oldConfig.diff(newConfig); 12988 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12989 Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" 12990 + Integer.toHexString(changes) + ", handles=0x" 12991 + Integer.toHexString(r.info.configChanges) 12992 + ", newConfig=" + newConfig); 12993 } 12994 if ((changes&(~r.info.configChanges)) != 0) { 12995 // Aha, the activity isn't handling the change, so DIE DIE DIE. 12996 r.configChangeFlags |= changes; 12997 r.startFreezingScreenLocked(r.app, globalChanges); 12998 if (r.app == null || r.app.thread == null) { 12999 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13000 "Switch is destroying non-running " + r); 13001 destroyActivityLocked(r, true); 13002 } else if (r.state == ActivityState.PAUSING) { 13003 // A little annoying: we are waiting for this activity to 13004 // finish pausing. Let's not do anything now, but just 13005 // flag that it needs to be restarted when done pausing. 13006 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13007 "Switch is skipping already pausing " + r); 13008 r.configDestroy = true; 13009 return true; 13010 } else if (r.state == ActivityState.RESUMED) { 13011 // Try to optimize this case: the configuration is changing 13012 // and we need to restart the top, resumed activity. 13013 // Instead of doing the normal handshaking, just say 13014 // "restart!". 13015 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13016 "Switch is restarting resumed " + r); 13017 relaunchActivityLocked(r, r.configChangeFlags, true); 13018 r.configChangeFlags = 0; 13019 } else { 13020 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13021 "Switch is restarting non-resumed " + r); 13022 relaunchActivityLocked(r, r.configChangeFlags, false); 13023 r.configChangeFlags = 0; 13024 } 13025 13026 // All done... tell the caller we weren't able to keep this 13027 // activity around. 13028 return false; 13029 } 13030 } 13031 13032 // Default case: the activity can handle this new configuration, so 13033 // hand it over. Note that we don't need to give it the new 13034 // configuration, since we always send configuration changes to all 13035 // process when they happen so it can just use whatever configuration 13036 // it last got. 13037 if (r.app != null && r.app.thread != null) { 13038 try { 13039 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r); 13040 r.app.thread.scheduleActivityConfigurationChanged(r); 13041 } catch (RemoteException e) { 13042 // If process died, whatever. 13043 } 13044 } 13045 r.stopFreezingScreenLocked(false); 13046 13047 return true; 13048 } 13049 13050 /** 13051 * Save the locale. You must be inside a synchronized (this) block. 13052 */ saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist)13053 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13054 if(isDiff) { 13055 SystemProperties.set("user.language", l.getLanguage()); 13056 SystemProperties.set("user.region", l.getCountry()); 13057 } 13058 13059 if(isPersist) { 13060 SystemProperties.set("persist.sys.language", l.getLanguage()); 13061 SystemProperties.set("persist.sys.country", l.getCountry()); 13062 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13063 } 13064 } 13065 13066 // ========================================================= 13067 // LIFETIME MANAGEMENT 13068 // ========================================================= 13069 computeOomAdjLocked( ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP)13070 private final int computeOomAdjLocked( 13071 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13072 if (mAdjSeq == app.adjSeq) { 13073 // This adjustment has already been computed. 13074 return app.curAdj; 13075 } 13076 13077 if (app.thread == null) { 13078 app.adjSeq = mAdjSeq; 13079 return (app.curAdj=EMPTY_APP_ADJ); 13080 } 13081 13082 if (app.maxAdj <= FOREGROUND_APP_ADJ) { 13083 // The max adjustment doesn't allow this app to be anything 13084 // below foreground, so it is not worth doing work for it. 13085 app.adjType = "fixed"; 13086 app.adjSeq = mAdjSeq; 13087 app.curRawAdj = app.maxAdj; 13088 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13089 return (app.curAdj=app.maxAdj); 13090 } 13091 13092 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13093 app.adjSource = null; 13094 app.adjTarget = null; 13095 13096 // Determine the importance of the process, starting with most 13097 // important to least, and assign an appropriate OOM adjustment. 13098 int adj; 13099 int N; 13100 if (app == TOP_APP) { 13101 // The last app on the list is the foreground app. 13102 adj = FOREGROUND_APP_ADJ; 13103 app.adjType = "top-activity"; 13104 } else if (app.instrumentationClass != null) { 13105 // Don't want to kill running instrumentation. 13106 adj = FOREGROUND_APP_ADJ; 13107 app.adjType = "instrumentation"; 13108 } else if (app.persistentActivities > 0) { 13109 // Special persistent activities... shouldn't be used these days. 13110 adj = FOREGROUND_APP_ADJ; 13111 app.adjType = "persistent"; 13112 } else if (app.curReceiver != null || 13113 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13114 // An app that is currently receiving a broadcast also 13115 // counts as being in the foreground. 13116 adj = FOREGROUND_APP_ADJ; 13117 app.adjType = "broadcast"; 13118 } else if (app.executingServices.size() > 0) { 13119 // An app that is currently executing a service callback also 13120 // counts as being in the foreground. 13121 adj = FOREGROUND_APP_ADJ; 13122 app.adjType = "exec-service"; 13123 } else if (app.foregroundServices) { 13124 // The user is aware of this app, so make it visible. 13125 adj = VISIBLE_APP_ADJ; 13126 app.adjType = "foreground-service"; 13127 } else if (app.forcingToForeground != null) { 13128 // The user is aware of this app, so make it visible. 13129 adj = VISIBLE_APP_ADJ; 13130 app.adjType = "force-foreground"; 13131 app.adjSource = app.forcingToForeground; 13132 } else if (app == mHomeProcess) { 13133 // This process is hosting what we currently consider to be the 13134 // home app, so we don't want to let it go into the background. 13135 adj = HOME_APP_ADJ; 13136 app.adjType = "home"; 13137 } else if ((N=app.activities.size()) != 0) { 13138 // This app is in the background with paused activities. 13139 adj = hiddenAdj; 13140 app.adjType = "bg-activities"; 13141 for (int j=0; j<N; j++) { 13142 if (((HistoryRecord)app.activities.get(j)).visible) { 13143 // This app has a visible activity! 13144 adj = VISIBLE_APP_ADJ; 13145 app.adjType = "visible"; 13146 break; 13147 } 13148 } 13149 } else { 13150 // A very not-needed process. 13151 adj = EMPTY_APP_ADJ; 13152 app.adjType = "empty"; 13153 } 13154 13155 // By default, we use the computed adjustment. It may be changed if 13156 // there are applications dependent on our services or providers, but 13157 // this gives us a baseline and makes sure we don't get into an 13158 // infinite recursion. 13159 app.adjSeq = mAdjSeq; 13160 app.curRawAdj = adj; 13161 app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj; 13162 13163 if (mBackupTarget != null && app == mBackupTarget.app) { 13164 // If possible we want to avoid killing apps while they're being backed up 13165 if (adj > BACKUP_APP_ADJ) { 13166 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13167 adj = BACKUP_APP_ADJ; 13168 app.adjType = "backup"; 13169 } 13170 } 13171 13172 if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) { 13173 final long now = SystemClock.uptimeMillis(); 13174 // This process is more important if the top activity is 13175 // bound to the service. 13176 Iterator jt = app.services.iterator(); 13177 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13178 ServiceRecord s = (ServiceRecord)jt.next(); 13179 if (s.startRequested) { 13180 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13181 // This service has seen some activity within 13182 // recent memory, so we will keep its process ahead 13183 // of the background processes. 13184 if (adj > SECONDARY_SERVER_ADJ) { 13185 adj = SECONDARY_SERVER_ADJ; 13186 app.adjType = "started-services"; 13187 } 13188 } 13189 } 13190 if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) { 13191 Iterator<ConnectionRecord> kt 13192 = s.connections.values().iterator(); 13193 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13194 // XXX should compute this based on the max of 13195 // all connected clients. 13196 ConnectionRecord cr = kt.next(); 13197 if (cr.binding.client == app) { 13198 // Binding to ourself is not interesting. 13199 continue; 13200 } 13201 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13202 ProcessRecord client = cr.binding.client; 13203 int myHiddenAdj = hiddenAdj; 13204 if (myHiddenAdj > client.hiddenAdj) { 13205 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 13206 myHiddenAdj = client.hiddenAdj; 13207 } else { 13208 myHiddenAdj = VISIBLE_APP_ADJ; 13209 } 13210 } 13211 int clientAdj = computeOomAdjLocked( 13212 client, myHiddenAdj, TOP_APP); 13213 if (adj > clientAdj) { 13214 adj = clientAdj > VISIBLE_APP_ADJ 13215 ? clientAdj : VISIBLE_APP_ADJ; 13216 app.adjType = "service"; 13217 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13218 .REASON_SERVICE_IN_USE; 13219 app.adjSource = cr.binding.client; 13220 app.adjTarget = s.serviceInfo.name; 13221 } 13222 } 13223 HistoryRecord a = cr.activity; 13224 //if (a != null) { 13225 // Log.i(TAG, "Connection to " + a ": state=" + a.state); 13226 //} 13227 if (a != null && adj > FOREGROUND_APP_ADJ && 13228 (a.state == ActivityState.RESUMED 13229 || a.state == ActivityState.PAUSING)) { 13230 adj = FOREGROUND_APP_ADJ; 13231 app.adjType = "service"; 13232 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13233 .REASON_SERVICE_IN_USE; 13234 app.adjSource = a; 13235 app.adjTarget = s.serviceInfo.name; 13236 } 13237 } 13238 } 13239 } 13240 13241 // Finally, f this process has active services running in it, we 13242 // would like to avoid killing it unless it would prevent the current 13243 // application from running. By default we put the process in 13244 // with the rest of the background processes; as we scan through 13245 // its services we may bump it up from there. 13246 if (adj > hiddenAdj) { 13247 adj = hiddenAdj; 13248 app.adjType = "bg-services"; 13249 } 13250 } 13251 13252 if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) { 13253 Iterator jt = app.pubProviders.values().iterator(); 13254 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13255 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 13256 if (cpr.clients.size() != 0) { 13257 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13258 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13259 ProcessRecord client = kt.next(); 13260 if (client == app) { 13261 // Being our own client is not interesting. 13262 continue; 13263 } 13264 int myHiddenAdj = hiddenAdj; 13265 if (myHiddenAdj > client.hiddenAdj) { 13266 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 13267 myHiddenAdj = client.hiddenAdj; 13268 } else { 13269 myHiddenAdj = FOREGROUND_APP_ADJ; 13270 } 13271 } 13272 int clientAdj = computeOomAdjLocked( 13273 client, myHiddenAdj, TOP_APP); 13274 if (adj > clientAdj) { 13275 adj = clientAdj > FOREGROUND_APP_ADJ 13276 ? clientAdj : FOREGROUND_APP_ADJ; 13277 app.adjType = "provider"; 13278 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13279 .REASON_PROVIDER_IN_USE; 13280 app.adjSource = client; 13281 app.adjTarget = cpr.info.name; 13282 } 13283 } 13284 } 13285 // If the provider has external (non-framework) process 13286 // dependencies, ensure that its adjustment is at least 13287 // FOREGROUND_APP_ADJ. 13288 if (cpr.externals != 0) { 13289 if (adj > FOREGROUND_APP_ADJ) { 13290 adj = FOREGROUND_APP_ADJ; 13291 app.adjType = "provider"; 13292 app.adjTarget = cpr.info.name; 13293 } 13294 } 13295 } 13296 13297 // Finally, if this process has published any content providers, 13298 // then its adjustment makes it at least as important as any of the 13299 // processes using those providers, and no less important than 13300 // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY. 13301 if (adj > CONTENT_PROVIDER_ADJ) { 13302 adj = CONTENT_PROVIDER_ADJ; 13303 app.adjType = "pub-providers"; 13304 } 13305 } 13306 13307 app.curRawAdj = adj; 13308 13309 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13310 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13311 if (adj > app.maxAdj) { 13312 adj = app.maxAdj; 13313 } 13314 13315 app.curAdj = adj; 13316 app.curSchedGroup = adj > VISIBLE_APP_ADJ 13317 ? Process.THREAD_GROUP_BG_NONINTERACTIVE 13318 : Process.THREAD_GROUP_DEFAULT; 13319 13320 return adj; 13321 } 13322 13323 /** 13324 * Ask a given process to GC right now. 13325 */ performAppGcLocked(ProcessRecord app)13326 final void performAppGcLocked(ProcessRecord app) { 13327 try { 13328 app.lastRequestedGc = SystemClock.uptimeMillis(); 13329 if (app.thread != null) { 13330 if (app.reportLowMemory) { 13331 app.reportLowMemory = false; 13332 app.thread.scheduleLowMemory(); 13333 } else { 13334 app.thread.processInBackground(); 13335 } 13336 } 13337 } catch (Exception e) { 13338 // whatever. 13339 } 13340 } 13341 13342 /** 13343 * Returns true if things are idle enough to perform GCs. 13344 */ canGcNow()13345 private final boolean canGcNow() { 13346 return mParallelBroadcasts.size() == 0 13347 && mOrderedBroadcasts.size() == 0 13348 && (mSleeping || (mResumedActivity != null && 13349 mResumedActivity.idle)); 13350 } 13351 13352 /** 13353 * Perform GCs on all processes that are waiting for it, but only 13354 * if things are idle. 13355 */ performAppGcsLocked()13356 final void performAppGcsLocked() { 13357 final int N = mProcessesToGc.size(); 13358 if (N <= 0) { 13359 return; 13360 } 13361 if (canGcNow()) { 13362 while (mProcessesToGc.size() > 0) { 13363 ProcessRecord proc = mProcessesToGc.remove(0); 13364 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { 13365 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13366 <= SystemClock.uptimeMillis()) { 13367 // To avoid spamming the system, we will GC processes one 13368 // at a time, waiting a few seconds between each. 13369 performAppGcLocked(proc); 13370 scheduleAppGcsLocked(); 13371 return; 13372 } else { 13373 // It hasn't been long enough since we last GCed this 13374 // process... put it in the list to wait for its time. 13375 addProcessToGcListLocked(proc); 13376 break; 13377 } 13378 } 13379 } 13380 13381 scheduleAppGcsLocked(); 13382 } 13383 } 13384 13385 /** 13386 * If all looks good, perform GCs on all processes waiting for them. 13387 */ performAppGcsIfAppropriateLocked()13388 final void performAppGcsIfAppropriateLocked() { 13389 if (canGcNow()) { 13390 performAppGcsLocked(); 13391 return; 13392 } 13393 // Still not idle, wait some more. 13394 scheduleAppGcsLocked(); 13395 } 13396 13397 /** 13398 * Schedule the execution of all pending app GCs. 13399 */ scheduleAppGcsLocked()13400 final void scheduleAppGcsLocked() { 13401 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13402 13403 if (mProcessesToGc.size() > 0) { 13404 // Schedule a GC for the time to the next process. 13405 ProcessRecord proc = mProcessesToGc.get(0); 13406 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13407 13408 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL; 13409 long now = SystemClock.uptimeMillis(); 13410 if (when < (now+GC_TIMEOUT)) { 13411 when = now + GC_TIMEOUT; 13412 } 13413 mHandler.sendMessageAtTime(msg, when); 13414 } 13415 } 13416 13417 /** 13418 * Add a process to the array of processes waiting to be GCed. Keeps the 13419 * list in sorted order by the last GC time. The process can't already be 13420 * on the list. 13421 */ addProcessToGcListLocked(ProcessRecord proc)13422 final void addProcessToGcListLocked(ProcessRecord proc) { 13423 boolean added = false; 13424 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13425 if (mProcessesToGc.get(i).lastRequestedGc < 13426 proc.lastRequestedGc) { 13427 added = true; 13428 mProcessesToGc.add(i+1, proc); 13429 break; 13430 } 13431 } 13432 if (!added) { 13433 mProcessesToGc.add(0, proc); 13434 } 13435 } 13436 13437 /** 13438 * Set up to ask a process to GC itself. This will either do it 13439 * immediately, or put it on the list of processes to gc the next 13440 * time things are idle. 13441 */ scheduleAppGcLocked(ProcessRecord app)13442 final void scheduleAppGcLocked(ProcessRecord app) { 13443 long now = SystemClock.uptimeMillis(); 13444 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13445 return; 13446 } 13447 if (!mProcessesToGc.contains(app)) { 13448 addProcessToGcListLocked(app); 13449 scheduleAppGcsLocked(); 13450 } 13451 } 13452 updateOomAdjLocked( ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP)13453 private final boolean updateOomAdjLocked( 13454 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13455 app.hiddenAdj = hiddenAdj; 13456 13457 if (app.thread == null) { 13458 return true; 13459 } 13460 13461 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP); 13462 13463 if (app.pid != 0 && app.pid != MY_PID) { 13464 if (app.curRawAdj != app.setRawAdj) { 13465 if (app.curRawAdj > FOREGROUND_APP_ADJ 13466 && app.setRawAdj <= FOREGROUND_APP_ADJ) { 13467 // If this app is transitioning from foreground to 13468 // non-foreground, have it do a gc. 13469 scheduleAppGcLocked(app); 13470 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ 13471 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { 13472 // Likewise do a gc when an app is moving in to the 13473 // background (such as a service stopping). 13474 scheduleAppGcLocked(app); 13475 } 13476 app.setRawAdj = app.curRawAdj; 13477 } 13478 if (adj != app.setAdj) { 13479 if (Process.setOomAdj(app.pid, adj)) { 13480 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v( 13481 TAG, "Set app " + app.processName + 13482 " oom adj to " + adj); 13483 app.setAdj = adj; 13484 } else { 13485 return false; 13486 } 13487 } 13488 if (app.setSchedGroup != app.curSchedGroup) { 13489 app.setSchedGroup = app.curSchedGroup; 13490 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, 13491 "Setting process group of " + app.processName 13492 + " to " + app.curSchedGroup); 13493 if (true) { 13494 long oldId = Binder.clearCallingIdentity(); 13495 try { 13496 Process.setProcessGroup(app.pid, app.curSchedGroup); 13497 } catch (Exception e) { 13498 Log.w(TAG, "Failed setting process group of " + app.pid 13499 + " to " + app.curSchedGroup); 13500 e.printStackTrace(); 13501 } finally { 13502 Binder.restoreCallingIdentity(oldId); 13503 } 13504 } 13505 if (false) { 13506 if (app.thread != null) { 13507 try { 13508 app.thread.setSchedulingGroup(app.curSchedGroup); 13509 } catch (RemoteException e) { 13510 } 13511 } 13512 } 13513 } 13514 } 13515 13516 return true; 13517 } 13518 resumedAppLocked()13519 private final HistoryRecord resumedAppLocked() { 13520 HistoryRecord resumedActivity = mResumedActivity; 13521 if (resumedActivity == null || resumedActivity.app == null) { 13522 resumedActivity = mPausingActivity; 13523 if (resumedActivity == null || resumedActivity.app == null) { 13524 resumedActivity = topRunningActivityLocked(null); 13525 } 13526 } 13527 return resumedActivity; 13528 } 13529 updateOomAdjLocked(ProcessRecord app)13530 private final boolean updateOomAdjLocked(ProcessRecord app) { 13531 final HistoryRecord TOP_ACT = resumedAppLocked(); 13532 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13533 int curAdj = app.curAdj; 13534 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13535 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13536 13537 mAdjSeq++; 13538 13539 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 13540 if (res) { 13541 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13542 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13543 if (nowHidden != wasHidden) { 13544 // Changed to/from hidden state, so apps after it in the LRU 13545 // list may also be changed. 13546 updateOomAdjLocked(); 13547 } 13548 } 13549 return res; 13550 } 13551 updateOomAdjLocked()13552 private final boolean updateOomAdjLocked() { 13553 boolean didOomAdj = true; 13554 final HistoryRecord TOP_ACT = resumedAppLocked(); 13555 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13556 13557 if (false) { 13558 RuntimeException e = new RuntimeException(); 13559 e.fillInStackTrace(); 13560 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13561 } 13562 13563 mAdjSeq++; 13564 13565 // First try updating the OOM adjustment for each of the 13566 // application processes based on their current state. 13567 int i = mLRUProcesses.size(); 13568 int curHiddenAdj = HIDDEN_APP_MIN_ADJ; 13569 while (i > 0) { 13570 i--; 13571 ProcessRecord app = mLRUProcesses.get(i); 13572 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) { 13573 if (curHiddenAdj < HIDDEN_APP_MAX_ADJ 13574 && app.curAdj == curHiddenAdj) { 13575 curHiddenAdj++; 13576 } 13577 } else { 13578 didOomAdj = false; 13579 } 13580 } 13581 13582 // todo: for now pretend like OOM ADJ didn't work, because things 13583 // aren't behaving as expected on Linux -- it's not killing processes. 13584 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj; 13585 } 13586 trimApplications()13587 private final void trimApplications() { 13588 synchronized (this) { 13589 int i; 13590 13591 // First remove any unused application processes whose package 13592 // has been removed. 13593 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13594 final ProcessRecord app = mRemovedProcesses.get(i); 13595 if (app.activities.size() == 0 13596 && app.curReceiver == null && app.services.size() == 0) { 13597 Log.i( 13598 TAG, "Exiting empty application process " 13599 + app.processName + " (" 13600 + (app.thread != null ? app.thread.asBinder() : null) 13601 + ")\n"); 13602 if (app.pid > 0 && app.pid != MY_PID) { 13603 Process.killProcess(app.pid); 13604 } else { 13605 try { 13606 app.thread.scheduleExit(); 13607 } catch (Exception e) { 13608 // Ignore exceptions. 13609 } 13610 } 13611 cleanUpApplicationRecordLocked(app, false, -1); 13612 mRemovedProcesses.remove(i); 13613 13614 if (app.persistent) { 13615 if (app.persistent) { 13616 addAppLocked(app.info); 13617 } 13618 } 13619 } 13620 } 13621 13622 // Now try updating the OOM adjustment for each of the 13623 // application processes based on their current state. 13624 // If the setOomAdj() API is not supported, then go with our 13625 // back-up plan... 13626 if (!updateOomAdjLocked()) { 13627 13628 // Count how many processes are running services. 13629 int numServiceProcs = 0; 13630 for (i=mLRUProcesses.size()-1; i>=0; i--) { 13631 final ProcessRecord app = mLRUProcesses.get(i); 13632 13633 if (app.persistent || app.services.size() != 0 13634 || app.curReceiver != null 13635 || app.persistentActivities > 0) { 13636 // Don't count processes holding services against our 13637 // maximum process count. 13638 if (localLOGV) Log.v( 13639 TAG, "Not trimming app " + app + " with services: " 13640 + app.services); 13641 numServiceProcs++; 13642 } 13643 } 13644 13645 int curMaxProcs = mProcessLimit; 13646 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES; 13647 if (mAlwaysFinishActivities) { 13648 curMaxProcs = 1; 13649 } 13650 curMaxProcs += numServiceProcs; 13651 13652 // Quit as many processes as we can to get down to the desired 13653 // process count. First remove any processes that no longer 13654 // have activites running in them. 13655 for ( i=0; 13656 i<mLRUProcesses.size() 13657 && mLRUProcesses.size() > curMaxProcs; 13658 i++) { 13659 final ProcessRecord app = mLRUProcesses.get(i); 13660 // Quit an application only if it is not currently 13661 // running any activities. 13662 if (!app.persistent && app.activities.size() == 0 13663 && app.curReceiver == null && app.services.size() == 0) { 13664 Log.i( 13665 TAG, "Exiting empty application process " 13666 + app.processName + " (" 13667 + (app.thread != null ? app.thread.asBinder() : null) 13668 + ")\n"); 13669 if (app.pid > 0 && app.pid != MY_PID) { 13670 Process.killProcess(app.pid); 13671 } else { 13672 try { 13673 app.thread.scheduleExit(); 13674 } catch (Exception e) { 13675 // Ignore exceptions. 13676 } 13677 } 13678 // todo: For now we assume the application is not buggy 13679 // or evil, and will quit as a result of our request. 13680 // Eventually we need to drive this off of the death 13681 // notification, and kill the process if it takes too long. 13682 cleanUpApplicationRecordLocked(app, false, i); 13683 i--; 13684 } 13685 } 13686 13687 // If we still have too many processes, now from the least 13688 // recently used process we start finishing activities. 13689 if (Config.LOGV) Log.v( 13690 TAG, "*** NOW HAVE " + mLRUProcesses.size() + 13691 " of " + curMaxProcs + " processes"); 13692 for ( i=0; 13693 i<mLRUProcesses.size() 13694 && mLRUProcesses.size() > curMaxProcs; 13695 i++) { 13696 final ProcessRecord app = mLRUProcesses.get(i); 13697 // Quit the application only if we have a state saved for 13698 // all of its activities. 13699 boolean canQuit = !app.persistent && app.curReceiver == null 13700 && app.services.size() == 0 13701 && app.persistentActivities == 0; 13702 int NUMA = app.activities.size(); 13703 int j; 13704 if (Config.LOGV) Log.v( 13705 TAG, "Looking to quit " + app.processName); 13706 for (j=0; j<NUMA && canQuit; j++) { 13707 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13708 if (Config.LOGV) Log.v( 13709 TAG, " " + r.intent.getComponent().flattenToShortString() 13710 + ": frozen=" + r.haveState + ", visible=" + r.visible); 13711 canQuit = (r.haveState || !r.stateNotNeeded) 13712 && !r.visible && r.stopped; 13713 } 13714 if (canQuit) { 13715 // Finish all of the activities, and then the app itself. 13716 for (j=0; j<NUMA; j++) { 13717 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13718 if (!r.finishing) { 13719 destroyActivityLocked(r, false); 13720 } 13721 r.resultTo = null; 13722 } 13723 Log.i(TAG, "Exiting application process " 13724 + app.processName + " (" 13725 + (app.thread != null ? app.thread.asBinder() : null) 13726 + ")\n"); 13727 if (app.pid > 0 && app.pid != MY_PID) { 13728 Process.killProcess(app.pid); 13729 } else { 13730 try { 13731 app.thread.scheduleExit(); 13732 } catch (Exception e) { 13733 // Ignore exceptions. 13734 } 13735 } 13736 // todo: For now we assume the application is not buggy 13737 // or evil, and will quit as a result of our request. 13738 // Eventually we need to drive this off of the death 13739 // notification, and kill the process if it takes too long. 13740 cleanUpApplicationRecordLocked(app, false, i); 13741 i--; 13742 //dump(); 13743 } 13744 } 13745 13746 } 13747 13748 int curMaxActivities = MAX_ACTIVITIES; 13749 if (mAlwaysFinishActivities) { 13750 curMaxActivities = 1; 13751 } 13752 13753 // Finally, if there are too many activities now running, try to 13754 // finish as many as we can to get back down to the limit. 13755 for ( i=0; 13756 i<mLRUActivities.size() 13757 && mLRUActivities.size() > curMaxActivities; 13758 i++) { 13759 final HistoryRecord r 13760 = (HistoryRecord)mLRUActivities.get(i); 13761 13762 // We can finish this one if we have its icicle saved and 13763 // it is not persistent. 13764 if ((r.haveState || !r.stateNotNeeded) && !r.visible 13765 && r.stopped && !r.persistent && !r.finishing) { 13766 final int origSize = mLRUActivities.size(); 13767 destroyActivityLocked(r, true); 13768 13769 // This will remove it from the LRU list, so keep 13770 // our index at the same value. Note that this check to 13771 // see if the size changes is just paranoia -- if 13772 // something unexpected happens, we don't want to end up 13773 // in an infinite loop. 13774 if (origSize > mLRUActivities.size()) { 13775 i--; 13776 } 13777 } 13778 } 13779 } 13780 } 13781 13782 /** This method sends the specified signal to each of the persistent apps */ signalPersistentProcesses(int sig)13783 public void signalPersistentProcesses(int sig) throws RemoteException { 13784 if (sig != Process.SIGNAL_USR1) { 13785 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13786 } 13787 13788 synchronized (this) { 13789 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13790 != PackageManager.PERMISSION_GRANTED) { 13791 throw new SecurityException("Requires permission " 13792 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13793 } 13794 13795 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 13796 ProcessRecord r = mLRUProcesses.get(i); 13797 if (r.thread != null && r.persistent) { 13798 Process.sendSignal(r.pid, sig); 13799 } 13800 } 13801 } 13802 } 13803 profileControl(String process, boolean start, String path, ParcelFileDescriptor fd)13804 public boolean profileControl(String process, boolean start, 13805 String path, ParcelFileDescriptor fd) throws RemoteException { 13806 13807 try { 13808 synchronized (this) { 13809 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13810 // its own permission. 13811 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13812 != PackageManager.PERMISSION_GRANTED) { 13813 throw new SecurityException("Requires permission " 13814 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13815 } 13816 13817 if (start && fd == null) { 13818 throw new IllegalArgumentException("null fd"); 13819 } 13820 13821 ProcessRecord proc = null; 13822 try { 13823 int pid = Integer.parseInt(process); 13824 synchronized (mPidsSelfLocked) { 13825 proc = mPidsSelfLocked.get(pid); 13826 } 13827 } catch (NumberFormatException e) { 13828 } 13829 13830 if (proc == null) { 13831 HashMap<String, SparseArray<ProcessRecord>> all 13832 = mProcessNames.getMap(); 13833 SparseArray<ProcessRecord> procs = all.get(process); 13834 if (procs != null && procs.size() > 0) { 13835 proc = procs.valueAt(0); 13836 } 13837 } 13838 13839 if (proc == null || proc.thread == null) { 13840 throw new IllegalArgumentException("Unknown process: " + process); 13841 } 13842 13843 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 13844 if (isSecure) { 13845 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13846 throw new SecurityException("Process not debuggable: " + proc); 13847 } 13848 } 13849 13850 proc.thread.profilerControl(start, path, fd); 13851 fd = null; 13852 return true; 13853 } 13854 } catch (RemoteException e) { 13855 throw new IllegalStateException("Process disappeared"); 13856 } finally { 13857 if (fd != null) { 13858 try { 13859 fd.close(); 13860 } catch (IOException e) { 13861 } 13862 } 13863 } 13864 } 13865 13866 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ monitor()13867 public void monitor() { 13868 synchronized (this) { } 13869 } 13870 } 13871