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.R; 20 import com.android.internal.os.BatteryStatsImpl; 21 import com.android.internal.os.ProcessStats; 22 import com.android.server.AttributeCache; 23 import com.android.server.IntentResolver; 24 import com.android.server.ProcessMap; 25 import com.android.server.SystemServer; 26 import com.android.server.Watchdog; 27 import com.android.server.am.ActivityStack.ActivityState; 28 import com.android.server.wm.WindowManagerService; 29 30 import dalvik.system.Zygote; 31 32 import android.app.Activity; 33 import android.app.ActivityManager; 34 import android.app.ActivityManagerNative; 35 import android.app.ActivityThread; 36 import android.app.AlertDialog; 37 import android.app.AppGlobals; 38 import android.app.ApplicationErrorReport; 39 import android.app.Dialog; 40 import android.app.IActivityController; 41 import android.app.IActivityWatcher; 42 import android.app.IApplicationThread; 43 import android.app.IInstrumentationWatcher; 44 import android.app.INotificationManager; 45 import android.app.IProcessObserver; 46 import android.app.IServiceConnection; 47 import android.app.IThumbnailReceiver; 48 import android.app.Instrumentation; 49 import android.app.Notification; 50 import android.app.NotificationManager; 51 import android.app.PendingIntent; 52 import android.app.Service; 53 import android.app.backup.IBackupManager; 54 import android.content.ActivityNotFoundException; 55 import android.content.BroadcastReceiver; 56 import android.content.ComponentCallbacks2; 57 import android.content.ComponentName; 58 import android.content.ContentResolver; 59 import android.content.Context; 60 import android.content.DialogInterface; 61 import android.content.Intent; 62 import android.content.IntentFilter; 63 import android.content.IIntentReceiver; 64 import android.content.IIntentSender; 65 import android.content.IntentSender; 66 import android.content.pm.ActivityInfo; 67 import android.content.pm.ApplicationInfo; 68 import android.content.pm.ConfigurationInfo; 69 import android.content.pm.IPackageDataObserver; 70 import android.content.pm.IPackageManager; 71 import android.content.pm.InstrumentationInfo; 72 import android.content.pm.PackageInfo; 73 import android.content.pm.PackageManager; 74 import android.content.pm.PathPermission; 75 import android.content.pm.ProviderInfo; 76 import android.content.pm.ResolveInfo; 77 import android.content.pm.ServiceInfo; 78 import android.content.pm.PackageManager.NameNotFoundException; 79 import android.content.res.CompatibilityInfo; 80 import android.content.res.Configuration; 81 import android.graphics.Bitmap; 82 import android.net.Proxy; 83 import android.net.ProxyProperties; 84 import android.net.Uri; 85 import android.os.Binder; 86 import android.os.Build; 87 import android.os.Bundle; 88 import android.os.Debug; 89 import android.os.DropBoxManager; 90 import android.os.Environment; 91 import android.os.FileObserver; 92 import android.os.FileUtils; 93 import android.os.Handler; 94 import android.os.IBinder; 95 import android.os.IPermissionController; 96 import android.os.Looper; 97 import android.os.Message; 98 import android.os.Parcel; 99 import android.os.ParcelFileDescriptor; 100 import android.os.Process; 101 import android.os.RemoteCallbackList; 102 import android.os.RemoteException; 103 import android.os.ServiceManager; 104 import android.os.StrictMode; 105 import android.os.SystemClock; 106 import android.os.SystemProperties; 107 import android.provider.Settings; 108 import android.text.format.Time; 109 import android.util.EventLog; 110 import android.util.Pair; 111 import android.util.Slog; 112 import android.util.Log; 113 import android.util.PrintWriterPrinter; 114 import android.util.SparseArray; 115 import android.util.TimeUtils; 116 import android.view.Gravity; 117 import android.view.LayoutInflater; 118 import android.view.View; 119 import android.view.WindowManager; 120 import android.view.WindowManagerPolicy; 121 122 import java.io.BufferedInputStream; 123 import java.io.BufferedOutputStream; 124 import java.io.BufferedReader; 125 import java.io.DataInputStream; 126 import java.io.DataOutputStream; 127 import java.io.File; 128 import java.io.FileDescriptor; 129 import java.io.FileInputStream; 130 import java.io.FileNotFoundException; 131 import java.io.FileOutputStream; 132 import java.io.IOException; 133 import java.io.InputStreamReader; 134 import java.io.PrintWriter; 135 import java.io.StringWriter; 136 import java.lang.IllegalStateException; 137 import java.lang.ref.WeakReference; 138 import java.util.ArrayList; 139 import java.util.Collections; 140 import java.util.Comparator; 141 import java.util.HashMap; 142 import java.util.HashSet; 143 import java.util.Iterator; 144 import java.util.List; 145 import java.util.Locale; 146 import java.util.Map; 147 import java.util.Set; 148 import java.util.concurrent.atomic.AtomicBoolean; 149 import java.util.concurrent.atomic.AtomicLong; 150 151 public final class ActivityManagerService extends ActivityManagerNative 152 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 153 static final String TAG = "ActivityManager"; 154 static final boolean DEBUG = false; 155 static final boolean localLOGV = DEBUG; 156 static final boolean DEBUG_SWITCH = localLOGV || false; 157 static final boolean DEBUG_TASKS = localLOGV || false; 158 static final boolean DEBUG_PAUSE = localLOGV || false; 159 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 160 static final boolean DEBUG_TRANSITION = localLOGV || false; 161 static final boolean DEBUG_BROADCAST = localLOGV || false; 162 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 163 static final boolean DEBUG_SERVICE = localLOGV || false; 164 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 165 static final boolean DEBUG_VISBILITY = localLOGV || false; 166 static final boolean DEBUG_PROCESSES = localLOGV || false; 167 static final boolean DEBUG_PROVIDER = localLOGV || false; 168 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 169 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 170 static final boolean DEBUG_RESULTS = localLOGV || false; 171 static final boolean DEBUG_BACKUP = localLOGV || false; 172 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 173 static final boolean DEBUG_POWER = localLOGV || false; 174 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 175 static final boolean VALIDATE_TOKENS = false; 176 static final boolean SHOW_ACTIVITY_START_TIME = true; 177 178 // Control over CPU and battery monitoring. 179 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 180 static final boolean MONITOR_CPU_USAGE = true; 181 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 182 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 183 static final boolean MONITOR_THREAD_CPU_USAGE = false; 184 185 // The flags that are set for all calls we make to the package manager. 186 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 187 188 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 189 190 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 191 192 // Maximum number of recent tasks that we can remember. 193 static final int MAX_RECENT_TASKS = 20; 194 195 // Amount of time after a call to stopAppSwitches() during which we will 196 // prevent further untrusted switches from happening. 197 static final long APP_SWITCH_DELAY_TIME = 5*1000; 198 199 // How long we wait for a launched process to attach to the activity manager 200 // before we decide it's never going to come up for real. 201 static final int PROC_START_TIMEOUT = 10*1000; 202 203 // How long we wait for a launched process to attach to the activity manager 204 // before we decide it's never going to come up for real, when the process was 205 // started with a wrapper for instrumentation (such as Valgrind) because it 206 // could take much longer than usual. 207 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 208 209 // How long to wait after going idle before forcing apps to GC. 210 static final int GC_TIMEOUT = 5*1000; 211 212 // The minimum amount of time between successive GC requests for a process. 213 static final int GC_MIN_INTERVAL = 60*1000; 214 215 // The rate at which we check for apps using excessive power -- 15 mins. 216 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 217 218 // The minimum sample duration we will allow before deciding we have 219 // enough data on wake locks to start killing things. 220 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 221 222 // The minimum sample duration we will allow before deciding we have 223 // enough data on CPU usage to start killing things. 224 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 225 226 // How long we allow a receiver to run before giving up on it. 227 static final int BROADCAST_TIMEOUT = 10*1000; 228 229 // How long we wait for a service to finish executing. 230 static final int SERVICE_TIMEOUT = 20*1000; 231 232 // How long a service needs to be running until restarting its process 233 // is no longer considered to be a relaunch of the service. 234 static final int SERVICE_RESTART_DURATION = 5*1000; 235 236 // How long a service needs to be running until it will start back at 237 // SERVICE_RESTART_DURATION after being killed. 238 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 239 240 // Multiplying factor to increase restart duration time by, for each time 241 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 242 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 243 244 // The minimum amount of time between restarting services that we allow. 245 // That is, when multiple services are restarting, we won't allow each 246 // to restart less than this amount of time from the last one. 247 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 248 249 // Maximum amount of time for there to be no activity on a service before 250 // we consider it non-essential and allow its process to go on the 251 // LRU background list. 252 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 253 254 // How long we wait until we timeout on key dispatching. 255 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 256 257 // How long we wait until we timeout on key dispatching during instrumentation. 258 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 259 260 static final int MY_PID = Process.myPid(); 261 262 static final String[] EMPTY_STRING_ARRAY = new String[0]; 263 264 public ActivityStack mMainStack; 265 266 /** 267 * Description of a request to start a new activity, which has been held 268 * due to app switches being disabled. 269 */ 270 static class PendingActivityLaunch { 271 ActivityRecord r; 272 ActivityRecord sourceRecord; 273 Uri[] grantedUriPermissions; 274 int grantedMode; 275 boolean onlyIfNeeded; 276 } 277 278 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 279 = new ArrayList<PendingActivityLaunch>(); 280 281 /** 282 * List of all active broadcasts that are to be executed immediately 283 * (without waiting for another broadcast to finish). Currently this only 284 * contains broadcasts to registered receivers, to avoid spinning up 285 * a bunch of processes to execute IntentReceiver components. 286 */ 287 final ArrayList<BroadcastRecord> mParallelBroadcasts 288 = new ArrayList<BroadcastRecord>(); 289 290 /** 291 * List of all active broadcasts that are to be executed one at a time. 292 * The object at the top of the list is the currently activity broadcasts; 293 * those after it are waiting for the top to finish.. 294 */ 295 final ArrayList<BroadcastRecord> mOrderedBroadcasts 296 = new ArrayList<BroadcastRecord>(); 297 298 /** 299 * Historical data of past broadcasts, for debugging. 300 */ 301 static final int MAX_BROADCAST_HISTORY = 25; 302 final BroadcastRecord[] mBroadcastHistory 303 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 304 305 /** 306 * Set when we current have a BROADCAST_INTENT_MSG in flight. 307 */ 308 boolean mBroadcastsScheduled = false; 309 310 /** 311 * Activity we have told the window manager to have key focus. 312 */ 313 ActivityRecord mFocusedActivity = null; 314 /** 315 * List of intents that were used to start the most recent tasks. 316 */ 317 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 318 319 /** 320 * Process management. 321 */ 322 final ProcessList mProcessList = new ProcessList(); 323 324 /** 325 * All of the applications we currently have running organized by name. 326 * The keys are strings of the application package name (as 327 * returned by the package manager), and the keys are ApplicationRecord 328 * objects. 329 */ 330 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 331 332 /** 333 * The currently running heavy-weight process, if any. 334 */ 335 ProcessRecord mHeavyWeightProcess = null; 336 337 /** 338 * The last time that various processes have crashed. 339 */ 340 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 341 342 /** 343 * Set of applications that we consider to be bad, and will reject 344 * incoming broadcasts from (which the user has no control over). 345 * Processes are added to this set when they have crashed twice within 346 * a minimum amount of time; they are removed from it when they are 347 * later restarted (hopefully due to some user action). The value is the 348 * time it was added to the list. 349 */ 350 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 351 352 /** 353 * All of the processes we currently have running organized by pid. 354 * The keys are the pid running the application. 355 * 356 * <p>NOTE: This object is protected by its own lock, NOT the global 357 * activity manager lock! 358 */ 359 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 360 361 /** 362 * All of the processes that have been forced to be foreground. The key 363 * is the pid of the caller who requested it (we hold a death 364 * link on it). 365 */ 366 abstract class ForegroundToken implements IBinder.DeathRecipient { 367 int pid; 368 IBinder token; 369 } 370 final SparseArray<ForegroundToken> mForegroundProcesses 371 = new SparseArray<ForegroundToken>(); 372 373 /** 374 * List of records for processes that someone had tried to start before the 375 * system was ready. We don't start them at that point, but ensure they 376 * are started by the time booting is complete. 377 */ 378 final ArrayList<ProcessRecord> mProcessesOnHold 379 = new ArrayList<ProcessRecord>(); 380 381 /** 382 * List of persistent applications that are in the process 383 * of being started. 384 */ 385 final ArrayList<ProcessRecord> mPersistentStartingProcesses 386 = new ArrayList<ProcessRecord>(); 387 388 /** 389 * Processes that are being forcibly torn down. 390 */ 391 final ArrayList<ProcessRecord> mRemovedProcesses 392 = new ArrayList<ProcessRecord>(); 393 394 /** 395 * List of running applications, sorted by recent usage. 396 * The first entry in the list is the least recently used. 397 * It contains ApplicationRecord objects. This list does NOT include 398 * any persistent application records (since we never want to exit them). 399 */ 400 final ArrayList<ProcessRecord> mLruProcesses 401 = new ArrayList<ProcessRecord>(); 402 403 /** 404 * List of processes that should gc as soon as things are idle. 405 */ 406 final ArrayList<ProcessRecord> mProcessesToGc 407 = new ArrayList<ProcessRecord>(); 408 409 /** 410 * This is the process holding what we currently consider to be 411 * the "home" activity. 412 */ 413 ProcessRecord mHomeProcess; 414 415 /** 416 * This is the process holding the activity the user last visited that 417 * is in a different process from the one they are currently in. 418 */ 419 ProcessRecord mPreviousProcess; 420 421 /** 422 * The time at which the previous process was last visible. 423 */ 424 long mPreviousProcessVisibleTime; 425 426 /** 427 * Packages that the user has asked to have run in screen size 428 * compatibility mode instead of filling the screen. 429 */ 430 final CompatModePackages mCompatModePackages; 431 432 /** 433 * Set of PendingResultRecord objects that are currently active. 434 */ 435 final HashSet mPendingResultRecords = new HashSet(); 436 437 /** 438 * Set of IntentSenderRecord objects that are currently active. 439 */ 440 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 441 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 442 443 /** 444 * Fingerprints (hashCode()) of stack traces that we've 445 * already logged DropBox entries for. Guarded by itself. If 446 * something (rogue user app) forces this over 447 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 448 */ 449 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 450 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 451 452 /** 453 * Strict Mode background batched logging state. 454 * 455 * The string buffer is guarded by itself, and its lock is also 456 * used to determine if another batched write is already 457 * in-flight. 458 */ 459 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 460 461 /** 462 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler. 463 */ 464 private boolean mPendingBroadcastTimeoutMessage; 465 466 /** 467 * Intent broadcast that we have tried to start, but are 468 * waiting for its application's process to be created. We only 469 * need one (instead of a list) because we always process broadcasts 470 * one at a time, so no others can be started while waiting for this 471 * one. 472 */ 473 BroadcastRecord mPendingBroadcast = null; 474 475 /** 476 * The receiver index that is pending, to restart the broadcast if needed. 477 */ 478 int mPendingBroadcastRecvIndex; 479 480 /** 481 * Keeps track of all IIntentReceivers that have been registered for 482 * broadcasts. Hash keys are the receiver IBinder, hash value is 483 * a ReceiverList. 484 */ 485 final HashMap mRegisteredReceivers = new HashMap(); 486 487 /** 488 * Resolver for broadcast intents to registered receivers. 489 * Holds BroadcastFilter (subclass of IntentFilter). 490 */ 491 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 492 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 493 @Override 494 protected boolean allowFilterResult( 495 BroadcastFilter filter, List<BroadcastFilter> dest) { 496 IBinder target = filter.receiverList.receiver.asBinder(); 497 for (int i=dest.size()-1; i>=0; i--) { 498 if (dest.get(i).receiverList.receiver.asBinder() == target) { 499 return false; 500 } 501 } 502 return true; 503 } 504 505 @Override 506 protected String packageForFilter(BroadcastFilter filter) { 507 return filter.packageName; 508 } 509 }; 510 511 /** 512 * State of all active sticky broadcasts. Keys are the action of the 513 * sticky Intent, values are an ArrayList of all broadcasted intents with 514 * that action (which should usually be one). 515 */ 516 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 517 new HashMap<String, ArrayList<Intent>>(); 518 519 /** 520 * All currently running services. 521 */ 522 final HashMap<ComponentName, ServiceRecord> mServices = 523 new HashMap<ComponentName, ServiceRecord>(); 524 525 /** 526 * All currently running services indexed by the Intent used to start them. 527 */ 528 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 529 new HashMap<Intent.FilterComparison, ServiceRecord>(); 530 531 /** 532 * All currently bound service connections. Keys are the IBinder of 533 * the client's IServiceConnection. 534 */ 535 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections 536 = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); 537 538 /** 539 * List of services that we have been asked to start, 540 * but haven't yet been able to. It is used to hold start requests 541 * while waiting for their corresponding application thread to get 542 * going. 543 */ 544 final ArrayList<ServiceRecord> mPendingServices 545 = new ArrayList<ServiceRecord>(); 546 547 /** 548 * List of services that are scheduled to restart following a crash. 549 */ 550 final ArrayList<ServiceRecord> mRestartingServices 551 = new ArrayList<ServiceRecord>(); 552 553 /** 554 * List of services that are in the process of being stopped. 555 */ 556 final ArrayList<ServiceRecord> mStoppingServices 557 = new ArrayList<ServiceRecord>(); 558 559 /** 560 * Backup/restore process management 561 */ 562 String mBackupAppName = null; 563 BackupRecord mBackupTarget = null; 564 565 /** 566 * List of PendingThumbnailsRecord objects of clients who are still 567 * waiting to receive all of the thumbnails for a task. 568 */ 569 final ArrayList mPendingThumbnails = new ArrayList(); 570 571 /** 572 * List of HistoryRecord objects that have been finished and must 573 * still report back to a pending thumbnail receiver. 574 */ 575 final ArrayList mCancelledThumbnails = new ArrayList(); 576 577 /** 578 * All of the currently running global content providers. Keys are a 579 * string containing the provider name and values are a 580 * ContentProviderRecord object containing the data about it. Note 581 * that a single provider may be published under multiple names, so 582 * there may be multiple entries here for a single one in mProvidersByClass. 583 */ 584 final HashMap<String, ContentProviderRecord> mProvidersByName 585 = new HashMap<String, ContentProviderRecord>(); 586 587 /** 588 * All of the currently running global content providers. Keys are a 589 * string containing the provider's implementation class and values are a 590 * ContentProviderRecord object containing the data about it. 591 */ 592 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass 593 = new HashMap<ComponentName, ContentProviderRecord>(); 594 595 /** 596 * List of content providers who have clients waiting for them. The 597 * application is currently being launched and the provider will be 598 * removed from this list once it is published. 599 */ 600 final ArrayList<ContentProviderRecord> mLaunchingProviders 601 = new ArrayList<ContentProviderRecord>(); 602 603 /** 604 * Global set of specific Uri permissions that have been granted. 605 */ 606 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 607 = new SparseArray<HashMap<Uri, UriPermission>>(); 608 609 CoreSettingsObserver mCoreSettingsObserver; 610 611 /** 612 * Thread-local storage used to carry caller permissions over through 613 * indirect content-provider access. 614 * @see #ActivityManagerService.openContentUri() 615 */ 616 private class Identity { 617 public int pid; 618 public int uid; 619 620 Identity(int _pid, int _uid) { 621 pid = _pid; 622 uid = _uid; 623 } 624 } 625 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 626 627 /** 628 * All information we have collected about the runtime performance of 629 * any user id that can impact battery performance. 630 */ 631 final BatteryStatsService mBatteryStatsService; 632 633 /** 634 * information about component usage 635 */ 636 final UsageStatsService mUsageStatsService; 637 638 /** 639 * Current configuration information. HistoryRecord objects are given 640 * a reference to this object to indicate which configuration they are 641 * currently running in, so this object must be kept immutable. 642 */ 643 Configuration mConfiguration = new Configuration(); 644 645 /** 646 * Current sequencing integer of the configuration, for skipping old 647 * configurations. 648 */ 649 int mConfigurationSeq = 0; 650 651 /** 652 * Hardware-reported OpenGLES version. 653 */ 654 final int GL_ES_VERSION; 655 656 /** 657 * List of initialization arguments to pass to all processes when binding applications to them. 658 * For example, references to the commonly used services. 659 */ 660 HashMap<String, IBinder> mAppBindArgs; 661 662 /** 663 * Temporary to avoid allocations. Protected by main lock. 664 */ 665 final StringBuilder mStringBuilder = new StringBuilder(256); 666 667 /** 668 * Used to control how we initialize the service. 669 */ 670 boolean mStartRunning = false; 671 ComponentName mTopComponent; 672 String mTopAction; 673 String mTopData; 674 boolean mProcessesReady = false; 675 boolean mSystemReady = false; 676 boolean mBooting = false; 677 boolean mWaitingUpdate = false; 678 boolean mDidUpdate = false; 679 boolean mOnBattery = false; 680 boolean mLaunchWarningShown = false; 681 682 Context mContext; 683 684 int mFactoryTest; 685 686 boolean mCheckedForSetup; 687 688 /** 689 * The time at which we will allow normal application switches again, 690 * after a call to {@link #stopAppSwitches()}. 691 */ 692 long mAppSwitchesAllowedTime; 693 694 /** 695 * This is set to true after the first switch after mAppSwitchesAllowedTime 696 * is set; any switches after that will clear the time. 697 */ 698 boolean mDidAppSwitch; 699 700 /** 701 * Last time (in realtime) at which we checked for power usage. 702 */ 703 long mLastPowerCheckRealtime; 704 705 /** 706 * Last time (in uptime) at which we checked for power usage. 707 */ 708 long mLastPowerCheckUptime; 709 710 /** 711 * Set while we are wanting to sleep, to prevent any 712 * activities from being started/resumed. 713 */ 714 boolean mSleeping = false; 715 716 /** 717 * Set if we are shutting down the system, similar to sleeping. 718 */ 719 boolean mShuttingDown = false; 720 721 /** 722 * Task identifier that activities are currently being started 723 * in. Incremented each time a new task is created. 724 * todo: Replace this with a TokenSpace class that generates non-repeating 725 * integers that won't wrap. 726 */ 727 int mCurTask = 1; 728 729 /** 730 * Current sequence id for oom_adj computation traversal. 731 */ 732 int mAdjSeq = 0; 733 734 /** 735 * Current sequence id for process LRU updating. 736 */ 737 int mLruSeq = 0; 738 739 /** 740 * Keep track of the number of service processes we last found, to 741 * determine on the next iteration which should be B services. 742 */ 743 int mNumServiceProcs = 0; 744 int mNewNumServiceProcs = 0; 745 746 /** 747 * System monitoring: number of processes that died since the last 748 * N procs were started. 749 */ 750 int[] mProcDeaths = new int[20]; 751 752 /** 753 * This is set if we had to do a delayed dexopt of an app before launching 754 * it, to increasing the ANR timeouts in that case. 755 */ 756 boolean mDidDexOpt; 757 758 String mDebugApp = null; 759 boolean mWaitForDebugger = false; 760 boolean mDebugTransient = false; 761 String mOrigDebugApp = null; 762 boolean mOrigWaitForDebugger = false; 763 boolean mAlwaysFinishActivities = false; 764 IActivityController mController = null; 765 String mProfileApp = null; 766 ProcessRecord mProfileProc = null; 767 String mProfileFile; 768 ParcelFileDescriptor mProfileFd; 769 int mProfileType = 0; 770 boolean mAutoStopProfiler = false; 771 772 final RemoteCallbackList<IActivityWatcher> mWatchers 773 = new RemoteCallbackList<IActivityWatcher>(); 774 775 final RemoteCallbackList<IProcessObserver> mProcessObservers 776 = new RemoteCallbackList<IProcessObserver>(); 777 778 /** 779 * Callback of last caller to {@link #requestPss}. 780 */ 781 Runnable mRequestPssCallback; 782 783 /** 784 * Remaining processes for which we are waiting results from the last 785 * call to {@link #requestPss}. 786 */ 787 final ArrayList<ProcessRecord> mRequestPssList 788 = new ArrayList<ProcessRecord>(); 789 790 /** 791 * Runtime statistics collection thread. This object's lock is used to 792 * protect all related state. 793 */ 794 final Thread mProcessStatsThread; 795 796 /** 797 * Used to collect process stats when showing not responding dialog. 798 * Protected by mProcessStatsThread. 799 */ 800 final ProcessStats mProcessStats = new ProcessStats( 801 MONITOR_THREAD_CPU_USAGE); 802 final AtomicLong mLastCpuTime = new AtomicLong(0); 803 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 804 805 long mLastWriteTime = 0; 806 807 /** 808 * Set to true after the system has finished booting. 809 */ 810 boolean mBooted = false; 811 812 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 813 int mProcessLimitOverride = -1; 814 815 WindowManagerService mWindowManager; 816 817 static ActivityManagerService mSelf; 818 static ActivityThread mSystemThread; 819 820 private final class AppDeathRecipient implements IBinder.DeathRecipient { 821 final ProcessRecord mApp; 822 final int mPid; 823 final IApplicationThread mAppThread; 824 825 AppDeathRecipient(ProcessRecord app, int pid, 826 IApplicationThread thread) { 827 if (localLOGV) Slog.v( 828 TAG, "New death recipient " + this 829 + " for thread " + thread.asBinder()); 830 mApp = app; 831 mPid = pid; 832 mAppThread = thread; 833 } 834 835 public void binderDied() { 836 if (localLOGV) Slog.v( 837 TAG, "Death received in " + this 838 + " for thread " + mAppThread.asBinder()); 839 synchronized(ActivityManagerService.this) { 840 appDiedLocked(mApp, mPid, mAppThread); 841 } 842 } 843 } 844 845 static final int SHOW_ERROR_MSG = 1; 846 static final int SHOW_NOT_RESPONDING_MSG = 2; 847 static final int SHOW_FACTORY_ERROR_MSG = 3; 848 static final int UPDATE_CONFIGURATION_MSG = 4; 849 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 850 static final int WAIT_FOR_DEBUGGER_MSG = 6; 851 static final int BROADCAST_INTENT_MSG = 7; 852 static final int BROADCAST_TIMEOUT_MSG = 8; 853 static final int SERVICE_TIMEOUT_MSG = 12; 854 static final int UPDATE_TIME_ZONE = 13; 855 static final int SHOW_UID_ERROR_MSG = 14; 856 static final int IM_FEELING_LUCKY_MSG = 15; 857 static final int PROC_START_TIMEOUT_MSG = 20; 858 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 859 static final int KILL_APPLICATION_MSG = 22; 860 static final int FINALIZE_PENDING_INTENT_MSG = 23; 861 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 862 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 863 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 864 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 865 static final int CLEAR_DNS_CACHE = 28; 866 static final int UPDATE_HTTP_PROXY = 29; 867 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 868 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31; 869 static final int DISPATCH_PROCESS_DIED = 32; 870 static final int REPORT_MEM_USAGE = 33; 871 872 AlertDialog mUidAlert; 873 CompatModeDialog mCompatModeDialog; 874 long mLastMemUsageReportTime = 0; 875 876 final Handler mHandler = new Handler() { 877 //public Handler() { 878 // if (localLOGV) Slog.v(TAG, "Handler started!"); 879 //} 880 881 public void handleMessage(Message msg) { 882 switch (msg.what) { 883 case SHOW_ERROR_MSG: { 884 HashMap data = (HashMap) msg.obj; 885 synchronized (ActivityManagerService.this) { 886 ProcessRecord proc = (ProcessRecord)data.get("app"); 887 if (proc != null && proc.crashDialog != null) { 888 Slog.e(TAG, "App already has crash dialog: " + proc); 889 return; 890 } 891 AppErrorResult res = (AppErrorResult) data.get("result"); 892 if (!mSleeping && !mShuttingDown) { 893 Dialog d = new AppErrorDialog(mContext, res, proc); 894 d.show(); 895 proc.crashDialog = d; 896 } else { 897 // The device is asleep, so just pretend that the user 898 // saw a crash dialog and hit "force quit". 899 res.set(0); 900 } 901 } 902 903 ensureBootCompleted(); 904 } break; 905 case SHOW_NOT_RESPONDING_MSG: { 906 synchronized (ActivityManagerService.this) { 907 HashMap data = (HashMap) msg.obj; 908 ProcessRecord proc = (ProcessRecord)data.get("app"); 909 if (proc != null && proc.anrDialog != null) { 910 Slog.e(TAG, "App already has anr dialog: " + proc); 911 return; 912 } 913 914 Intent intent = new Intent("android.intent.action.ANR"); 915 if (!mProcessesReady) { 916 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 917 } 918 broadcastIntentLocked(null, null, intent, 919 null, null, 0, null, null, null, 920 false, false, MY_PID, Process.SYSTEM_UID); 921 922 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 923 mContext, proc, (ActivityRecord)data.get("activity")); 924 d.show(); 925 proc.anrDialog = d; 926 } 927 928 ensureBootCompleted(); 929 } break; 930 case SHOW_STRICT_MODE_VIOLATION_MSG: { 931 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 932 synchronized (ActivityManagerService.this) { 933 ProcessRecord proc = (ProcessRecord) data.get("app"); 934 if (proc == null) { 935 Slog.e(TAG, "App not found when showing strict mode dialog."); 936 break; 937 } 938 if (proc.crashDialog != null) { 939 Slog.e(TAG, "App already has strict mode dialog: " + proc); 940 return; 941 } 942 AppErrorResult res = (AppErrorResult) data.get("result"); 943 if (!mSleeping && !mShuttingDown) { 944 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 945 d.show(); 946 proc.crashDialog = d; 947 } else { 948 // The device is asleep, so just pretend that the user 949 // saw a crash dialog and hit "force quit". 950 res.set(0); 951 } 952 } 953 ensureBootCompleted(); 954 } break; 955 case SHOW_FACTORY_ERROR_MSG: { 956 Dialog d = new FactoryErrorDialog( 957 mContext, msg.getData().getCharSequence("msg")); 958 d.show(); 959 ensureBootCompleted(); 960 } break; 961 case UPDATE_CONFIGURATION_MSG: { 962 final ContentResolver resolver = mContext.getContentResolver(); 963 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 964 } break; 965 case GC_BACKGROUND_PROCESSES_MSG: { 966 synchronized (ActivityManagerService.this) { 967 performAppGcsIfAppropriateLocked(); 968 } 969 } break; 970 case WAIT_FOR_DEBUGGER_MSG: { 971 synchronized (ActivityManagerService.this) { 972 ProcessRecord app = (ProcessRecord)msg.obj; 973 if (msg.arg1 != 0) { 974 if (!app.waitedForDebugger) { 975 Dialog d = new AppWaitingForDebuggerDialog( 976 ActivityManagerService.this, 977 mContext, app); 978 app.waitDialog = d; 979 app.waitedForDebugger = true; 980 d.show(); 981 } 982 } else { 983 if (app.waitDialog != null) { 984 app.waitDialog.dismiss(); 985 app.waitDialog = null; 986 } 987 } 988 } 989 } break; 990 case BROADCAST_INTENT_MSG: { 991 if (DEBUG_BROADCAST) Slog.v( 992 TAG, "Received BROADCAST_INTENT_MSG"); 993 processNextBroadcast(true); 994 } break; 995 case BROADCAST_TIMEOUT_MSG: { 996 synchronized (ActivityManagerService.this) { 997 broadcastTimeoutLocked(true); 998 } 999 } break; 1000 case SERVICE_TIMEOUT_MSG: { 1001 if (mDidDexOpt) { 1002 mDidDexOpt = false; 1003 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1004 nmsg.obj = msg.obj; 1005 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1006 return; 1007 } 1008 serviceTimeout((ProcessRecord)msg.obj); 1009 } break; 1010 case UPDATE_TIME_ZONE: { 1011 synchronized (ActivityManagerService.this) { 1012 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1013 ProcessRecord r = mLruProcesses.get(i); 1014 if (r.thread != null) { 1015 try { 1016 r.thread.updateTimeZone(); 1017 } catch (RemoteException ex) { 1018 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1019 } 1020 } 1021 } 1022 } 1023 } break; 1024 case CLEAR_DNS_CACHE: { 1025 synchronized (ActivityManagerService.this) { 1026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1027 ProcessRecord r = mLruProcesses.get(i); 1028 if (r.thread != null) { 1029 try { 1030 r.thread.clearDnsCache(); 1031 } catch (RemoteException ex) { 1032 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1033 } 1034 } 1035 } 1036 } 1037 } break; 1038 case UPDATE_HTTP_PROXY: { 1039 ProxyProperties proxy = (ProxyProperties)msg.obj; 1040 String host = ""; 1041 String port = ""; 1042 String exclList = ""; 1043 if (proxy != null) { 1044 host = proxy.getHost(); 1045 port = Integer.toString(proxy.getPort()); 1046 exclList = proxy.getExclusionList(); 1047 } 1048 synchronized (ActivityManagerService.this) { 1049 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1050 ProcessRecord r = mLruProcesses.get(i); 1051 if (r.thread != null) { 1052 try { 1053 r.thread.setHttpProxy(host, port, exclList); 1054 } catch (RemoteException ex) { 1055 Slog.w(TAG, "Failed to update http proxy for: " + 1056 r.info.processName); 1057 } 1058 } 1059 } 1060 } 1061 } break; 1062 case SHOW_UID_ERROR_MSG: { 1063 // XXX This is a temporary dialog, no need to localize. 1064 AlertDialog d = new BaseErrorDialog(mContext); 1065 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1066 d.setCancelable(false); 1067 d.setTitle("System UIDs Inconsistent"); 1068 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1069 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1070 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1071 mUidAlert = d; 1072 d.show(); 1073 } break; 1074 case IM_FEELING_LUCKY_MSG: { 1075 if (mUidAlert != null) { 1076 mUidAlert.dismiss(); 1077 mUidAlert = null; 1078 } 1079 } break; 1080 case PROC_START_TIMEOUT_MSG: { 1081 if (mDidDexOpt) { 1082 mDidDexOpt = false; 1083 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1084 nmsg.obj = msg.obj; 1085 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1086 return; 1087 } 1088 ProcessRecord app = (ProcessRecord)msg.obj; 1089 synchronized (ActivityManagerService.this) { 1090 processStartTimedOutLocked(app); 1091 } 1092 } break; 1093 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1094 synchronized (ActivityManagerService.this) { 1095 doPendingActivityLaunchesLocked(true); 1096 } 1097 } break; 1098 case KILL_APPLICATION_MSG: { 1099 synchronized (ActivityManagerService.this) { 1100 int uid = msg.arg1; 1101 boolean restart = (msg.arg2 == 1); 1102 String pkg = (String) msg.obj; 1103 forceStopPackageLocked(pkg, uid, restart, false, true, false); 1104 } 1105 } break; 1106 case FINALIZE_PENDING_INTENT_MSG: { 1107 ((PendingIntentRecord)msg.obj).completeFinalize(); 1108 } break; 1109 case POST_HEAVY_NOTIFICATION_MSG: { 1110 INotificationManager inm = NotificationManager.getService(); 1111 if (inm == null) { 1112 return; 1113 } 1114 1115 ActivityRecord root = (ActivityRecord)msg.obj; 1116 ProcessRecord process = root.app; 1117 if (process == null) { 1118 return; 1119 } 1120 1121 try { 1122 Context context = mContext.createPackageContext(process.info.packageName, 0); 1123 String text = mContext.getString(R.string.heavy_weight_notification, 1124 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1125 Notification notification = new Notification(); 1126 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1127 notification.when = 0; 1128 notification.flags = Notification.FLAG_ONGOING_EVENT; 1129 notification.tickerText = text; 1130 notification.defaults = 0; // please be quiet 1131 notification.sound = null; 1132 notification.vibrate = null; 1133 notification.setLatestEventInfo(context, text, 1134 mContext.getText(R.string.heavy_weight_notification_detail), 1135 PendingIntent.getActivity(mContext, 0, root.intent, 1136 PendingIntent.FLAG_CANCEL_CURRENT)); 1137 1138 try { 1139 int[] outId = new int[1]; 1140 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1141 notification, outId); 1142 } catch (RuntimeException e) { 1143 Slog.w(ActivityManagerService.TAG, 1144 "Error showing notification for heavy-weight app", e); 1145 } catch (RemoteException e) { 1146 } 1147 } catch (NameNotFoundException e) { 1148 Slog.w(TAG, "Unable to create context for heavy notification", e); 1149 } 1150 } break; 1151 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1152 INotificationManager inm = NotificationManager.getService(); 1153 if (inm == null) { 1154 return; 1155 } 1156 try { 1157 inm.cancelNotification("android", 1158 R.string.heavy_weight_notification); 1159 } catch (RuntimeException e) { 1160 Slog.w(ActivityManagerService.TAG, 1161 "Error canceling notification for service", e); 1162 } catch (RemoteException e) { 1163 } 1164 } break; 1165 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1166 synchronized (ActivityManagerService.this) { 1167 checkExcessivePowerUsageLocked(true); 1168 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1169 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1170 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1171 } 1172 } break; 1173 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1174 synchronized (ActivityManagerService.this) { 1175 ActivityRecord ar = (ActivityRecord)msg.obj; 1176 if (mCompatModeDialog != null) { 1177 if (mCompatModeDialog.mAppInfo.packageName.equals( 1178 ar.info.applicationInfo.packageName)) { 1179 return; 1180 } 1181 mCompatModeDialog.dismiss(); 1182 mCompatModeDialog = null; 1183 } 1184 if (ar != null && false) { 1185 if (mCompatModePackages.getPackageAskCompatModeLocked( 1186 ar.packageName)) { 1187 int mode = mCompatModePackages.computeCompatModeLocked( 1188 ar.info.applicationInfo); 1189 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1190 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1191 mCompatModeDialog = new CompatModeDialog( 1192 ActivityManagerService.this, mContext, 1193 ar.info.applicationInfo); 1194 mCompatModeDialog.show(); 1195 } 1196 } 1197 } 1198 } 1199 break; 1200 } 1201 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: { 1202 final int pid = msg.arg1; 1203 final int uid = msg.arg2; 1204 final boolean foregroundActivities = (Boolean) msg.obj; 1205 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities); 1206 break; 1207 } 1208 case DISPATCH_PROCESS_DIED: { 1209 final int pid = msg.arg1; 1210 final int uid = msg.arg2; 1211 dispatchProcessDied(pid, uid); 1212 break; 1213 } 1214 case REPORT_MEM_USAGE: { 1215 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1216 if (!isDebuggable) { 1217 return; 1218 } 1219 synchronized (ActivityManagerService.this) { 1220 long now = SystemClock.uptimeMillis(); 1221 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1222 // Don't report more than every 5 minutes to somewhat 1223 // avoid spamming. 1224 return; 1225 } 1226 mLastMemUsageReportTime = now; 1227 } 1228 Thread thread = new Thread() { 1229 @Override public void run() { 1230 StringBuilder dropBuilder = new StringBuilder(1024); 1231 StringBuilder logBuilder = new StringBuilder(1024); 1232 StringWriter oomSw = new StringWriter(); 1233 PrintWriter oomPw = new PrintWriter(oomSw); 1234 StringWriter catSw = new StringWriter(); 1235 PrintWriter catPw = new PrintWriter(catSw); 1236 String[] emptyArgs = new String[] { }; 1237 StringBuilder tag = new StringBuilder(128); 1238 StringBuilder stack = new StringBuilder(128); 1239 tag.append("Low on memory -- "); 1240 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1241 tag, stack); 1242 dropBuilder.append(stack); 1243 dropBuilder.append('\n'); 1244 dropBuilder.append('\n'); 1245 String oomString = oomSw.toString(); 1246 dropBuilder.append(oomString); 1247 dropBuilder.append('\n'); 1248 logBuilder.append(oomString); 1249 try { 1250 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1251 "procrank", }); 1252 final InputStreamReader converter = new InputStreamReader( 1253 proc.getInputStream()); 1254 BufferedReader in = new BufferedReader(converter); 1255 String line; 1256 while (true) { 1257 line = in.readLine(); 1258 if (line == null) { 1259 break; 1260 } 1261 if (line.length() > 0) { 1262 logBuilder.append(line); 1263 logBuilder.append('\n'); 1264 } 1265 dropBuilder.append(line); 1266 dropBuilder.append('\n'); 1267 } 1268 converter.close(); 1269 } catch (IOException e) { 1270 } 1271 synchronized (ActivityManagerService.this) { 1272 catPw.println(); 1273 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1274 catPw.println(); 1275 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null); 1276 catPw.println(); 1277 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1278 } 1279 dropBuilder.append(catSw.toString()); 1280 addErrorToDropBox("lowmem", null, "system_server", null, 1281 null, tag.toString(), dropBuilder.toString(), null, null); 1282 Slog.i(TAG, logBuilder.toString()); 1283 synchronized (ActivityManagerService.this) { 1284 long now = SystemClock.uptimeMillis(); 1285 if (mLastMemUsageReportTime < now) { 1286 mLastMemUsageReportTime = now; 1287 } 1288 } 1289 } 1290 }; 1291 thread.start(); 1292 break; 1293 } 1294 } 1295 } 1296 }; 1297 1298 public static void setSystemProcess() { 1299 try { 1300 ActivityManagerService m = mSelf; 1301 1302 ServiceManager.addService("activity", m); 1303 ServiceManager.addService("meminfo", new MemBinder(m)); 1304 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1305 if (MONITOR_CPU_USAGE) { 1306 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1307 } 1308 ServiceManager.addService("permission", new PermissionController(m)); 1309 1310 ApplicationInfo info = 1311 mSelf.mContext.getPackageManager().getApplicationInfo( 1312 "android", STOCK_PM_FLAGS); 1313 mSystemThread.installSystemApplicationInfo(info); 1314 1315 synchronized (mSelf) { 1316 ProcessRecord app = mSelf.newProcessRecordLocked( 1317 mSystemThread.getApplicationThread(), info, 1318 info.processName); 1319 app.persistent = true; 1320 app.pid = MY_PID; 1321 app.maxAdj = ProcessList.SYSTEM_ADJ; 1322 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1323 synchronized (mSelf.mPidsSelfLocked) { 1324 mSelf.mPidsSelfLocked.put(app.pid, app); 1325 } 1326 mSelf.updateLruProcessLocked(app, true, true); 1327 } 1328 } catch (PackageManager.NameNotFoundException e) { 1329 throw new RuntimeException( 1330 "Unable to find android system package", e); 1331 } 1332 } 1333 1334 public void setWindowManager(WindowManagerService wm) { 1335 mWindowManager = wm; 1336 } 1337 1338 public static final Context main(int factoryTest) { 1339 AThread thr = new AThread(); 1340 thr.start(); 1341 1342 synchronized (thr) { 1343 while (thr.mService == null) { 1344 try { 1345 thr.wait(); 1346 } catch (InterruptedException e) { 1347 } 1348 } 1349 } 1350 1351 ActivityManagerService m = thr.mService; 1352 mSelf = m; 1353 ActivityThread at = ActivityThread.systemMain(); 1354 mSystemThread = at; 1355 Context context = at.getSystemContext(); 1356 context.setTheme(android.R.style.Theme_Holo); 1357 m.mContext = context; 1358 m.mFactoryTest = factoryTest; 1359 m.mMainStack = new ActivityStack(m, context, true); 1360 1361 m.mBatteryStatsService.publish(context); 1362 m.mUsageStatsService.publish(context); 1363 1364 synchronized (thr) { 1365 thr.mReady = true; 1366 thr.notifyAll(); 1367 } 1368 1369 m.startRunning(null, null, null, null); 1370 1371 return context; 1372 } 1373 1374 public static ActivityManagerService self() { 1375 return mSelf; 1376 } 1377 1378 static class AThread extends Thread { 1379 ActivityManagerService mService; 1380 boolean mReady = false; 1381 1382 public AThread() { 1383 super("ActivityManager"); 1384 } 1385 1386 public void run() { 1387 Looper.prepare(); 1388 1389 android.os.Process.setThreadPriority( 1390 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1391 android.os.Process.setCanSelfBackground(false); 1392 1393 ActivityManagerService m = new ActivityManagerService(); 1394 1395 synchronized (this) { 1396 mService = m; 1397 notifyAll(); 1398 } 1399 1400 synchronized (this) { 1401 while (!mReady) { 1402 try { 1403 wait(); 1404 } catch (InterruptedException e) { 1405 } 1406 } 1407 } 1408 1409 // For debug builds, log event loop stalls to dropbox for analysis. 1410 if (StrictMode.conditionallyEnableDebugLogging()) { 1411 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1412 } 1413 1414 Looper.loop(); 1415 } 1416 } 1417 1418 static class MemBinder extends Binder { 1419 ActivityManagerService mActivityManagerService; 1420 MemBinder(ActivityManagerService activityManagerService) { 1421 mActivityManagerService = activityManagerService; 1422 } 1423 1424 @Override 1425 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1426 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1427 != PackageManager.PERMISSION_GRANTED) { 1428 pw.println("Permission Denial: can't dump meminfo from from pid=" 1429 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1430 + " without permission " + android.Manifest.permission.DUMP); 1431 return; 1432 } 1433 1434 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1435 false, null, null, null); 1436 } 1437 } 1438 1439 static class GraphicsBinder extends Binder { 1440 ActivityManagerService mActivityManagerService; 1441 GraphicsBinder(ActivityManagerService activityManagerService) { 1442 mActivityManagerService = activityManagerService; 1443 } 1444 1445 @Override 1446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1447 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1448 != PackageManager.PERMISSION_GRANTED) { 1449 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1450 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1451 + " without permission " + android.Manifest.permission.DUMP); 1452 return; 1453 } 1454 1455 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1456 } 1457 } 1458 1459 static class CpuBinder extends Binder { 1460 ActivityManagerService mActivityManagerService; 1461 CpuBinder(ActivityManagerService activityManagerService) { 1462 mActivityManagerService = activityManagerService; 1463 } 1464 1465 @Override 1466 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1467 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1468 != PackageManager.PERMISSION_GRANTED) { 1469 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1470 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1471 + " without permission " + android.Manifest.permission.DUMP); 1472 return; 1473 } 1474 1475 synchronized (mActivityManagerService.mProcessStatsThread) { 1476 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1477 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1478 SystemClock.uptimeMillis())); 1479 } 1480 } 1481 } 1482 1483 private ActivityManagerService() { 1484 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1485 1486 File dataDir = Environment.getDataDirectory(); 1487 File systemDir = new File(dataDir, "system"); 1488 systemDir.mkdirs(); 1489 mBatteryStatsService = new BatteryStatsService(new File( 1490 systemDir, "batterystats.bin").toString()); 1491 mBatteryStatsService.getActiveStatistics().readLocked(); 1492 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1493 mOnBattery = DEBUG_POWER ? true 1494 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1495 mBatteryStatsService.getActiveStatistics().setCallback(this); 1496 1497 mUsageStatsService = new UsageStatsService(new File( 1498 systemDir, "usagestats").toString()); 1499 1500 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1501 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1502 1503 mConfiguration.setToDefaults(); 1504 mConfiguration.locale = Locale.getDefault(); 1505 mConfigurationSeq = mConfiguration.seq = 1; 1506 mProcessStats.init(); 1507 1508 mCompatModePackages = new CompatModePackages(this, systemDir); 1509 1510 // Add ourself to the Watchdog monitors. 1511 Watchdog.getInstance().addMonitor(this); 1512 1513 mProcessStatsThread = new Thread("ProcessStats") { 1514 public void run() { 1515 while (true) { 1516 try { 1517 try { 1518 synchronized(this) { 1519 final long now = SystemClock.uptimeMillis(); 1520 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1521 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1522 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1523 // + ", write delay=" + nextWriteDelay); 1524 if (nextWriteDelay < nextCpuDelay) { 1525 nextCpuDelay = nextWriteDelay; 1526 } 1527 if (nextCpuDelay > 0) { 1528 mProcessStatsMutexFree.set(true); 1529 this.wait(nextCpuDelay); 1530 } 1531 } 1532 } catch (InterruptedException e) { 1533 } 1534 updateCpuStatsNow(); 1535 } catch (Exception e) { 1536 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1537 } 1538 } 1539 } 1540 }; 1541 mProcessStatsThread.start(); 1542 } 1543 1544 @Override 1545 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1546 throws RemoteException { 1547 try { 1548 return super.onTransact(code, data, reply, flags); 1549 } catch (RuntimeException e) { 1550 // The activity manager only throws security exceptions, so let's 1551 // log all others. 1552 if (!(e instanceof SecurityException)) { 1553 Slog.e(TAG, "Activity Manager Crash", e); 1554 } 1555 throw e; 1556 } 1557 } 1558 1559 void updateCpuStats() { 1560 final long now = SystemClock.uptimeMillis(); 1561 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1562 return; 1563 } 1564 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1565 synchronized (mProcessStatsThread) { 1566 mProcessStatsThread.notify(); 1567 } 1568 } 1569 } 1570 1571 void updateCpuStatsNow() { 1572 synchronized (mProcessStatsThread) { 1573 mProcessStatsMutexFree.set(false); 1574 final long now = SystemClock.uptimeMillis(); 1575 boolean haveNewCpuStats = false; 1576 1577 if (MONITOR_CPU_USAGE && 1578 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1579 mLastCpuTime.set(now); 1580 haveNewCpuStats = true; 1581 mProcessStats.update(); 1582 //Slog.i(TAG, mProcessStats.printCurrentState()); 1583 //Slog.i(TAG, "Total CPU usage: " 1584 // + mProcessStats.getTotalCpuPercent() + "%"); 1585 1586 // Slog the cpu usage if the property is set. 1587 if ("true".equals(SystemProperties.get("events.cpu"))) { 1588 int user = mProcessStats.getLastUserTime(); 1589 int system = mProcessStats.getLastSystemTime(); 1590 int iowait = mProcessStats.getLastIoWaitTime(); 1591 int irq = mProcessStats.getLastIrqTime(); 1592 int softIrq = mProcessStats.getLastSoftIrqTime(); 1593 int idle = mProcessStats.getLastIdleTime(); 1594 1595 int total = user + system + iowait + irq + softIrq + idle; 1596 if (total == 0) total = 1; 1597 1598 EventLog.writeEvent(EventLogTags.CPU, 1599 ((user+system+iowait+irq+softIrq) * 100) / total, 1600 (user * 100) / total, 1601 (system * 100) / total, 1602 (iowait * 100) / total, 1603 (irq * 100) / total, 1604 (softIrq * 100) / total); 1605 } 1606 } 1607 1608 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1609 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1610 synchronized(bstats) { 1611 synchronized(mPidsSelfLocked) { 1612 if (haveNewCpuStats) { 1613 if (mOnBattery) { 1614 int perc = bstats.startAddingCpuLocked(); 1615 int totalUTime = 0; 1616 int totalSTime = 0; 1617 final int N = mProcessStats.countStats(); 1618 for (int i=0; i<N; i++) { 1619 ProcessStats.Stats st = mProcessStats.getStats(i); 1620 if (!st.working) { 1621 continue; 1622 } 1623 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1624 int otherUTime = (st.rel_utime*perc)/100; 1625 int otherSTime = (st.rel_stime*perc)/100; 1626 totalUTime += otherUTime; 1627 totalSTime += otherSTime; 1628 if (pr != null) { 1629 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1630 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1631 st.rel_stime-otherSTime); 1632 ps.addSpeedStepTimes(cpuSpeedTimes); 1633 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1634 } else { 1635 BatteryStatsImpl.Uid.Proc ps = 1636 bstats.getProcessStatsLocked(st.name, st.pid); 1637 if (ps != null) { 1638 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1639 st.rel_stime-otherSTime); 1640 ps.addSpeedStepTimes(cpuSpeedTimes); 1641 } 1642 } 1643 } 1644 bstats.finishAddingCpuLocked(perc, totalUTime, 1645 totalSTime, cpuSpeedTimes); 1646 } 1647 } 1648 } 1649 1650 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1651 mLastWriteTime = now; 1652 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1653 } 1654 } 1655 } 1656 } 1657 1658 @Override 1659 public void batteryNeedsCpuUpdate() { 1660 updateCpuStatsNow(); 1661 } 1662 1663 @Override 1664 public void batteryPowerChanged(boolean onBattery) { 1665 // When plugging in, update the CPU stats first before changing 1666 // the plug state. 1667 updateCpuStatsNow(); 1668 synchronized (this) { 1669 synchronized(mPidsSelfLocked) { 1670 mOnBattery = DEBUG_POWER ? true : onBattery; 1671 } 1672 } 1673 } 1674 1675 /** 1676 * Initialize the application bind args. These are passed to each 1677 * process when the bindApplication() IPC is sent to the process. They're 1678 * lazily setup to make sure the services are running when they're asked for. 1679 */ 1680 private HashMap<String, IBinder> getCommonServicesLocked() { 1681 if (mAppBindArgs == null) { 1682 mAppBindArgs = new HashMap<String, IBinder>(); 1683 1684 // Setup the application init args 1685 mAppBindArgs.put("package", ServiceManager.getService("package")); 1686 mAppBindArgs.put("window", ServiceManager.getService("window")); 1687 mAppBindArgs.put(Context.ALARM_SERVICE, 1688 ServiceManager.getService(Context.ALARM_SERVICE)); 1689 } 1690 return mAppBindArgs; 1691 } 1692 1693 final void setFocusedActivityLocked(ActivityRecord r) { 1694 if (mFocusedActivity != r) { 1695 mFocusedActivity = r; 1696 if (r != null) { 1697 mWindowManager.setFocusedApp(r.appToken, true); 1698 } 1699 } 1700 } 1701 1702 private final void updateLruProcessInternalLocked(ProcessRecord app, 1703 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1704 // put it on the LRU to keep track of when it should be exited. 1705 int lrui = mLruProcesses.indexOf(app); 1706 if (lrui >= 0) mLruProcesses.remove(lrui); 1707 1708 int i = mLruProcesses.size()-1; 1709 int skipTop = 0; 1710 1711 app.lruSeq = mLruSeq; 1712 1713 // compute the new weight for this process. 1714 if (updateActivityTime) { 1715 app.lastActivityTime = SystemClock.uptimeMillis(); 1716 } 1717 if (app.activities.size() > 0) { 1718 // If this process has activities, we more strongly want to keep 1719 // it around. 1720 app.lruWeight = app.lastActivityTime; 1721 } else if (app.pubProviders.size() > 0) { 1722 // If this process contains content providers, we want to keep 1723 // it a little more strongly. 1724 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1725 // Also don't let it kick out the first few "real" hidden processes. 1726 skipTop = ProcessList.MIN_HIDDEN_APPS; 1727 } else { 1728 // If this process doesn't have activities, we less strongly 1729 // want to keep it around, and generally want to avoid getting 1730 // in front of any very recently used activities. 1731 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1732 // Also don't let it kick out the first few "real" hidden processes. 1733 skipTop = ProcessList.MIN_HIDDEN_APPS; 1734 } 1735 1736 while (i >= 0) { 1737 ProcessRecord p = mLruProcesses.get(i); 1738 // If this app shouldn't be in front of the first N background 1739 // apps, then skip over that many that are currently hidden. 1740 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1741 skipTop--; 1742 } 1743 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1744 mLruProcesses.add(i+1, app); 1745 break; 1746 } 1747 i--; 1748 } 1749 if (i < 0) { 1750 mLruProcesses.add(0, app); 1751 } 1752 1753 // If the app is currently using a content provider or service, 1754 // bump those processes as well. 1755 if (app.connections.size() > 0) { 1756 for (ConnectionRecord cr : app.connections) { 1757 if (cr.binding != null && cr.binding.service != null 1758 && cr.binding.service.app != null 1759 && cr.binding.service.app.lruSeq != mLruSeq) { 1760 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, 1761 updateActivityTime, i+1); 1762 } 1763 } 1764 } 1765 if (app.conProviders.size() > 0) { 1766 for (ContentProviderRecord cpr : app.conProviders.keySet()) { 1767 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1768 updateLruProcessInternalLocked(cpr.proc, oomAdj, 1769 updateActivityTime, i+1); 1770 } 1771 } 1772 } 1773 1774 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1775 if (oomAdj) { 1776 updateOomAdjLocked(); 1777 } 1778 } 1779 1780 final void updateLruProcessLocked(ProcessRecord app, 1781 boolean oomAdj, boolean updateActivityTime) { 1782 mLruSeq++; 1783 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1784 } 1785 1786 final ProcessRecord getProcessRecordLocked( 1787 String processName, int uid) { 1788 if (uid == Process.SYSTEM_UID) { 1789 // The system gets to run in any process. If there are multiple 1790 // processes with the same uid, just pick the first (this 1791 // should never happen). 1792 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1793 processName); 1794 return procs != null ? procs.valueAt(0) : null; 1795 } 1796 ProcessRecord proc = mProcessNames.get(processName, uid); 1797 return proc; 1798 } 1799 1800 void ensurePackageDexOpt(String packageName) { 1801 IPackageManager pm = AppGlobals.getPackageManager(); 1802 try { 1803 if (pm.performDexOpt(packageName)) { 1804 mDidDexOpt = true; 1805 } 1806 } catch (RemoteException e) { 1807 } 1808 } 1809 1810 boolean isNextTransitionForward() { 1811 int transit = mWindowManager.getPendingAppTransition(); 1812 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1813 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1814 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1815 } 1816 1817 final ProcessRecord startProcessLocked(String processName, 1818 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1819 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1820 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1821 // We don't have to do anything more if: 1822 // (1) There is an existing application record; and 1823 // (2) The caller doesn't think it is dead, OR there is no thread 1824 // object attached to it so we know it couldn't have crashed; and 1825 // (3) There is a pid assigned to it, so it is either starting or 1826 // already running. 1827 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1828 + " app=" + app + " knownToBeDead=" + knownToBeDead 1829 + " thread=" + (app != null ? app.thread : null) 1830 + " pid=" + (app != null ? app.pid : -1)); 1831 if (app != null && app.pid > 0) { 1832 if (!knownToBeDead || app.thread == null) { 1833 // We already have the app running, or are waiting for it to 1834 // come up (we have a pid but not yet its thread), so keep it. 1835 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1836 // If this is a new package in the process, add the package to the list 1837 app.addPackage(info.packageName); 1838 return app; 1839 } else { 1840 // An application record is attached to a previous process, 1841 // clean it up now. 1842 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1843 handleAppDiedLocked(app, true, true); 1844 } 1845 } 1846 1847 String hostingNameStr = hostingName != null 1848 ? hostingName.flattenToShortString() : null; 1849 1850 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1851 // If we are in the background, then check to see if this process 1852 // is bad. If so, we will just silently fail. 1853 if (mBadProcesses.get(info.processName, info.uid) != null) { 1854 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1855 + "/" + info.processName); 1856 return null; 1857 } 1858 } else { 1859 // When the user is explicitly starting a process, then clear its 1860 // crash count so that we won't make it bad until they see at 1861 // least one crash dialog again, and make the process good again 1862 // if it had been bad. 1863 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1864 + "/" + info.processName); 1865 mProcessCrashTimes.remove(info.processName, info.uid); 1866 if (mBadProcesses.get(info.processName, info.uid) != null) { 1867 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1868 info.processName); 1869 mBadProcesses.remove(info.processName, info.uid); 1870 if (app != null) { 1871 app.bad = false; 1872 } 1873 } 1874 } 1875 1876 if (app == null) { 1877 app = newProcessRecordLocked(null, info, processName); 1878 mProcessNames.put(processName, info.uid, app); 1879 } else { 1880 // If this is a new package in the process, add the package to the list 1881 app.addPackage(info.packageName); 1882 } 1883 1884 // If the system is not ready yet, then hold off on starting this 1885 // process until it is. 1886 if (!mProcessesReady 1887 && !isAllowedWhileBooting(info) 1888 && !allowWhileBooting) { 1889 if (!mProcessesOnHold.contains(app)) { 1890 mProcessesOnHold.add(app); 1891 } 1892 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1893 return app; 1894 } 1895 1896 startProcessLocked(app, hostingType, hostingNameStr); 1897 return (app.pid != 0) ? app : null; 1898 } 1899 1900 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1901 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1902 } 1903 1904 private final void startProcessLocked(ProcessRecord app, 1905 String hostingType, String hostingNameStr) { 1906 if (app.pid > 0 && app.pid != MY_PID) { 1907 synchronized (mPidsSelfLocked) { 1908 mPidsSelfLocked.remove(app.pid); 1909 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1910 } 1911 app.pid = 0; 1912 } 1913 1914 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1915 "startProcessLocked removing on hold: " + app); 1916 mProcessesOnHold.remove(app); 1917 1918 updateCpuStats(); 1919 1920 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1921 mProcDeaths[0] = 0; 1922 1923 try { 1924 int uid = app.info.uid; 1925 int[] gids = null; 1926 try { 1927 gids = mContext.getPackageManager().getPackageGids( 1928 app.info.packageName); 1929 } catch (PackageManager.NameNotFoundException e) { 1930 Slog.w(TAG, "Unable to retrieve gids", e); 1931 } 1932 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1933 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1934 && mTopComponent != null 1935 && app.processName.equals(mTopComponent.getPackageName())) { 1936 uid = 0; 1937 } 1938 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1939 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1940 uid = 0; 1941 } 1942 } 1943 int debugFlags = 0; 1944 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1945 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1946 // Also turn on CheckJNI for debuggable apps. It's quite 1947 // awkward to turn on otherwise. 1948 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1949 } 1950 // Run the app in safe mode if its manifest requests so or the 1951 // system is booted in safe mode. 1952 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 1953 Zygote.systemInSafeMode == true) { 1954 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1955 } 1956 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1957 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1958 } 1959 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1960 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1961 } 1962 if ("1".equals(SystemProperties.get("debug.assert"))) { 1963 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1964 } 1965 1966 // Start the process. It will either succeed and return a result containing 1967 // the PID of the new process, or else throw a RuntimeException. 1968 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 1969 app.processName, uid, uid, gids, debugFlags, 1970 app.info.targetSdkVersion, null); 1971 1972 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 1973 synchronized (bs) { 1974 if (bs.isOnBattery()) { 1975 app.batteryStats.incStartsLocked(); 1976 } 1977 } 1978 1979 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 1980 app.processName, hostingType, 1981 hostingNameStr != null ? hostingNameStr : ""); 1982 1983 if (app.persistent) { 1984 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 1985 } 1986 1987 StringBuilder buf = mStringBuilder; 1988 buf.setLength(0); 1989 buf.append("Start proc "); 1990 buf.append(app.processName); 1991 buf.append(" for "); 1992 buf.append(hostingType); 1993 if (hostingNameStr != null) { 1994 buf.append(" "); 1995 buf.append(hostingNameStr); 1996 } 1997 buf.append(": pid="); 1998 buf.append(startResult.pid); 1999 buf.append(" uid="); 2000 buf.append(uid); 2001 buf.append(" gids={"); 2002 if (gids != null) { 2003 for (int gi=0; gi<gids.length; gi++) { 2004 if (gi != 0) buf.append(", "); 2005 buf.append(gids[gi]); 2006 2007 } 2008 } 2009 buf.append("}"); 2010 Slog.i(TAG, buf.toString()); 2011 app.pid = startResult.pid; 2012 app.usingWrapper = startResult.usingWrapper; 2013 app.removed = false; 2014 synchronized (mPidsSelfLocked) { 2015 this.mPidsSelfLocked.put(startResult.pid, app); 2016 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2017 msg.obj = app; 2018 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2019 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2020 } 2021 } catch (RuntimeException e) { 2022 // XXX do better error recovery. 2023 app.pid = 0; 2024 Slog.e(TAG, "Failure starting process " + app.processName, e); 2025 } 2026 } 2027 2028 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2029 if (resumed) { 2030 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2031 } else { 2032 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2033 } 2034 } 2035 2036 boolean startHomeActivityLocked() { 2037 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2038 && mTopAction == null) { 2039 // We are running in factory test mode, but unable to find 2040 // the factory test app, so just sit around displaying the 2041 // error message and don't try to start anything. 2042 return false; 2043 } 2044 Intent intent = new Intent( 2045 mTopAction, 2046 mTopData != null ? Uri.parse(mTopData) : null); 2047 intent.setComponent(mTopComponent); 2048 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2049 intent.addCategory(Intent.CATEGORY_HOME); 2050 } 2051 ActivityInfo aInfo = 2052 intent.resolveActivityInfo(mContext.getPackageManager(), 2053 STOCK_PM_FLAGS); 2054 if (aInfo != null) { 2055 intent.setComponent(new ComponentName( 2056 aInfo.applicationInfo.packageName, aInfo.name)); 2057 // Don't do this if the home app is currently being 2058 // instrumented. 2059 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2060 aInfo.applicationInfo.uid); 2061 if (app == null || app.instrumentationClass == null) { 2062 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2063 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo, 2064 null, null, 0, 0, 0, false, false, null); 2065 } 2066 } 2067 2068 2069 return true; 2070 } 2071 2072 /** 2073 * Starts the "new version setup screen" if appropriate. 2074 */ 2075 void startSetupActivityLocked() { 2076 // Only do this once per boot. 2077 if (mCheckedForSetup) { 2078 return; 2079 } 2080 2081 // We will show this screen if the current one is a different 2082 // version than the last one shown, and we are not running in 2083 // low-level factory test mode. 2084 final ContentResolver resolver = mContext.getContentResolver(); 2085 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2086 Settings.Secure.getInt(resolver, 2087 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2088 mCheckedForSetup = true; 2089 2090 // See if we should be showing the platform update setup UI. 2091 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2092 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2093 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2094 2095 // We don't allow third party apps to replace this. 2096 ResolveInfo ri = null; 2097 for (int i=0; ris != null && i<ris.size(); i++) { 2098 if ((ris.get(i).activityInfo.applicationInfo.flags 2099 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2100 ri = ris.get(i); 2101 break; 2102 } 2103 } 2104 2105 if (ri != null) { 2106 String vers = ri.activityInfo.metaData != null 2107 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2108 : null; 2109 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2110 vers = ri.activityInfo.applicationInfo.metaData.getString( 2111 Intent.METADATA_SETUP_VERSION); 2112 } 2113 String lastVers = Settings.Secure.getString( 2114 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2115 if (vers != null && !vers.equals(lastVers)) { 2116 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2117 intent.setComponent(new ComponentName( 2118 ri.activityInfo.packageName, ri.activityInfo.name)); 2119 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2120 null, null, 0, 0, 0, false, false, null); 2121 } 2122 } 2123 } 2124 } 2125 2126 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2127 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2128 } 2129 2130 public int getFrontActivityScreenCompatMode() { 2131 synchronized (this) { 2132 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2133 } 2134 } 2135 2136 public void setFrontActivityScreenCompatMode(int mode) { 2137 synchronized (this) { 2138 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2139 } 2140 } 2141 2142 public int getPackageScreenCompatMode(String packageName) { 2143 synchronized (this) { 2144 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2145 } 2146 } 2147 2148 public void setPackageScreenCompatMode(String packageName, int mode) { 2149 synchronized (this) { 2150 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2151 } 2152 } 2153 2154 public boolean getPackageAskScreenCompat(String packageName) { 2155 synchronized (this) { 2156 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2157 } 2158 } 2159 2160 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2161 synchronized (this) { 2162 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2163 } 2164 } 2165 2166 void reportResumedActivityLocked(ActivityRecord r) { 2167 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2168 2169 final int identHash = System.identityHashCode(r); 2170 updateUsageStats(r, true); 2171 2172 int i = mWatchers.beginBroadcast(); 2173 while (i > 0) { 2174 i--; 2175 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2176 if (w != null) { 2177 try { 2178 w.activityResuming(identHash); 2179 } catch (RemoteException e) { 2180 } 2181 } 2182 } 2183 mWatchers.finishBroadcast(); 2184 } 2185 2186 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 2187 int i = mProcessObservers.beginBroadcast(); 2188 while (i > 0) { 2189 i--; 2190 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2191 if (observer != null) { 2192 try { 2193 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities); 2194 } catch (RemoteException e) { 2195 } 2196 } 2197 } 2198 mProcessObservers.finishBroadcast(); 2199 } 2200 2201 private void dispatchProcessDied(int pid, int uid) { 2202 int i = mProcessObservers.beginBroadcast(); 2203 while (i > 0) { 2204 i--; 2205 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2206 if (observer != null) { 2207 try { 2208 observer.onProcessDied(pid, uid); 2209 } catch (RemoteException e) { 2210 } 2211 } 2212 } 2213 mProcessObservers.finishBroadcast(); 2214 } 2215 2216 final void doPendingActivityLaunchesLocked(boolean doResume) { 2217 final int N = mPendingActivityLaunches.size(); 2218 if (N <= 0) { 2219 return; 2220 } 2221 for (int i=0; i<N; i++) { 2222 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2223 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2224 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 2225 doResume && i == (N-1)); 2226 } 2227 mPendingActivityLaunches.clear(); 2228 } 2229 2230 public final int startActivity(IApplicationThread caller, 2231 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2232 int grantedMode, IBinder resultTo, 2233 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, 2234 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 2235 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2236 grantedUriPermissions, grantedMode, resultTo, resultWho, 2237 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, 2238 null, null); 2239 } 2240 2241 public final WaitResult startActivityAndWait(IApplicationThread caller, 2242 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2243 int grantedMode, IBinder resultTo, 2244 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, 2245 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 2246 WaitResult res = new WaitResult(); 2247 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2248 grantedUriPermissions, grantedMode, resultTo, resultWho, 2249 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, 2250 res, null); 2251 return res; 2252 } 2253 2254 public final int startActivityWithConfig(IApplicationThread caller, 2255 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2256 int grantedMode, IBinder resultTo, 2257 String resultWho, int requestCode, boolean onlyIfNeeded, 2258 boolean debug, Configuration config) { 2259 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2260 grantedUriPermissions, grantedMode, resultTo, resultWho, 2261 requestCode, onlyIfNeeded, debug, null, null, false, null, config); 2262 } 2263 2264 public int startActivityIntentSender(IApplicationThread caller, 2265 IntentSender intent, Intent fillInIntent, String resolvedType, 2266 IBinder resultTo, String resultWho, int requestCode, 2267 int flagsMask, int flagsValues) { 2268 // Refuse possible leaked file descriptors 2269 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2270 throw new IllegalArgumentException("File descriptors passed in Intent"); 2271 } 2272 2273 IIntentSender sender = intent.getTarget(); 2274 if (!(sender instanceof PendingIntentRecord)) { 2275 throw new IllegalArgumentException("Bad PendingIntent object"); 2276 } 2277 2278 PendingIntentRecord pir = (PendingIntentRecord)sender; 2279 2280 synchronized (this) { 2281 // If this is coming from the currently resumed activity, it is 2282 // effectively saying that app switches are allowed at this point. 2283 if (mMainStack.mResumedActivity != null 2284 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2285 Binder.getCallingUid()) { 2286 mAppSwitchesAllowedTime = 0; 2287 } 2288 } 2289 2290 return pir.sendInner(0, fillInIntent, resolvedType, null, 2291 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 2292 } 2293 2294 public boolean startNextMatchingActivity(IBinder callingActivity, 2295 Intent intent) { 2296 // Refuse possible leaked file descriptors 2297 if (intent != null && intent.hasFileDescriptors() == true) { 2298 throw new IllegalArgumentException("File descriptors passed in Intent"); 2299 } 2300 2301 synchronized (this) { 2302 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2303 if (r == null) { 2304 return false; 2305 } 2306 if (r.app == null || r.app.thread == null) { 2307 // The caller is not running... d'oh! 2308 return false; 2309 } 2310 intent = new Intent(intent); 2311 // The caller is not allowed to change the data. 2312 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2313 // And we are resetting to find the next component... 2314 intent.setComponent(null); 2315 2316 ActivityInfo aInfo = null; 2317 try { 2318 List<ResolveInfo> resolves = 2319 AppGlobals.getPackageManager().queryIntentActivities( 2320 intent, r.resolvedType, 2321 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 2322 2323 // Look for the original activity in the list... 2324 final int N = resolves != null ? resolves.size() : 0; 2325 for (int i=0; i<N; i++) { 2326 ResolveInfo rInfo = resolves.get(i); 2327 if (rInfo.activityInfo.packageName.equals(r.packageName) 2328 && rInfo.activityInfo.name.equals(r.info.name)) { 2329 // We found the current one... the next matching is 2330 // after it. 2331 i++; 2332 if (i<N) { 2333 aInfo = resolves.get(i).activityInfo; 2334 } 2335 break; 2336 } 2337 } 2338 } catch (RemoteException e) { 2339 } 2340 2341 if (aInfo == null) { 2342 // Nobody who is next! 2343 return false; 2344 } 2345 2346 intent.setComponent(new ComponentName( 2347 aInfo.applicationInfo.packageName, aInfo.name)); 2348 intent.setFlags(intent.getFlags()&~( 2349 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2350 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2351 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2352 Intent.FLAG_ACTIVITY_NEW_TASK)); 2353 2354 // Okay now we need to start the new activity, replacing the 2355 // currently running activity. This is a little tricky because 2356 // we want to start the new one as if the current one is finished, 2357 // but not finish the current one first so that there is no flicker. 2358 // And thus... 2359 final boolean wasFinishing = r.finishing; 2360 r.finishing = true; 2361 2362 // Propagate reply information over to the new activity. 2363 final ActivityRecord resultTo = r.resultTo; 2364 final String resultWho = r.resultWho; 2365 final int requestCode = r.requestCode; 2366 r.resultTo = null; 2367 if (resultTo != null) { 2368 resultTo.removeResultsLocked(r, resultWho, requestCode); 2369 } 2370 2371 final long origId = Binder.clearCallingIdentity(); 2372 // XXX we are not dealing with propagating grantedUriPermissions... 2373 // those are not yet exposed to user code, so there is no need. 2374 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2375 r.resolvedType, null, 0, aInfo, 2376 resultTo != null ? resultTo.appToken : null, resultWho, 2377 requestCode, -1, r.launchedFromUid, false, false, null); 2378 Binder.restoreCallingIdentity(origId); 2379 2380 r.finishing = wasFinishing; 2381 if (res != START_SUCCESS) { 2382 return false; 2383 } 2384 return true; 2385 } 2386 } 2387 2388 public final int startActivityInPackage(int uid, 2389 Intent intent, String resolvedType, IBinder resultTo, 2390 String resultWho, int requestCode, boolean onlyIfNeeded) { 2391 2392 // This is so super not safe, that only the system (or okay root) 2393 // can do it. 2394 final int callingUid = Binder.getCallingUid(); 2395 if (callingUid != 0 && callingUid != Process.myUid()) { 2396 throw new SecurityException( 2397 "startActivityInPackage only available to the system"); 2398 } 2399 2400 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2401 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, 2402 null, null, false, null, null); 2403 } 2404 2405 public final int startActivities(IApplicationThread caller, 2406 Intent[] intents, String[] resolvedTypes, IBinder resultTo) { 2407 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo); 2408 } 2409 2410 public final int startActivitiesInPackage(int uid, 2411 Intent[] intents, String[] resolvedTypes, IBinder resultTo) { 2412 2413 // This is so super not safe, that only the system (or okay root) 2414 // can do it. 2415 final int callingUid = Binder.getCallingUid(); 2416 if (callingUid != 0 && callingUid != Process.myUid()) { 2417 throw new SecurityException( 2418 "startActivityInPackage only available to the system"); 2419 } 2420 2421 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo); 2422 } 2423 2424 final void addRecentTaskLocked(TaskRecord task) { 2425 int N = mRecentTasks.size(); 2426 // Quick case: check if the top-most recent task is the same. 2427 if (N > 0 && mRecentTasks.get(0) == task) { 2428 return; 2429 } 2430 // Remove any existing entries that are the same kind of task. 2431 for (int i=0; i<N; i++) { 2432 TaskRecord tr = mRecentTasks.get(i); 2433 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 2434 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 2435 mRecentTasks.remove(i); 2436 i--; 2437 N--; 2438 if (task.intent == null) { 2439 // If the new recent task we are adding is not fully 2440 // specified, then replace it with the existing recent task. 2441 task = tr; 2442 } 2443 } 2444 } 2445 if (N >= MAX_RECENT_TASKS) { 2446 mRecentTasks.remove(N-1); 2447 } 2448 mRecentTasks.add(0, task); 2449 } 2450 2451 public void setRequestedOrientation(IBinder token, 2452 int requestedOrientation) { 2453 synchronized (this) { 2454 ActivityRecord r = mMainStack.isInStackLocked(token); 2455 if (r == null) { 2456 return; 2457 } 2458 final long origId = Binder.clearCallingIdentity(); 2459 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2460 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2461 mConfiguration, 2462 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2463 if (config != null) { 2464 r.frozenBeforeDestroy = true; 2465 if (!updateConfigurationLocked(config, r, false, false)) { 2466 mMainStack.resumeTopActivityLocked(null); 2467 } 2468 } 2469 Binder.restoreCallingIdentity(origId); 2470 } 2471 } 2472 2473 public int getRequestedOrientation(IBinder token) { 2474 synchronized (this) { 2475 ActivityRecord r = mMainStack.isInStackLocked(token); 2476 if (r == null) { 2477 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2478 } 2479 return mWindowManager.getAppOrientation(r.appToken); 2480 } 2481 } 2482 2483 /** 2484 * This is the internal entry point for handling Activity.finish(). 2485 * 2486 * @param token The Binder token referencing the Activity we want to finish. 2487 * @param resultCode Result code, if any, from this Activity. 2488 * @param resultData Result data (Intent), if any, from this Activity. 2489 * 2490 * @return Returns true if the activity successfully finished, or false if it is still running. 2491 */ 2492 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2493 // Refuse possible leaked file descriptors 2494 if (resultData != null && resultData.hasFileDescriptors() == true) { 2495 throw new IllegalArgumentException("File descriptors passed in Intent"); 2496 } 2497 2498 synchronized(this) { 2499 if (mController != null) { 2500 // Find the first activity that is not finishing. 2501 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2502 if (next != null) { 2503 // ask watcher if this is allowed 2504 boolean resumeOK = true; 2505 try { 2506 resumeOK = mController.activityResuming(next.packageName); 2507 } catch (RemoteException e) { 2508 mController = null; 2509 } 2510 2511 if (!resumeOK) { 2512 return false; 2513 } 2514 } 2515 } 2516 final long origId = Binder.clearCallingIdentity(); 2517 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2518 resultData, "app-request"); 2519 Binder.restoreCallingIdentity(origId); 2520 return res; 2521 } 2522 } 2523 2524 public final void finishHeavyWeightApp() { 2525 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2526 != PackageManager.PERMISSION_GRANTED) { 2527 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2528 + Binder.getCallingPid() 2529 + ", uid=" + Binder.getCallingUid() 2530 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2531 Slog.w(TAG, msg); 2532 throw new SecurityException(msg); 2533 } 2534 2535 synchronized(this) { 2536 if (mHeavyWeightProcess == null) { 2537 return; 2538 } 2539 2540 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2541 mHeavyWeightProcess.activities); 2542 for (int i=0; i<activities.size(); i++) { 2543 ActivityRecord r = activities.get(i); 2544 if (!r.finishing) { 2545 int index = mMainStack.indexOfTokenLocked(r.appToken); 2546 if (index >= 0) { 2547 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2548 null, "finish-heavy"); 2549 } 2550 } 2551 } 2552 2553 mHeavyWeightProcess = null; 2554 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2555 } 2556 } 2557 2558 public void crashApplication(int uid, int initialPid, String packageName, 2559 String message) { 2560 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2561 != PackageManager.PERMISSION_GRANTED) { 2562 String msg = "Permission Denial: crashApplication() from pid=" 2563 + Binder.getCallingPid() 2564 + ", uid=" + Binder.getCallingUid() 2565 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2566 Slog.w(TAG, msg); 2567 throw new SecurityException(msg); 2568 } 2569 2570 synchronized(this) { 2571 ProcessRecord proc = null; 2572 2573 // Figure out which process to kill. We don't trust that initialPid 2574 // still has any relation to current pids, so must scan through the 2575 // list. 2576 synchronized (mPidsSelfLocked) { 2577 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2578 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2579 if (p.info.uid != uid) { 2580 continue; 2581 } 2582 if (p.pid == initialPid) { 2583 proc = p; 2584 break; 2585 } 2586 for (String str : p.pkgList) { 2587 if (str.equals(packageName)) { 2588 proc = p; 2589 } 2590 } 2591 } 2592 } 2593 2594 if (proc == null) { 2595 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2596 + " initialPid=" + initialPid 2597 + " packageName=" + packageName); 2598 return; 2599 } 2600 2601 if (proc.thread != null) { 2602 if (proc.pid == Process.myPid()) { 2603 Log.w(TAG, "crashApplication: trying to crash self!"); 2604 return; 2605 } 2606 long ident = Binder.clearCallingIdentity(); 2607 try { 2608 proc.thread.scheduleCrash(message); 2609 } catch (RemoteException e) { 2610 } 2611 Binder.restoreCallingIdentity(ident); 2612 } 2613 } 2614 } 2615 2616 public final void finishSubActivity(IBinder token, String resultWho, 2617 int requestCode) { 2618 synchronized(this) { 2619 ActivityRecord self = mMainStack.isInStackLocked(token); 2620 if (self == null) { 2621 return; 2622 } 2623 2624 final long origId = Binder.clearCallingIdentity(); 2625 2626 int i; 2627 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2628 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2629 if (r.resultTo == self && r.requestCode == requestCode) { 2630 if ((r.resultWho == null && resultWho == null) || 2631 (r.resultWho != null && r.resultWho.equals(resultWho))) { 2632 mMainStack.finishActivityLocked(r, i, 2633 Activity.RESULT_CANCELED, null, "request-sub"); 2634 } 2635 } 2636 } 2637 2638 Binder.restoreCallingIdentity(origId); 2639 } 2640 } 2641 2642 public boolean willActivityBeVisible(IBinder token) { 2643 synchronized(this) { 2644 int i; 2645 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2646 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2647 if (r.appToken == token) { 2648 return true; 2649 } 2650 if (r.fullscreen && !r.finishing) { 2651 return false; 2652 } 2653 } 2654 return true; 2655 } 2656 } 2657 2658 public void overridePendingTransition(IBinder token, String packageName, 2659 int enterAnim, int exitAnim) { 2660 synchronized(this) { 2661 ActivityRecord self = mMainStack.isInStackLocked(token); 2662 if (self == null) { 2663 return; 2664 } 2665 2666 final long origId = Binder.clearCallingIdentity(); 2667 2668 if (self.state == ActivityState.RESUMED 2669 || self.state == ActivityState.PAUSING) { 2670 mWindowManager.overridePendingAppTransition(packageName, 2671 enterAnim, exitAnim); 2672 } 2673 2674 Binder.restoreCallingIdentity(origId); 2675 } 2676 } 2677 2678 /** 2679 * Main function for removing an existing process from the activity manager 2680 * as a result of that process going away. Clears out all connections 2681 * to the process. 2682 */ 2683 private final void handleAppDiedLocked(ProcessRecord app, 2684 boolean restarting, boolean allowRestart) { 2685 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2686 if (!restarting) { 2687 mLruProcesses.remove(app); 2688 } 2689 2690 if (mProfileProc == app) { 2691 clearProfilerLocked(); 2692 } 2693 2694 // Just in case... 2695 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2696 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2697 mMainStack.mPausingActivity = null; 2698 } 2699 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2700 mMainStack.mLastPausedActivity = null; 2701 } 2702 2703 // Remove this application's activities from active lists. 2704 mMainStack.removeHistoryRecordsForAppLocked(app); 2705 2706 boolean atTop = true; 2707 boolean hasVisibleActivities = false; 2708 2709 // Clean out the history list. 2710 int i = mMainStack.mHistory.size(); 2711 if (localLOGV) Slog.v( 2712 TAG, "Removing app " + app + " from history with " + i + " entries"); 2713 while (i > 0) { 2714 i--; 2715 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2716 if (localLOGV) Slog.v( 2717 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2718 if (r.app == app) { 2719 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2720 if (ActivityStack.DEBUG_ADD_REMOVE) { 2721 RuntimeException here = new RuntimeException("here"); 2722 here.fillInStackTrace(); 2723 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2724 + ": haveState=" + r.haveState 2725 + " stateNotNeeded=" + r.stateNotNeeded 2726 + " finishing=" + r.finishing 2727 + " state=" + r.state, here); 2728 } 2729 if (!r.finishing) { 2730 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2731 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2732 System.identityHashCode(r), 2733 r.task.taskId, r.shortComponentName, 2734 "proc died without state saved"); 2735 } 2736 mMainStack.removeActivityFromHistoryLocked(r); 2737 2738 } else { 2739 // We have the current state for this activity, so 2740 // it can be restarted later when needed. 2741 if (localLOGV) Slog.v( 2742 TAG, "Keeping entry, setting app to null"); 2743 if (r.visible) { 2744 hasVisibleActivities = true; 2745 } 2746 r.app = null; 2747 r.nowVisible = false; 2748 if (!r.haveState) { 2749 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2750 "App died, clearing saved state of " + r); 2751 r.icicle = null; 2752 } 2753 } 2754 2755 r.stack.cleanUpActivityLocked(r, true, true); 2756 } 2757 atTop = false; 2758 } 2759 2760 app.activities.clear(); 2761 2762 if (app.instrumentationClass != null) { 2763 Slog.w(TAG, "Crash of app " + app.processName 2764 + " running instrumentation " + app.instrumentationClass); 2765 Bundle info = new Bundle(); 2766 info.putString("shortMsg", "Process crashed."); 2767 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2768 } 2769 2770 if (!restarting) { 2771 if (!mMainStack.resumeTopActivityLocked(null)) { 2772 // If there was nothing to resume, and we are not already 2773 // restarting this process, but there is a visible activity that 2774 // is hosted by the process... then make sure all visible 2775 // activities are running, taking care of restarting this 2776 // process. 2777 if (hasVisibleActivities) { 2778 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2779 } 2780 } 2781 } 2782 } 2783 2784 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2785 IBinder threadBinder = thread.asBinder(); 2786 2787 // Find the application record. 2788 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2789 ProcessRecord rec = mLruProcesses.get(i); 2790 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2791 return i; 2792 } 2793 } 2794 return -1; 2795 } 2796 2797 final ProcessRecord getRecordForAppLocked( 2798 IApplicationThread thread) { 2799 if (thread == null) { 2800 return null; 2801 } 2802 2803 int appIndex = getLRURecordIndexForAppLocked(thread); 2804 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2805 } 2806 2807 final void appDiedLocked(ProcessRecord app, int pid, 2808 IApplicationThread thread) { 2809 2810 mProcDeaths[0]++; 2811 2812 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2813 synchronized (stats) { 2814 stats.noteProcessDiedLocked(app.info.uid, pid); 2815 } 2816 2817 // Clean up already done if the process has been re-started. 2818 if (app.pid == pid && app.thread != null && 2819 app.thread.asBinder() == thread.asBinder()) { 2820 if (!app.killedBackground) { 2821 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2822 + ") has died."); 2823 } 2824 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2825 if (localLOGV) Slog.v( 2826 TAG, "Dying app: " + app + ", pid: " + pid 2827 + ", thread: " + thread.asBinder()); 2828 boolean doLowMem = app.instrumentationClass == null; 2829 handleAppDiedLocked(app, false, true); 2830 2831 if (doLowMem) { 2832 // If there are no longer any background processes running, 2833 // and the app that died was not running instrumentation, 2834 // then tell everyone we are now low on memory. 2835 boolean haveBg = false; 2836 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2837 ProcessRecord rec = mLruProcesses.get(i); 2838 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2839 haveBg = true; 2840 break; 2841 } 2842 } 2843 2844 if (!haveBg) { 2845 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2846 long now = SystemClock.uptimeMillis(); 2847 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2848 ProcessRecord rec = mLruProcesses.get(i); 2849 if (rec != app && rec.thread != null && 2850 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2851 // The low memory report is overriding any current 2852 // state for a GC request. Make sure to do 2853 // heavy/important/visible/foreground processes first. 2854 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2855 rec.lastRequestedGc = 0; 2856 } else { 2857 rec.lastRequestedGc = rec.lastLowMemory; 2858 } 2859 rec.reportLowMemory = true; 2860 rec.lastLowMemory = now; 2861 mProcessesToGc.remove(rec); 2862 addProcessToGcListLocked(rec); 2863 } 2864 } 2865 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 2866 scheduleAppGcsLocked(); 2867 } 2868 } 2869 } else if (app.pid != pid) { 2870 // A new process has already been started. 2871 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2872 + ") has died and restarted (pid " + app.pid + ")."); 2873 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2874 } else if (DEBUG_PROCESSES) { 2875 Slog.d(TAG, "Received spurious death notification for thread " 2876 + thread.asBinder()); 2877 } 2878 } 2879 2880 /** 2881 * If a stack trace dump file is configured, dump process stack traces. 2882 * @param clearTraces causes the dump file to be erased prior to the new 2883 * traces being written, if true; when false, the new traces will be 2884 * appended to any existing file content. 2885 * @param firstPids of dalvik VM processes to dump stack traces for first 2886 * @param lastPids of dalvik VM processes to dump stack traces for last 2887 * @return file containing stack traces, or null if no dump file is configured 2888 */ 2889 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 2890 ProcessStats processStats, SparseArray<Boolean> lastPids) { 2891 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 2892 if (tracesPath == null || tracesPath.length() == 0) { 2893 return null; 2894 } 2895 2896 File tracesFile = new File(tracesPath); 2897 try { 2898 File tracesDir = tracesFile.getParentFile(); 2899 if (!tracesDir.exists()) tracesFile.mkdirs(); 2900 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 2901 2902 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 2903 tracesFile.createNewFile(); 2904 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 2905 } catch (IOException e) { 2906 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 2907 return null; 2908 } 2909 2910 dumpStackTraces(tracesPath, firstPids, processStats, lastPids); 2911 return tracesFile; 2912 } 2913 2914 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 2915 ProcessStats processStats, SparseArray<Boolean> lastPids) { 2916 // Use a FileObserver to detect when traces finish writing. 2917 // The order of traces is considered important to maintain for legibility. 2918 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 2919 public synchronized void onEvent(int event, String path) { notify(); } 2920 }; 2921 2922 try { 2923 observer.startWatching(); 2924 2925 // First collect all of the stacks of the most important pids. 2926 if (firstPids != null) { 2927 try { 2928 int num = firstPids.size(); 2929 for (int i = 0; i < num; i++) { 2930 synchronized (observer) { 2931 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 2932 observer.wait(200); // Wait for write-close, give up after 200msec 2933 } 2934 } 2935 } catch (InterruptedException e) { 2936 Log.wtf(TAG, e); 2937 } 2938 } 2939 2940 // Next measure CPU usage. 2941 if (processStats != null) { 2942 processStats.init(); 2943 System.gc(); 2944 processStats.update(); 2945 try { 2946 synchronized (processStats) { 2947 processStats.wait(500); // measure over 1/2 second. 2948 } 2949 } catch (InterruptedException e) { 2950 } 2951 processStats.update(); 2952 2953 // We'll take the stack crawls of just the top apps using CPU. 2954 final int N = processStats.countWorkingStats(); 2955 int numProcs = 0; 2956 for (int i=0; i<N && numProcs<5; i++) { 2957 ProcessStats.Stats stats = processStats.getWorkingStats(i); 2958 if (lastPids.indexOfKey(stats.pid) >= 0) { 2959 numProcs++; 2960 try { 2961 synchronized (observer) { 2962 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 2963 observer.wait(200); // Wait for write-close, give up after 200msec 2964 } 2965 } catch (InterruptedException e) { 2966 Log.wtf(TAG, e); 2967 } 2968 2969 } 2970 } 2971 } 2972 2973 } finally { 2974 observer.stopWatching(); 2975 } 2976 } 2977 2978 private final class AppNotResponding implements Runnable { 2979 private final ProcessRecord mApp; 2980 private final String mAnnotation; 2981 2982 public AppNotResponding(ProcessRecord app, String annotation) { 2983 mApp = app; 2984 mAnnotation = annotation; 2985 } 2986 2987 @Override 2988 public void run() { 2989 appNotResponding(mApp, null, null, mAnnotation); 2990 } 2991 } 2992 2993 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 2994 if (IS_USER_BUILD) { 2995 return; 2996 } 2997 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 2998 if (tracesPath == null || tracesPath.length() == 0) { 2999 return; 3000 } 3001 3002 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3003 StrictMode.allowThreadDiskWrites(); 3004 try { 3005 final File tracesFile = new File(tracesPath); 3006 final File tracesDir = tracesFile.getParentFile(); 3007 final File tracesTmp = new File(tracesDir, "__tmp__"); 3008 try { 3009 if (!tracesDir.exists()) tracesFile.mkdirs(); 3010 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3011 3012 if (tracesFile.exists()) { 3013 tracesTmp.delete(); 3014 tracesFile.renameTo(tracesTmp); 3015 } 3016 StringBuilder sb = new StringBuilder(); 3017 Time tobj = new Time(); 3018 tobj.set(System.currentTimeMillis()); 3019 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3020 sb.append(": "); 3021 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3022 sb.append(" since "); 3023 sb.append(msg); 3024 FileOutputStream fos = new FileOutputStream(tracesFile); 3025 fos.write(sb.toString().getBytes()); 3026 if (app == null) { 3027 fos.write("\n*** No application process!".getBytes()); 3028 } 3029 fos.close(); 3030 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3031 } catch (IOException e) { 3032 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3033 return; 3034 } 3035 3036 if (app != null) { 3037 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3038 firstPids.add(app.pid); 3039 dumpStackTraces(tracesPath, firstPids, null, null); 3040 } 3041 3042 File lastTracesFile = null; 3043 File curTracesFile = null; 3044 for (int i=9; i>=0; i--) { 3045 String name = String.format("slow%02d.txt", i); 3046 curTracesFile = new File(tracesDir, name); 3047 if (curTracesFile.exists()) { 3048 if (lastTracesFile != null) { 3049 curTracesFile.renameTo(lastTracesFile); 3050 } else { 3051 curTracesFile.delete(); 3052 } 3053 } 3054 lastTracesFile = curTracesFile; 3055 } 3056 tracesFile.renameTo(curTracesFile); 3057 if (tracesTmp.exists()) { 3058 tracesTmp.renameTo(tracesFile); 3059 } 3060 } finally { 3061 StrictMode.setThreadPolicy(oldPolicy); 3062 } 3063 } 3064 3065 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3066 ActivityRecord parent, final String annotation) { 3067 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3068 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3069 3070 if (mController != null) { 3071 try { 3072 // 0 == continue, -1 = kill process immediately 3073 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3074 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3075 } catch (RemoteException e) { 3076 mController = null; 3077 } 3078 } 3079 3080 long anrTime = SystemClock.uptimeMillis(); 3081 if (MONITOR_CPU_USAGE) { 3082 updateCpuStatsNow(); 3083 } 3084 3085 synchronized (this) { 3086 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3087 if (mShuttingDown) { 3088 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3089 return; 3090 } else if (app.notResponding) { 3091 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3092 return; 3093 } else if (app.crashing) { 3094 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3095 return; 3096 } 3097 3098 // In case we come through here for the same app before completing 3099 // this one, mark as anring now so we will bail out. 3100 app.notResponding = true; 3101 3102 // Log the ANR to the event log. 3103 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3104 annotation); 3105 3106 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3107 firstPids.add(app.pid); 3108 3109 int parentPid = app.pid; 3110 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3111 if (parentPid != app.pid) firstPids.add(parentPid); 3112 3113 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3114 3115 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3116 ProcessRecord r = mLruProcesses.get(i); 3117 if (r != null && r.thread != null) { 3118 int pid = r.pid; 3119 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3120 if (r.persistent) { 3121 firstPids.add(pid); 3122 } else { 3123 lastPids.put(pid, Boolean.TRUE); 3124 } 3125 } 3126 } 3127 } 3128 } 3129 3130 // Log the ANR to the main log. 3131 StringBuilder info = mStringBuilder; 3132 info.setLength(0); 3133 info.append("ANR in ").append(app.processName); 3134 if (activity != null && activity.shortComponentName != null) { 3135 info.append(" (").append(activity.shortComponentName).append(")"); 3136 } 3137 info.append("\n"); 3138 if (annotation != null) { 3139 info.append("Reason: ").append(annotation).append("\n"); 3140 } 3141 if (parent != null && parent != activity) { 3142 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3143 } 3144 3145 final ProcessStats processStats = new ProcessStats(true); 3146 3147 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids); 3148 3149 String cpuInfo = null; 3150 if (MONITOR_CPU_USAGE) { 3151 updateCpuStatsNow(); 3152 synchronized (mProcessStatsThread) { 3153 cpuInfo = mProcessStats.printCurrentState(anrTime); 3154 } 3155 info.append(processStats.printCurrentLoad()); 3156 info.append(cpuInfo); 3157 } 3158 3159 info.append(processStats.printCurrentState(anrTime)); 3160 3161 Slog.e(TAG, info.toString()); 3162 if (tracesFile == null) { 3163 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3164 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3165 } 3166 3167 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3168 cpuInfo, tracesFile, null); 3169 3170 if (mController != null) { 3171 try { 3172 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3173 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3174 if (res != 0) { 3175 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3176 return; 3177 } 3178 } catch (RemoteException e) { 3179 mController = null; 3180 } 3181 } 3182 3183 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3184 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3185 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3186 3187 synchronized (this) { 3188 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3189 Slog.w(TAG, "Killing " + app + ": background ANR"); 3190 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3191 app.processName, app.setAdj, "background ANR"); 3192 Process.killProcessQuiet(app.pid); 3193 return; 3194 } 3195 3196 // Set the app's notResponding state, and look up the errorReportReceiver 3197 makeAppNotRespondingLocked(app, 3198 activity != null ? activity.shortComponentName : null, 3199 annotation != null ? "ANR " + annotation : "ANR", 3200 info.toString()); 3201 3202 // Bring up the infamous App Not Responding dialog 3203 Message msg = Message.obtain(); 3204 HashMap map = new HashMap(); 3205 msg.what = SHOW_NOT_RESPONDING_MSG; 3206 msg.obj = map; 3207 map.put("app", app); 3208 if (activity != null) { 3209 map.put("activity", activity); 3210 } 3211 3212 mHandler.sendMessage(msg); 3213 } 3214 } 3215 3216 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3217 if (!mLaunchWarningShown) { 3218 mLaunchWarningShown = true; 3219 mHandler.post(new Runnable() { 3220 @Override 3221 public void run() { 3222 synchronized (ActivityManagerService.this) { 3223 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3224 d.show(); 3225 mHandler.postDelayed(new Runnable() { 3226 @Override 3227 public void run() { 3228 synchronized (ActivityManagerService.this) { 3229 d.dismiss(); 3230 mLaunchWarningShown = false; 3231 } 3232 } 3233 }, 4000); 3234 } 3235 } 3236 }); 3237 } 3238 } 3239 3240 public boolean clearApplicationUserData(final String packageName, 3241 final IPackageDataObserver observer) { 3242 int uid = Binder.getCallingUid(); 3243 int pid = Binder.getCallingPid(); 3244 long callingId = Binder.clearCallingIdentity(); 3245 try { 3246 IPackageManager pm = AppGlobals.getPackageManager(); 3247 int pkgUid = -1; 3248 synchronized(this) { 3249 try { 3250 pkgUid = pm.getPackageUid(packageName); 3251 } catch (RemoteException e) { 3252 } 3253 if (pkgUid == -1) { 3254 Slog.w(TAG, "Invalid packageName:" + packageName); 3255 return false; 3256 } 3257 if (uid == pkgUid || checkComponentPermission( 3258 android.Manifest.permission.CLEAR_APP_USER_DATA, 3259 pid, uid, -1, true) 3260 == PackageManager.PERMISSION_GRANTED) { 3261 forceStopPackageLocked(packageName, pkgUid); 3262 } else { 3263 throw new SecurityException(pid+" does not have permission:"+ 3264 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3265 "for process:"+packageName); 3266 } 3267 } 3268 3269 try { 3270 //clear application user data 3271 pm.clearApplicationUserData(packageName, observer); 3272 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3273 Uri.fromParts("package", packageName, null)); 3274 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3275 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3276 null, null, 0, null, null, null, false, false); 3277 } catch (RemoteException e) { 3278 } 3279 } finally { 3280 Binder.restoreCallingIdentity(callingId); 3281 } 3282 return true; 3283 } 3284 3285 public void killBackgroundProcesses(final String packageName) { 3286 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3287 != PackageManager.PERMISSION_GRANTED && 3288 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3289 != PackageManager.PERMISSION_GRANTED) { 3290 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3291 + Binder.getCallingPid() 3292 + ", uid=" + Binder.getCallingUid() 3293 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3294 Slog.w(TAG, msg); 3295 throw new SecurityException(msg); 3296 } 3297 3298 long callingId = Binder.clearCallingIdentity(); 3299 try { 3300 IPackageManager pm = AppGlobals.getPackageManager(); 3301 int pkgUid = -1; 3302 synchronized(this) { 3303 try { 3304 pkgUid = pm.getPackageUid(packageName); 3305 } catch (RemoteException e) { 3306 } 3307 if (pkgUid == -1) { 3308 Slog.w(TAG, "Invalid packageName: " + packageName); 3309 return; 3310 } 3311 killPackageProcessesLocked(packageName, pkgUid, 3312 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3313 } 3314 } finally { 3315 Binder.restoreCallingIdentity(callingId); 3316 } 3317 } 3318 3319 public void killAllBackgroundProcesses() { 3320 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3321 != PackageManager.PERMISSION_GRANTED) { 3322 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3323 + Binder.getCallingPid() 3324 + ", uid=" + Binder.getCallingUid() 3325 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3326 Slog.w(TAG, msg); 3327 throw new SecurityException(msg); 3328 } 3329 3330 long callingId = Binder.clearCallingIdentity(); 3331 try { 3332 synchronized(this) { 3333 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3334 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3335 final int NA = apps.size(); 3336 for (int ia=0; ia<NA; ia++) { 3337 ProcessRecord app = apps.valueAt(ia); 3338 if (app.persistent) { 3339 // we don't kill persistent processes 3340 continue; 3341 } 3342 if (app.removed) { 3343 procs.add(app); 3344 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3345 app.removed = true; 3346 procs.add(app); 3347 } 3348 } 3349 } 3350 3351 int N = procs.size(); 3352 for (int i=0; i<N; i++) { 3353 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3354 } 3355 } 3356 } finally { 3357 Binder.restoreCallingIdentity(callingId); 3358 } 3359 } 3360 3361 public void forceStopPackage(final String packageName) { 3362 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3363 != PackageManager.PERMISSION_GRANTED) { 3364 String msg = "Permission Denial: forceStopPackage() from pid=" 3365 + Binder.getCallingPid() 3366 + ", uid=" + Binder.getCallingUid() 3367 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3368 Slog.w(TAG, msg); 3369 throw new SecurityException(msg); 3370 } 3371 3372 long callingId = Binder.clearCallingIdentity(); 3373 try { 3374 IPackageManager pm = AppGlobals.getPackageManager(); 3375 int pkgUid = -1; 3376 synchronized(this) { 3377 try { 3378 pkgUid = pm.getPackageUid(packageName); 3379 } catch (RemoteException e) { 3380 } 3381 if (pkgUid == -1) { 3382 Slog.w(TAG, "Invalid packageName: " + packageName); 3383 return; 3384 } 3385 forceStopPackageLocked(packageName, pkgUid); 3386 try { 3387 pm.setPackageStoppedState(packageName, true); 3388 } catch (RemoteException e) { 3389 } catch (IllegalArgumentException e) { 3390 Slog.w(TAG, "Failed trying to unstop package " 3391 + packageName + ": " + e); 3392 } 3393 } 3394 } finally { 3395 Binder.restoreCallingIdentity(callingId); 3396 } 3397 } 3398 3399 /* 3400 * The pkg name and uid have to be specified. 3401 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3402 */ 3403 public void killApplicationWithUid(String pkg, int uid) { 3404 if (pkg == null) { 3405 return; 3406 } 3407 // Make sure the uid is valid. 3408 if (uid < 0) { 3409 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3410 return; 3411 } 3412 int callerUid = Binder.getCallingUid(); 3413 // Only the system server can kill an application 3414 if (callerUid == Process.SYSTEM_UID) { 3415 // Post an aysnc message to kill the application 3416 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3417 msg.arg1 = uid; 3418 msg.arg2 = 0; 3419 msg.obj = pkg; 3420 mHandler.sendMessage(msg); 3421 } else { 3422 throw new SecurityException(callerUid + " cannot kill pkg: " + 3423 pkg); 3424 } 3425 } 3426 3427 public void closeSystemDialogs(String reason) { 3428 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3430 if (reason != null) { 3431 intent.putExtra("reason", reason); 3432 } 3433 3434 final int uid = Binder.getCallingUid(); 3435 final long origId = Binder.clearCallingIdentity(); 3436 synchronized (this) { 3437 int i = mWatchers.beginBroadcast(); 3438 while (i > 0) { 3439 i--; 3440 IActivityWatcher w = mWatchers.getBroadcastItem(i); 3441 if (w != null) { 3442 try { 3443 w.closingSystemDialogs(reason); 3444 } catch (RemoteException e) { 3445 } 3446 } 3447 } 3448 mWatchers.finishBroadcast(); 3449 3450 mWindowManager.closeSystemDialogs(reason); 3451 3452 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 3453 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3454 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3455 r.stack.finishActivityLocked(r, i, 3456 Activity.RESULT_CANCELED, null, "close-sys"); 3457 } 3458 } 3459 3460 broadcastIntentLocked(null, null, intent, null, 3461 null, 0, null, null, null, false, false, -1, uid); 3462 } 3463 Binder.restoreCallingIdentity(origId); 3464 } 3465 3466 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3467 throws RemoteException { 3468 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3469 for (int i=pids.length-1; i>=0; i--) { 3470 infos[i] = new Debug.MemoryInfo(); 3471 Debug.getMemoryInfo(pids[i], infos[i]); 3472 } 3473 return infos; 3474 } 3475 3476 public long[] getProcessPss(int[] pids) throws RemoteException { 3477 long[] pss = new long[pids.length]; 3478 for (int i=pids.length-1; i>=0; i--) { 3479 pss[i] = Debug.getPss(pids[i]); 3480 } 3481 return pss; 3482 } 3483 3484 public void killApplicationProcess(String processName, int uid) { 3485 if (processName == null) { 3486 return; 3487 } 3488 3489 int callerUid = Binder.getCallingUid(); 3490 // Only the system server can kill an application 3491 if (callerUid == Process.SYSTEM_UID) { 3492 synchronized (this) { 3493 ProcessRecord app = getProcessRecordLocked(processName, uid); 3494 if (app != null && app.thread != null) { 3495 try { 3496 app.thread.scheduleSuicide(); 3497 } catch (RemoteException e) { 3498 // If the other end already died, then our work here is done. 3499 } 3500 } else { 3501 Slog.w(TAG, "Process/uid not found attempting kill of " 3502 + processName + " / " + uid); 3503 } 3504 } 3505 } else { 3506 throw new SecurityException(callerUid + " cannot kill app process: " + 3507 processName); 3508 } 3509 } 3510 3511 private void forceStopPackageLocked(final String packageName, int uid) { 3512 forceStopPackageLocked(packageName, uid, false, false, true, false); 3513 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3514 Uri.fromParts("package", packageName, null)); 3515 if (!mProcessesReady) { 3516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3517 } 3518 intent.putExtra(Intent.EXTRA_UID, uid); 3519 broadcastIntentLocked(null, null, intent, 3520 null, null, 0, null, null, null, 3521 false, false, MY_PID, Process.SYSTEM_UID); 3522 } 3523 3524 private final boolean killPackageProcessesLocked(String packageName, int uid, 3525 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3526 boolean evenPersistent, String reason) { 3527 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3528 3529 // Remove all processes this package may have touched: all with the 3530 // same UID (except for the system or root user), and all whose name 3531 // matches the package name. 3532 final String procNamePrefix = packageName + ":"; 3533 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3534 final int NA = apps.size(); 3535 for (int ia=0; ia<NA; ia++) { 3536 ProcessRecord app = apps.valueAt(ia); 3537 if (app.persistent && !evenPersistent) { 3538 // we don't kill persistent processes 3539 continue; 3540 } 3541 if (app.removed) { 3542 if (doit) { 3543 procs.add(app); 3544 } 3545 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3546 || app.processName.equals(packageName) 3547 || app.processName.startsWith(procNamePrefix)) { 3548 if (app.setAdj >= minOomAdj) { 3549 if (!doit) { 3550 return true; 3551 } 3552 app.removed = true; 3553 procs.add(app); 3554 } 3555 } 3556 } 3557 } 3558 3559 int N = procs.size(); 3560 for (int i=0; i<N; i++) { 3561 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3562 } 3563 return N > 0; 3564 } 3565 3566 private final boolean forceStopPackageLocked(String name, int uid, 3567 boolean callerWillRestart, boolean purgeCache, boolean doit, 3568 boolean evenPersistent) { 3569 int i; 3570 int N; 3571 3572 if (uid < 0) { 3573 try { 3574 uid = AppGlobals.getPackageManager().getPackageUid(name); 3575 } catch (RemoteException e) { 3576 } 3577 } 3578 3579 if (doit) { 3580 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3581 3582 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3583 while (badApps.hasNext()) { 3584 SparseArray<Long> ba = badApps.next(); 3585 if (ba.get(uid) != null) { 3586 badApps.remove(); 3587 } 3588 } 3589 } 3590 3591 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3592 callerWillRestart, false, doit, evenPersistent, "force stop"); 3593 3594 TaskRecord lastTask = null; 3595 for (i=0; i<mMainStack.mHistory.size(); i++) { 3596 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3597 final boolean samePackage = r.packageName.equals(name); 3598 if ((samePackage || r.task == lastTask) 3599 && (r.app == null || evenPersistent || !r.app.persistent)) { 3600 if (!doit) { 3601 if (r.finishing) { 3602 // If this activity is just finishing, then it is not 3603 // interesting as far as something to stop. 3604 continue; 3605 } 3606 return true; 3607 } 3608 didSomething = true; 3609 Slog.i(TAG, " Force finishing activity " + r); 3610 if (samePackage) { 3611 if (r.app != null) { 3612 r.app.removed = true; 3613 } 3614 r.app = null; 3615 } 3616 lastTask = r.task; 3617 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3618 null, "force-stop")) { 3619 i--; 3620 } 3621 } 3622 } 3623 3624 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 3625 for (ServiceRecord service : mServices.values()) { 3626 if (service.packageName.equals(name) 3627 && (service.app == null || evenPersistent || !service.app.persistent)) { 3628 if (!doit) { 3629 return true; 3630 } 3631 didSomething = true; 3632 Slog.i(TAG, " Force stopping service " + service); 3633 if (service.app != null) { 3634 service.app.removed = true; 3635 } 3636 service.app = null; 3637 services.add(service); 3638 } 3639 } 3640 3641 N = services.size(); 3642 for (i=0; i<N; i++) { 3643 bringDownServiceLocked(services.get(i), true); 3644 } 3645 3646 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3647 for (ContentProviderRecord provider : mProvidersByClass.values()) { 3648 if (provider.info.packageName.equals(name) 3649 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3650 if (!doit) { 3651 return true; 3652 } 3653 didSomething = true; 3654 providers.add(provider); 3655 } 3656 } 3657 3658 N = providers.size(); 3659 for (i=0; i<N; i++) { 3660 removeDyingProviderLocked(null, providers.get(i)); 3661 } 3662 3663 if (doit) { 3664 if (purgeCache) { 3665 AttributeCache ac = AttributeCache.instance(); 3666 if (ac != null) { 3667 ac.removePackage(name); 3668 } 3669 } 3670 if (mBooted) { 3671 mMainStack.resumeTopActivityLocked(null); 3672 mMainStack.scheduleIdleLocked(); 3673 } 3674 } 3675 3676 return didSomething; 3677 } 3678 3679 private final boolean removeProcessLocked(ProcessRecord app, 3680 boolean callerWillRestart, boolean allowRestart, String reason) { 3681 final String name = app.processName; 3682 final int uid = app.info.uid; 3683 if (DEBUG_PROCESSES) Slog.d( 3684 TAG, "Force removing proc " + app.toShortString() + " (" + name 3685 + "/" + uid + ")"); 3686 3687 mProcessNames.remove(name, uid); 3688 if (mHeavyWeightProcess == app) { 3689 mHeavyWeightProcess = null; 3690 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3691 } 3692 boolean needRestart = false; 3693 if (app.pid > 0 && app.pid != MY_PID) { 3694 int pid = app.pid; 3695 synchronized (mPidsSelfLocked) { 3696 mPidsSelfLocked.remove(pid); 3697 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3698 } 3699 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3700 handleAppDiedLocked(app, true, allowRestart); 3701 mLruProcesses.remove(app); 3702 Process.killProcessQuiet(pid); 3703 3704 if (app.persistent) { 3705 if (!callerWillRestart) { 3706 addAppLocked(app.info); 3707 } else { 3708 needRestart = true; 3709 } 3710 } 3711 } else { 3712 mRemovedProcesses.add(app); 3713 } 3714 3715 return needRestart; 3716 } 3717 3718 private final void processStartTimedOutLocked(ProcessRecord app) { 3719 final int pid = app.pid; 3720 boolean gone = false; 3721 synchronized (mPidsSelfLocked) { 3722 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3723 if (knownApp != null && knownApp.thread == null) { 3724 mPidsSelfLocked.remove(pid); 3725 gone = true; 3726 } 3727 } 3728 3729 if (gone) { 3730 Slog.w(TAG, "Process " + app + " failed to attach"); 3731 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 3732 app.processName); 3733 mProcessNames.remove(app.processName, app.info.uid); 3734 if (mHeavyWeightProcess == app) { 3735 mHeavyWeightProcess = null; 3736 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3737 } 3738 // Take care of any launching providers waiting for this process. 3739 checkAppInLaunchingProvidersLocked(app, true); 3740 // Take care of any services that are waiting for the process. 3741 for (int i=0; i<mPendingServices.size(); i++) { 3742 ServiceRecord sr = mPendingServices.get(i); 3743 if (app.info.uid == sr.appInfo.uid 3744 && app.processName.equals(sr.processName)) { 3745 Slog.w(TAG, "Forcing bringing down service: " + sr); 3746 mPendingServices.remove(i); 3747 i--; 3748 bringDownServiceLocked(sr, true); 3749 } 3750 } 3751 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3752 app.processName, app.setAdj, "start timeout"); 3753 Process.killProcessQuiet(pid); 3754 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3755 Slog.w(TAG, "Unattached app died before backup, skipping"); 3756 try { 3757 IBackupManager bm = IBackupManager.Stub.asInterface( 3758 ServiceManager.getService(Context.BACKUP_SERVICE)); 3759 bm.agentDisconnected(app.info.packageName); 3760 } catch (RemoteException e) { 3761 // Can't happen; the backup manager is local 3762 } 3763 } 3764 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 3765 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3766 mPendingBroadcast.state = BroadcastRecord.IDLE; 3767 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 3768 mPendingBroadcast = null; 3769 scheduleBroadcastsLocked(); 3770 } 3771 } else { 3772 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3773 } 3774 } 3775 3776 private final boolean attachApplicationLocked(IApplicationThread thread, 3777 int pid) { 3778 3779 // Find the application record that is being attached... either via 3780 // the pid if we are running in multiple processes, or just pull the 3781 // next app record if we are emulating process with anonymous threads. 3782 ProcessRecord app; 3783 if (pid != MY_PID && pid >= 0) { 3784 synchronized (mPidsSelfLocked) { 3785 app = mPidsSelfLocked.get(pid); 3786 } 3787 } else { 3788 app = null; 3789 } 3790 3791 if (app == null) { 3792 Slog.w(TAG, "No pending application record for pid " + pid 3793 + " (IApplicationThread " + thread + "); dropping process"); 3794 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3795 if (pid > 0 && pid != MY_PID) { 3796 Process.killProcessQuiet(pid); 3797 } else { 3798 try { 3799 thread.scheduleExit(); 3800 } catch (Exception e) { 3801 // Ignore exceptions. 3802 } 3803 } 3804 return false; 3805 } 3806 3807 // If this application record is still attached to a previous 3808 // process, clean it up now. 3809 if (app.thread != null) { 3810 handleAppDiedLocked(app, true, true); 3811 } 3812 3813 // Tell the process all about itself. 3814 3815 if (localLOGV) Slog.v( 3816 TAG, "Binding process pid " + pid + " to record " + app); 3817 3818 String processName = app.processName; 3819 try { 3820 AppDeathRecipient adr = new AppDeathRecipient( 3821 app, pid, thread); 3822 thread.asBinder().linkToDeath(adr, 0); 3823 app.deathRecipient = adr; 3824 } catch (RemoteException e) { 3825 app.resetPackageList(); 3826 startProcessLocked(app, "link fail", processName); 3827 return false; 3828 } 3829 3830 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3831 3832 app.thread = thread; 3833 app.curAdj = app.setAdj = -100; 3834 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3835 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3836 app.forcingToForeground = null; 3837 app.foregroundServices = false; 3838 app.hasShownUi = false; 3839 app.debugging = false; 3840 3841 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3842 3843 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3844 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3845 3846 if (!normalMode) { 3847 Slog.i(TAG, "Launching preboot mode app: " + app); 3848 } 3849 3850 if (localLOGV) Slog.v( 3851 TAG, "New app record " + app 3852 + " thread=" + thread.asBinder() + " pid=" + pid); 3853 try { 3854 int testMode = IApplicationThread.DEBUG_OFF; 3855 if (mDebugApp != null && mDebugApp.equals(processName)) { 3856 testMode = mWaitForDebugger 3857 ? IApplicationThread.DEBUG_WAIT 3858 : IApplicationThread.DEBUG_ON; 3859 app.debugging = true; 3860 if (mDebugTransient) { 3861 mDebugApp = mOrigDebugApp; 3862 mWaitForDebugger = mOrigWaitForDebugger; 3863 } 3864 } 3865 String profileFile = app.instrumentationProfileFile; 3866 ParcelFileDescriptor profileFd = null; 3867 boolean profileAutoStop = false; 3868 if (mProfileApp != null && mProfileApp.equals(processName)) { 3869 mProfileProc = app; 3870 profileFile = mProfileFile; 3871 profileFd = mProfileFd; 3872 profileAutoStop = mAutoStopProfiler; 3873 } 3874 3875 // If the app is being launched for restore or full backup, set it up specially 3876 boolean isRestrictedBackupMode = false; 3877 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3878 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3879 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3880 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3881 } 3882 3883 ensurePackageDexOpt(app.instrumentationInfo != null 3884 ? app.instrumentationInfo.packageName 3885 : app.info.packageName); 3886 if (app.instrumentationClass != null) { 3887 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3888 } 3889 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3890 + processName + " with config " + mConfiguration); 3891 ApplicationInfo appInfo = app.instrumentationInfo != null 3892 ? app.instrumentationInfo : app.info; 3893 app.compat = compatibilityInfoForPackageLocked(appInfo); 3894 if (profileFd != null) { 3895 profileFd = profileFd.dup(); 3896 } 3897 thread.bindApplication(processName, appInfo, providers, 3898 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 3899 app.instrumentationArguments, app.instrumentationWatcher, testMode, 3900 isRestrictedBackupMode || !normalMode, app.persistent, 3901 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 3902 mCoreSettingsObserver.getCoreSettingsLocked()); 3903 updateLruProcessLocked(app, false, true); 3904 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 3905 } catch (Exception e) { 3906 // todo: Yikes! What should we do? For now we will try to 3907 // start another process, but that could easily get us in 3908 // an infinite loop of restarting processes... 3909 Slog.w(TAG, "Exception thrown during bind!", e); 3910 3911 app.resetPackageList(); 3912 app.unlinkDeathRecipient(); 3913 startProcessLocked(app, "bind fail", processName); 3914 return false; 3915 } 3916 3917 // Remove this record from the list of starting applications. 3918 mPersistentStartingProcesses.remove(app); 3919 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3920 "Attach application locked removing on hold: " + app); 3921 mProcessesOnHold.remove(app); 3922 3923 boolean badApp = false; 3924 boolean didSomething = false; 3925 3926 // See if the top visible activity is waiting to run in this process... 3927 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 3928 if (hr != null && normalMode) { 3929 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 3930 && processName.equals(hr.processName)) { 3931 try { 3932 if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 3933 didSomething = true; 3934 } 3935 } catch (Exception e) { 3936 Slog.w(TAG, "Exception in new application when starting activity " 3937 + hr.intent.getComponent().flattenToShortString(), e); 3938 badApp = true; 3939 } 3940 } else { 3941 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 3942 } 3943 } 3944 3945 // Find any services that should be running in this process... 3946 if (!badApp && mPendingServices.size() > 0) { 3947 ServiceRecord sr = null; 3948 try { 3949 for (int i=0; i<mPendingServices.size(); i++) { 3950 sr = mPendingServices.get(i); 3951 if (app.info.uid != sr.appInfo.uid 3952 || !processName.equals(sr.processName)) { 3953 continue; 3954 } 3955 3956 mPendingServices.remove(i); 3957 i--; 3958 realStartServiceLocked(sr, app); 3959 didSomething = true; 3960 } 3961 } catch (Exception e) { 3962 Slog.w(TAG, "Exception in new application when starting service " 3963 + sr.shortName, e); 3964 badApp = true; 3965 } 3966 } 3967 3968 // Check if the next broadcast receiver is in this process... 3969 BroadcastRecord br = mPendingBroadcast; 3970 if (!badApp && br != null && br.curApp == app) { 3971 try { 3972 mPendingBroadcast = null; 3973 processCurBroadcastLocked(br, app); 3974 didSomething = true; 3975 } catch (Exception e) { 3976 Slog.w(TAG, "Exception in new application when starting receiver " 3977 + br.curComponent.flattenToShortString(), e); 3978 badApp = true; 3979 logBroadcastReceiverDiscardLocked(br); 3980 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 3981 br.resultExtras, br.resultAbort, true); 3982 scheduleBroadcastsLocked(); 3983 // We need to reset the state if we fails to start the receiver. 3984 br.state = BroadcastRecord.IDLE; 3985 } 3986 } 3987 3988 // Check whether the next backup agent is in this process... 3989 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 3990 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 3991 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 3992 try { 3993 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 3994 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 3995 mBackupTarget.backupMode); 3996 } catch (Exception e) { 3997 Slog.w(TAG, "Exception scheduling backup agent creation: "); 3998 e.printStackTrace(); 3999 } 4000 } 4001 4002 if (badApp) { 4003 // todo: Also need to kill application to deal with all 4004 // kinds of exceptions. 4005 handleAppDiedLocked(app, false, true); 4006 return false; 4007 } 4008 4009 if (!didSomething) { 4010 updateOomAdjLocked(); 4011 } 4012 4013 return true; 4014 } 4015 4016 public final void attachApplication(IApplicationThread thread) { 4017 synchronized (this) { 4018 int callingPid = Binder.getCallingPid(); 4019 final long origId = Binder.clearCallingIdentity(); 4020 attachApplicationLocked(thread, callingPid); 4021 Binder.restoreCallingIdentity(origId); 4022 } 4023 } 4024 4025 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4026 final long origId = Binder.clearCallingIdentity(); 4027 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4028 if (stopProfiling) { 4029 synchronized (this) { 4030 if (mProfileProc == r.app) { 4031 if (mProfileFd != null) { 4032 try { 4033 mProfileFd.close(); 4034 } catch (IOException e) { 4035 } 4036 clearProfilerLocked(); 4037 } 4038 } 4039 } 4040 } 4041 Binder.restoreCallingIdentity(origId); 4042 } 4043 4044 void enableScreenAfterBoot() { 4045 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4046 SystemClock.uptimeMillis()); 4047 mWindowManager.enableScreenAfterBoot(); 4048 } 4049 4050 public void showBootMessage(final CharSequence msg, final boolean always) { 4051 mWindowManager.showBootMessage(msg, always); 4052 } 4053 4054 public void dismissKeyguardOnNextActivity() { 4055 synchronized (this) { 4056 mMainStack.dismissKeyguardOnNextActivityLocked(); 4057 } 4058 } 4059 4060 final void finishBooting() { 4061 IntentFilter pkgFilter = new IntentFilter(); 4062 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4063 pkgFilter.addDataScheme("package"); 4064 mContext.registerReceiver(new BroadcastReceiver() { 4065 @Override 4066 public void onReceive(Context context, Intent intent) { 4067 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4068 if (pkgs != null) { 4069 for (String pkg : pkgs) { 4070 synchronized (ActivityManagerService.this) { 4071 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) { 4072 setResultCode(Activity.RESULT_OK); 4073 return; 4074 } 4075 } 4076 } 4077 } 4078 } 4079 }, pkgFilter); 4080 4081 synchronized (this) { 4082 // Ensure that any processes we had put on hold are now started 4083 // up. 4084 final int NP = mProcessesOnHold.size(); 4085 if (NP > 0) { 4086 ArrayList<ProcessRecord> procs = 4087 new ArrayList<ProcessRecord>(mProcessesOnHold); 4088 for (int ip=0; ip<NP; ip++) { 4089 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4090 + procs.get(ip)); 4091 startProcessLocked(procs.get(ip), "on-hold", null); 4092 } 4093 } 4094 4095 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4096 // Start looking for apps that are abusing wake locks. 4097 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4098 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4099 // Tell anyone interested that we are done booting! 4100 SystemProperties.set("sys.boot_completed", "1"); 4101 broadcastIntentLocked(null, null, 4102 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4103 null, null, 0, null, null, 4104 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4105 false, false, MY_PID, Process.SYSTEM_UID); 4106 } 4107 } 4108 } 4109 4110 final void ensureBootCompleted() { 4111 boolean booting; 4112 boolean enableScreen; 4113 synchronized (this) { 4114 booting = mBooting; 4115 mBooting = false; 4116 enableScreen = !mBooted; 4117 mBooted = true; 4118 } 4119 4120 if (booting) { 4121 finishBooting(); 4122 } 4123 4124 if (enableScreen) { 4125 enableScreenAfterBoot(); 4126 } 4127 } 4128 4129 public final void activityPaused(IBinder token) { 4130 final long origId = Binder.clearCallingIdentity(); 4131 mMainStack.activityPaused(token, false); 4132 Binder.restoreCallingIdentity(origId); 4133 } 4134 4135 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4136 CharSequence description) { 4137 if (localLOGV) Slog.v( 4138 TAG, "Activity stopped: token=" + token); 4139 4140 // Refuse possible leaked file descriptors 4141 if (icicle != null && icicle.hasFileDescriptors()) { 4142 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4143 } 4144 4145 ActivityRecord r = null; 4146 4147 final long origId = Binder.clearCallingIdentity(); 4148 4149 synchronized (this) { 4150 r = mMainStack.isInStackLocked(token); 4151 if (r != null) { 4152 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4153 } 4154 } 4155 4156 if (r != null) { 4157 sendPendingThumbnail(r, null, null, null, false); 4158 } 4159 4160 trimApplications(); 4161 4162 Binder.restoreCallingIdentity(origId); 4163 } 4164 4165 public final void activityDestroyed(IBinder token) { 4166 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4167 mMainStack.activityDestroyed(token); 4168 } 4169 4170 public String getCallingPackage(IBinder token) { 4171 synchronized (this) { 4172 ActivityRecord r = getCallingRecordLocked(token); 4173 return r != null && r.app != null ? r.info.packageName : null; 4174 } 4175 } 4176 4177 public ComponentName getCallingActivity(IBinder token) { 4178 synchronized (this) { 4179 ActivityRecord r = getCallingRecordLocked(token); 4180 return r != null ? r.intent.getComponent() : null; 4181 } 4182 } 4183 4184 private ActivityRecord getCallingRecordLocked(IBinder token) { 4185 ActivityRecord r = mMainStack.isInStackLocked(token); 4186 if (r == null) { 4187 return null; 4188 } 4189 return r.resultTo; 4190 } 4191 4192 public ComponentName getActivityClassForToken(IBinder token) { 4193 synchronized(this) { 4194 ActivityRecord r = mMainStack.isInStackLocked(token); 4195 if (r == null) { 4196 return null; 4197 } 4198 return r.intent.getComponent(); 4199 } 4200 } 4201 4202 public String getPackageForToken(IBinder token) { 4203 synchronized(this) { 4204 ActivityRecord r = mMainStack.isInStackLocked(token); 4205 if (r == null) { 4206 return null; 4207 } 4208 return r.packageName; 4209 } 4210 } 4211 4212 public IIntentSender getIntentSender(int type, 4213 String packageName, IBinder token, String resultWho, 4214 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) { 4215 // Refuse possible leaked file descriptors 4216 if (intents != null) { 4217 if (intents.length < 1) { 4218 throw new IllegalArgumentException("Intents array length must be >= 1"); 4219 } 4220 for (int i=0; i<intents.length; i++) { 4221 Intent intent = intents[i]; 4222 if (intent != null) { 4223 if (intent.hasFileDescriptors()) { 4224 throw new IllegalArgumentException("File descriptors passed in Intent"); 4225 } 4226 if (type == INTENT_SENDER_BROADCAST && 4227 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4228 throw new IllegalArgumentException( 4229 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4230 } 4231 intents[i] = new Intent(intent); 4232 } 4233 } 4234 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4235 throw new IllegalArgumentException( 4236 "Intent array length does not match resolvedTypes length"); 4237 } 4238 } 4239 4240 synchronized(this) { 4241 int callingUid = Binder.getCallingUid(); 4242 try { 4243 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4244 int uid = AppGlobals.getPackageManager() 4245 .getPackageUid(packageName); 4246 if (uid != Binder.getCallingUid()) { 4247 String msg = "Permission Denial: getIntentSender() from pid=" 4248 + Binder.getCallingPid() 4249 + ", uid=" + Binder.getCallingUid() 4250 + ", (need uid=" + uid + ")" 4251 + " is not allowed to send as package " + packageName; 4252 Slog.w(TAG, msg); 4253 throw new SecurityException(msg); 4254 } 4255 } 4256 4257 return getIntentSenderLocked(type, packageName, callingUid, 4258 token, resultWho, requestCode, intents, resolvedTypes, flags); 4259 4260 } catch (RemoteException e) { 4261 throw new SecurityException(e); 4262 } 4263 } 4264 } 4265 4266 IIntentSender getIntentSenderLocked(int type, 4267 String packageName, int callingUid, IBinder token, String resultWho, 4268 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) { 4269 ActivityRecord activity = null; 4270 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 4271 activity = mMainStack.isInStackLocked(token); 4272 if (activity == null) { 4273 return null; 4274 } 4275 if (activity.finishing) { 4276 return null; 4277 } 4278 } 4279 4280 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4281 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4282 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4283 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4284 |PendingIntent.FLAG_UPDATE_CURRENT); 4285 4286 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4287 type, packageName, activity, resultWho, 4288 requestCode, intents, resolvedTypes, flags); 4289 WeakReference<PendingIntentRecord> ref; 4290 ref = mIntentSenderRecords.get(key); 4291 PendingIntentRecord rec = ref != null ? ref.get() : null; 4292 if (rec != null) { 4293 if (!cancelCurrent) { 4294 if (updateCurrent) { 4295 if (rec.key.requestIntent != null) { 4296 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null); 4297 } 4298 if (intents != null) { 4299 intents[intents.length-1] = rec.key.requestIntent; 4300 rec.key.allIntents = intents; 4301 rec.key.allResolvedTypes = resolvedTypes; 4302 } else { 4303 rec.key.allIntents = null; 4304 rec.key.allResolvedTypes = null; 4305 } 4306 } 4307 return rec; 4308 } 4309 rec.canceled = true; 4310 mIntentSenderRecords.remove(key); 4311 } 4312 if (noCreate) { 4313 return rec; 4314 } 4315 rec = new PendingIntentRecord(this, key, callingUid); 4316 mIntentSenderRecords.put(key, rec.ref); 4317 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 4318 if (activity.pendingResults == null) { 4319 activity.pendingResults 4320 = new HashSet<WeakReference<PendingIntentRecord>>(); 4321 } 4322 activity.pendingResults.add(rec.ref); 4323 } 4324 return rec; 4325 } 4326 4327 public void cancelIntentSender(IIntentSender sender) { 4328 if (!(sender instanceof PendingIntentRecord)) { 4329 return; 4330 } 4331 synchronized(this) { 4332 PendingIntentRecord rec = (PendingIntentRecord)sender; 4333 try { 4334 int uid = AppGlobals.getPackageManager() 4335 .getPackageUid(rec.key.packageName); 4336 if (uid != Binder.getCallingUid()) { 4337 String msg = "Permission Denial: cancelIntentSender() from pid=" 4338 + Binder.getCallingPid() 4339 + ", uid=" + Binder.getCallingUid() 4340 + " is not allowed to cancel packges " 4341 + rec.key.packageName; 4342 Slog.w(TAG, msg); 4343 throw new SecurityException(msg); 4344 } 4345 } catch (RemoteException e) { 4346 throw new SecurityException(e); 4347 } 4348 cancelIntentSenderLocked(rec, true); 4349 } 4350 } 4351 4352 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4353 rec.canceled = true; 4354 mIntentSenderRecords.remove(rec.key); 4355 if (cleanActivity && rec.key.activity != null) { 4356 rec.key.activity.pendingResults.remove(rec.ref); 4357 } 4358 } 4359 4360 public String getPackageForIntentSender(IIntentSender pendingResult) { 4361 if (!(pendingResult instanceof PendingIntentRecord)) { 4362 return null; 4363 } 4364 try { 4365 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4366 return res.key.packageName; 4367 } catch (ClassCastException e) { 4368 } 4369 return null; 4370 } 4371 4372 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4373 if (!(pendingResult instanceof PendingIntentRecord)) { 4374 return false; 4375 } 4376 try { 4377 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4378 if (res.key.allIntents == null) { 4379 return false; 4380 } 4381 for (int i=0; i<res.key.allIntents.length; i++) { 4382 Intent intent = res.key.allIntents[i]; 4383 if (intent.getPackage() != null && intent.getComponent() != null) { 4384 return false; 4385 } 4386 } 4387 return true; 4388 } catch (ClassCastException e) { 4389 } 4390 return false; 4391 } 4392 4393 public void setProcessLimit(int max) { 4394 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4395 "setProcessLimit()"); 4396 synchronized (this) { 4397 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4398 mProcessLimitOverride = max; 4399 } 4400 trimApplications(); 4401 } 4402 4403 public int getProcessLimit() { 4404 synchronized (this) { 4405 return mProcessLimitOverride; 4406 } 4407 } 4408 4409 void foregroundTokenDied(ForegroundToken token) { 4410 synchronized (ActivityManagerService.this) { 4411 synchronized (mPidsSelfLocked) { 4412 ForegroundToken cur 4413 = mForegroundProcesses.get(token.pid); 4414 if (cur != token) { 4415 return; 4416 } 4417 mForegroundProcesses.remove(token.pid); 4418 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4419 if (pr == null) { 4420 return; 4421 } 4422 pr.forcingToForeground = null; 4423 pr.foregroundServices = false; 4424 } 4425 updateOomAdjLocked(); 4426 } 4427 } 4428 4429 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4430 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4431 "setProcessForeground()"); 4432 synchronized(this) { 4433 boolean changed = false; 4434 4435 synchronized (mPidsSelfLocked) { 4436 ProcessRecord pr = mPidsSelfLocked.get(pid); 4437 if (pr == null) { 4438 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4439 return; 4440 } 4441 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4442 if (oldToken != null) { 4443 oldToken.token.unlinkToDeath(oldToken, 0); 4444 mForegroundProcesses.remove(pid); 4445 pr.forcingToForeground = null; 4446 changed = true; 4447 } 4448 if (isForeground && token != null) { 4449 ForegroundToken newToken = new ForegroundToken() { 4450 public void binderDied() { 4451 foregroundTokenDied(this); 4452 } 4453 }; 4454 newToken.pid = pid; 4455 newToken.token = token; 4456 try { 4457 token.linkToDeath(newToken, 0); 4458 mForegroundProcesses.put(pid, newToken); 4459 pr.forcingToForeground = token; 4460 changed = true; 4461 } catch (RemoteException e) { 4462 // If the process died while doing this, we will later 4463 // do the cleanup with the process death link. 4464 } 4465 } 4466 } 4467 4468 if (changed) { 4469 updateOomAdjLocked(); 4470 } 4471 } 4472 } 4473 4474 // ========================================================= 4475 // PERMISSIONS 4476 // ========================================================= 4477 4478 static class PermissionController extends IPermissionController.Stub { 4479 ActivityManagerService mActivityManagerService; 4480 PermissionController(ActivityManagerService activityManagerService) { 4481 mActivityManagerService = activityManagerService; 4482 } 4483 4484 public boolean checkPermission(String permission, int pid, int uid) { 4485 return mActivityManagerService.checkPermission(permission, pid, 4486 uid) == PackageManager.PERMISSION_GRANTED; 4487 } 4488 } 4489 4490 /** 4491 * This can be called with or without the global lock held. 4492 */ 4493 int checkComponentPermission(String permission, int pid, int uid, 4494 int owningUid, boolean exported) { 4495 // We might be performing an operation on behalf of an indirect binder 4496 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4497 // client identity accordingly before proceeding. 4498 Identity tlsIdentity = sCallerIdentity.get(); 4499 if (tlsIdentity != null) { 4500 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4501 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4502 uid = tlsIdentity.uid; 4503 pid = tlsIdentity.pid; 4504 } 4505 4506 // Root, system server and our own process get to do everything. 4507 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) { 4508 return PackageManager.PERMISSION_GRANTED; 4509 } 4510 // If there is a uid that owns whatever is being accessed, it has 4511 // blanket access to it regardless of the permissions it requires. 4512 if (owningUid >= 0 && uid == owningUid) { 4513 return PackageManager.PERMISSION_GRANTED; 4514 } 4515 // If the target is not exported, then nobody else can get to it. 4516 if (!exported) { 4517 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid); 4518 return PackageManager.PERMISSION_DENIED; 4519 } 4520 if (permission == null) { 4521 return PackageManager.PERMISSION_GRANTED; 4522 } 4523 try { 4524 return AppGlobals.getPackageManager() 4525 .checkUidPermission(permission, uid); 4526 } catch (RemoteException e) { 4527 // Should never happen, but if it does... deny! 4528 Slog.e(TAG, "PackageManager is dead?!?", e); 4529 } 4530 return PackageManager.PERMISSION_DENIED; 4531 } 4532 4533 /** 4534 * As the only public entry point for permissions checking, this method 4535 * can enforce the semantic that requesting a check on a null global 4536 * permission is automatically denied. (Internally a null permission 4537 * string is used when calling {@link #checkComponentPermission} in cases 4538 * when only uid-based security is needed.) 4539 * 4540 * This can be called with or without the global lock held. 4541 */ 4542 public int checkPermission(String permission, int pid, int uid) { 4543 if (permission == null) { 4544 return PackageManager.PERMISSION_DENIED; 4545 } 4546 return checkComponentPermission(permission, pid, uid, -1, true); 4547 } 4548 4549 /** 4550 * Binder IPC calls go through the public entry point. 4551 * This can be called with or without the global lock held. 4552 */ 4553 int checkCallingPermission(String permission) { 4554 return checkPermission(permission, 4555 Binder.getCallingPid(), 4556 Binder.getCallingUid()); 4557 } 4558 4559 /** 4560 * This can be called with or without the global lock held. 4561 */ 4562 void enforceCallingPermission(String permission, String func) { 4563 if (checkCallingPermission(permission) 4564 == PackageManager.PERMISSION_GRANTED) { 4565 return; 4566 } 4567 4568 String msg = "Permission Denial: " + func + " from pid=" 4569 + Binder.getCallingPid() 4570 + ", uid=" + Binder.getCallingUid() 4571 + " requires " + permission; 4572 Slog.w(TAG, msg); 4573 throw new SecurityException(msg); 4574 } 4575 4576 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 4577 ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4578 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4579 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4580 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4581 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4582 try { 4583 // Is the component private from the target uid? 4584 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid; 4585 4586 // Acceptable if the there is no read permission needed from the 4587 // target or the target is holding the read permission. 4588 if (!readPerm) { 4589 if ((!prv && pi.readPermission == null) || 4590 (pm.checkUidPermission(pi.readPermission, uid) 4591 == PackageManager.PERMISSION_GRANTED)) { 4592 readPerm = true; 4593 } 4594 } 4595 4596 // Acceptable if the there is no write permission needed from the 4597 // target or the target is holding the read permission. 4598 if (!writePerm) { 4599 if (!prv && (pi.writePermission == null) || 4600 (pm.checkUidPermission(pi.writePermission, uid) 4601 == PackageManager.PERMISSION_GRANTED)) { 4602 writePerm = true; 4603 } 4604 } 4605 4606 // Acceptable if there is a path permission matching the URI that 4607 // the target holds the permission on. 4608 PathPermission[] pps = pi.pathPermissions; 4609 if (pps != null && (!readPerm || !writePerm)) { 4610 final String path = uri.getPath(); 4611 int i = pps.length; 4612 while (i > 0 && (!readPerm || !writePerm)) { 4613 i--; 4614 PathPermission pp = pps[i]; 4615 if (!readPerm) { 4616 final String pprperm = pp.getReadPermission(); 4617 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4618 + pprperm + " for " + pp.getPath() 4619 + ": match=" + pp.match(path) 4620 + " check=" + pm.checkUidPermission(pprperm, uid)); 4621 if (pprperm != null && pp.match(path) && 4622 (pm.checkUidPermission(pprperm, uid) 4623 == PackageManager.PERMISSION_GRANTED)) { 4624 readPerm = true; 4625 } 4626 } 4627 if (!writePerm) { 4628 final String ppwperm = pp.getWritePermission(); 4629 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4630 + ppwperm + " for " + pp.getPath() 4631 + ": match=" + pp.match(path) 4632 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4633 if (ppwperm != null && pp.match(path) && 4634 (pm.checkUidPermission(ppwperm, uid) 4635 == PackageManager.PERMISSION_GRANTED)) { 4636 writePerm = true; 4637 } 4638 } 4639 } 4640 } 4641 } catch (RemoteException e) { 4642 return false; 4643 } 4644 4645 return readPerm && writePerm; 4646 } 4647 4648 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4649 int modeFlags) { 4650 // Root gets to do everything. 4651 if (uid == 0) { 4652 return true; 4653 } 4654 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4655 if (perms == null) return false; 4656 UriPermission perm = perms.get(uri); 4657 if (perm == null) return false; 4658 return (modeFlags&perm.modeFlags) == modeFlags; 4659 } 4660 4661 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4662 // Another redirected-binder-call permissions check as in 4663 // {@link checkComponentPermission}. 4664 Identity tlsIdentity = sCallerIdentity.get(); 4665 if (tlsIdentity != null) { 4666 uid = tlsIdentity.uid; 4667 pid = tlsIdentity.pid; 4668 } 4669 4670 // Our own process gets to do everything. 4671 if (pid == MY_PID) { 4672 return PackageManager.PERMISSION_GRANTED; 4673 } 4674 synchronized(this) { 4675 return checkUriPermissionLocked(uri, uid, modeFlags) 4676 ? PackageManager.PERMISSION_GRANTED 4677 : PackageManager.PERMISSION_DENIED; 4678 } 4679 } 4680 4681 /** 4682 * Check if the targetPkg can be granted permission to access uri by 4683 * the callingUid using the given modeFlags. Throws a security exception 4684 * if callingUid is not allowed to do this. Returns the uid of the target 4685 * if the URI permission grant should be performed; returns -1 if it is not 4686 * needed (for example targetPkg already has permission to access the URI). 4687 */ 4688 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4689 Uri uri, int modeFlags) { 4690 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4691 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4692 if (modeFlags == 0) { 4693 return -1; 4694 } 4695 4696 if (targetPkg != null) { 4697 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4698 "Checking grant " + targetPkg + " permission to " + uri); 4699 } 4700 4701 final IPackageManager pm = AppGlobals.getPackageManager(); 4702 4703 // If this is not a content: uri, we can't do anything with it. 4704 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4705 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4706 "Can't grant URI permission for non-content URI: " + uri); 4707 return -1; 4708 } 4709 4710 String name = uri.getAuthority(); 4711 ProviderInfo pi = null; 4712 ContentProviderRecord cpr = mProvidersByName.get(name); 4713 if (cpr != null) { 4714 pi = cpr.info; 4715 } else { 4716 try { 4717 pi = pm.resolveContentProvider(name, 4718 PackageManager.GET_URI_PERMISSION_PATTERNS); 4719 } catch (RemoteException ex) { 4720 } 4721 } 4722 if (pi == null) { 4723 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4724 return -1; 4725 } 4726 4727 int targetUid; 4728 if (targetPkg != null) { 4729 try { 4730 targetUid = pm.getPackageUid(targetPkg); 4731 if (targetUid < 0) { 4732 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4733 "Can't grant URI permission no uid for: " + targetPkg); 4734 return -1; 4735 } 4736 } catch (RemoteException ex) { 4737 return -1; 4738 } 4739 } else { 4740 targetUid = -1; 4741 } 4742 4743 if (targetUid >= 0) { 4744 // First... does the target actually need this permission? 4745 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4746 // No need to grant the target this permission. 4747 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4748 "Target " + targetPkg + " already has full permission to " + uri); 4749 return -1; 4750 } 4751 } else { 4752 // First... there is no target package, so can anyone access it? 4753 boolean allowed = pi.exported; 4754 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4755 if (pi.readPermission != null) { 4756 allowed = false; 4757 } 4758 } 4759 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4760 if (pi.writePermission != null) { 4761 allowed = false; 4762 } 4763 } 4764 if (allowed) { 4765 return -1; 4766 } 4767 } 4768 4769 // Second... is the provider allowing granting of URI permissions? 4770 if (!pi.grantUriPermissions) { 4771 throw new SecurityException("Provider " + pi.packageName 4772 + "/" + pi.name 4773 + " does not allow granting of Uri permissions (uri " 4774 + uri + ")"); 4775 } 4776 if (pi.uriPermissionPatterns != null) { 4777 final int N = pi.uriPermissionPatterns.length; 4778 boolean allowed = false; 4779 for (int i=0; i<N; i++) { 4780 if (pi.uriPermissionPatterns[i] != null 4781 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4782 allowed = true; 4783 break; 4784 } 4785 } 4786 if (!allowed) { 4787 throw new SecurityException("Provider " + pi.packageName 4788 + "/" + pi.name 4789 + " does not allow granting of permission to path of Uri " 4790 + uri); 4791 } 4792 } 4793 4794 // Third... does the caller itself have permission to access 4795 // this uri? 4796 if (callingUid != Process.myUid()) { 4797 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4798 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4799 throw new SecurityException("Uid " + callingUid 4800 + " does not have permission to uri " + uri); 4801 } 4802 } 4803 } 4804 4805 return targetUid; 4806 } 4807 4808 public int checkGrantUriPermission(int callingUid, String targetPkg, 4809 Uri uri, int modeFlags) { 4810 synchronized(this) { 4811 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); 4812 } 4813 } 4814 4815 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4816 Uri uri, int modeFlags, UriPermissionOwner owner) { 4817 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4818 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4819 if (modeFlags == 0) { 4820 return; 4821 } 4822 4823 // So here we are: the caller has the assumed permission 4824 // to the uri, and the target doesn't. Let's now give this to 4825 // the target. 4826 4827 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4828 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4829 4830 HashMap<Uri, UriPermission> targetUris 4831 = mGrantedUriPermissions.get(targetUid); 4832 if (targetUris == null) { 4833 targetUris = new HashMap<Uri, UriPermission>(); 4834 mGrantedUriPermissions.put(targetUid, targetUris); 4835 } 4836 4837 UriPermission perm = targetUris.get(uri); 4838 if (perm == null) { 4839 perm = new UriPermission(targetUid, uri); 4840 targetUris.put(uri, perm); 4841 } 4842 4843 perm.modeFlags |= modeFlags; 4844 if (owner == null) { 4845 perm.globalModeFlags |= modeFlags; 4846 } else { 4847 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4848 perm.readOwners.add(owner); 4849 owner.addReadPermission(perm); 4850 } 4851 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4852 perm.writeOwners.add(owner); 4853 owner.addWritePermission(perm); 4854 } 4855 } 4856 } 4857 4858 void grantUriPermissionLocked(int callingUid, 4859 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 4860 if (targetPkg == null) { 4861 throw new NullPointerException("targetPkg"); 4862 } 4863 4864 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); 4865 if (targetUid < 0) { 4866 return; 4867 } 4868 4869 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 4870 } 4871 4872 /** 4873 * Like checkGrantUriPermissionLocked, but takes an Intent. 4874 */ 4875 int checkGrantUriPermissionFromIntentLocked(int callingUid, 4876 String targetPkg, Intent intent) { 4877 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4878 "Checking URI perm to " + (intent != null ? intent.getData() : null) 4879 + " from " + intent + "; flags=0x" 4880 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 4881 4882 if (targetPkg == null) { 4883 throw new NullPointerException("targetPkg"); 4884 } 4885 4886 if (intent == null) { 4887 return -1; 4888 } 4889 Uri data = intent.getData(); 4890 if (data == null) { 4891 return -1; 4892 } 4893 return checkGrantUriPermissionLocked(callingUid, targetPkg, data, 4894 intent.getFlags()); 4895 } 4896 4897 /** 4898 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 4899 */ 4900 void grantUriPermissionUncheckedFromIntentLocked(int targetUid, 4901 String targetPkg, Intent intent, UriPermissionOwner owner) { 4902 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(), 4903 intent.getFlags(), owner); 4904 } 4905 4906 void grantUriPermissionFromIntentLocked(int callingUid, 4907 String targetPkg, Intent intent, UriPermissionOwner owner) { 4908 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent); 4909 if (targetUid < 0) { 4910 return; 4911 } 4912 4913 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner); 4914 } 4915 4916 public void grantUriPermission(IApplicationThread caller, String targetPkg, 4917 Uri uri, int modeFlags) { 4918 synchronized(this) { 4919 final ProcessRecord r = getRecordForAppLocked(caller); 4920 if (r == null) { 4921 throw new SecurityException("Unable to find app for caller " 4922 + caller 4923 + " when granting permission to uri " + uri); 4924 } 4925 if (targetPkg == null) { 4926 throw new IllegalArgumentException("null target"); 4927 } 4928 if (uri == null) { 4929 throw new IllegalArgumentException("null uri"); 4930 } 4931 4932 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 4933 null); 4934 } 4935 } 4936 4937 void removeUriPermissionIfNeededLocked(UriPermission perm) { 4938 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 4939 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 4940 HashMap<Uri, UriPermission> perms 4941 = mGrantedUriPermissions.get(perm.uid); 4942 if (perms != null) { 4943 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4944 "Removing " + perm.uid + " permission to " + perm.uri); 4945 perms.remove(perm.uri); 4946 if (perms.size() == 0) { 4947 mGrantedUriPermissions.remove(perm.uid); 4948 } 4949 } 4950 } 4951 } 4952 4953 private void revokeUriPermissionLocked(int callingUid, Uri uri, 4954 int modeFlags) { 4955 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4956 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4957 if (modeFlags == 0) { 4958 return; 4959 } 4960 4961 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4962 "Revoking all granted permissions to " + uri); 4963 4964 final IPackageManager pm = AppGlobals.getPackageManager(); 4965 4966 final String authority = uri.getAuthority(); 4967 ProviderInfo pi = null; 4968 ContentProviderRecord cpr = mProvidersByName.get(authority); 4969 if (cpr != null) { 4970 pi = cpr.info; 4971 } else { 4972 try { 4973 pi = pm.resolveContentProvider(authority, 4974 PackageManager.GET_URI_PERMISSION_PATTERNS); 4975 } catch (RemoteException ex) { 4976 } 4977 } 4978 if (pi == null) { 4979 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 4980 return; 4981 } 4982 4983 // Does the caller have this permission on the URI? 4984 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4985 // Right now, if you are not the original owner of the permission, 4986 // you are not allowed to revoke it. 4987 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4988 throw new SecurityException("Uid " + callingUid 4989 + " does not have permission to uri " + uri); 4990 //} 4991 } 4992 4993 // Go through all of the permissions and remove any that match. 4994 final List<String> SEGMENTS = uri.getPathSegments(); 4995 if (SEGMENTS != null) { 4996 final int NS = SEGMENTS.size(); 4997 int N = mGrantedUriPermissions.size(); 4998 for (int i=0; i<N; i++) { 4999 HashMap<Uri, UriPermission> perms 5000 = mGrantedUriPermissions.valueAt(i); 5001 Iterator<UriPermission> it = perms.values().iterator(); 5002 toploop: 5003 while (it.hasNext()) { 5004 UriPermission perm = it.next(); 5005 Uri targetUri = perm.uri; 5006 if (!authority.equals(targetUri.getAuthority())) { 5007 continue; 5008 } 5009 List<String> targetSegments = targetUri.getPathSegments(); 5010 if (targetSegments == null) { 5011 continue; 5012 } 5013 if (targetSegments.size() < NS) { 5014 continue; 5015 } 5016 for (int j=0; j<NS; j++) { 5017 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5018 continue toploop; 5019 } 5020 } 5021 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5022 "Revoking " + perm.uid + " permission to " + perm.uri); 5023 perm.clearModes(modeFlags); 5024 if (perm.modeFlags == 0) { 5025 it.remove(); 5026 } 5027 } 5028 if (perms.size() == 0) { 5029 mGrantedUriPermissions.remove( 5030 mGrantedUriPermissions.keyAt(i)); 5031 N--; 5032 i--; 5033 } 5034 } 5035 } 5036 } 5037 5038 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5039 int modeFlags) { 5040 synchronized(this) { 5041 final ProcessRecord r = getRecordForAppLocked(caller); 5042 if (r == null) { 5043 throw new SecurityException("Unable to find app for caller " 5044 + caller 5045 + " when revoking permission to uri " + uri); 5046 } 5047 if (uri == null) { 5048 Slog.w(TAG, "revokeUriPermission: null uri"); 5049 return; 5050 } 5051 5052 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5053 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5054 if (modeFlags == 0) { 5055 return; 5056 } 5057 5058 final IPackageManager pm = AppGlobals.getPackageManager(); 5059 5060 final String authority = uri.getAuthority(); 5061 ProviderInfo pi = null; 5062 ContentProviderRecord cpr = mProvidersByName.get(authority); 5063 if (cpr != null) { 5064 pi = cpr.info; 5065 } else { 5066 try { 5067 pi = pm.resolveContentProvider(authority, 5068 PackageManager.GET_URI_PERMISSION_PATTERNS); 5069 } catch (RemoteException ex) { 5070 } 5071 } 5072 if (pi == null) { 5073 Slog.w(TAG, "No content provider found for permission revoke: " 5074 + uri.toSafeString()); 5075 return; 5076 } 5077 5078 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 5079 } 5080 } 5081 5082 @Override 5083 public IBinder newUriPermissionOwner(String name) { 5084 synchronized(this) { 5085 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5086 return owner.getExternalTokenLocked(); 5087 } 5088 } 5089 5090 @Override 5091 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5092 Uri uri, int modeFlags) { 5093 synchronized(this) { 5094 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5095 if (owner == null) { 5096 throw new IllegalArgumentException("Unknown owner: " + token); 5097 } 5098 if (fromUid != Binder.getCallingUid()) { 5099 if (Binder.getCallingUid() != Process.myUid()) { 5100 // Only system code can grant URI permissions on behalf 5101 // of other users. 5102 throw new SecurityException("nice try"); 5103 } 5104 } 5105 if (targetPkg == null) { 5106 throw new IllegalArgumentException("null target"); 5107 } 5108 if (uri == null) { 5109 throw new IllegalArgumentException("null uri"); 5110 } 5111 5112 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5113 } 5114 } 5115 5116 @Override 5117 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5118 synchronized(this) { 5119 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5120 if (owner == null) { 5121 throw new IllegalArgumentException("Unknown owner: " + token); 5122 } 5123 5124 if (uri == null) { 5125 owner.removeUriPermissionsLocked(mode); 5126 } else { 5127 owner.removeUriPermissionLocked(uri, mode); 5128 } 5129 } 5130 } 5131 5132 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5133 synchronized (this) { 5134 ProcessRecord app = 5135 who != null ? getRecordForAppLocked(who) : null; 5136 if (app == null) return; 5137 5138 Message msg = Message.obtain(); 5139 msg.what = WAIT_FOR_DEBUGGER_MSG; 5140 msg.obj = app; 5141 msg.arg1 = waiting ? 1 : 0; 5142 mHandler.sendMessage(msg); 5143 } 5144 } 5145 5146 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5147 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5148 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5149 outInfo.availMem = Process.getFreeMemory(); 5150 outInfo.threshold = homeAppMem; 5151 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5152 outInfo.hiddenAppThreshold = hiddenAppMem; 5153 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5154 ProcessList.SERVICE_ADJ); 5155 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5156 ProcessList.VISIBLE_APP_ADJ); 5157 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5158 ProcessList.FOREGROUND_APP_ADJ); 5159 } 5160 5161 // ========================================================= 5162 // TASK MANAGEMENT 5163 // ========================================================= 5164 5165 public List getTasks(int maxNum, int flags, 5166 IThumbnailReceiver receiver) { 5167 ArrayList list = new ArrayList(); 5168 5169 PendingThumbnailsRecord pending = null; 5170 IApplicationThread topThumbnail = null; 5171 ActivityRecord topRecord = null; 5172 5173 synchronized(this) { 5174 if (localLOGV) Slog.v( 5175 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5176 + ", receiver=" + receiver); 5177 5178 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5179 != PackageManager.PERMISSION_GRANTED) { 5180 if (receiver != null) { 5181 // If the caller wants to wait for pending thumbnails, 5182 // it ain't gonna get them. 5183 try { 5184 receiver.finished(); 5185 } catch (RemoteException ex) { 5186 } 5187 } 5188 String msg = "Permission Denial: getTasks() from pid=" 5189 + Binder.getCallingPid() 5190 + ", uid=" + Binder.getCallingUid() 5191 + " requires " + android.Manifest.permission.GET_TASKS; 5192 Slog.w(TAG, msg); 5193 throw new SecurityException(msg); 5194 } 5195 5196 int pos = mMainStack.mHistory.size()-1; 5197 ActivityRecord next = 5198 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5199 ActivityRecord top = null; 5200 TaskRecord curTask = null; 5201 int numActivities = 0; 5202 int numRunning = 0; 5203 while (pos >= 0 && maxNum > 0) { 5204 final ActivityRecord r = next; 5205 pos--; 5206 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5207 5208 // Initialize state for next task if needed. 5209 if (top == null || 5210 (top.state == ActivityState.INITIALIZING 5211 && top.task == r.task)) { 5212 top = r; 5213 curTask = r.task; 5214 numActivities = numRunning = 0; 5215 } 5216 5217 // Add 'r' into the current task. 5218 numActivities++; 5219 if (r.app != null && r.app.thread != null) { 5220 numRunning++; 5221 } 5222 5223 if (localLOGV) Slog.v( 5224 TAG, r.intent.getComponent().flattenToShortString() 5225 + ": task=" + r.task); 5226 5227 // If the next one is a different task, generate a new 5228 // TaskInfo entry for what we have. 5229 if (next == null || next.task != curTask) { 5230 ActivityManager.RunningTaskInfo ci 5231 = new ActivityManager.RunningTaskInfo(); 5232 ci.id = curTask.taskId; 5233 ci.baseActivity = r.intent.getComponent(); 5234 ci.topActivity = top.intent.getComponent(); 5235 if (top.thumbHolder != null) { 5236 ci.description = top.thumbHolder.lastDescription; 5237 } 5238 ci.numActivities = numActivities; 5239 ci.numRunning = numRunning; 5240 //System.out.println( 5241 // "#" + maxNum + ": " + " descr=" + ci.description); 5242 if (ci.thumbnail == null && receiver != null) { 5243 if (localLOGV) Slog.v( 5244 TAG, "State=" + top.state + "Idle=" + top.idle 5245 + " app=" + top.app 5246 + " thr=" + (top.app != null ? top.app.thread : null)); 5247 if (top.state == ActivityState.RESUMED 5248 || top.state == ActivityState.PAUSING) { 5249 if (top.idle && top.app != null 5250 && top.app.thread != null) { 5251 topRecord = top; 5252 topThumbnail = top.app.thread; 5253 } else { 5254 top.thumbnailNeeded = true; 5255 } 5256 } 5257 if (pending == null) { 5258 pending = new PendingThumbnailsRecord(receiver); 5259 } 5260 pending.pendingRecords.add(top); 5261 } 5262 list.add(ci); 5263 maxNum--; 5264 top = null; 5265 } 5266 } 5267 5268 if (pending != null) { 5269 mPendingThumbnails.add(pending); 5270 } 5271 } 5272 5273 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5274 5275 if (topThumbnail != null) { 5276 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5277 try { 5278 topThumbnail.requestThumbnail(topRecord.appToken); 5279 } catch (Exception e) { 5280 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5281 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5282 } 5283 } 5284 5285 if (pending == null && receiver != null) { 5286 // In this case all thumbnails were available and the client 5287 // is being asked to be told when the remaining ones come in... 5288 // which is unusually, since the top-most currently running 5289 // activity should never have a canned thumbnail! Oh well. 5290 try { 5291 receiver.finished(); 5292 } catch (RemoteException ex) { 5293 } 5294 } 5295 5296 return list; 5297 } 5298 5299 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5300 int flags) { 5301 synchronized (this) { 5302 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5303 "getRecentTasks()"); 5304 5305 IPackageManager pm = AppGlobals.getPackageManager(); 5306 5307 final int N = mRecentTasks.size(); 5308 ArrayList<ActivityManager.RecentTaskInfo> res 5309 = new ArrayList<ActivityManager.RecentTaskInfo>( 5310 maxNum < N ? maxNum : N); 5311 for (int i=0; i<N && maxNum > 0; i++) { 5312 TaskRecord tr = mRecentTasks.get(i); 5313 // Return the entry if desired by the caller. We always return 5314 // the first entry, because callers always expect this to be the 5315 // forground app. We may filter others if the caller has 5316 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5317 // we should exclude the entry. 5318 if (i == 0 5319 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5320 || (tr.intent == null) 5321 || ((tr.intent.getFlags() 5322 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5323 ActivityManager.RecentTaskInfo rti 5324 = new ActivityManager.RecentTaskInfo(); 5325 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5326 rti.persistentId = tr.taskId; 5327 rti.baseIntent = new Intent( 5328 tr.intent != null ? tr.intent : tr.affinityIntent); 5329 rti.origActivity = tr.origActivity; 5330 rti.description = tr.lastDescription; 5331 5332 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5333 // Check whether this activity is currently available. 5334 try { 5335 if (rti.origActivity != null) { 5336 if (pm.getActivityInfo(rti.origActivity, 0) == null) { 5337 continue; 5338 } 5339 } else if (rti.baseIntent != null) { 5340 if (pm.queryIntentActivities(rti.baseIntent, 5341 null, 0) == null) { 5342 continue; 5343 } 5344 } 5345 } catch (RemoteException e) { 5346 // Will never happen. 5347 } 5348 } 5349 5350 res.add(rti); 5351 maxNum--; 5352 } 5353 } 5354 return res; 5355 } 5356 } 5357 5358 private TaskRecord taskForIdLocked(int id) { 5359 final int N = mRecentTasks.size(); 5360 for (int i=0; i<N; i++) { 5361 TaskRecord tr = mRecentTasks.get(i); 5362 if (tr.taskId == id) { 5363 return tr; 5364 } 5365 } 5366 return null; 5367 } 5368 5369 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5370 synchronized (this) { 5371 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5372 "getTaskThumbnails()"); 5373 TaskRecord tr = taskForIdLocked(id); 5374 if (tr != null) { 5375 return mMainStack.getTaskThumbnailsLocked(tr); 5376 } 5377 } 5378 return null; 5379 } 5380 5381 public boolean removeSubTask(int taskId, int subTaskIndex) { 5382 synchronized (this) { 5383 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5384 "removeSubTask()"); 5385 long ident = Binder.clearCallingIdentity(); 5386 try { 5387 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null; 5388 } finally { 5389 Binder.restoreCallingIdentity(ident); 5390 } 5391 } 5392 } 5393 5394 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) { 5395 TaskRecord tr = root.task; 5396 Intent baseIntent = new Intent( 5397 tr.intent != null ? tr.intent : tr.affinityIntent); 5398 ComponentName component = baseIntent.getComponent(); 5399 if (component == null) { 5400 Slog.w(TAG, "Now component for base intent of task: " + tr); 5401 return; 5402 } 5403 5404 // Find any running services associated with this app. 5405 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5406 for (ServiceRecord sr : mServices.values()) { 5407 if (sr.packageName.equals(component.getPackageName())) { 5408 services.add(sr); 5409 } 5410 } 5411 5412 // Take care of any running services associated with the app. 5413 for (int i=0; i<services.size(); i++) { 5414 ServiceRecord sr = services.get(i); 5415 if (sr.startRequested) { 5416 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { 5417 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); 5418 stopServiceLocked(sr); 5419 } else { 5420 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, 5421 sr.makeNextStartId(), baseIntent, -1)); 5422 if (sr.app != null && sr.app.thread != null) { 5423 sendServiceArgsLocked(sr, false); 5424 } 5425 } 5426 } 5427 } 5428 5429 if (killProcesses) { 5430 // Find any running processes associated with this app. 5431 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5432 SparseArray<ProcessRecord> appProcs 5433 = mProcessNames.getMap().get(component.getPackageName()); 5434 if (appProcs != null) { 5435 for (int i=0; i<appProcs.size(); i++) { 5436 procs.add(appProcs.valueAt(i)); 5437 } 5438 } 5439 5440 // Kill the running processes. 5441 for (int i=0; i<procs.size(); i++) { 5442 ProcessRecord pr = procs.get(i); 5443 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5444 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5445 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5446 pr.processName, pr.setAdj, "remove task"); 5447 Process.killProcessQuiet(pr.pid); 5448 } else { 5449 pr.waitingToKill = "remove task"; 5450 } 5451 } 5452 } 5453 } 5454 5455 public boolean removeTask(int taskId, int flags) { 5456 synchronized (this) { 5457 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5458 "removeTask()"); 5459 long ident = Binder.clearCallingIdentity(); 5460 try { 5461 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1); 5462 if (r != null) { 5463 mRecentTasks.remove(r.task); 5464 cleanUpRemovedTaskLocked(r, 5465 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0); 5466 return true; 5467 } else { 5468 TaskRecord tr = null; 5469 int i=0; 5470 while (i < mRecentTasks.size()) { 5471 TaskRecord t = mRecentTasks.get(i); 5472 if (t.taskId == taskId) { 5473 tr = t; 5474 break; 5475 } 5476 i++; 5477 } 5478 if (tr != null) { 5479 if (tr.numActivities <= 0) { 5480 // Caller is just removing a recent task that is 5481 // not actively running. That is easy! 5482 mRecentTasks.remove(i); 5483 } else { 5484 Slog.w(TAG, "removeTask: task " + taskId 5485 + " does not have activities to remove, " 5486 + " but numActivities=" + tr.numActivities 5487 + ": " + tr); 5488 } 5489 } 5490 } 5491 } finally { 5492 Binder.restoreCallingIdentity(ident); 5493 } 5494 } 5495 return false; 5496 } 5497 5498 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5499 int j; 5500 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5501 TaskRecord jt = startTask; 5502 5503 // First look backwards 5504 for (j=startIndex-1; j>=0; j--) { 5505 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5506 if (r.task != jt) { 5507 jt = r.task; 5508 if (affinity.equals(jt.affinity)) { 5509 return j; 5510 } 5511 } 5512 } 5513 5514 // Now look forwards 5515 final int N = mMainStack.mHistory.size(); 5516 jt = startTask; 5517 for (j=startIndex+1; j<N; j++) { 5518 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5519 if (r.task != jt) { 5520 if (affinity.equals(jt.affinity)) { 5521 return j; 5522 } 5523 jt = r.task; 5524 } 5525 } 5526 5527 // Might it be at the top? 5528 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5529 return N-1; 5530 } 5531 5532 return -1; 5533 } 5534 5535 /** 5536 * TODO: Add mController hook 5537 */ 5538 public void moveTaskToFront(int task, int flags) { 5539 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5540 "moveTaskToFront()"); 5541 5542 synchronized(this) { 5543 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5544 Binder.getCallingUid(), "Task to front")) { 5545 return; 5546 } 5547 final long origId = Binder.clearCallingIdentity(); 5548 try { 5549 TaskRecord tr = taskForIdLocked(task); 5550 if (tr != null) { 5551 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5552 mMainStack.mUserLeaving = true; 5553 } 5554 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5555 // Caller wants the home activity moved with it. To accomplish this, 5556 // we'll just move the home task to the top first. 5557 mMainStack.moveHomeToFrontLocked(); 5558 } 5559 mMainStack.moveTaskToFrontLocked(tr, null); 5560 return; 5561 } 5562 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5563 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5564 if (hr.task.taskId == task) { 5565 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5566 mMainStack.mUserLeaving = true; 5567 } 5568 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5569 // Caller wants the home activity moved with it. To accomplish this, 5570 // we'll just move the home task to the top first. 5571 mMainStack.moveHomeToFrontLocked(); 5572 } 5573 mMainStack.moveTaskToFrontLocked(hr.task, null); 5574 return; 5575 } 5576 } 5577 } finally { 5578 Binder.restoreCallingIdentity(origId); 5579 } 5580 } 5581 } 5582 5583 public void moveTaskToBack(int task) { 5584 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5585 "moveTaskToBack()"); 5586 5587 synchronized(this) { 5588 if (mMainStack.mResumedActivity != null 5589 && mMainStack.mResumedActivity.task.taskId == task) { 5590 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5591 Binder.getCallingUid(), "Task to back")) { 5592 return; 5593 } 5594 } 5595 final long origId = Binder.clearCallingIdentity(); 5596 mMainStack.moveTaskToBackLocked(task, null); 5597 Binder.restoreCallingIdentity(origId); 5598 } 5599 } 5600 5601 /** 5602 * Moves an activity, and all of the other activities within the same task, to the bottom 5603 * of the history stack. The activity's order within the task is unchanged. 5604 * 5605 * @param token A reference to the activity we wish to move 5606 * @param nonRoot If false then this only works if the activity is the root 5607 * of a task; if true it will work for any activity in a task. 5608 * @return Returns true if the move completed, false if not. 5609 */ 5610 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5611 synchronized(this) { 5612 final long origId = Binder.clearCallingIdentity(); 5613 int taskId = getTaskForActivityLocked(token, !nonRoot); 5614 if (taskId >= 0) { 5615 return mMainStack.moveTaskToBackLocked(taskId, null); 5616 } 5617 Binder.restoreCallingIdentity(origId); 5618 } 5619 return false; 5620 } 5621 5622 public void moveTaskBackwards(int task) { 5623 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5624 "moveTaskBackwards()"); 5625 5626 synchronized(this) { 5627 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5628 Binder.getCallingUid(), "Task backwards")) { 5629 return; 5630 } 5631 final long origId = Binder.clearCallingIdentity(); 5632 moveTaskBackwardsLocked(task); 5633 Binder.restoreCallingIdentity(origId); 5634 } 5635 } 5636 5637 private final void moveTaskBackwardsLocked(int task) { 5638 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5639 } 5640 5641 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5642 synchronized(this) { 5643 return getTaskForActivityLocked(token, onlyRoot); 5644 } 5645 } 5646 5647 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5648 final int N = mMainStack.mHistory.size(); 5649 TaskRecord lastTask = null; 5650 for (int i=0; i<N; i++) { 5651 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5652 if (r.appToken == token) { 5653 if (!onlyRoot || lastTask != r.task) { 5654 return r.task.taskId; 5655 } 5656 return -1; 5657 } 5658 lastTask = r.task; 5659 } 5660 5661 return -1; 5662 } 5663 5664 public void finishOtherInstances(IBinder token, ComponentName className) { 5665 synchronized(this) { 5666 final long origId = Binder.clearCallingIdentity(); 5667 5668 int N = mMainStack.mHistory.size(); 5669 TaskRecord lastTask = null; 5670 for (int i=0; i<N; i++) { 5671 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5672 if (r.realActivity.equals(className) 5673 && r.appToken != token && lastTask != r.task) { 5674 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 5675 null, "others")) { 5676 i--; 5677 N--; 5678 } 5679 } 5680 lastTask = r.task; 5681 } 5682 5683 Binder.restoreCallingIdentity(origId); 5684 } 5685 } 5686 5687 // ========================================================= 5688 // THUMBNAILS 5689 // ========================================================= 5690 5691 public void reportThumbnail(IBinder token, 5692 Bitmap thumbnail, CharSequence description) { 5693 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5694 final long origId = Binder.clearCallingIdentity(); 5695 sendPendingThumbnail(null, token, thumbnail, description, true); 5696 Binder.restoreCallingIdentity(origId); 5697 } 5698 5699 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5700 Bitmap thumbnail, CharSequence description, boolean always) { 5701 TaskRecord task = null; 5702 ArrayList receivers = null; 5703 5704 //System.out.println("Send pending thumbnail: " + r); 5705 5706 synchronized(this) { 5707 if (r == null) { 5708 r = mMainStack.isInStackLocked(token); 5709 if (r == null) { 5710 return; 5711 } 5712 } 5713 if (thumbnail == null && r.thumbHolder != null) { 5714 thumbnail = r.thumbHolder.lastThumbnail; 5715 description = r.thumbHolder.lastDescription; 5716 } 5717 if (thumbnail == null && !always) { 5718 // If there is no thumbnail, and this entry is not actually 5719 // going away, then abort for now and pick up the next 5720 // thumbnail we get. 5721 return; 5722 } 5723 task = r.task; 5724 5725 int N = mPendingThumbnails.size(); 5726 int i=0; 5727 while (i<N) { 5728 PendingThumbnailsRecord pr = 5729 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5730 //System.out.println("Looking in " + pr.pendingRecords); 5731 if (pr.pendingRecords.remove(r)) { 5732 if (receivers == null) { 5733 receivers = new ArrayList(); 5734 } 5735 receivers.add(pr); 5736 if (pr.pendingRecords.size() == 0) { 5737 pr.finished = true; 5738 mPendingThumbnails.remove(i); 5739 N--; 5740 continue; 5741 } 5742 } 5743 i++; 5744 } 5745 } 5746 5747 if (receivers != null) { 5748 final int N = receivers.size(); 5749 for (int i=0; i<N; i++) { 5750 try { 5751 PendingThumbnailsRecord pr = 5752 (PendingThumbnailsRecord)receivers.get(i); 5753 pr.receiver.newThumbnail( 5754 task != null ? task.taskId : -1, thumbnail, description); 5755 if (pr.finished) { 5756 pr.receiver.finished(); 5757 } 5758 } catch (Exception e) { 5759 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5760 } 5761 } 5762 } 5763 } 5764 5765 // ========================================================= 5766 // CONTENT PROVIDERS 5767 // ========================================================= 5768 5769 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5770 List<ProviderInfo> providers = null; 5771 try { 5772 providers = AppGlobals.getPackageManager(). 5773 queryContentProviders(app.processName, app.info.uid, 5774 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5775 } catch (RemoteException ex) { 5776 } 5777 if (providers != null) { 5778 final int N = providers.size(); 5779 for (int i=0; i<N; i++) { 5780 ProviderInfo cpi = 5781 (ProviderInfo)providers.get(i); 5782 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5783 ContentProviderRecord cpr = mProvidersByClass.get(comp); 5784 if (cpr == null) { 5785 cpr = new ContentProviderRecord(cpi, app.info, comp); 5786 mProvidersByClass.put(comp, cpr); 5787 } 5788 app.pubProviders.put(cpi.name, cpr); 5789 app.addPackage(cpi.applicationInfo.packageName); 5790 ensurePackageDexOpt(cpi.applicationInfo.packageName); 5791 } 5792 } 5793 return providers; 5794 } 5795 5796 private final String checkContentProviderPermissionLocked( 5797 ProviderInfo cpi, ProcessRecord r) { 5798 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 5799 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 5800 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 5801 cpi.applicationInfo.uid, cpi.exported) 5802 == PackageManager.PERMISSION_GRANTED) { 5803 return null; 5804 } 5805 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 5806 cpi.applicationInfo.uid, cpi.exported) 5807 == PackageManager.PERMISSION_GRANTED) { 5808 return null; 5809 } 5810 5811 PathPermission[] pps = cpi.pathPermissions; 5812 if (pps != null) { 5813 int i = pps.length; 5814 while (i > 0) { 5815 i--; 5816 PathPermission pp = pps[i]; 5817 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 5818 cpi.applicationInfo.uid, cpi.exported) 5819 == PackageManager.PERMISSION_GRANTED) { 5820 return null; 5821 } 5822 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 5823 cpi.applicationInfo.uid, cpi.exported) 5824 == PackageManager.PERMISSION_GRANTED) { 5825 return null; 5826 } 5827 } 5828 } 5829 5830 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 5831 if (perms != null) { 5832 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 5833 if (uri.getKey().getAuthority().equals(cpi.authority)) { 5834 return null; 5835 } 5836 } 5837 } 5838 5839 String msg; 5840 if (!cpi.exported) { 5841 msg = "Permission Denial: opening provider " + cpi.name 5842 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 5843 + ", uid=" + callingUid + ") that is not exported from uid " 5844 + cpi.applicationInfo.uid; 5845 } else { 5846 msg = "Permission Denial: opening provider " + cpi.name 5847 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 5848 + ", uid=" + callingUid + ") requires " 5849 + cpi.readPermission + " or " + cpi.writePermission; 5850 } 5851 Slog.w(TAG, msg); 5852 return msg; 5853 } 5854 5855 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) { 5856 if (r != null) { 5857 Integer cnt = r.conProviders.get(cpr); 5858 if (DEBUG_PROVIDER) Slog.v(TAG, 5859 "Adding provider requested by " 5860 + r.processName + " from process " 5861 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 5862 + " cnt=" + (cnt == null ? 1 : cnt)); 5863 if (cnt == null) { 5864 cpr.clients.add(r); 5865 r.conProviders.put(cpr, new Integer(1)); 5866 return true; 5867 } else { 5868 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 5869 } 5870 } else { 5871 cpr.externals++; 5872 } 5873 return false; 5874 } 5875 5876 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) { 5877 if (r != null) { 5878 Integer cnt = r.conProviders.get(cpr); 5879 if (DEBUG_PROVIDER) Slog.v(TAG, 5880 "Removing provider requested by " 5881 + r.processName + " from process " 5882 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 5883 + " cnt=" + cnt); 5884 if (cnt == null || cnt.intValue() <= 1) { 5885 cpr.clients.remove(r); 5886 r.conProviders.remove(cpr); 5887 return true; 5888 } else { 5889 r.conProviders.put(cpr, new Integer(cnt.intValue()-1)); 5890 } 5891 } else { 5892 cpr.externals++; 5893 } 5894 return false; 5895 } 5896 5897 private final ContentProviderHolder getContentProviderImpl( 5898 IApplicationThread caller, String name) { 5899 ContentProviderRecord cpr; 5900 ProviderInfo cpi = null; 5901 5902 synchronized(this) { 5903 ProcessRecord r = null; 5904 if (caller != null) { 5905 r = getRecordForAppLocked(caller); 5906 if (r == null) { 5907 throw new SecurityException( 5908 "Unable to find app for caller " + caller 5909 + " (pid=" + Binder.getCallingPid() 5910 + ") when getting content provider " + name); 5911 } 5912 } 5913 5914 // First check if this content provider has been published... 5915 cpr = mProvidersByName.get(name); 5916 boolean providerRunning = cpr != null; 5917 if (providerRunning) { 5918 cpi = cpr.info; 5919 String msg; 5920 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 5921 throw new SecurityException(msg); 5922 } 5923 5924 if (r != null && cpr.canRunHere(r)) { 5925 // This provider has been published or is in the process 5926 // of being published... but it is also allowed to run 5927 // in the caller's process, so don't make a connection 5928 // and just let the caller instantiate its own instance. 5929 if (cpr.provider != null) { 5930 // don't give caller the provider object, it needs 5931 // to make its own. 5932 cpr = new ContentProviderRecord(cpr); 5933 } 5934 return cpr; 5935 } 5936 5937 final long origId = Binder.clearCallingIdentity(); 5938 5939 // In this case the provider instance already exists, so we can 5940 // return it right away. 5941 final boolean countChanged = incProviderCount(r, cpr); 5942 if (countChanged) { 5943 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 5944 // If this is a perceptible app accessing the provider, 5945 // make sure to count it as being accessed and thus 5946 // back up on the LRU list. This is good because 5947 // content providers are often expensive to start. 5948 updateLruProcessLocked(cpr.proc, false, true); 5949 } 5950 } 5951 5952 if (cpr.proc != null) { 5953 if (false) { 5954 if (cpr.name.flattenToShortString().equals( 5955 "com.android.providers.calendar/.CalendarProvider2")) { 5956 Slog.v(TAG, "****************** KILLING " 5957 + cpr.name.flattenToShortString()); 5958 Process.killProcess(cpr.proc.pid); 5959 } 5960 } 5961 boolean success = updateOomAdjLocked(cpr.proc); 5962 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 5963 // NOTE: there is still a race here where a signal could be 5964 // pending on the process even though we managed to update its 5965 // adj level. Not sure what to do about this, but at least 5966 // the race is now smaller. 5967 if (!success) { 5968 // Uh oh... it looks like the provider's process 5969 // has been killed on us. We need to wait for a new 5970 // process to be started, and make sure its death 5971 // doesn't kill our process. 5972 Slog.i(TAG, 5973 "Existing provider " + cpr.name.flattenToShortString() 5974 + " is crashing; detaching " + r); 5975 boolean lastRef = decProviderCount(r, cpr); 5976 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 5977 if (!lastRef) { 5978 // This wasn't the last ref our process had on 5979 // the provider... we have now been killed, bail. 5980 return null; 5981 } 5982 providerRunning = false; 5983 } 5984 } 5985 5986 Binder.restoreCallingIdentity(origId); 5987 } 5988 5989 if (!providerRunning) { 5990 try { 5991 cpi = AppGlobals.getPackageManager(). 5992 resolveContentProvider(name, 5993 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5994 } catch (RemoteException ex) { 5995 } 5996 if (cpi == null) { 5997 return null; 5998 } 5999 6000 String msg; 6001 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6002 throw new SecurityException(msg); 6003 } 6004 6005 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6006 && !cpi.processName.equals("system")) { 6007 // If this content provider does not run in the system 6008 // process, and the system is not yet ready to run other 6009 // processes, then fail fast instead of hanging. 6010 throw new IllegalArgumentException( 6011 "Attempt to launch content provider before system ready"); 6012 } 6013 6014 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6015 cpr = mProvidersByClass.get(comp); 6016 final boolean firstClass = cpr == null; 6017 if (firstClass) { 6018 try { 6019 ApplicationInfo ai = 6020 AppGlobals.getPackageManager(). 6021 getApplicationInfo( 6022 cpi.applicationInfo.packageName, 6023 STOCK_PM_FLAGS); 6024 if (ai == null) { 6025 Slog.w(TAG, "No package info for content provider " 6026 + cpi.name); 6027 return null; 6028 } 6029 cpr = new ContentProviderRecord(cpi, ai, comp); 6030 } catch (RemoteException ex) { 6031 // pm is in same process, this will never happen. 6032 } 6033 } 6034 6035 if (r != null && cpr.canRunHere(r)) { 6036 // If this is a multiprocess provider, then just return its 6037 // info and allow the caller to instantiate it. Only do 6038 // this if the provider is the same user as the caller's 6039 // process, or can run as root (so can be in any process). 6040 return cpr; 6041 } 6042 6043 if (DEBUG_PROVIDER) { 6044 RuntimeException e = new RuntimeException("here"); 6045 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 6046 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6047 } 6048 6049 // This is single process, and our app is now connecting to it. 6050 // See if we are already in the process of launching this 6051 // provider. 6052 final int N = mLaunchingProviders.size(); 6053 int i; 6054 for (i=0; i<N; i++) { 6055 if (mLaunchingProviders.get(i) == cpr) { 6056 break; 6057 } 6058 } 6059 6060 // If the provider is not already being launched, then get it 6061 // started. 6062 if (i >= N) { 6063 final long origId = Binder.clearCallingIdentity(); 6064 6065 try { 6066 // Content provider is now in use, its package can't be stopped. 6067 try { 6068 AppGlobals.getPackageManager().setPackageStoppedState( 6069 cpr.appInfo.packageName, false); 6070 } catch (RemoteException e) { 6071 } catch (IllegalArgumentException e) { 6072 Slog.w(TAG, "Failed trying to unstop package " 6073 + cpr.appInfo.packageName + ": " + e); 6074 } 6075 6076 ProcessRecord proc = startProcessLocked(cpi.processName, 6077 cpr.appInfo, false, 0, "content provider", 6078 new ComponentName(cpi.applicationInfo.packageName, 6079 cpi.name), false); 6080 if (proc == null) { 6081 Slog.w(TAG, "Unable to launch app " 6082 + cpi.applicationInfo.packageName + "/" 6083 + cpi.applicationInfo.uid + " for provider " 6084 + name + ": process is bad"); 6085 return null; 6086 } 6087 cpr.launchingApp = proc; 6088 mLaunchingProviders.add(cpr); 6089 } finally { 6090 Binder.restoreCallingIdentity(origId); 6091 } 6092 } 6093 6094 // Make sure the provider is published (the same provider class 6095 // may be published under multiple names). 6096 if (firstClass) { 6097 mProvidersByClass.put(comp, cpr); 6098 } 6099 mProvidersByName.put(name, cpr); 6100 incProviderCount(r, cpr); 6101 } 6102 } 6103 6104 // Wait for the provider to be published... 6105 synchronized (cpr) { 6106 while (cpr.provider == null) { 6107 if (cpr.launchingApp == null) { 6108 Slog.w(TAG, "Unable to launch app " 6109 + cpi.applicationInfo.packageName + "/" 6110 + cpi.applicationInfo.uid + " for provider " 6111 + name + ": launching app became null"); 6112 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6113 cpi.applicationInfo.packageName, 6114 cpi.applicationInfo.uid, name); 6115 return null; 6116 } 6117 try { 6118 cpr.wait(); 6119 } catch (InterruptedException ex) { 6120 } 6121 } 6122 } 6123 return cpr; 6124 } 6125 6126 public final ContentProviderHolder getContentProvider( 6127 IApplicationThread caller, String name) { 6128 if (caller == null) { 6129 String msg = "null IApplicationThread when getting content provider " 6130 + name; 6131 Slog.w(TAG, msg); 6132 throw new SecurityException(msg); 6133 } 6134 6135 return getContentProviderImpl(caller, name); 6136 } 6137 6138 private ContentProviderHolder getContentProviderExternal(String name) { 6139 return getContentProviderImpl(null, name); 6140 } 6141 6142 /** 6143 * Drop a content provider from a ProcessRecord's bookkeeping 6144 * @param cpr 6145 */ 6146 public void removeContentProvider(IApplicationThread caller, String name) { 6147 synchronized (this) { 6148 ContentProviderRecord cpr = mProvidersByName.get(name); 6149 if(cpr == null) { 6150 // remove from mProvidersByClass 6151 if (DEBUG_PROVIDER) Slog.v(TAG, name + 6152 " provider not found in providers list"); 6153 return; 6154 } 6155 final ProcessRecord r = getRecordForAppLocked(caller); 6156 if (r == null) { 6157 throw new SecurityException( 6158 "Unable to find app for caller " + caller + 6159 " when removing content provider " + name); 6160 } 6161 //update content provider record entry info 6162 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6163 ContentProviderRecord localCpr = mProvidersByClass.get(comp); 6164 if (localCpr.proc == r) { 6165 //should not happen. taken care of as a local provider 6166 Slog.w(TAG, "removeContentProvider called on local provider: " 6167 + cpr.info.name + " in process " + r.processName); 6168 return; 6169 } else { 6170 if (decProviderCount(r, localCpr)) { 6171 updateOomAdjLocked(); 6172 } 6173 } 6174 } 6175 } 6176 6177 private void removeContentProviderExternal(String name) { 6178 synchronized (this) { 6179 ContentProviderRecord cpr = mProvidersByName.get(name); 6180 if(cpr == null) { 6181 //remove from mProvidersByClass 6182 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6183 return; 6184 } 6185 6186 //update content provider record entry info 6187 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6188 ContentProviderRecord localCpr = mProvidersByClass.get(comp); 6189 localCpr.externals--; 6190 if (localCpr.externals < 0) { 6191 Slog.e(TAG, "Externals < 0 for content provider " + localCpr); 6192 } 6193 updateOomAdjLocked(); 6194 } 6195 } 6196 6197 public final void publishContentProviders(IApplicationThread caller, 6198 List<ContentProviderHolder> providers) { 6199 if (providers == null) { 6200 return; 6201 } 6202 6203 synchronized(this) { 6204 final ProcessRecord r = getRecordForAppLocked(caller); 6205 if (r == null) { 6206 throw new SecurityException( 6207 "Unable to find app for caller " + caller 6208 + " (pid=" + Binder.getCallingPid() 6209 + ") when publishing content providers"); 6210 } 6211 6212 final long origId = Binder.clearCallingIdentity(); 6213 6214 final int N = providers.size(); 6215 for (int i=0; i<N; i++) { 6216 ContentProviderHolder src = providers.get(i); 6217 if (src == null || src.info == null || src.provider == null) { 6218 continue; 6219 } 6220 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6221 if (dst != null) { 6222 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6223 mProvidersByClass.put(comp, dst); 6224 String names[] = dst.info.authority.split(";"); 6225 for (int j = 0; j < names.length; j++) { 6226 mProvidersByName.put(names[j], dst); 6227 } 6228 6229 int NL = mLaunchingProviders.size(); 6230 int j; 6231 for (j=0; j<NL; j++) { 6232 if (mLaunchingProviders.get(j) == dst) { 6233 mLaunchingProviders.remove(j); 6234 j--; 6235 NL--; 6236 } 6237 } 6238 synchronized (dst) { 6239 dst.provider = src.provider; 6240 dst.proc = r; 6241 dst.notifyAll(); 6242 } 6243 updateOomAdjLocked(r); 6244 } 6245 } 6246 6247 Binder.restoreCallingIdentity(origId); 6248 } 6249 } 6250 6251 public static final void installSystemProviders() { 6252 List<ProviderInfo> providers; 6253 synchronized (mSelf) { 6254 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6255 providers = mSelf.generateApplicationProvidersLocked(app); 6256 if (providers != null) { 6257 for (int i=providers.size()-1; i>=0; i--) { 6258 ProviderInfo pi = (ProviderInfo)providers.get(i); 6259 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6260 Slog.w(TAG, "Not installing system proc provider " + pi.name 6261 + ": not system .apk"); 6262 providers.remove(i); 6263 } 6264 } 6265 } 6266 } 6267 if (providers != null) { 6268 mSystemThread.installSystemProviders(providers); 6269 } 6270 6271 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6272 6273 mSelf.mUsageStatsService.monitorPackages(); 6274 } 6275 6276 /** 6277 * Allows app to retrieve the MIME type of a URI without having permission 6278 * to access its content provider. 6279 * 6280 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6281 * 6282 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6283 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6284 */ 6285 public String getProviderMimeType(Uri uri) { 6286 final String name = uri.getAuthority(); 6287 final long ident = Binder.clearCallingIdentity(); 6288 ContentProviderHolder holder = null; 6289 6290 try { 6291 holder = getContentProviderExternal(name); 6292 if (holder != null) { 6293 return holder.provider.getType(uri); 6294 } 6295 } catch (RemoteException e) { 6296 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6297 return null; 6298 } finally { 6299 if (holder != null) { 6300 removeContentProviderExternal(name); 6301 } 6302 Binder.restoreCallingIdentity(ident); 6303 } 6304 6305 return null; 6306 } 6307 6308 // ========================================================= 6309 // GLOBAL MANAGEMENT 6310 // ========================================================= 6311 6312 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6313 ApplicationInfo info, String customProcess) { 6314 String proc = customProcess != null ? customProcess : info.processName; 6315 BatteryStatsImpl.Uid.Proc ps = null; 6316 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6317 synchronized (stats) { 6318 ps = stats.getProcessStatsLocked(info.uid, proc); 6319 } 6320 return new ProcessRecord(ps, thread, info, proc); 6321 } 6322 6323 final ProcessRecord addAppLocked(ApplicationInfo info) { 6324 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 6325 6326 if (app == null) { 6327 app = newProcessRecordLocked(null, info, null); 6328 mProcessNames.put(info.processName, info.uid, app); 6329 updateLruProcessLocked(app, true, true); 6330 } 6331 6332 // This package really, really can not be stopped. 6333 try { 6334 AppGlobals.getPackageManager().setPackageStoppedState( 6335 info.packageName, false); 6336 } catch (RemoteException e) { 6337 } catch (IllegalArgumentException e) { 6338 Slog.w(TAG, "Failed trying to unstop package " 6339 + info.packageName + ": " + e); 6340 } 6341 6342 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6343 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6344 app.persistent = true; 6345 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6346 } 6347 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6348 mPersistentStartingProcesses.add(app); 6349 startProcessLocked(app, "added application", app.processName); 6350 } 6351 6352 return app; 6353 } 6354 6355 public void unhandledBack() { 6356 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6357 "unhandledBack()"); 6358 6359 synchronized(this) { 6360 int count = mMainStack.mHistory.size(); 6361 if (DEBUG_SWITCH) Slog.d( 6362 TAG, "Performing unhandledBack(): stack size = " + count); 6363 if (count > 1) { 6364 final long origId = Binder.clearCallingIdentity(); 6365 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6366 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6367 Binder.restoreCallingIdentity(origId); 6368 } 6369 } 6370 } 6371 6372 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6373 String name = uri.getAuthority(); 6374 ContentProviderHolder cph = getContentProviderExternal(name); 6375 ParcelFileDescriptor pfd = null; 6376 if (cph != null) { 6377 // We record the binder invoker's uid in thread-local storage before 6378 // going to the content provider to open the file. Later, in the code 6379 // that handles all permissions checks, we look for this uid and use 6380 // that rather than the Activity Manager's own uid. The effect is that 6381 // we do the check against the caller's permissions even though it looks 6382 // to the content provider like the Activity Manager itself is making 6383 // the request. 6384 sCallerIdentity.set(new Identity( 6385 Binder.getCallingPid(), Binder.getCallingUid())); 6386 try { 6387 pfd = cph.provider.openFile(uri, "r"); 6388 } catch (FileNotFoundException e) { 6389 // do nothing; pfd will be returned null 6390 } finally { 6391 // Ensure that whatever happens, we clean up the identity state 6392 sCallerIdentity.remove(); 6393 } 6394 6395 // We've got the fd now, so we're done with the provider. 6396 removeContentProviderExternal(name); 6397 } else { 6398 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6399 } 6400 return pfd; 6401 } 6402 6403 // Actually is sleeping or shutting down or whatever else in the future 6404 // is an inactive state. 6405 public boolean isSleeping() { 6406 return mSleeping || mShuttingDown; 6407 } 6408 6409 public void goingToSleep() { 6410 synchronized(this) { 6411 mSleeping = true; 6412 mWindowManager.setEventDispatching(false); 6413 6414 mMainStack.stopIfSleepingLocked(); 6415 6416 // Initialize the wake times of all processes. 6417 checkExcessivePowerUsageLocked(false); 6418 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6419 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6420 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6421 } 6422 } 6423 6424 public boolean shutdown(int timeout) { 6425 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6426 != PackageManager.PERMISSION_GRANTED) { 6427 throw new SecurityException("Requires permission " 6428 + android.Manifest.permission.SHUTDOWN); 6429 } 6430 6431 boolean timedout = false; 6432 6433 synchronized(this) { 6434 mShuttingDown = true; 6435 mWindowManager.setEventDispatching(false); 6436 6437 if (mMainStack.mResumedActivity != null) { 6438 mMainStack.stopIfSleepingLocked(); 6439 final long endTime = System.currentTimeMillis() + timeout; 6440 while (mMainStack.mResumedActivity != null 6441 || mMainStack.mPausingActivity != null) { 6442 long delay = endTime - System.currentTimeMillis(); 6443 if (delay <= 0) { 6444 Slog.w(TAG, "Activity manager shutdown timed out"); 6445 timedout = true; 6446 break; 6447 } 6448 try { 6449 this.wait(); 6450 } catch (InterruptedException e) { 6451 } 6452 } 6453 } 6454 } 6455 6456 mUsageStatsService.shutdown(); 6457 mBatteryStatsService.shutdown(); 6458 6459 return timedout; 6460 } 6461 6462 public final void activitySlept(IBinder token) { 6463 if (localLOGV) Slog.v( 6464 TAG, "Activity slept: token=" + token); 6465 6466 ActivityRecord r = null; 6467 6468 final long origId = Binder.clearCallingIdentity(); 6469 6470 synchronized (this) { 6471 r = mMainStack.isInStackLocked(token); 6472 if (r != null) { 6473 mMainStack.activitySleptLocked(r); 6474 } 6475 } 6476 6477 Binder.restoreCallingIdentity(origId); 6478 } 6479 6480 public void wakingUp() { 6481 synchronized(this) { 6482 mWindowManager.setEventDispatching(true); 6483 mSleeping = false; 6484 mMainStack.awakeFromSleepingLocked(); 6485 mMainStack.resumeTopActivityLocked(null); 6486 } 6487 } 6488 6489 public void stopAppSwitches() { 6490 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6491 != PackageManager.PERMISSION_GRANTED) { 6492 throw new SecurityException("Requires permission " 6493 + android.Manifest.permission.STOP_APP_SWITCHES); 6494 } 6495 6496 synchronized(this) { 6497 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6498 + APP_SWITCH_DELAY_TIME; 6499 mDidAppSwitch = false; 6500 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6501 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6502 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6503 } 6504 } 6505 6506 public void resumeAppSwitches() { 6507 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6508 != PackageManager.PERMISSION_GRANTED) { 6509 throw new SecurityException("Requires permission " 6510 + android.Manifest.permission.STOP_APP_SWITCHES); 6511 } 6512 6513 synchronized(this) { 6514 // Note that we don't execute any pending app switches... we will 6515 // let those wait until either the timeout, or the next start 6516 // activity request. 6517 mAppSwitchesAllowedTime = 0; 6518 } 6519 } 6520 6521 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6522 String name) { 6523 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6524 return true; 6525 } 6526 6527 final int perm = checkComponentPermission( 6528 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6529 callingUid, -1, true); 6530 if (perm == PackageManager.PERMISSION_GRANTED) { 6531 return true; 6532 } 6533 6534 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6535 return false; 6536 } 6537 6538 public void setDebugApp(String packageName, boolean waitForDebugger, 6539 boolean persistent) { 6540 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 6541 "setDebugApp()"); 6542 6543 // Note that this is not really thread safe if there are multiple 6544 // callers into it at the same time, but that's not a situation we 6545 // care about. 6546 if (persistent) { 6547 final ContentResolver resolver = mContext.getContentResolver(); 6548 Settings.System.putString( 6549 resolver, Settings.System.DEBUG_APP, 6550 packageName); 6551 Settings.System.putInt( 6552 resolver, Settings.System.WAIT_FOR_DEBUGGER, 6553 waitForDebugger ? 1 : 0); 6554 } 6555 6556 synchronized (this) { 6557 if (!persistent) { 6558 mOrigDebugApp = mDebugApp; 6559 mOrigWaitForDebugger = mWaitForDebugger; 6560 } 6561 mDebugApp = packageName; 6562 mWaitForDebugger = waitForDebugger; 6563 mDebugTransient = !persistent; 6564 if (packageName != null) { 6565 final long origId = Binder.clearCallingIdentity(); 6566 forceStopPackageLocked(packageName, -1, false, false, true, true); 6567 Binder.restoreCallingIdentity(origId); 6568 } 6569 } 6570 } 6571 6572 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 6573 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 6574 synchronized (this) { 6575 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6576 if (!isDebuggable) { 6577 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 6578 throw new SecurityException("Process not debuggable: " + app.packageName); 6579 } 6580 } 6581 mProfileApp = processName; 6582 mProfileFile = profileFile; 6583 if (mProfileFd != null) { 6584 try { 6585 mProfileFd.close(); 6586 } catch (IOException e) { 6587 } 6588 mProfileFd = null; 6589 } 6590 mProfileFd = profileFd; 6591 mProfileType = 0; 6592 mAutoStopProfiler = autoStopProfiler; 6593 } 6594 } 6595 6596 public void setAlwaysFinish(boolean enabled) { 6597 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 6598 "setAlwaysFinish()"); 6599 6600 Settings.System.putInt( 6601 mContext.getContentResolver(), 6602 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 6603 6604 synchronized (this) { 6605 mAlwaysFinishActivities = enabled; 6606 } 6607 } 6608 6609 public void setActivityController(IActivityController controller) { 6610 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 6611 "setActivityController()"); 6612 synchronized (this) { 6613 mController = controller; 6614 } 6615 } 6616 6617 public boolean isUserAMonkey() { 6618 // For now the fact that there is a controller implies 6619 // we have a monkey. 6620 synchronized (this) { 6621 return mController != null; 6622 } 6623 } 6624 6625 public void registerActivityWatcher(IActivityWatcher watcher) { 6626 synchronized (this) { 6627 mWatchers.register(watcher); 6628 } 6629 } 6630 6631 public void unregisterActivityWatcher(IActivityWatcher watcher) { 6632 synchronized (this) { 6633 mWatchers.unregister(watcher); 6634 } 6635 } 6636 6637 public void registerProcessObserver(IProcessObserver observer) { 6638 mProcessObservers.register(observer); 6639 } 6640 6641 public void unregisterProcessObserver(IProcessObserver observer) { 6642 mProcessObservers.unregister(observer); 6643 } 6644 6645 public void setImmersive(IBinder token, boolean immersive) { 6646 synchronized(this) { 6647 ActivityRecord r = mMainStack.isInStackLocked(token); 6648 if (r == null) { 6649 throw new IllegalArgumentException(); 6650 } 6651 r.immersive = immersive; 6652 } 6653 } 6654 6655 public boolean isImmersive(IBinder token) { 6656 synchronized (this) { 6657 ActivityRecord r = mMainStack.isInStackLocked(token); 6658 if (r == null) { 6659 throw new IllegalArgumentException(); 6660 } 6661 return r.immersive; 6662 } 6663 } 6664 6665 public boolean isTopActivityImmersive() { 6666 synchronized (this) { 6667 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 6668 return (r != null) ? r.immersive : false; 6669 } 6670 } 6671 6672 public final void enterSafeMode() { 6673 synchronized(this) { 6674 // It only makes sense to do this before the system is ready 6675 // and started launching other packages. 6676 if (!mSystemReady) { 6677 try { 6678 AppGlobals.getPackageManager().enterSafeMode(); 6679 } catch (RemoteException e) { 6680 } 6681 } 6682 } 6683 } 6684 6685 public final void showSafeModeOverlay() { 6686 View v = LayoutInflater.from(mContext).inflate( 6687 com.android.internal.R.layout.safe_mode, null); 6688 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 6689 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 6690 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 6691 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 6692 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 6693 lp.format = v.getBackground().getOpacity(); 6694 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 6695 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 6696 ((WindowManager)mContext.getSystemService( 6697 Context.WINDOW_SERVICE)).addView(v, lp); 6698 } 6699 6700 public void noteWakeupAlarm(IIntentSender sender) { 6701 if (!(sender instanceof PendingIntentRecord)) { 6702 return; 6703 } 6704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6705 synchronized (stats) { 6706 if (mBatteryStatsService.isOnBattery()) { 6707 mBatteryStatsService.enforceCallingPermission(); 6708 PendingIntentRecord rec = (PendingIntentRecord)sender; 6709 int MY_UID = Binder.getCallingUid(); 6710 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 6711 BatteryStatsImpl.Uid.Pkg pkg = 6712 stats.getPackageStatsLocked(uid, rec.key.packageName); 6713 pkg.incWakeupsLocked(); 6714 } 6715 } 6716 } 6717 6718 public boolean killPids(int[] pids, String pReason, boolean secure) { 6719 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6720 throw new SecurityException("killPids only available to the system"); 6721 } 6722 String reason = (pReason == null) ? "Unknown" : pReason; 6723 // XXX Note: don't acquire main activity lock here, because the window 6724 // manager calls in with its locks held. 6725 6726 boolean killed = false; 6727 synchronized (mPidsSelfLocked) { 6728 int[] types = new int[pids.length]; 6729 int worstType = 0; 6730 for (int i=0; i<pids.length; i++) { 6731 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 6732 if (proc != null) { 6733 int type = proc.setAdj; 6734 types[i] = type; 6735 if (type > worstType) { 6736 worstType = type; 6737 } 6738 } 6739 } 6740 6741 // If the worst oom_adj is somewhere in the hidden proc LRU range, 6742 // then constrain it so we will kill all hidden procs. 6743 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 6744 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 6745 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 6746 } 6747 6748 // If this is not a secure call, don't let it kill processes that 6749 // are important. 6750 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 6751 worstType = ProcessList.SERVICE_ADJ; 6752 } 6753 6754 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 6755 for (int i=0; i<pids.length; i++) { 6756 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 6757 if (proc == null) { 6758 continue; 6759 } 6760 int adj = proc.setAdj; 6761 if (adj >= worstType && !proc.killedBackground) { 6762 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 6763 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 6764 proc.processName, adj, reason); 6765 killed = true; 6766 proc.killedBackground = true; 6767 Process.killProcessQuiet(pids[i]); 6768 } 6769 } 6770 } 6771 return killed; 6772 } 6773 6774 public final void startRunning(String pkg, String cls, String action, 6775 String data) { 6776 synchronized(this) { 6777 if (mStartRunning) { 6778 return; 6779 } 6780 mStartRunning = true; 6781 mTopComponent = pkg != null && cls != null 6782 ? new ComponentName(pkg, cls) : null; 6783 mTopAction = action != null ? action : Intent.ACTION_MAIN; 6784 mTopData = data; 6785 if (!mSystemReady) { 6786 return; 6787 } 6788 } 6789 6790 systemReady(null); 6791 } 6792 6793 private void retrieveSettings() { 6794 final ContentResolver resolver = mContext.getContentResolver(); 6795 String debugApp = Settings.System.getString( 6796 resolver, Settings.System.DEBUG_APP); 6797 boolean waitForDebugger = Settings.System.getInt( 6798 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 6799 boolean alwaysFinishActivities = Settings.System.getInt( 6800 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 6801 6802 Configuration configuration = new Configuration(); 6803 Settings.System.getConfiguration(resolver, configuration); 6804 6805 synchronized (this) { 6806 mDebugApp = mOrigDebugApp = debugApp; 6807 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 6808 mAlwaysFinishActivities = alwaysFinishActivities; 6809 // This happens before any activities are started, so we can 6810 // change mConfiguration in-place. 6811 updateConfigurationLocked(configuration, null, false, true); 6812 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 6813 } 6814 } 6815 6816 public boolean testIsSystemReady() { 6817 // no need to synchronize(this) just to read & return the value 6818 return mSystemReady; 6819 } 6820 6821 private static File getCalledPreBootReceiversFile() { 6822 File dataDir = Environment.getDataDirectory(); 6823 File systemDir = new File(dataDir, "system"); 6824 File fname = new File(systemDir, "called_pre_boots.dat"); 6825 return fname; 6826 } 6827 6828 static final int LAST_DONE_VERSION = 10000; 6829 6830 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 6831 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 6832 File file = getCalledPreBootReceiversFile(); 6833 FileInputStream fis = null; 6834 try { 6835 fis = new FileInputStream(file); 6836 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 6837 int fvers = dis.readInt(); 6838 if (fvers == LAST_DONE_VERSION) { 6839 String vers = dis.readUTF(); 6840 String codename = dis.readUTF(); 6841 String build = dis.readUTF(); 6842 if (android.os.Build.VERSION.RELEASE.equals(vers) 6843 && android.os.Build.VERSION.CODENAME.equals(codename) 6844 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 6845 int num = dis.readInt(); 6846 while (num > 0) { 6847 num--; 6848 String pkg = dis.readUTF(); 6849 String cls = dis.readUTF(); 6850 lastDoneReceivers.add(new ComponentName(pkg, cls)); 6851 } 6852 } 6853 } 6854 } catch (FileNotFoundException e) { 6855 } catch (IOException e) { 6856 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 6857 } finally { 6858 if (fis != null) { 6859 try { 6860 fis.close(); 6861 } catch (IOException e) { 6862 } 6863 } 6864 } 6865 return lastDoneReceivers; 6866 } 6867 6868 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 6869 File file = getCalledPreBootReceiversFile(); 6870 FileOutputStream fos = null; 6871 DataOutputStream dos = null; 6872 try { 6873 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 6874 fos = new FileOutputStream(file); 6875 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 6876 dos.writeInt(LAST_DONE_VERSION); 6877 dos.writeUTF(android.os.Build.VERSION.RELEASE); 6878 dos.writeUTF(android.os.Build.VERSION.CODENAME); 6879 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 6880 dos.writeInt(list.size()); 6881 for (int i=0; i<list.size(); i++) { 6882 dos.writeUTF(list.get(i).getPackageName()); 6883 dos.writeUTF(list.get(i).getClassName()); 6884 } 6885 } catch (IOException e) { 6886 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 6887 file.delete(); 6888 } finally { 6889 FileUtils.sync(fos); 6890 if (dos != null) { 6891 try { 6892 dos.close(); 6893 } catch (IOException e) { 6894 // TODO Auto-generated catch block 6895 e.printStackTrace(); 6896 } 6897 } 6898 } 6899 } 6900 6901 public void systemReady(final Runnable goingCallback) { 6902 synchronized(this) { 6903 if (mSystemReady) { 6904 if (goingCallback != null) goingCallback.run(); 6905 return; 6906 } 6907 6908 // Check to see if there are any update receivers to run. 6909 if (!mDidUpdate) { 6910 if (mWaitingUpdate) { 6911 return; 6912 } 6913 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 6914 List<ResolveInfo> ris = null; 6915 try { 6916 ris = AppGlobals.getPackageManager().queryIntentReceivers( 6917 intent, null, 0); 6918 } catch (RemoteException e) { 6919 } 6920 if (ris != null) { 6921 for (int i=ris.size()-1; i>=0; i--) { 6922 if ((ris.get(i).activityInfo.applicationInfo.flags 6923 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6924 ris.remove(i); 6925 } 6926 } 6927 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 6928 6929 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 6930 6931 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 6932 for (int i=0; i<ris.size(); i++) { 6933 ActivityInfo ai = ris.get(i).activityInfo; 6934 ComponentName comp = new ComponentName(ai.packageName, ai.name); 6935 if (lastDoneReceivers.contains(comp)) { 6936 ris.remove(i); 6937 i--; 6938 } 6939 } 6940 6941 for (int i=0; i<ris.size(); i++) { 6942 ActivityInfo ai = ris.get(i).activityInfo; 6943 ComponentName comp = new ComponentName(ai.packageName, ai.name); 6944 doneReceivers.add(comp); 6945 intent.setComponent(comp); 6946 IIntentReceiver finisher = null; 6947 if (i == ris.size()-1) { 6948 finisher = new IIntentReceiver.Stub() { 6949 public void performReceive(Intent intent, int resultCode, 6950 String data, Bundle extras, boolean ordered, 6951 boolean sticky) { 6952 // The raw IIntentReceiver interface is called 6953 // with the AM lock held, so redispatch to 6954 // execute our code without the lock. 6955 mHandler.post(new Runnable() { 6956 public void run() { 6957 synchronized (ActivityManagerService.this) { 6958 mDidUpdate = true; 6959 } 6960 writeLastDonePreBootReceivers(doneReceivers); 6961 showBootMessage(mContext.getText( 6962 R.string.android_upgrading_complete), 6963 false); 6964 systemReady(goingCallback); 6965 } 6966 }); 6967 } 6968 }; 6969 } 6970 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 6971 broadcastIntentLocked(null, null, intent, null, finisher, 6972 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 6973 if (finisher != null) { 6974 mWaitingUpdate = true; 6975 } 6976 } 6977 } 6978 if (mWaitingUpdate) { 6979 return; 6980 } 6981 mDidUpdate = true; 6982 } 6983 6984 mSystemReady = true; 6985 if (!mStartRunning) { 6986 return; 6987 } 6988 } 6989 6990 ArrayList<ProcessRecord> procsToKill = null; 6991 synchronized(mPidsSelfLocked) { 6992 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 6993 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 6994 if (!isAllowedWhileBooting(proc.info)){ 6995 if (procsToKill == null) { 6996 procsToKill = new ArrayList<ProcessRecord>(); 6997 } 6998 procsToKill.add(proc); 6999 } 7000 } 7001 } 7002 7003 synchronized(this) { 7004 if (procsToKill != null) { 7005 for (int i=procsToKill.size()-1; i>=0; i--) { 7006 ProcessRecord proc = procsToKill.get(i); 7007 Slog.i(TAG, "Removing system update proc: " + proc); 7008 removeProcessLocked(proc, true, false, "system update done"); 7009 } 7010 } 7011 7012 // Now that we have cleaned up any update processes, we 7013 // are ready to start launching real processes and know that 7014 // we won't trample on them any more. 7015 mProcessesReady = true; 7016 } 7017 7018 Slog.i(TAG, "System now ready"); 7019 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7020 SystemClock.uptimeMillis()); 7021 7022 synchronized(this) { 7023 // Make sure we have no pre-ready processes sitting around. 7024 7025 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7026 ResolveInfo ri = mContext.getPackageManager() 7027 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7028 STOCK_PM_FLAGS); 7029 CharSequence errorMsg = null; 7030 if (ri != null) { 7031 ActivityInfo ai = ri.activityInfo; 7032 ApplicationInfo app = ai.applicationInfo; 7033 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7034 mTopAction = Intent.ACTION_FACTORY_TEST; 7035 mTopData = null; 7036 mTopComponent = new ComponentName(app.packageName, 7037 ai.name); 7038 } else { 7039 errorMsg = mContext.getResources().getText( 7040 com.android.internal.R.string.factorytest_not_system); 7041 } 7042 } else { 7043 errorMsg = mContext.getResources().getText( 7044 com.android.internal.R.string.factorytest_no_action); 7045 } 7046 if (errorMsg != null) { 7047 mTopAction = null; 7048 mTopData = null; 7049 mTopComponent = null; 7050 Message msg = Message.obtain(); 7051 msg.what = SHOW_FACTORY_ERROR_MSG; 7052 msg.getData().putCharSequence("msg", errorMsg); 7053 mHandler.sendMessage(msg); 7054 } 7055 } 7056 } 7057 7058 retrieveSettings(); 7059 7060 if (goingCallback != null) goingCallback.run(); 7061 7062 synchronized (this) { 7063 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7064 try { 7065 List apps = AppGlobals.getPackageManager(). 7066 getPersistentApplications(STOCK_PM_FLAGS); 7067 if (apps != null) { 7068 int N = apps.size(); 7069 int i; 7070 for (i=0; i<N; i++) { 7071 ApplicationInfo info 7072 = (ApplicationInfo)apps.get(i); 7073 if (info != null && 7074 !info.packageName.equals("android")) { 7075 addAppLocked(info); 7076 } 7077 } 7078 } 7079 } catch (RemoteException ex) { 7080 // pm is in same process, this will never happen. 7081 } 7082 } 7083 7084 // Start up initial activity. 7085 mBooting = true; 7086 7087 try { 7088 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7089 Message msg = Message.obtain(); 7090 msg.what = SHOW_UID_ERROR_MSG; 7091 mHandler.sendMessage(msg); 7092 } 7093 } catch (RemoteException e) { 7094 } 7095 7096 mMainStack.resumeTopActivityLocked(null); 7097 } 7098 } 7099 7100 private boolean makeAppCrashingLocked(ProcessRecord app, 7101 String shortMsg, String longMsg, String stackTrace) { 7102 app.crashing = true; 7103 app.crashingReport = generateProcessError(app, 7104 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7105 startAppProblemLocked(app); 7106 app.stopFreezingAllLocked(); 7107 return handleAppCrashLocked(app); 7108 } 7109 7110 private void makeAppNotRespondingLocked(ProcessRecord app, 7111 String activity, String shortMsg, String longMsg) { 7112 app.notResponding = true; 7113 app.notRespondingReport = generateProcessError(app, 7114 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7115 activity, shortMsg, longMsg, null); 7116 startAppProblemLocked(app); 7117 app.stopFreezingAllLocked(); 7118 } 7119 7120 /** 7121 * Generate a process error record, suitable for attachment to a ProcessRecord. 7122 * 7123 * @param app The ProcessRecord in which the error occurred. 7124 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7125 * ActivityManager.AppErrorStateInfo 7126 * @param activity The activity associated with the crash, if known. 7127 * @param shortMsg Short message describing the crash. 7128 * @param longMsg Long message describing the crash. 7129 * @param stackTrace Full crash stack trace, may be null. 7130 * 7131 * @return Returns a fully-formed AppErrorStateInfo record. 7132 */ 7133 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7134 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7135 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7136 7137 report.condition = condition; 7138 report.processName = app.processName; 7139 report.pid = app.pid; 7140 report.uid = app.info.uid; 7141 report.tag = activity; 7142 report.shortMsg = shortMsg; 7143 report.longMsg = longMsg; 7144 report.stackTrace = stackTrace; 7145 7146 return report; 7147 } 7148 7149 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7150 synchronized (this) { 7151 app.crashing = false; 7152 app.crashingReport = null; 7153 app.notResponding = false; 7154 app.notRespondingReport = null; 7155 if (app.anrDialog == fromDialog) { 7156 app.anrDialog = null; 7157 } 7158 if (app.waitDialog == fromDialog) { 7159 app.waitDialog = null; 7160 } 7161 if (app.pid > 0 && app.pid != MY_PID) { 7162 handleAppCrashLocked(app); 7163 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7164 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7165 app.processName, app.setAdj, "user's request after error"); 7166 Process.killProcessQuiet(app.pid); 7167 } 7168 } 7169 } 7170 7171 private boolean handleAppCrashLocked(ProcessRecord app) { 7172 long now = SystemClock.uptimeMillis(); 7173 7174 Long crashTime = mProcessCrashTimes.get(app.info.processName, 7175 app.info.uid); 7176 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7177 // This process loses! 7178 Slog.w(TAG, "Process " + app.info.processName 7179 + " has crashed too many times: killing!"); 7180 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7181 app.info.processName, app.info.uid); 7182 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7183 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7184 if (r.app == app) { 7185 Slog.w(TAG, " Force finishing activity " 7186 + r.intent.getComponent().flattenToShortString()); 7187 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7188 } 7189 } 7190 if (!app.persistent) { 7191 // We don't want to start this process again until the user 7192 // explicitly does so... but for persistent process, we really 7193 // need to keep it running. If a persistent process is actually 7194 // repeatedly crashing, then badness for everyone. 7195 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid, 7196 app.info.processName); 7197 mBadProcesses.put(app.info.processName, app.info.uid, now); 7198 app.bad = true; 7199 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 7200 app.removed = true; 7201 // Don't let services in this process be restarted and potentially 7202 // annoy the user repeatedly. Unless it is persistent, since those 7203 // processes run critical code. 7204 removeProcessLocked(app, false, false, "crash"); 7205 mMainStack.resumeTopActivityLocked(null); 7206 return false; 7207 } 7208 mMainStack.resumeTopActivityLocked(null); 7209 } else { 7210 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7211 if (r.app == app) { 7212 // If the top running activity is from this crashing 7213 // process, then terminate it to avoid getting in a loop. 7214 Slog.w(TAG, " Force finishing activity " 7215 + r.intent.getComponent().flattenToShortString()); 7216 int index = mMainStack.indexOfActivityLocked(r); 7217 r.stack.finishActivityLocked(r, index, 7218 Activity.RESULT_CANCELED, null, "crashed"); 7219 // Also terminate any activities below it that aren't yet 7220 // stopped, to avoid a situation where one will get 7221 // re-start our crashing activity once it gets resumed again. 7222 index--; 7223 if (index >= 0) { 7224 r = (ActivityRecord)mMainStack.mHistory.get(index); 7225 if (r.state == ActivityState.RESUMED 7226 || r.state == ActivityState.PAUSING 7227 || r.state == ActivityState.PAUSED) { 7228 if (!r.isHomeActivity || mHomeProcess != r.app) { 7229 Slog.w(TAG, " Force finishing activity " 7230 + r.intent.getComponent().flattenToShortString()); 7231 r.stack.finishActivityLocked(r, index, 7232 Activity.RESULT_CANCELED, null, "crashed"); 7233 } 7234 } 7235 } 7236 } 7237 } 7238 7239 // Bump up the crash count of any services currently running in the proc. 7240 if (app.services.size() != 0) { 7241 // Any services running in the application need to be placed 7242 // back in the pending list. 7243 Iterator<ServiceRecord> it = app.services.iterator(); 7244 while (it.hasNext()) { 7245 ServiceRecord sr = it.next(); 7246 sr.crashCount++; 7247 } 7248 } 7249 7250 // If the crashing process is what we consider to be the "home process" and it has been 7251 // replaced by a third-party app, clear the package preferred activities from packages 7252 // with a home activity running in the process to prevent a repeatedly crashing app 7253 // from blocking the user to manually clear the list. 7254 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7255 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7256 Iterator it = mHomeProcess.activities.iterator(); 7257 while (it.hasNext()) { 7258 ActivityRecord r = (ActivityRecord)it.next(); 7259 if (r.isHomeActivity) { 7260 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7261 try { 7262 ActivityThread.getPackageManager() 7263 .clearPackagePreferredActivities(r.packageName); 7264 } catch (RemoteException c) { 7265 // pm is in same process, this will never happen. 7266 } 7267 } 7268 } 7269 } 7270 7271 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 7272 return true; 7273 } 7274 7275 void startAppProblemLocked(ProcessRecord app) { 7276 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7277 mContext, app.info.packageName, app.info.flags); 7278 skipCurrentReceiverLocked(app); 7279 } 7280 7281 void skipCurrentReceiverLocked(ProcessRecord app) { 7282 boolean reschedule = false; 7283 BroadcastRecord r = app.curReceiver; 7284 if (r != null) { 7285 // The current broadcast is waiting for this app's receiver 7286 // to be finished. Looks like that's not going to happen, so 7287 // let the broadcast continue. 7288 logBroadcastReceiverDiscardLocked(r); 7289 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 7290 r.resultExtras, r.resultAbort, true); 7291 reschedule = true; 7292 } 7293 r = mPendingBroadcast; 7294 if (r != null && r.curApp == app) { 7295 if (DEBUG_BROADCAST) Slog.v(TAG, 7296 "skip & discard pending app " + r); 7297 logBroadcastReceiverDiscardLocked(r); 7298 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 7299 r.resultExtras, r.resultAbort, true); 7300 reschedule = true; 7301 } 7302 if (reschedule) { 7303 scheduleBroadcastsLocked(); 7304 } 7305 } 7306 7307 /** 7308 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7309 * The application process will exit immediately after this call returns. 7310 * @param app object of the crashing app, null for the system server 7311 * @param crashInfo describing the exception 7312 */ 7313 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7314 ProcessRecord r = findAppProcess(app, "Crash"); 7315 final String processName = app == null ? "system_server" 7316 : (r == null ? "unknown" : r.processName); 7317 7318 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7319 processName, 7320 r == null ? -1 : r.info.flags, 7321 crashInfo.exceptionClassName, 7322 crashInfo.exceptionMessage, 7323 crashInfo.throwFileName, 7324 crashInfo.throwLineNumber); 7325 7326 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7327 7328 crashApplication(r, crashInfo); 7329 } 7330 7331 public void handleApplicationStrictModeViolation( 7332 IBinder app, 7333 int violationMask, 7334 StrictMode.ViolationInfo info) { 7335 ProcessRecord r = findAppProcess(app, "StrictMode"); 7336 if (r == null) { 7337 return; 7338 } 7339 7340 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7341 Integer stackFingerprint = info.hashCode(); 7342 boolean logIt = true; 7343 synchronized (mAlreadyLoggedViolatedStacks) { 7344 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7345 logIt = false; 7346 // TODO: sub-sample into EventLog for these, with 7347 // the info.durationMillis? Then we'd get 7348 // the relative pain numbers, without logging all 7349 // the stack traces repeatedly. We'd want to do 7350 // likewise in the client code, which also does 7351 // dup suppression, before the Binder call. 7352 } else { 7353 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7354 mAlreadyLoggedViolatedStacks.clear(); 7355 } 7356 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7357 } 7358 } 7359 if (logIt) { 7360 logStrictModeViolationToDropBox(r, info); 7361 } 7362 } 7363 7364 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7365 AppErrorResult result = new AppErrorResult(); 7366 synchronized (this) { 7367 final long origId = Binder.clearCallingIdentity(); 7368 7369 Message msg = Message.obtain(); 7370 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7371 HashMap<String, Object> data = new HashMap<String, Object>(); 7372 data.put("result", result); 7373 data.put("app", r); 7374 data.put("violationMask", violationMask); 7375 data.put("info", info); 7376 msg.obj = data; 7377 mHandler.sendMessage(msg); 7378 7379 Binder.restoreCallingIdentity(origId); 7380 } 7381 int res = result.get(); 7382 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7383 } 7384 } 7385 7386 // Depending on the policy in effect, there could be a bunch of 7387 // these in quick succession so we try to batch these together to 7388 // minimize disk writes, number of dropbox entries, and maximize 7389 // compression, by having more fewer, larger records. 7390 private void logStrictModeViolationToDropBox( 7391 ProcessRecord process, 7392 StrictMode.ViolationInfo info) { 7393 if (info == null) { 7394 return; 7395 } 7396 final boolean isSystemApp = process == null || 7397 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7398 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7399 final String processName = process == null ? "unknown" : process.processName; 7400 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7401 final DropBoxManager dbox = (DropBoxManager) 7402 mContext.getSystemService(Context.DROPBOX_SERVICE); 7403 7404 // Exit early if the dropbox isn't configured to accept this report type. 7405 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7406 7407 boolean bufferWasEmpty; 7408 boolean needsFlush; 7409 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7410 synchronized (sb) { 7411 bufferWasEmpty = sb.length() == 0; 7412 appendDropBoxProcessHeaders(process, processName, sb); 7413 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7414 sb.append("System-App: ").append(isSystemApp).append("\n"); 7415 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7416 if (info.violationNumThisLoop != 0) { 7417 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7418 } 7419 if (info.numAnimationsRunning != 0) { 7420 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7421 } 7422 if (info.broadcastIntentAction != null) { 7423 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7424 } 7425 if (info.durationMillis != -1) { 7426 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7427 } 7428 if (info.numInstances != -1) { 7429 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7430 } 7431 if (info.tags != null) { 7432 for (String tag : info.tags) { 7433 sb.append("Span-Tag: ").append(tag).append("\n"); 7434 } 7435 } 7436 sb.append("\n"); 7437 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7438 sb.append(info.crashInfo.stackTrace); 7439 } 7440 sb.append("\n"); 7441 7442 // Only buffer up to ~64k. Various logging bits truncate 7443 // things at 128k. 7444 needsFlush = (sb.length() > 64 * 1024); 7445 } 7446 7447 // Flush immediately if the buffer's grown too large, or this 7448 // is a non-system app. Non-system apps are isolated with a 7449 // different tag & policy and not batched. 7450 // 7451 // Batching is useful during internal testing with 7452 // StrictMode settings turned up high. Without batching, 7453 // thousands of separate files could be created on boot. 7454 if (!isSystemApp || needsFlush) { 7455 new Thread("Error dump: " + dropboxTag) { 7456 @Override 7457 public void run() { 7458 String report; 7459 synchronized (sb) { 7460 report = sb.toString(); 7461 sb.delete(0, sb.length()); 7462 sb.trimToSize(); 7463 } 7464 if (report.length() != 0) { 7465 dbox.addText(dropboxTag, report); 7466 } 7467 } 7468 }.start(); 7469 return; 7470 } 7471 7472 // System app batching: 7473 if (!bufferWasEmpty) { 7474 // An existing dropbox-writing thread is outstanding, so 7475 // we don't need to start it up. The existing thread will 7476 // catch the buffer appends we just did. 7477 return; 7478 } 7479 7480 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7481 // (After this point, we shouldn't access AMS internal data structures.) 7482 new Thread("Error dump: " + dropboxTag) { 7483 @Override 7484 public void run() { 7485 // 5 second sleep to let stacks arrive and be batched together 7486 try { 7487 Thread.sleep(5000); // 5 seconds 7488 } catch (InterruptedException e) {} 7489 7490 String errorReport; 7491 synchronized (mStrictModeBuffer) { 7492 errorReport = mStrictModeBuffer.toString(); 7493 if (errorReport.length() == 0) { 7494 return; 7495 } 7496 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 7497 mStrictModeBuffer.trimToSize(); 7498 } 7499 dbox.addText(dropboxTag, errorReport); 7500 } 7501 }.start(); 7502 } 7503 7504 /** 7505 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 7506 * @param app object of the crashing app, null for the system server 7507 * @param tag reported by the caller 7508 * @param crashInfo describing the context of the error 7509 * @return true if the process should exit immediately (WTF is fatal) 7510 */ 7511 public boolean handleApplicationWtf(IBinder app, String tag, 7512 ApplicationErrorReport.CrashInfo crashInfo) { 7513 ProcessRecord r = findAppProcess(app, "WTF"); 7514 final String processName = app == null ? "system_server" 7515 : (r == null ? "unknown" : r.processName); 7516 7517 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 7518 processName, 7519 r == null ? -1 : r.info.flags, 7520 tag, crashInfo.exceptionMessage); 7521 7522 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 7523 7524 if (r != null && r.pid != Process.myPid() && 7525 Settings.Secure.getInt(mContext.getContentResolver(), 7526 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 7527 crashApplication(r, crashInfo); 7528 return true; 7529 } else { 7530 return false; 7531 } 7532 } 7533 7534 /** 7535 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 7536 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 7537 */ 7538 private ProcessRecord findAppProcess(IBinder app, String reason) { 7539 if (app == null) { 7540 return null; 7541 } 7542 7543 synchronized (this) { 7544 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 7545 final int NA = apps.size(); 7546 for (int ia=0; ia<NA; ia++) { 7547 ProcessRecord p = apps.valueAt(ia); 7548 if (p.thread != null && p.thread.asBinder() == app) { 7549 return p; 7550 } 7551 } 7552 } 7553 7554 Slog.w(TAG, "Can't find mystery application for " + reason 7555 + " from pid=" + Binder.getCallingPid() 7556 + " uid=" + Binder.getCallingUid() + ": " + app); 7557 return null; 7558 } 7559 } 7560 7561 /** 7562 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 7563 * to append various headers to the dropbox log text. 7564 */ 7565 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 7566 StringBuilder sb) { 7567 // Watchdog thread ends up invoking this function (with 7568 // a null ProcessRecord) to add the stack file to dropbox. 7569 // Do not acquire a lock on this (am) in such cases, as it 7570 // could cause a potential deadlock, if and when watchdog 7571 // is invoked due to unavailability of lock on am and it 7572 // would prevent watchdog from killing system_server. 7573 if (process == null) { 7574 sb.append("Process: ").append(processName).append("\n"); 7575 return; 7576 } 7577 // Note: ProcessRecord 'process' is guarded by the service 7578 // instance. (notably process.pkgList, which could otherwise change 7579 // concurrently during execution of this method) 7580 synchronized (this) { 7581 sb.append("Process: ").append(processName).append("\n"); 7582 int flags = process.info.flags; 7583 IPackageManager pm = AppGlobals.getPackageManager(); 7584 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 7585 for (String pkg : process.pkgList) { 7586 sb.append("Package: ").append(pkg); 7587 try { 7588 PackageInfo pi = pm.getPackageInfo(pkg, 0); 7589 if (pi != null) { 7590 sb.append(" v").append(pi.versionCode); 7591 if (pi.versionName != null) { 7592 sb.append(" (").append(pi.versionName).append(")"); 7593 } 7594 } 7595 } catch (RemoteException e) { 7596 Slog.e(TAG, "Error getting package info: " + pkg, e); 7597 } 7598 sb.append("\n"); 7599 } 7600 } 7601 } 7602 7603 private static String processClass(ProcessRecord process) { 7604 if (process == null || process.pid == MY_PID) { 7605 return "system_server"; 7606 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7607 return "system_app"; 7608 } else { 7609 return "data_app"; 7610 } 7611 } 7612 7613 /** 7614 * Write a description of an error (crash, WTF, ANR) to the drop box. 7615 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 7616 * @param process which caused the error, null means the system server 7617 * @param activity which triggered the error, null if unknown 7618 * @param parent activity related to the error, null if unknown 7619 * @param subject line related to the error, null if absent 7620 * @param report in long form describing the error, null if absent 7621 * @param logFile to include in the report, null if none 7622 * @param crashInfo giving an application stack trace, null if absent 7623 */ 7624 public void addErrorToDropBox(String eventType, 7625 ProcessRecord process, String processName, ActivityRecord activity, 7626 ActivityRecord parent, String subject, 7627 final String report, final File logFile, 7628 final ApplicationErrorReport.CrashInfo crashInfo) { 7629 // NOTE -- this must never acquire the ActivityManagerService lock, 7630 // otherwise the watchdog may be prevented from resetting the system. 7631 7632 final String dropboxTag = processClass(process) + "_" + eventType; 7633 final DropBoxManager dbox = (DropBoxManager) 7634 mContext.getSystemService(Context.DROPBOX_SERVICE); 7635 7636 // Exit early if the dropbox isn't configured to accept this report type. 7637 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7638 7639 final StringBuilder sb = new StringBuilder(1024); 7640 appendDropBoxProcessHeaders(process, processName, sb); 7641 if (activity != null) { 7642 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 7643 } 7644 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 7645 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 7646 } 7647 if (parent != null && parent != activity) { 7648 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 7649 } 7650 if (subject != null) { 7651 sb.append("Subject: ").append(subject).append("\n"); 7652 } 7653 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7654 if (Debug.isDebuggerConnected()) { 7655 sb.append("Debugger: Connected\n"); 7656 } 7657 sb.append("\n"); 7658 7659 // Do the rest in a worker thread to avoid blocking the caller on I/O 7660 // (After this point, we shouldn't access AMS internal data structures.) 7661 Thread worker = new Thread("Error dump: " + dropboxTag) { 7662 @Override 7663 public void run() { 7664 if (report != null) { 7665 sb.append(report); 7666 } 7667 if (logFile != null) { 7668 try { 7669 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 7670 } catch (IOException e) { 7671 Slog.e(TAG, "Error reading " + logFile, e); 7672 } 7673 } 7674 if (crashInfo != null && crashInfo.stackTrace != null) { 7675 sb.append(crashInfo.stackTrace); 7676 } 7677 7678 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 7679 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 7680 if (lines > 0) { 7681 sb.append("\n"); 7682 7683 // Merge several logcat streams, and take the last N lines 7684 InputStreamReader input = null; 7685 try { 7686 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 7687 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 7688 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 7689 7690 try { logcat.getOutputStream().close(); } catch (IOException e) {} 7691 try { logcat.getErrorStream().close(); } catch (IOException e) {} 7692 input = new InputStreamReader(logcat.getInputStream()); 7693 7694 int num; 7695 char[] buf = new char[8192]; 7696 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 7697 } catch (IOException e) { 7698 Slog.e(TAG, "Error running logcat", e); 7699 } finally { 7700 if (input != null) try { input.close(); } catch (IOException e) {} 7701 } 7702 } 7703 7704 dbox.addText(dropboxTag, sb.toString()); 7705 } 7706 }; 7707 7708 if (process == null || process.pid == MY_PID) { 7709 worker.run(); // We may be about to die -- need to run this synchronously 7710 } else { 7711 worker.start(); 7712 } 7713 } 7714 7715 /** 7716 * Bring up the "unexpected error" dialog box for a crashing app. 7717 * Deal with edge cases (intercepts from instrumented applications, 7718 * ActivityController, error intent receivers, that sort of thing). 7719 * @param r the application crashing 7720 * @param crashInfo describing the failure 7721 */ 7722 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 7723 long timeMillis = System.currentTimeMillis(); 7724 String shortMsg = crashInfo.exceptionClassName; 7725 String longMsg = crashInfo.exceptionMessage; 7726 String stackTrace = crashInfo.stackTrace; 7727 if (shortMsg != null && longMsg != null) { 7728 longMsg = shortMsg + ": " + longMsg; 7729 } else if (shortMsg != null) { 7730 longMsg = shortMsg; 7731 } 7732 7733 AppErrorResult result = new AppErrorResult(); 7734 synchronized (this) { 7735 if (mController != null) { 7736 try { 7737 String name = r != null ? r.processName : null; 7738 int pid = r != null ? r.pid : Binder.getCallingPid(); 7739 if (!mController.appCrashed(name, pid, 7740 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 7741 Slog.w(TAG, "Force-killing crashed app " + name 7742 + " at watcher's request"); 7743 Process.killProcess(pid); 7744 return; 7745 } 7746 } catch (RemoteException e) { 7747 mController = null; 7748 } 7749 } 7750 7751 final long origId = Binder.clearCallingIdentity(); 7752 7753 // If this process is running instrumentation, finish it. 7754 if (r != null && r.instrumentationClass != null) { 7755 Slog.w(TAG, "Error in app " + r.processName 7756 + " running instrumentation " + r.instrumentationClass + ":"); 7757 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 7758 if (longMsg != null) Slog.w(TAG, " " + longMsg); 7759 Bundle info = new Bundle(); 7760 info.putString("shortMsg", shortMsg); 7761 info.putString("longMsg", longMsg); 7762 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 7763 Binder.restoreCallingIdentity(origId); 7764 return; 7765 } 7766 7767 // If we can't identify the process or it's already exceeded its crash quota, 7768 // quit right away without showing a crash dialog. 7769 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 7770 Binder.restoreCallingIdentity(origId); 7771 return; 7772 } 7773 7774 Message msg = Message.obtain(); 7775 msg.what = SHOW_ERROR_MSG; 7776 HashMap data = new HashMap(); 7777 data.put("result", result); 7778 data.put("app", r); 7779 msg.obj = data; 7780 mHandler.sendMessage(msg); 7781 7782 Binder.restoreCallingIdentity(origId); 7783 } 7784 7785 int res = result.get(); 7786 7787 Intent appErrorIntent = null; 7788 synchronized (this) { 7789 if (r != null) { 7790 mProcessCrashTimes.put(r.info.processName, r.info.uid, 7791 SystemClock.uptimeMillis()); 7792 } 7793 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 7794 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 7795 } 7796 } 7797 7798 if (appErrorIntent != null) { 7799 try { 7800 mContext.startActivity(appErrorIntent); 7801 } catch (ActivityNotFoundException e) { 7802 Slog.w(TAG, "bug report receiver dissappeared", e); 7803 } 7804 } 7805 } 7806 7807 Intent createAppErrorIntentLocked(ProcessRecord r, 7808 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 7809 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 7810 if (report == null) { 7811 return null; 7812 } 7813 Intent result = new Intent(Intent.ACTION_APP_ERROR); 7814 result.setComponent(r.errorReportReceiver); 7815 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 7816 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7817 return result; 7818 } 7819 7820 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 7821 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 7822 if (r.errorReportReceiver == null) { 7823 return null; 7824 } 7825 7826 if (!r.crashing && !r.notResponding) { 7827 return null; 7828 } 7829 7830 ApplicationErrorReport report = new ApplicationErrorReport(); 7831 report.packageName = r.info.packageName; 7832 report.installerPackageName = r.errorReportReceiver.getPackageName(); 7833 report.processName = r.processName; 7834 report.time = timeMillis; 7835 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 7836 7837 if (r.crashing) { 7838 report.type = ApplicationErrorReport.TYPE_CRASH; 7839 report.crashInfo = crashInfo; 7840 } else if (r.notResponding) { 7841 report.type = ApplicationErrorReport.TYPE_ANR; 7842 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 7843 7844 report.anrInfo.activity = r.notRespondingReport.tag; 7845 report.anrInfo.cause = r.notRespondingReport.shortMsg; 7846 report.anrInfo.info = r.notRespondingReport.longMsg; 7847 } 7848 7849 return report; 7850 } 7851 7852 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 7853 // assume our apps are happy - lazy create the list 7854 List<ActivityManager.ProcessErrorStateInfo> errList = null; 7855 7856 synchronized (this) { 7857 7858 // iterate across all processes 7859 for (int i=mLruProcesses.size()-1; i>=0; i--) { 7860 ProcessRecord app = mLruProcesses.get(i); 7861 if ((app.thread != null) && (app.crashing || app.notResponding)) { 7862 // This one's in trouble, so we'll generate a report for it 7863 // crashes are higher priority (in case there's a crash *and* an anr) 7864 ActivityManager.ProcessErrorStateInfo report = null; 7865 if (app.crashing) { 7866 report = app.crashingReport; 7867 } else if (app.notResponding) { 7868 report = app.notRespondingReport; 7869 } 7870 7871 if (report != null) { 7872 if (errList == null) { 7873 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 7874 } 7875 errList.add(report); 7876 } else { 7877 Slog.w(TAG, "Missing app error report, app = " + app.processName + 7878 " crashing = " + app.crashing + 7879 " notResponding = " + app.notResponding); 7880 } 7881 } 7882 } 7883 } 7884 7885 return errList; 7886 } 7887 7888 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 7889 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 7890 if (currApp != null) { 7891 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 7892 } 7893 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 7894 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 7895 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 7896 } else if (adj >= ProcessList.HOME_APP_ADJ) { 7897 if (currApp != null) { 7898 currApp.lru = 0; 7899 } 7900 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 7901 } else if (adj >= ProcessList.SERVICE_ADJ) { 7902 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 7903 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 7904 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 7905 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 7906 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 7907 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 7908 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 7909 } else { 7910 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 7911 } 7912 } 7913 7914 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 7915 // Lazy instantiation of list 7916 List<ActivityManager.RunningAppProcessInfo> runList = null; 7917 synchronized (this) { 7918 // Iterate across all processes 7919 for (int i=mLruProcesses.size()-1; i>=0; i--) { 7920 ProcessRecord app = mLruProcesses.get(i); 7921 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 7922 // Generate process state info for running application 7923 ActivityManager.RunningAppProcessInfo currApp = 7924 new ActivityManager.RunningAppProcessInfo(app.processName, 7925 app.pid, app.getPackageList()); 7926 currApp.uid = app.info.uid; 7927 if (mHeavyWeightProcess == app) { 7928 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 7929 } 7930 if (app.persistent) { 7931 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 7932 } 7933 int adj = app.curAdj; 7934 currApp.importance = oomAdjToImportance(adj, currApp); 7935 currApp.importanceReasonCode = app.adjTypeCode; 7936 if (app.adjSource instanceof ProcessRecord) { 7937 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 7938 currApp.importanceReasonImportance = oomAdjToImportance( 7939 app.adjSourceOom, null); 7940 } else if (app.adjSource instanceof ActivityRecord) { 7941 ActivityRecord r = (ActivityRecord)app.adjSource; 7942 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 7943 } 7944 if (app.adjTarget instanceof ComponentName) { 7945 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 7946 } 7947 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 7948 // + " lru=" + currApp.lru); 7949 if (runList == null) { 7950 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 7951 } 7952 runList.add(currApp); 7953 } 7954 } 7955 } 7956 return runList; 7957 } 7958 7959 public List<ApplicationInfo> getRunningExternalApplications() { 7960 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 7961 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 7962 if (runningApps != null && runningApps.size() > 0) { 7963 Set<String> extList = new HashSet<String>(); 7964 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 7965 if (app.pkgList != null) { 7966 for (String pkg : app.pkgList) { 7967 extList.add(pkg); 7968 } 7969 } 7970 } 7971 IPackageManager pm = AppGlobals.getPackageManager(); 7972 for (String pkg : extList) { 7973 try { 7974 ApplicationInfo info = pm.getApplicationInfo(pkg, 0); 7975 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 7976 retList.add(info); 7977 } 7978 } catch (RemoteException e) { 7979 } 7980 } 7981 } 7982 return retList; 7983 } 7984 7985 @Override 7986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 7987 if (checkCallingPermission(android.Manifest.permission.DUMP) 7988 != PackageManager.PERMISSION_GRANTED) { 7989 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 7990 + Binder.getCallingPid() 7991 + ", uid=" + Binder.getCallingUid() 7992 + " without permission " 7993 + android.Manifest.permission.DUMP); 7994 return; 7995 } 7996 7997 boolean dumpAll = false; 7998 boolean dumpClient = false; 7999 String dumpPackage = null; 8000 8001 int opti = 0; 8002 while (opti < args.length) { 8003 String opt = args[opti]; 8004 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8005 break; 8006 } 8007 opti++; 8008 if ("-a".equals(opt)) { 8009 dumpAll = true; 8010 } else if ("-c".equals(opt)) { 8011 dumpClient = true; 8012 } else if ("-h".equals(opt)) { 8013 pw.println("Activity manager dump options:"); 8014 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8015 pw.println(" cmd may be one of:"); 8016 pw.println(" a[ctivities]: activity stack state"); 8017 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8018 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8019 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8020 pw.println(" o[om]: out of memory management"); 8021 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8022 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8023 pw.println(" service [COMP_SPEC]: service client-side state"); 8024 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8025 pw.println(" all: dump all activities"); 8026 pw.println(" top: dump the top activity"); 8027 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8028 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8029 pw.println(" a partial substring in a component name, a"); 8030 pw.println(" hex object identifier."); 8031 pw.println(" -a: include all available server state."); 8032 pw.println(" -c: include client state."); 8033 return; 8034 } else { 8035 pw.println("Unknown argument: " + opt + "; use -h for help"); 8036 } 8037 } 8038 8039 // Is the caller requesting to dump a particular piece of data? 8040 if (opti < args.length) { 8041 String cmd = args[opti]; 8042 opti++; 8043 if ("activities".equals(cmd) || "a".equals(cmd)) { 8044 synchronized (this) { 8045 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8046 } 8047 return; 8048 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8049 String[] newArgs; 8050 String name; 8051 if (opti >= args.length) { 8052 name = null; 8053 newArgs = EMPTY_STRING_ARRAY; 8054 } else { 8055 name = args[opti]; 8056 opti++; 8057 newArgs = new String[args.length - opti]; 8058 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8059 args.length - opti); 8060 } 8061 synchronized (this) { 8062 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8063 } 8064 return; 8065 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8066 String[] newArgs; 8067 String name; 8068 if (opti >= args.length) { 8069 name = null; 8070 newArgs = EMPTY_STRING_ARRAY; 8071 } else { 8072 name = args[opti]; 8073 opti++; 8074 newArgs = new String[args.length - opti]; 8075 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8076 args.length - opti); 8077 } 8078 synchronized (this) { 8079 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8080 } 8081 return; 8082 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8083 String[] newArgs; 8084 String name; 8085 if (opti >= args.length) { 8086 name = null; 8087 newArgs = EMPTY_STRING_ARRAY; 8088 } else { 8089 name = args[opti]; 8090 opti++; 8091 newArgs = new String[args.length - opti]; 8092 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8093 args.length - opti); 8094 } 8095 synchronized (this) { 8096 dumpProcessesLocked(fd, pw, args, opti, true, name); 8097 } 8098 return; 8099 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8100 synchronized (this) { 8101 dumpOomLocked(fd, pw, args, opti, true); 8102 } 8103 return; 8104 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8105 synchronized (this) { 8106 dumpProvidersLocked(fd, pw, args, opti, true, null); 8107 } 8108 return; 8109 } else if ("service".equals(cmd)) { 8110 String[] newArgs; 8111 String name; 8112 if (opti >= args.length) { 8113 name = null; 8114 newArgs = EMPTY_STRING_ARRAY; 8115 } else { 8116 name = args[opti]; 8117 opti++; 8118 newArgs = new String[args.length - opti]; 8119 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8120 args.length - opti); 8121 } 8122 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8123 pw.println("No services match: " + name); 8124 pw.println("Use -h for help."); 8125 } 8126 return; 8127 } else if ("package".equals(cmd)) { 8128 String[] newArgs; 8129 if (opti >= args.length) { 8130 pw.println("package: no package name specified"); 8131 pw.println("Use -h for help."); 8132 return; 8133 } else { 8134 dumpPackage = args[opti]; 8135 opti++; 8136 newArgs = new String[args.length - opti]; 8137 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8138 args.length - opti); 8139 args = newArgs; 8140 opti = 0; 8141 } 8142 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8143 synchronized (this) { 8144 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8145 } 8146 return; 8147 } else { 8148 // Dumping a single activity? 8149 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8150 pw.println("Bad activity command, or no activities match: " + cmd); 8151 pw.println("Use -h for help."); 8152 } 8153 return; 8154 } 8155 } 8156 8157 // No piece of data specified, dump everything. 8158 synchronized (this) { 8159 boolean needSep; 8160 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8161 if (needSep) { 8162 pw.println(" "); 8163 } 8164 if (dumpAll) { 8165 pw.println("-------------------------------------------------------------------------------"); 8166 } 8167 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8168 if (needSep) { 8169 pw.println(" "); 8170 } 8171 if (dumpAll) { 8172 pw.println("-------------------------------------------------------------------------------"); 8173 } 8174 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8175 if (needSep) { 8176 pw.println(" "); 8177 } 8178 if (dumpAll) { 8179 pw.println("-------------------------------------------------------------------------------"); 8180 } 8181 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8182 if (needSep) { 8183 pw.println(" "); 8184 } 8185 if (dumpAll) { 8186 pw.println("-------------------------------------------------------------------------------"); 8187 } 8188 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8189 if (needSep) { 8190 pw.println(" "); 8191 } 8192 if (dumpAll) { 8193 pw.println("-------------------------------------------------------------------------------"); 8194 } 8195 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8196 } 8197 } 8198 8199 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8200 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8201 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8202 pw.println(" Main stack:"); 8203 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8204 dumpPackage); 8205 pw.println(" "); 8206 pw.println(" Running activities (most recent first):"); 8207 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8208 dumpPackage); 8209 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8210 pw.println(" "); 8211 pw.println(" Activities waiting for another to become visible:"); 8212 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8213 !dumpAll, false, dumpPackage); 8214 } 8215 if (mMainStack.mStoppingActivities.size() > 0) { 8216 pw.println(" "); 8217 pw.println(" Activities waiting to stop:"); 8218 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8219 !dumpAll, false, dumpPackage); 8220 } 8221 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8222 pw.println(" "); 8223 pw.println(" Activities waiting to sleep:"); 8224 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8225 !dumpAll, false, dumpPackage); 8226 } 8227 if (mMainStack.mFinishingActivities.size() > 0) { 8228 pw.println(" "); 8229 pw.println(" Activities waiting to finish:"); 8230 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8231 !dumpAll, false, dumpPackage); 8232 } 8233 8234 pw.println(" "); 8235 if (mMainStack.mPausingActivity != null) { 8236 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8237 } 8238 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8239 pw.println(" mFocusedActivity: " + mFocusedActivity); 8240 if (dumpAll) { 8241 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8242 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8243 pw.println(" mDismissKeyguardOnNextActivity: " 8244 + mMainStack.mDismissKeyguardOnNextActivity); 8245 } 8246 8247 if (mRecentTasks.size() > 0) { 8248 pw.println(); 8249 pw.println(" Recent tasks:"); 8250 8251 final int N = mRecentTasks.size(); 8252 for (int i=0; i<N; i++) { 8253 TaskRecord tr = mRecentTasks.get(i); 8254 if (dumpPackage != null) { 8255 if (tr.realActivity == null || 8256 !dumpPackage.equals(tr.realActivity)) { 8257 continue; 8258 } 8259 } 8260 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8261 pw.println(tr); 8262 if (dumpAll) { 8263 mRecentTasks.get(i).dump(pw, " "); 8264 } 8265 } 8266 } 8267 8268 if (dumpAll) { 8269 pw.println(" "); 8270 pw.println(" mCurTask: " + mCurTask); 8271 } 8272 8273 return true; 8274 } 8275 8276 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8277 int opti, boolean dumpAll, String dumpPackage) { 8278 boolean needSep = false; 8279 int numPers = 0; 8280 8281 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8282 8283 if (dumpAll) { 8284 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8285 final int NA = procs.size(); 8286 for (int ia=0; ia<NA; ia++) { 8287 ProcessRecord r = procs.valueAt(ia); 8288 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8289 continue; 8290 } 8291 if (!needSep) { 8292 pw.println(" All known processes:"); 8293 needSep = true; 8294 } 8295 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8296 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8297 pw.print(" "); pw.println(r); 8298 r.dump(pw, " "); 8299 if (r.persistent) { 8300 numPers++; 8301 } 8302 } 8303 } 8304 } 8305 8306 if (mLruProcesses.size() > 0) { 8307 if (needSep) pw.println(" "); 8308 needSep = true; 8309 pw.println(" Process LRU list (sorted by oom_adj):"); 8310 dumpProcessOomList(pw, this, mLruProcesses, " ", 8311 "Proc", "PERS", false, dumpPackage); 8312 needSep = true; 8313 } 8314 8315 if (dumpAll) { 8316 synchronized (mPidsSelfLocked) { 8317 boolean printed = false; 8318 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8319 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8320 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8321 continue; 8322 } 8323 if (!printed) { 8324 if (needSep) pw.println(" "); 8325 needSep = true; 8326 pw.println(" PID mappings:"); 8327 printed = true; 8328 } 8329 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8330 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8331 } 8332 } 8333 } 8334 8335 if (mForegroundProcesses.size() > 0) { 8336 synchronized (mPidsSelfLocked) { 8337 boolean printed = false; 8338 for (int i=0; i<mForegroundProcesses.size(); i++) { 8339 ProcessRecord r = mPidsSelfLocked.get( 8340 mForegroundProcesses.valueAt(i).pid); 8341 if (dumpPackage != null && (r == null 8342 || !dumpPackage.equals(r.info.packageName))) { 8343 continue; 8344 } 8345 if (!printed) { 8346 if (needSep) pw.println(" "); 8347 needSep = true; 8348 pw.println(" Foreground Processes:"); 8349 printed = true; 8350 } 8351 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8352 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8353 } 8354 } 8355 } 8356 8357 if (mPersistentStartingProcesses.size() > 0) { 8358 if (needSep) pw.println(" "); 8359 needSep = true; 8360 pw.println(" Persisent processes that are starting:"); 8361 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8362 "Starting Norm", "Restarting PERS", dumpPackage); 8363 } 8364 8365 if (mRemovedProcesses.size() > 0) { 8366 if (needSep) pw.println(" "); 8367 needSep = true; 8368 pw.println(" Processes that are being removed:"); 8369 dumpProcessList(pw, this, mRemovedProcesses, " ", 8370 "Removed Norm", "Removed PERS", dumpPackage); 8371 } 8372 8373 if (mProcessesOnHold.size() > 0) { 8374 if (needSep) pw.println(" "); 8375 needSep = true; 8376 pw.println(" Processes that are on old until the system is ready:"); 8377 dumpProcessList(pw, this, mProcessesOnHold, " ", 8378 "OnHold Norm", "OnHold PERS", dumpPackage); 8379 } 8380 8381 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8382 8383 if (mProcessCrashTimes.getMap().size() > 0) { 8384 boolean printed = false; 8385 long now = SystemClock.uptimeMillis(); 8386 for (Map.Entry<String, SparseArray<Long>> procs 8387 : mProcessCrashTimes.getMap().entrySet()) { 8388 String pname = procs.getKey(); 8389 SparseArray<Long> uids = procs.getValue(); 8390 final int N = uids.size(); 8391 for (int i=0; i<N; i++) { 8392 int puid = uids.keyAt(i); 8393 ProcessRecord r = mProcessNames.get(pname, puid); 8394 if (dumpPackage != null && (r == null 8395 || !dumpPackage.equals(r.info.packageName))) { 8396 continue; 8397 } 8398 if (!printed) { 8399 if (needSep) pw.println(" "); 8400 needSep = true; 8401 pw.println(" Time since processes crashed:"); 8402 printed = true; 8403 } 8404 pw.print(" Process "); pw.print(pname); 8405 pw.print(" uid "); pw.print(puid); 8406 pw.print(": last crashed "); 8407 pw.print((now-uids.valueAt(i))); 8408 pw.println(" ms ago"); 8409 } 8410 } 8411 } 8412 8413 if (mBadProcesses.getMap().size() > 0) { 8414 boolean printed = false; 8415 for (Map.Entry<String, SparseArray<Long>> procs 8416 : mBadProcesses.getMap().entrySet()) { 8417 String pname = procs.getKey(); 8418 SparseArray<Long> uids = procs.getValue(); 8419 final int N = uids.size(); 8420 for (int i=0; i<N; i++) { 8421 int puid = uids.keyAt(i); 8422 ProcessRecord r = mProcessNames.get(pname, puid); 8423 if (dumpPackage != null && (r == null 8424 || !dumpPackage.equals(r.info.packageName))) { 8425 continue; 8426 } 8427 if (!printed) { 8428 if (needSep) pw.println(" "); 8429 needSep = true; 8430 pw.println(" Bad processes:"); 8431 } 8432 pw.print(" Bad process "); pw.print(pname); 8433 pw.print(" uid "); pw.print(puid); 8434 pw.print(": crashed at time "); 8435 pw.println(uids.valueAt(i)); 8436 } 8437 } 8438 } 8439 8440 pw.println(); 8441 pw.println(" mHomeProcess: " + mHomeProcess); 8442 pw.println(" mPreviousProcess: " + mPreviousProcess); 8443 if (dumpAll) { 8444 StringBuilder sb = new StringBuilder(128); 8445 sb.append(" mPreviousProcessVisibleTime: "); 8446 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 8447 pw.println(sb); 8448 } 8449 if (mHeavyWeightProcess != null) { 8450 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8451 } 8452 pw.println(" mConfiguration: " + mConfiguration); 8453 if (dumpAll) { 8454 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 8455 if (mCompatModePackages.getPackages().size() > 0) { 8456 boolean printed = false; 8457 for (Map.Entry<String, Integer> entry 8458 : mCompatModePackages.getPackages().entrySet()) { 8459 String pkg = entry.getKey(); 8460 int mode = entry.getValue(); 8461 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 8462 continue; 8463 } 8464 if (!printed) { 8465 pw.println(" mScreenCompatPackages:"); 8466 printed = true; 8467 } 8468 pw.print(" "); pw.print(pkg); pw.print(": "); 8469 pw.print(mode); pw.println(); 8470 } 8471 } 8472 } 8473 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 8474 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 8475 || mOrigWaitForDebugger) { 8476 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 8477 + " mDebugTransient=" + mDebugTransient 8478 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 8479 } 8480 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 8481 || mProfileFd != null) { 8482 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 8483 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 8484 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 8485 + mAutoStopProfiler); 8486 } 8487 if (mAlwaysFinishActivities || mController != null) { 8488 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 8489 + " mController=" + mController); 8490 } 8491 if (dumpAll) { 8492 pw.println(" Total persistent processes: " + numPers); 8493 pw.println(" mStartRunning=" + mStartRunning 8494 + " mProcessesReady=" + mProcessesReady 8495 + " mSystemReady=" + mSystemReady); 8496 pw.println(" mBooting=" + mBooting 8497 + " mBooted=" + mBooted 8498 + " mFactoryTest=" + mFactoryTest); 8499 pw.print(" mLastPowerCheckRealtime="); 8500 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 8501 pw.println(""); 8502 pw.print(" mLastPowerCheckUptime="); 8503 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 8504 pw.println(""); 8505 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 8506 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 8507 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 8508 pw.println(" mNumServiceProcs=" + mNumServiceProcs 8509 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 8510 } 8511 8512 return true; 8513 } 8514 8515 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 8516 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 8517 if (mProcessesToGc.size() > 0) { 8518 boolean printed = false; 8519 long now = SystemClock.uptimeMillis(); 8520 for (int i=0; i<mProcessesToGc.size(); i++) { 8521 ProcessRecord proc = mProcessesToGc.get(i); 8522 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 8523 continue; 8524 } 8525 if (!printed) { 8526 if (needSep) pw.println(" "); 8527 needSep = true; 8528 pw.println(" Processes that are waiting to GC:"); 8529 printed = true; 8530 } 8531 pw.print(" Process "); pw.println(proc); 8532 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 8533 pw.print(", last gced="); 8534 pw.print(now-proc.lastRequestedGc); 8535 pw.print(" ms ago, last lowMem="); 8536 pw.print(now-proc.lastLowMemory); 8537 pw.println(" ms ago"); 8538 8539 } 8540 } 8541 return needSep; 8542 } 8543 8544 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8545 int opti, boolean dumpAll) { 8546 boolean needSep = false; 8547 8548 if (mLruProcesses.size() > 0) { 8549 if (needSep) pw.println(" "); 8550 needSep = true; 8551 pw.println(" OOM levels:"); 8552 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 8553 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 8554 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 8555 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 8556 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 8557 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 8558 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 8559 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 8560 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 8561 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 8562 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 8563 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 8564 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 8565 8566 if (needSep) pw.println(" "); 8567 needSep = true; 8568 pw.println(" Process OOM control:"); 8569 dumpProcessOomList(pw, this, mLruProcesses, " ", 8570 "Proc", "PERS", true, null); 8571 needSep = true; 8572 } 8573 8574 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 8575 8576 pw.println(); 8577 pw.println(" mHomeProcess: " + mHomeProcess); 8578 pw.println(" mPreviousProcess: " + mPreviousProcess); 8579 if (mHeavyWeightProcess != null) { 8580 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8581 } 8582 8583 return true; 8584 } 8585 8586 /** 8587 * There are three ways to call this: 8588 * - no service specified: dump all the services 8589 * - a flattened component name that matched an existing service was specified as the 8590 * first arg: dump that one service 8591 * - the first arg isn't the flattened component name of an existing service: 8592 * dump all services whose component contains the first arg as a substring 8593 */ 8594 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 8595 int opti, boolean dumpAll) { 8596 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 8597 8598 if ("all".equals(name)) { 8599 synchronized (this) { 8600 for (ServiceRecord r1 : mServices.values()) { 8601 services.add(r1); 8602 } 8603 } 8604 } else { 8605 ComponentName componentName = name != null 8606 ? ComponentName.unflattenFromString(name) : null; 8607 int objectId = 0; 8608 if (componentName == null) { 8609 // Not a '/' separated full component name; maybe an object ID? 8610 try { 8611 objectId = Integer.parseInt(name, 16); 8612 name = null; 8613 componentName = null; 8614 } catch (RuntimeException e) { 8615 } 8616 } 8617 8618 synchronized (this) { 8619 for (ServiceRecord r1 : mServices.values()) { 8620 if (componentName != null) { 8621 if (r1.name.equals(componentName)) { 8622 services.add(r1); 8623 } 8624 } else if (name != null) { 8625 if (r1.name.flattenToString().contains(name)) { 8626 services.add(r1); 8627 } 8628 } else if (System.identityHashCode(r1) == objectId) { 8629 services.add(r1); 8630 } 8631 } 8632 } 8633 } 8634 8635 if (services.size() <= 0) { 8636 return false; 8637 } 8638 8639 boolean needSep = false; 8640 for (int i=0; i<services.size(); i++) { 8641 if (needSep) { 8642 pw.println(); 8643 } 8644 needSep = true; 8645 dumpService("", fd, pw, services.get(i), args, dumpAll); 8646 } 8647 return true; 8648 } 8649 8650 /** 8651 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 8652 * there is a thread associated with the service. 8653 */ 8654 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 8655 final ServiceRecord r, String[] args, boolean dumpAll) { 8656 String innerPrefix = prefix + " "; 8657 synchronized (this) { 8658 pw.print(prefix); pw.print("SERVICE "); 8659 pw.print(r.shortName); pw.print(" "); 8660 pw.print(Integer.toHexString(System.identityHashCode(r))); 8661 pw.print(" pid="); 8662 if (r.app != null) pw.println(r.app.pid); 8663 else pw.println("(not running)"); 8664 if (dumpAll) { 8665 r.dump(pw, innerPrefix); 8666 } 8667 } 8668 if (r.app != null && r.app.thread != null) { 8669 pw.print(prefix); pw.println(" Client:"); 8670 pw.flush(); 8671 try { 8672 TransferPipe tp = new TransferPipe(); 8673 try { 8674 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 8675 tp.setBufferPrefix(prefix + " "); 8676 tp.go(fd); 8677 } finally { 8678 tp.kill(); 8679 } 8680 } catch (IOException e) { 8681 pw.println(prefix + " Failure while dumping the service: " + e); 8682 } catch (RemoteException e) { 8683 pw.println(prefix + " Got a RemoteException while dumping the service"); 8684 } 8685 } 8686 } 8687 8688 static class ItemMatcher { 8689 ArrayList<ComponentName> components; 8690 ArrayList<String> strings; 8691 ArrayList<Integer> objects; 8692 boolean all; 8693 8694 ItemMatcher() { 8695 all = true; 8696 } 8697 8698 void build(String name) { 8699 ComponentName componentName = ComponentName.unflattenFromString(name); 8700 if (componentName != null) { 8701 if (components == null) { 8702 components = new ArrayList<ComponentName>(); 8703 } 8704 components.add(componentName); 8705 all = false; 8706 } else { 8707 int objectId = 0; 8708 // Not a '/' separated full component name; maybe an object ID? 8709 try { 8710 objectId = Integer.parseInt(name, 16); 8711 if (objects == null) { 8712 objects = new ArrayList<Integer>(); 8713 } 8714 objects.add(objectId); 8715 all = false; 8716 } catch (RuntimeException e) { 8717 // Not an integer; just do string match. 8718 if (strings == null) { 8719 strings = new ArrayList<String>(); 8720 } 8721 strings.add(name); 8722 all = false; 8723 } 8724 } 8725 } 8726 8727 int build(String[] args, int opti) { 8728 for (; opti<args.length; opti++) { 8729 String name = args[opti]; 8730 if ("--".equals(name)) { 8731 return opti+1; 8732 } 8733 build(name); 8734 } 8735 return opti; 8736 } 8737 8738 boolean match(Object object, ComponentName comp) { 8739 if (all) { 8740 return true; 8741 } 8742 if (components != null) { 8743 for (int i=0; i<components.size(); i++) { 8744 if (components.get(i).equals(comp)) { 8745 return true; 8746 } 8747 } 8748 } 8749 if (objects != null) { 8750 for (int i=0; i<objects.size(); i++) { 8751 if (System.identityHashCode(object) == objects.get(i)) { 8752 return true; 8753 } 8754 } 8755 } 8756 if (strings != null) { 8757 String flat = comp.flattenToString(); 8758 for (int i=0; i<strings.size(); i++) { 8759 if (flat.contains(strings.get(i))) { 8760 return true; 8761 } 8762 } 8763 } 8764 return false; 8765 } 8766 } 8767 8768 /** 8769 * There are three things that cmd can be: 8770 * - a flattened component name that matches an existing activity 8771 * - the cmd arg isn't the flattened component name of an existing activity: 8772 * dump all activity whose component contains the cmd as a substring 8773 * - A hex number of the ActivityRecord object instance. 8774 */ 8775 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 8776 int opti, boolean dumpAll) { 8777 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 8778 8779 if ("all".equals(name)) { 8780 synchronized (this) { 8781 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 8782 activities.add(r1); 8783 } 8784 } 8785 } else if ("top".equals(name)) { 8786 synchronized (this) { 8787 final int N = mMainStack.mHistory.size(); 8788 if (N > 0) { 8789 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 8790 } 8791 } 8792 } else { 8793 ItemMatcher matcher = new ItemMatcher(); 8794 matcher.build(name); 8795 8796 synchronized (this) { 8797 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 8798 if (matcher.match(r1, r1.intent.getComponent())) { 8799 activities.add(r1); 8800 } 8801 } 8802 } 8803 } 8804 8805 if (activities.size() <= 0) { 8806 return false; 8807 } 8808 8809 String[] newArgs = new String[args.length - opti]; 8810 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8811 8812 TaskRecord lastTask = null; 8813 boolean needSep = false; 8814 for (int i=activities.size()-1; i>=0; i--) { 8815 ActivityRecord r = (ActivityRecord)activities.get(i); 8816 if (needSep) { 8817 pw.println(); 8818 } 8819 needSep = true; 8820 synchronized (this) { 8821 if (lastTask != r.task) { 8822 lastTask = r.task; 8823 pw.print("TASK "); pw.print(lastTask.affinity); 8824 pw.print(" id="); pw.println(lastTask.taskId); 8825 if (dumpAll) { 8826 lastTask.dump(pw, " "); 8827 } 8828 } 8829 } 8830 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 8831 } 8832 return true; 8833 } 8834 8835 /** 8836 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 8837 * there is a thread associated with the activity. 8838 */ 8839 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 8840 final ActivityRecord r, String[] args, boolean dumpAll) { 8841 String innerPrefix = prefix + " "; 8842 synchronized (this) { 8843 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 8844 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 8845 pw.print(" pid="); 8846 if (r.app != null) pw.println(r.app.pid); 8847 else pw.println("(not running)"); 8848 if (dumpAll) { 8849 r.dump(pw, innerPrefix); 8850 } 8851 } 8852 if (r.app != null && r.app.thread != null) { 8853 // flush anything that is already in the PrintWriter since the thread is going 8854 // to write to the file descriptor directly 8855 pw.flush(); 8856 try { 8857 TransferPipe tp = new TransferPipe(); 8858 try { 8859 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 8860 r.appToken, innerPrefix, args); 8861 tp.go(fd); 8862 } finally { 8863 tp.kill(); 8864 } 8865 } catch (IOException e) { 8866 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 8867 } catch (RemoteException e) { 8868 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 8869 } 8870 } 8871 } 8872 8873 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8874 int opti, boolean dumpAll, String dumpPackage) { 8875 boolean needSep = false; 8876 8877 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 8878 if (dumpAll) { 8879 if (mRegisteredReceivers.size() > 0) { 8880 boolean printed = false; 8881 Iterator it = mRegisteredReceivers.values().iterator(); 8882 while (it.hasNext()) { 8883 ReceiverList r = (ReceiverList)it.next(); 8884 if (dumpPackage != null && (r.app == null || 8885 !dumpPackage.equals(r.app.info.packageName))) { 8886 continue; 8887 } 8888 if (!printed) { 8889 pw.println(" Registered Receivers:"); 8890 needSep = true; 8891 printed = true; 8892 } 8893 pw.print(" * "); pw.println(r); 8894 r.dump(pw, " "); 8895 } 8896 } 8897 8898 if (mReceiverResolver.dump(pw, needSep ? 8899 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 8900 " ", dumpPackage, false)) { 8901 needSep = true; 8902 } 8903 } 8904 8905 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 8906 || mPendingBroadcast != null) { 8907 boolean printed = false; 8908 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 8909 BroadcastRecord br = mParallelBroadcasts.get(i); 8910 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) { 8911 continue; 8912 } 8913 if (!printed) { 8914 if (needSep) { 8915 pw.println(); 8916 } 8917 needSep = true; 8918 pw.println(" Active broadcasts:"); 8919 } 8920 pw.println(" Broadcast #" + i + ":"); 8921 br.dump(pw, " "); 8922 } 8923 printed = false; 8924 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 8925 BroadcastRecord br = mOrderedBroadcasts.get(i); 8926 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) { 8927 continue; 8928 } 8929 if (!printed) { 8930 if (needSep) { 8931 pw.println(); 8932 } 8933 needSep = true; 8934 pw.println(" Active ordered broadcasts:"); 8935 } 8936 pw.println(" Ordered Broadcast #" + i + ":"); 8937 mOrderedBroadcasts.get(i).dump(pw, " "); 8938 } 8939 if (dumpPackage == null || (mPendingBroadcast != null 8940 && dumpPackage.equals(mPendingBroadcast.callerPackage))) { 8941 if (needSep) { 8942 pw.println(); 8943 } 8944 pw.println(" Pending broadcast:"); 8945 if (mPendingBroadcast != null) { 8946 mPendingBroadcast.dump(pw, " "); 8947 } else { 8948 pw.println(" (null)"); 8949 } 8950 needSep = true; 8951 } 8952 } 8953 8954 boolean printed = false; 8955 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 8956 BroadcastRecord r = mBroadcastHistory[i]; 8957 if (r == null) { 8958 break; 8959 } 8960 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) { 8961 continue; 8962 } 8963 if (!printed) { 8964 if (needSep) { 8965 pw.println(); 8966 } 8967 needSep = true; 8968 pw.println(" Historical broadcasts:"); 8969 printed = true; 8970 } 8971 if (dumpAll) { 8972 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":"); 8973 r.dump(pw, " "); 8974 } else { 8975 if (i >= 50) { 8976 pw.println(" ..."); 8977 break; 8978 } 8979 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r); 8980 } 8981 } 8982 needSep = true; 8983 8984 if (mStickyBroadcasts != null && dumpPackage == null) { 8985 if (needSep) { 8986 pw.println(); 8987 } 8988 needSep = true; 8989 pw.println(" Sticky broadcasts:"); 8990 StringBuilder sb = new StringBuilder(128); 8991 for (Map.Entry<String, ArrayList<Intent>> ent 8992 : mStickyBroadcasts.entrySet()) { 8993 pw.print(" * Sticky action "); pw.print(ent.getKey()); 8994 if (dumpAll) { 8995 pw.println(":"); 8996 ArrayList<Intent> intents = ent.getValue(); 8997 final int N = intents.size(); 8998 for (int i=0; i<N; i++) { 8999 sb.setLength(0); 9000 sb.append(" Intent: "); 9001 intents.get(i).toShortString(sb, false, true, false); 9002 pw.println(sb.toString()); 9003 Bundle bundle = intents.get(i).getExtras(); 9004 if (bundle != null) { 9005 pw.print(" "); 9006 pw.println(bundle.toString()); 9007 } 9008 } 9009 } else { 9010 pw.println(""); 9011 } 9012 } 9013 needSep = true; 9014 } 9015 9016 if (dumpAll) { 9017 pw.println(); 9018 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 9019 pw.println(" mHandler:"); 9020 mHandler.dump(new PrintWriterPrinter(pw), " "); 9021 needSep = true; 9022 } 9023 9024 return needSep; 9025 } 9026 9027 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9028 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9029 boolean needSep = false; 9030 9031 ItemMatcher matcher = new ItemMatcher(); 9032 matcher.build(args, opti); 9033 9034 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 9035 if (mServices.size() > 0) { 9036 boolean printed = false; 9037 long nowReal = SystemClock.elapsedRealtime(); 9038 Iterator<ServiceRecord> it = mServices.values().iterator(); 9039 needSep = false; 9040 while (it.hasNext()) { 9041 ServiceRecord r = it.next(); 9042 if (!matcher.match(r, r.name)) { 9043 continue; 9044 } 9045 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9046 continue; 9047 } 9048 if (!printed) { 9049 pw.println(" Active services:"); 9050 printed = true; 9051 } 9052 if (needSep) { 9053 pw.println(); 9054 } 9055 pw.print(" * "); pw.println(r); 9056 if (dumpAll) { 9057 r.dump(pw, " "); 9058 needSep = true; 9059 } else { 9060 pw.print(" app="); pw.println(r.app); 9061 pw.print(" created="); 9062 TimeUtils.formatDuration(r.createTime, nowReal, pw); 9063 pw.print(" started="); pw.print(r.startRequested); 9064 pw.print(" connections="); pw.println(r.connections.size()); 9065 if (r.connections.size() > 0) { 9066 pw.println(" Connections:"); 9067 for (ArrayList<ConnectionRecord> clist : r.connections.values()) { 9068 for (int i=0; i<clist.size(); i++) { 9069 ConnectionRecord conn = clist.get(i); 9070 pw.print(" "); 9071 pw.print(conn.binding.intent.intent.getIntent().toShortString( 9072 false, false, false)); 9073 pw.print(" -> "); 9074 ProcessRecord proc = conn.binding.client; 9075 pw.println(proc != null ? proc.toShortString() : "null"); 9076 } 9077 } 9078 } 9079 } 9080 if (dumpClient && r.app != null && r.app.thread != null) { 9081 pw.println(" Client:"); 9082 pw.flush(); 9083 try { 9084 TransferPipe tp = new TransferPipe(); 9085 try { 9086 r.app.thread.dumpService( 9087 tp.getWriteFd().getFileDescriptor(), r, args); 9088 tp.setBufferPrefix(" "); 9089 // Short timeout, since blocking here can 9090 // deadlock with the application. 9091 tp.go(fd, 2000); 9092 } finally { 9093 tp.kill(); 9094 } 9095 } catch (IOException e) { 9096 pw.println(" Failure while dumping the service: " + e); 9097 } catch (RemoteException e) { 9098 pw.println(" Got a RemoteException while dumping the service"); 9099 } 9100 needSep = true; 9101 } 9102 } 9103 needSep = printed; 9104 } 9105 9106 if (mPendingServices.size() > 0) { 9107 boolean printed = false; 9108 for (int i=0; i<mPendingServices.size(); i++) { 9109 ServiceRecord r = mPendingServices.get(i); 9110 if (!matcher.match(r, r.name)) { 9111 continue; 9112 } 9113 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9114 continue; 9115 } 9116 if (!printed) { 9117 if (needSep) pw.println(" "); 9118 needSep = true; 9119 pw.println(" Pending services:"); 9120 printed = true; 9121 } 9122 pw.print(" * Pending "); pw.println(r); 9123 r.dump(pw, " "); 9124 } 9125 needSep = true; 9126 } 9127 9128 if (mRestartingServices.size() > 0) { 9129 boolean printed = false; 9130 for (int i=0; i<mRestartingServices.size(); i++) { 9131 ServiceRecord r = mRestartingServices.get(i); 9132 if (!matcher.match(r, r.name)) { 9133 continue; 9134 } 9135 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9136 continue; 9137 } 9138 if (!printed) { 9139 if (needSep) pw.println(" "); 9140 needSep = true; 9141 pw.println(" Restarting services:"); 9142 printed = true; 9143 } 9144 pw.print(" * Restarting "); pw.println(r); 9145 r.dump(pw, " "); 9146 } 9147 needSep = true; 9148 } 9149 9150 if (mStoppingServices.size() > 0) { 9151 boolean printed = false; 9152 for (int i=0; i<mStoppingServices.size(); i++) { 9153 ServiceRecord r = mStoppingServices.get(i); 9154 if (!matcher.match(r, r.name)) { 9155 continue; 9156 } 9157 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9158 continue; 9159 } 9160 if (!printed) { 9161 if (needSep) pw.println(" "); 9162 needSep = true; 9163 pw.println(" Stopping services:"); 9164 printed = true; 9165 } 9166 pw.print(" * Stopping "); pw.println(r); 9167 r.dump(pw, " "); 9168 } 9169 needSep = true; 9170 } 9171 9172 if (dumpAll) { 9173 if (mServiceConnections.size() > 0) { 9174 boolean printed = false; 9175 Iterator<ArrayList<ConnectionRecord>> it 9176 = mServiceConnections.values().iterator(); 9177 while (it.hasNext()) { 9178 ArrayList<ConnectionRecord> r = it.next(); 9179 for (int i=0; i<r.size(); i++) { 9180 ConnectionRecord cr = r.get(i); 9181 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 9182 continue; 9183 } 9184 if (dumpPackage != null && (cr.binding.client == null 9185 || !dumpPackage.equals(cr.binding.client.info.packageName))) { 9186 continue; 9187 } 9188 if (!printed) { 9189 if (needSep) pw.println(" "); 9190 needSep = true; 9191 pw.println(" Connection bindings to services:"); 9192 printed = true; 9193 } 9194 pw.print(" * "); pw.println(cr); 9195 cr.dump(pw, " "); 9196 } 9197 } 9198 needSep = true; 9199 } 9200 } 9201 9202 return needSep; 9203 } 9204 9205 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9206 int opti, boolean dumpAll, String dumpPackage) { 9207 boolean needSep = false; 9208 9209 ItemMatcher matcher = new ItemMatcher(); 9210 matcher.build(args, opti); 9211 9212 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9213 if (mProvidersByClass.size() > 0) { 9214 boolean printed = false; 9215 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it 9216 = mProvidersByClass.entrySet().iterator(); 9217 while (it.hasNext()) { 9218 Map.Entry<ComponentName, ContentProviderRecord> e = it.next(); 9219 ContentProviderRecord r = e.getValue(); 9220 ComponentName comp = e.getKey(); 9221 String cls = comp.getClassName(); 9222 int end = cls.lastIndexOf('.'); 9223 if (end > 0 && end < (cls.length()-2)) { 9224 cls = cls.substring(end+1); 9225 } 9226 if (!matcher.match(r, comp)) { 9227 continue; 9228 } 9229 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) { 9230 continue; 9231 } 9232 if (!printed) { 9233 if (needSep) pw.println(" "); 9234 needSep = true; 9235 pw.println(" Published content providers (by class):"); 9236 printed = true; 9237 } 9238 pw.print(" * "); pw.print(cls); pw.print(" ("); 9239 pw.print(comp.flattenToShortString()); pw.println(")"); 9240 if (dumpAll) { 9241 r.dump(pw, " "); 9242 } else { 9243 if (r.proc != null) { 9244 pw.print(" "); pw.println(r.proc); 9245 } else { 9246 pw.println(); 9247 } 9248 if (r.clients.size() > 0) { 9249 pw.println(" Clients:"); 9250 for (ProcessRecord cproc : r.clients) { 9251 pw.print(" - "); pw.println(cproc); 9252 } 9253 } 9254 } 9255 } 9256 } 9257 9258 if (dumpAll) { 9259 if (mProvidersByName.size() > 0) { 9260 boolean printed = false; 9261 Iterator<Map.Entry<String, ContentProviderRecord>> it 9262 = mProvidersByName.entrySet().iterator(); 9263 while (it.hasNext()) { 9264 Map.Entry<String, ContentProviderRecord> e = it.next(); 9265 ContentProviderRecord r = e.getValue(); 9266 if (!matcher.match(r, r.name)) { 9267 continue; 9268 } 9269 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9270 continue; 9271 } 9272 if (!printed) { 9273 if (needSep) pw.println(" "); 9274 needSep = true; 9275 pw.println(" Authority to provider mappings:"); 9276 printed = true; 9277 } 9278 pw.print(" "); pw.print(e.getKey()); pw.println(":"); 9279 pw.print(" "); pw.println(r); 9280 } 9281 } 9282 } 9283 9284 if (mLaunchingProviders.size() > 0) { 9285 boolean printed = false; 9286 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9287 ContentProviderRecord r = mLaunchingProviders.get(i); 9288 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9289 continue; 9290 } 9291 if (!printed) { 9292 if (needSep) pw.println(" "); 9293 needSep = true; 9294 pw.println(" Launching content providers:"); 9295 printed = true; 9296 } 9297 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9298 pw.println(r); 9299 } 9300 } 9301 9302 if (mGrantedUriPermissions.size() > 0) { 9303 if (needSep) pw.println(); 9304 needSep = true; 9305 pw.println("Granted Uri Permissions:"); 9306 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9307 int uid = mGrantedUriPermissions.keyAt(i); 9308 HashMap<Uri, UriPermission> perms 9309 = mGrantedUriPermissions.valueAt(i); 9310 pw.print(" * UID "); pw.print(uid); 9311 pw.println(" holds:"); 9312 for (UriPermission perm : perms.values()) { 9313 pw.print(" "); pw.println(perm); 9314 if (dumpAll) { 9315 perm.dump(pw, " "); 9316 } 9317 } 9318 } 9319 needSep = true; 9320 } 9321 9322 return needSep; 9323 } 9324 9325 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9326 int opti, boolean dumpAll, String dumpPackage) { 9327 boolean needSep = false; 9328 9329 if (mIntentSenderRecords.size() > 0) { 9330 boolean printed = false; 9331 Iterator<WeakReference<PendingIntentRecord>> it 9332 = mIntentSenderRecords.values().iterator(); 9333 while (it.hasNext()) { 9334 WeakReference<PendingIntentRecord> ref = it.next(); 9335 PendingIntentRecord rec = ref != null ? ref.get(): null; 9336 if (dumpPackage != null && (rec == null 9337 || !dumpPackage.equals(rec.key.packageName))) { 9338 continue; 9339 } 9340 if (!printed) { 9341 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9342 printed = true; 9343 } 9344 needSep = true; 9345 if (rec != null) { 9346 pw.print(" * "); pw.println(rec); 9347 if (dumpAll) { 9348 rec.dump(pw, " "); 9349 } 9350 } else { 9351 pw.print(" * "); pw.println(ref); 9352 } 9353 } 9354 } 9355 9356 return needSep; 9357 } 9358 9359 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9360 String prefix, String label, boolean complete, boolean brief, boolean client, 9361 String dumpPackage) { 9362 TaskRecord lastTask = null; 9363 boolean needNL = false; 9364 final String innerPrefix = prefix + " "; 9365 final String[] args = new String[0]; 9366 for (int i=list.size()-1; i>=0; i--) { 9367 final ActivityRecord r = (ActivityRecord)list.get(i); 9368 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9369 continue; 9370 } 9371 final boolean full = !brief && (complete || !r.isInHistory()); 9372 if (needNL) { 9373 pw.println(" "); 9374 needNL = false; 9375 } 9376 if (lastTask != r.task) { 9377 lastTask = r.task; 9378 pw.print(prefix); 9379 pw.print(full ? "* " : " "); 9380 pw.println(lastTask); 9381 if (full) { 9382 lastTask.dump(pw, prefix + " "); 9383 } else if (complete) { 9384 // Complete + brief == give a summary. Isn't that obvious?!? 9385 if (lastTask.intent != null) { 9386 pw.print(prefix); pw.print(" "); 9387 pw.println(lastTask.intent.toInsecureString()); 9388 } 9389 } 9390 } 9391 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9392 pw.print(" #"); pw.print(i); pw.print(": "); 9393 pw.println(r); 9394 if (full) { 9395 r.dump(pw, innerPrefix); 9396 } else if (complete) { 9397 // Complete + brief == give a summary. Isn't that obvious?!? 9398 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9399 if (r.app != null) { 9400 pw.print(innerPrefix); pw.println(r.app); 9401 } 9402 } 9403 if (client && r.app != null && r.app.thread != null) { 9404 // flush anything that is already in the PrintWriter since the thread is going 9405 // to write to the file descriptor directly 9406 pw.flush(); 9407 try { 9408 TransferPipe tp = new TransferPipe(); 9409 try { 9410 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9411 r.appToken, innerPrefix, args); 9412 // Short timeout, since blocking here can 9413 // deadlock with the application. 9414 tp.go(fd, 2000); 9415 } finally { 9416 tp.kill(); 9417 } 9418 } catch (IOException e) { 9419 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9420 } catch (RemoteException e) { 9421 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9422 } 9423 needNL = true; 9424 } 9425 } 9426 } 9427 9428 private static String buildOomTag(String prefix, String space, int val, int base) { 9429 if (val == base) { 9430 if (space == null) return prefix; 9431 return prefix + " "; 9432 } 9433 return prefix + "+" + Integer.toString(val-base); 9434 } 9435 9436 private static final int dumpProcessList(PrintWriter pw, 9437 ActivityManagerService service, List list, 9438 String prefix, String normalLabel, String persistentLabel, 9439 String dumpPackage) { 9440 int numPers = 0; 9441 final int N = list.size()-1; 9442 for (int i=N; i>=0; i--) { 9443 ProcessRecord r = (ProcessRecord)list.get(i); 9444 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9445 continue; 9446 } 9447 pw.println(String.format("%s%s #%2d: %s", 9448 prefix, (r.persistent ? persistentLabel : normalLabel), 9449 i, r.toString())); 9450 if (r.persistent) { 9451 numPers++; 9452 } 9453 } 9454 return numPers; 9455 } 9456 9457 private static final boolean dumpProcessOomList(PrintWriter pw, 9458 ActivityManagerService service, List<ProcessRecord> origList, 9459 String prefix, String normalLabel, String persistentLabel, 9460 boolean inclDetails, String dumpPackage) { 9461 9462 ArrayList<Pair<ProcessRecord, Integer>> list 9463 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9464 for (int i=0; i<origList.size(); i++) { 9465 ProcessRecord r = origList.get(i); 9466 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9467 continue; 9468 } 9469 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9470 } 9471 9472 if (list.size() <= 0) { 9473 return false; 9474 } 9475 9476 Comparator<Pair<ProcessRecord, Integer>> comparator 9477 = new Comparator<Pair<ProcessRecord, Integer>>() { 9478 @Override 9479 public int compare(Pair<ProcessRecord, Integer> object1, 9480 Pair<ProcessRecord, Integer> object2) { 9481 if (object1.first.setAdj != object2.first.setAdj) { 9482 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9483 } 9484 if (object1.second.intValue() != object2.second.intValue()) { 9485 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9486 } 9487 return 0; 9488 } 9489 }; 9490 9491 Collections.sort(list, comparator); 9492 9493 final long curRealtime = SystemClock.elapsedRealtime(); 9494 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9495 final long curUptime = SystemClock.uptimeMillis(); 9496 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9497 9498 for (int i=list.size()-1; i>=0; i--) { 9499 ProcessRecord r = list.get(i).first; 9500 String oomAdj; 9501 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9502 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9503 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9504 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9505 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9506 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9507 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9508 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9509 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9510 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9511 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9512 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9513 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9514 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9515 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9516 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9517 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9518 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9519 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9520 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9521 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9522 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9523 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9524 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9525 } else { 9526 oomAdj = Integer.toString(r.setAdj); 9527 } 9528 String schedGroup; 9529 switch (r.setSchedGroup) { 9530 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9531 schedGroup = "B"; 9532 break; 9533 case Process.THREAD_GROUP_DEFAULT: 9534 schedGroup = "F"; 9535 break; 9536 default: 9537 schedGroup = Integer.toString(r.setSchedGroup); 9538 break; 9539 } 9540 String foreground; 9541 if (r.foregroundActivities) { 9542 foreground = "A"; 9543 } else if (r.foregroundServices) { 9544 foreground = "S"; 9545 } else { 9546 foreground = " "; 9547 } 9548 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9549 prefix, (r.persistent ? persistentLabel : normalLabel), 9550 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9551 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9552 if (r.adjSource != null || r.adjTarget != null) { 9553 pw.print(prefix); 9554 pw.print(" "); 9555 if (r.adjTarget instanceof ComponentName) { 9556 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9557 } else if (r.adjTarget != null) { 9558 pw.print(r.adjTarget.toString()); 9559 } else { 9560 pw.print("{null}"); 9561 } 9562 pw.print("<="); 9563 if (r.adjSource instanceof ProcessRecord) { 9564 pw.print("Proc{"); 9565 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9566 pw.println("}"); 9567 } else if (r.adjSource != null) { 9568 pw.println(r.adjSource.toString()); 9569 } else { 9570 pw.println("{null}"); 9571 } 9572 } 9573 if (inclDetails) { 9574 pw.print(prefix); 9575 pw.print(" "); 9576 pw.print("oom: max="); pw.print(r.maxAdj); 9577 pw.print(" hidden="); pw.print(r.hiddenAdj); 9578 pw.print(" curRaw="); pw.print(r.curRawAdj); 9579 pw.print(" setRaw="); pw.print(r.setRawAdj); 9580 pw.print(" cur="); pw.print(r.curAdj); 9581 pw.print(" set="); pw.println(r.setAdj); 9582 pw.print(prefix); 9583 pw.print(" "); 9584 pw.print("keeping="); pw.print(r.keeping); 9585 pw.print(" hidden="); pw.print(r.hidden); 9586 pw.print(" empty="); pw.print(r.empty); 9587 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9588 9589 if (!r.keeping) { 9590 if (r.lastWakeTime != 0) { 9591 long wtime; 9592 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9593 synchronized (stats) { 9594 wtime = stats.getProcessWakeTime(r.info.uid, 9595 r.pid, curRealtime); 9596 } 9597 long timeUsed = wtime - r.lastWakeTime; 9598 pw.print(prefix); 9599 pw.print(" "); 9600 pw.print("keep awake over "); 9601 TimeUtils.formatDuration(realtimeSince, pw); 9602 pw.print(" used "); 9603 TimeUtils.formatDuration(timeUsed, pw); 9604 pw.print(" ("); 9605 pw.print((timeUsed*100)/realtimeSince); 9606 pw.println("%)"); 9607 } 9608 if (r.lastCpuTime != 0) { 9609 long timeUsed = r.curCpuTime - r.lastCpuTime; 9610 pw.print(prefix); 9611 pw.print(" "); 9612 pw.print("run cpu over "); 9613 TimeUtils.formatDuration(uptimeSince, pw); 9614 pw.print(" used "); 9615 TimeUtils.formatDuration(timeUsed, pw); 9616 pw.print(" ("); 9617 pw.print((timeUsed*100)/uptimeSince); 9618 pw.println("%)"); 9619 } 9620 } 9621 } 9622 } 9623 return true; 9624 } 9625 9626 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9627 ArrayList<ProcessRecord> procs; 9628 synchronized (this) { 9629 if (args != null && args.length > start 9630 && args[start].charAt(0) != '-') { 9631 procs = new ArrayList<ProcessRecord>(); 9632 int pid = -1; 9633 try { 9634 pid = Integer.parseInt(args[start]); 9635 } catch (NumberFormatException e) { 9636 9637 } 9638 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9639 ProcessRecord proc = mLruProcesses.get(i); 9640 if (proc.pid == pid) { 9641 procs.add(proc); 9642 } else if (proc.processName.equals(args[start])) { 9643 procs.add(proc); 9644 } 9645 } 9646 if (procs.size() <= 0) { 9647 pw.println("No process found for: " + args[start]); 9648 return null; 9649 } 9650 } else { 9651 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9652 } 9653 } 9654 return procs; 9655 } 9656 9657 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9658 PrintWriter pw, String[] args) { 9659 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9660 if (procs == null) { 9661 return; 9662 } 9663 9664 long uptime = SystemClock.uptimeMillis(); 9665 long realtime = SystemClock.elapsedRealtime(); 9666 pw.println("Applications Graphics Acceleration Info:"); 9667 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9668 9669 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9670 ProcessRecord r = procs.get(i); 9671 if (r.thread != null) { 9672 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9673 pw.flush(); 9674 try { 9675 TransferPipe tp = new TransferPipe(); 9676 try { 9677 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9678 tp.go(fd); 9679 } finally { 9680 tp.kill(); 9681 } 9682 } catch (IOException e) { 9683 pw.println("Failure while dumping the app: " + r); 9684 pw.flush(); 9685 } catch (RemoteException e) { 9686 pw.println("Got a RemoteException while dumping the app " + r); 9687 pw.flush(); 9688 } 9689 } 9690 } 9691 } 9692 9693 final static class MemItem { 9694 final String label; 9695 final String shortLabel; 9696 final long pss; 9697 final int id; 9698 ArrayList<MemItem> subitems; 9699 9700 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9701 label = _label; 9702 shortLabel = _shortLabel; 9703 pss = _pss; 9704 id = _id; 9705 } 9706 } 9707 9708 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9709 boolean sort) { 9710 if (sort) { 9711 Collections.sort(items, new Comparator<MemItem>() { 9712 @Override 9713 public int compare(MemItem lhs, MemItem rhs) { 9714 if (lhs.pss < rhs.pss) { 9715 return 1; 9716 } else if (lhs.pss > rhs.pss) { 9717 return -1; 9718 } 9719 return 0; 9720 } 9721 }); 9722 } 9723 9724 for (int i=0; i<items.size(); i++) { 9725 MemItem mi = items.get(i); 9726 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9727 if (mi.subitems != null) { 9728 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9729 } 9730 } 9731 } 9732 9733 // These are in KB. 9734 static final long[] DUMP_MEM_BUCKETS = new long[] { 9735 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9736 120*1024, 160*1024, 200*1024, 9737 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9738 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9739 }; 9740 9741 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9742 boolean stackLike) { 9743 int start = label.lastIndexOf('.'); 9744 if (start >= 0) start++; 9745 else start = 0; 9746 int end = label.length(); 9747 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9748 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9749 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9750 out.append(bucket); 9751 out.append(stackLike ? "MB." : "MB "); 9752 out.append(label, start, end); 9753 return; 9754 } 9755 } 9756 out.append(memKB/1024); 9757 out.append(stackLike ? "MB." : "MB "); 9758 out.append(label, start, end); 9759 } 9760 9761 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9762 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9763 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9764 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9765 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9766 }; 9767 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9768 "System", "Persistent", "Foreground", 9769 "Visible", "Perceptible", "Heavy Weight", 9770 "Backup", "A Services", "Home", "Previous", 9771 "B Services", "Background" 9772 }; 9773 9774 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9775 PrintWriter pw, String prefix, String[] args, boolean brief, 9776 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9777 boolean dumpAll = false; 9778 boolean oomOnly = false; 9779 9780 int opti = 0; 9781 while (opti < args.length) { 9782 String opt = args[opti]; 9783 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9784 break; 9785 } 9786 opti++; 9787 if ("-a".equals(opt)) { 9788 dumpAll = true; 9789 } else if ("--oom".equals(opt)) { 9790 oomOnly = true; 9791 } else if ("-h".equals(opt)) { 9792 pw.println("meminfo dump options: [-a] [--oom] [process]"); 9793 pw.println(" -a: include all available information for each process."); 9794 pw.println(" --oom: only show processes organized by oom adj."); 9795 pw.println("If [process] is specified it can be the name or "); 9796 pw.println("pid of a specific process to dump."); 9797 return; 9798 } else { 9799 pw.println("Unknown argument: " + opt + "; use -h for help"); 9800 } 9801 } 9802 9803 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 9804 if (procs == null) { 9805 return; 9806 } 9807 9808 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9809 long uptime = SystemClock.uptimeMillis(); 9810 long realtime = SystemClock.elapsedRealtime(); 9811 9812 if (procs.size() == 1 || isCheckinRequest) { 9813 dumpAll = true; 9814 } 9815 9816 if (isCheckinRequest) { 9817 // short checkin version 9818 pw.println(uptime + "," + realtime); 9819 pw.flush(); 9820 } else { 9821 pw.println("Applications Memory Usage (kB):"); 9822 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9823 } 9824 9825 String[] innerArgs = new String[args.length-opti]; 9826 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 9827 9828 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 9829 long nativePss=0, dalvikPss=0, otherPss=0; 9830 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 9831 9832 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 9833 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 9834 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 9835 9836 long totalPss = 0; 9837 9838 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9839 ProcessRecord r = procs.get(i); 9840 if (r.thread != null) { 9841 if (!isCheckinRequest && dumpAll) { 9842 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9843 pw.flush(); 9844 } 9845 Debug.MemoryInfo mi = null; 9846 if (dumpAll) { 9847 try { 9848 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 9849 } catch (RemoteException e) { 9850 if (!isCheckinRequest) { 9851 pw.println("Got RemoteException!"); 9852 pw.flush(); 9853 } 9854 } 9855 } else { 9856 mi = new Debug.MemoryInfo(); 9857 Debug.getMemoryInfo(r.pid, mi); 9858 } 9859 9860 if (!isCheckinRequest && mi != null) { 9861 long myTotalPss = mi.getTotalPss(); 9862 totalPss += myTotalPss; 9863 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 9864 r.processName, myTotalPss, 0); 9865 procMems.add(pssItem); 9866 9867 nativePss += mi.nativePss; 9868 dalvikPss += mi.dalvikPss; 9869 otherPss += mi.otherPss; 9870 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 9871 long mem = mi.getOtherPss(j); 9872 miscPss[j] += mem; 9873 otherPss -= mem; 9874 } 9875 9876 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 9877 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 9878 || oomIndex == (oomPss.length-1)) { 9879 oomPss[oomIndex] += myTotalPss; 9880 if (oomProcs[oomIndex] == null) { 9881 oomProcs[oomIndex] = new ArrayList<MemItem>(); 9882 } 9883 oomProcs[oomIndex].add(pssItem); 9884 break; 9885 } 9886 } 9887 } 9888 } 9889 } 9890 9891 if (!isCheckinRequest && procs.size() > 1) { 9892 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 9893 9894 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 9895 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 9896 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 9897 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 9898 String label = Debug.MemoryInfo.getOtherLabel(j); 9899 catMems.add(new MemItem(label, label, miscPss[j], j)); 9900 } 9901 9902 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 9903 for (int j=0; j<oomPss.length; j++) { 9904 if (oomPss[j] != 0) { 9905 String label = DUMP_MEM_OOM_LABEL[j]; 9906 MemItem item = new MemItem(label, label, oomPss[j], 9907 DUMP_MEM_OOM_ADJ[j]); 9908 item.subitems = oomProcs[j]; 9909 oomMems.add(item); 9910 } 9911 } 9912 9913 if (outTag != null || outStack != null) { 9914 if (outTag != null) { 9915 appendMemBucket(outTag, totalPss, "total", false); 9916 } 9917 if (outStack != null) { 9918 appendMemBucket(outStack, totalPss, "total", true); 9919 } 9920 boolean firstLine = true; 9921 for (int i=0; i<oomMems.size(); i++) { 9922 MemItem miCat = oomMems.get(i); 9923 if (miCat.subitems == null || miCat.subitems.size() < 1) { 9924 continue; 9925 } 9926 if (miCat.id < ProcessList.SERVICE_ADJ 9927 || miCat.id == ProcessList.HOME_APP_ADJ 9928 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 9929 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 9930 outTag.append(" / "); 9931 } 9932 if (outStack != null) { 9933 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 9934 if (firstLine) { 9935 outStack.append(":"); 9936 firstLine = false; 9937 } 9938 outStack.append("\n\t at "); 9939 } else { 9940 outStack.append("$"); 9941 } 9942 } 9943 for (int j=0; j<miCat.subitems.size(); j++) { 9944 MemItem mi = miCat.subitems.get(j); 9945 if (j > 0) { 9946 if (outTag != null) { 9947 outTag.append(" "); 9948 } 9949 if (outStack != null) { 9950 outStack.append("$"); 9951 } 9952 } 9953 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 9954 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 9955 } 9956 if (outStack != null) { 9957 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 9958 } 9959 } 9960 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 9961 outStack.append("("); 9962 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 9963 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 9964 outStack.append(DUMP_MEM_OOM_LABEL[k]); 9965 outStack.append(":"); 9966 outStack.append(DUMP_MEM_OOM_ADJ[k]); 9967 } 9968 } 9969 outStack.append(")"); 9970 } 9971 } 9972 } 9973 } 9974 9975 if (!brief && !oomOnly) { 9976 pw.println(); 9977 pw.println("Total PSS by process:"); 9978 dumpMemItems(pw, " ", procMems, true); 9979 pw.println(); 9980 } 9981 pw.println("Total PSS by OOM adjustment:"); 9982 dumpMemItems(pw, " ", oomMems, false); 9983 if (!oomOnly) { 9984 PrintWriter out = categoryPw != null ? categoryPw : pw; 9985 out.println(); 9986 out.println("Total PSS by category:"); 9987 dumpMemItems(out, " ", catMems, true); 9988 } 9989 pw.println(); 9990 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 9991 } 9992 } 9993 9994 /** 9995 * Searches array of arguments for the specified string 9996 * @param args array of argument strings 9997 * @param value value to search for 9998 * @return true if the value is contained in the array 9999 */ 10000 private static boolean scanArgs(String[] args, String value) { 10001 if (args != null) { 10002 for (String arg : args) { 10003 if (value.equals(arg)) { 10004 return true; 10005 } 10006 } 10007 } 10008 return false; 10009 } 10010 10011 private final void killServicesLocked(ProcessRecord app, 10012 boolean allowRestart) { 10013 // Report disconnected services. 10014 if (false) { 10015 // XXX we are letting the client link to the service for 10016 // death notifications. 10017 if (app.services.size() > 0) { 10018 Iterator<ServiceRecord> it = app.services.iterator(); 10019 while (it.hasNext()) { 10020 ServiceRecord r = it.next(); 10021 if (r.connections.size() > 0) { 10022 Iterator<ArrayList<ConnectionRecord>> jt 10023 = r.connections.values().iterator(); 10024 while (jt.hasNext()) { 10025 ArrayList<ConnectionRecord> cl = jt.next(); 10026 for (int i=0; i<cl.size(); i++) { 10027 ConnectionRecord c = cl.get(i); 10028 if (c.binding.client != app) { 10029 try { 10030 //c.conn.connected(r.className, null); 10031 } catch (Exception e) { 10032 // todo: this should be asynchronous! 10033 Slog.w(TAG, "Exception thrown disconnected servce " 10034 + r.shortName 10035 + " from app " + app.processName, e); 10036 } 10037 } 10038 } 10039 } 10040 } 10041 } 10042 } 10043 } 10044 10045 // Clean up any connections this application has to other services. 10046 if (app.connections.size() > 0) { 10047 Iterator<ConnectionRecord> it = app.connections.iterator(); 10048 while (it.hasNext()) { 10049 ConnectionRecord r = it.next(); 10050 removeConnectionLocked(r, app, null); 10051 } 10052 } 10053 app.connections.clear(); 10054 10055 if (app.services.size() != 0) { 10056 // Any services running in the application need to be placed 10057 // back in the pending list. 10058 Iterator<ServiceRecord> it = app.services.iterator(); 10059 while (it.hasNext()) { 10060 ServiceRecord sr = it.next(); 10061 synchronized (sr.stats.getBatteryStats()) { 10062 sr.stats.stopLaunchedLocked(); 10063 } 10064 sr.app = null; 10065 sr.executeNesting = 0; 10066 if (mStoppingServices.remove(sr)) { 10067 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10068 } 10069 10070 boolean hasClients = sr.bindings.size() > 0; 10071 if (hasClients) { 10072 Iterator<IntentBindRecord> bindings 10073 = sr.bindings.values().iterator(); 10074 while (bindings.hasNext()) { 10075 IntentBindRecord b = bindings.next(); 10076 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10077 + ": shouldUnbind=" + b.hasBound); 10078 b.binder = null; 10079 b.requested = b.received = b.hasBound = false; 10080 } 10081 } 10082 10083 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 10084 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 10085 Slog.w(TAG, "Service crashed " + sr.crashCount 10086 + " times, stopping: " + sr); 10087 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10088 sr.crashCount, sr.shortName, app.pid); 10089 bringDownServiceLocked(sr, true); 10090 } else if (!allowRestart) { 10091 bringDownServiceLocked(sr, true); 10092 } else { 10093 boolean canceled = scheduleServiceRestartLocked(sr, true); 10094 10095 // Should the service remain running? Note that in the 10096 // extreme case of so many attempts to deliver a command 10097 // that it failed we also will stop it here. 10098 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10099 if (sr.pendingStarts.size() == 0) { 10100 sr.startRequested = false; 10101 if (!hasClients) { 10102 // Whoops, no reason to restart! 10103 bringDownServiceLocked(sr, true); 10104 } 10105 } 10106 } 10107 } 10108 } 10109 10110 if (!allowRestart) { 10111 app.services.clear(); 10112 } 10113 } 10114 10115 // Make sure we have no more records on the stopping list. 10116 int i = mStoppingServices.size(); 10117 while (i > 0) { 10118 i--; 10119 ServiceRecord sr = mStoppingServices.get(i); 10120 if (sr.app == app) { 10121 mStoppingServices.remove(i); 10122 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10123 } 10124 } 10125 10126 app.executingServices.clear(); 10127 } 10128 10129 private final void removeDyingProviderLocked(ProcessRecord proc, 10130 ContentProviderRecord cpr) { 10131 synchronized (cpr) { 10132 cpr.launchingApp = null; 10133 cpr.notifyAll(); 10134 } 10135 10136 mProvidersByClass.remove(cpr.name); 10137 String names[] = cpr.info.authority.split(";"); 10138 for (int j = 0; j < names.length; j++) { 10139 mProvidersByName.remove(names[j]); 10140 } 10141 10142 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 10143 while (cit.hasNext()) { 10144 ProcessRecord capp = cit.next(); 10145 if (!capp.persistent && capp.thread != null 10146 && capp.pid != 0 10147 && capp.pid != MY_PID) { 10148 Slog.i(TAG, "Kill " + capp.processName 10149 + " (pid " + capp.pid + "): provider " + cpr.info.name 10150 + " in dying process " + (proc != null ? proc.processName : "??")); 10151 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10152 capp.processName, capp.setAdj, "dying provider " 10153 + cpr.name.toShortString()); 10154 Process.killProcessQuiet(capp.pid); 10155 } 10156 } 10157 10158 mLaunchingProviders.remove(cpr); 10159 } 10160 10161 /** 10162 * Main code for cleaning up a process when it has gone away. This is 10163 * called both as a result of the process dying, or directly when stopping 10164 * a process when running in single process mode. 10165 */ 10166 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10167 boolean restarting, boolean allowRestart, int index) { 10168 if (index >= 0) { 10169 mLruProcesses.remove(index); 10170 } 10171 10172 mProcessesToGc.remove(app); 10173 10174 // Dismiss any open dialogs. 10175 if (app.crashDialog != null) { 10176 app.crashDialog.dismiss(); 10177 app.crashDialog = null; 10178 } 10179 if (app.anrDialog != null) { 10180 app.anrDialog.dismiss(); 10181 app.anrDialog = null; 10182 } 10183 if (app.waitDialog != null) { 10184 app.waitDialog.dismiss(); 10185 app.waitDialog = null; 10186 } 10187 10188 app.crashing = false; 10189 app.notResponding = false; 10190 10191 app.resetPackageList(); 10192 app.unlinkDeathRecipient(); 10193 app.thread = null; 10194 app.forcingToForeground = null; 10195 app.foregroundServices = false; 10196 app.foregroundActivities = false; 10197 app.hasShownUi = false; 10198 app.hasAboveClient = false; 10199 10200 killServicesLocked(app, allowRestart); 10201 10202 boolean restart = false; 10203 10204 int NL = mLaunchingProviders.size(); 10205 10206 // Remove published content providers. 10207 if (!app.pubProviders.isEmpty()) { 10208 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10209 while (it.hasNext()) { 10210 ContentProviderRecord cpr = it.next(); 10211 cpr.provider = null; 10212 cpr.proc = null; 10213 10214 // See if someone is waiting for this provider... in which 10215 // case we don't remove it, but just let it restart. 10216 int i = 0; 10217 if (!app.bad && allowRestart) { 10218 for (; i<NL; i++) { 10219 if (mLaunchingProviders.get(i) == cpr) { 10220 restart = true; 10221 break; 10222 } 10223 } 10224 } else { 10225 i = NL; 10226 } 10227 10228 if (i >= NL) { 10229 removeDyingProviderLocked(app, cpr); 10230 NL = mLaunchingProviders.size(); 10231 } 10232 } 10233 app.pubProviders.clear(); 10234 } 10235 10236 // Take care of any launching providers waiting for this process. 10237 if (checkAppInLaunchingProvidersLocked(app, false)) { 10238 restart = true; 10239 } 10240 10241 // Unregister from connected content providers. 10242 if (!app.conProviders.isEmpty()) { 10243 Iterator it = app.conProviders.keySet().iterator(); 10244 while (it.hasNext()) { 10245 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10246 cpr.clients.remove(app); 10247 } 10248 app.conProviders.clear(); 10249 } 10250 10251 // At this point there may be remaining entries in mLaunchingProviders 10252 // where we were the only one waiting, so they are no longer of use. 10253 // Look for these and clean up if found. 10254 // XXX Commented out for now. Trying to figure out a way to reproduce 10255 // the actual situation to identify what is actually going on. 10256 if (false) { 10257 for (int i=0; i<NL; i++) { 10258 ContentProviderRecord cpr = (ContentProviderRecord) 10259 mLaunchingProviders.get(i); 10260 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 10261 synchronized (cpr) { 10262 cpr.launchingApp = null; 10263 cpr.notifyAll(); 10264 } 10265 } 10266 } 10267 } 10268 10269 skipCurrentReceiverLocked(app); 10270 10271 // Unregister any receivers. 10272 if (app.receivers.size() > 0) { 10273 Iterator<ReceiverList> it = app.receivers.iterator(); 10274 while (it.hasNext()) { 10275 removeReceiverLocked(it.next()); 10276 } 10277 app.receivers.clear(); 10278 } 10279 10280 // If the app is undergoing backup, tell the backup manager about it 10281 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10282 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10283 try { 10284 IBackupManager bm = IBackupManager.Stub.asInterface( 10285 ServiceManager.getService(Context.BACKUP_SERVICE)); 10286 bm.agentDisconnected(app.info.packageName); 10287 } catch (RemoteException e) { 10288 // can't happen; backup manager is local 10289 } 10290 } 10291 10292 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10293 10294 // If the caller is restarting this app, then leave it in its 10295 // current lists and let the caller take care of it. 10296 if (restarting) { 10297 return; 10298 } 10299 10300 if (!app.persistent) { 10301 if (DEBUG_PROCESSES) Slog.v(TAG, 10302 "Removing non-persistent process during cleanup: " + app); 10303 mProcessNames.remove(app.processName, app.info.uid); 10304 if (mHeavyWeightProcess == app) { 10305 mHeavyWeightProcess = null; 10306 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10307 } 10308 } else if (!app.removed) { 10309 // This app is persistent, so we need to keep its record around. 10310 // If it is not already on the pending app list, add it there 10311 // and start a new process for it. 10312 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10313 mPersistentStartingProcesses.add(app); 10314 restart = true; 10315 } 10316 } 10317 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10318 "Clean-up removing on hold: " + app); 10319 mProcessesOnHold.remove(app); 10320 10321 if (app == mHomeProcess) { 10322 mHomeProcess = null; 10323 } 10324 if (app == mPreviousProcess) { 10325 mPreviousProcess = null; 10326 } 10327 10328 if (restart) { 10329 // We have components that still need to be running in the 10330 // process, so re-launch it. 10331 mProcessNames.put(app.processName, app.info.uid, app); 10332 startProcessLocked(app, "restart", app.processName); 10333 } else if (app.pid > 0 && app.pid != MY_PID) { 10334 // Goodbye! 10335 synchronized (mPidsSelfLocked) { 10336 mPidsSelfLocked.remove(app.pid); 10337 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10338 } 10339 app.setPid(0); 10340 } 10341 } 10342 10343 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10344 // Look through the content providers we are waiting to have launched, 10345 // and if any run in this process then either schedule a restart of 10346 // the process or kill the client waiting for it if this process has 10347 // gone bad. 10348 int NL = mLaunchingProviders.size(); 10349 boolean restart = false; 10350 for (int i=0; i<NL; i++) { 10351 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10352 if (cpr.launchingApp == app) { 10353 if (!alwaysBad && !app.bad) { 10354 restart = true; 10355 } else { 10356 removeDyingProviderLocked(app, cpr); 10357 NL = mLaunchingProviders.size(); 10358 } 10359 } 10360 } 10361 return restart; 10362 } 10363 10364 // ========================================================= 10365 // SERVICES 10366 // ========================================================= 10367 10368 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10369 ActivityManager.RunningServiceInfo info = 10370 new ActivityManager.RunningServiceInfo(); 10371 info.service = r.name; 10372 if (r.app != null) { 10373 info.pid = r.app.pid; 10374 } 10375 info.uid = r.appInfo.uid; 10376 info.process = r.processName; 10377 info.foreground = r.isForeground; 10378 info.activeSince = r.createTime; 10379 info.started = r.startRequested; 10380 info.clientCount = r.connections.size(); 10381 info.crashCount = r.crashCount; 10382 info.lastActivityTime = r.lastActivity; 10383 if (r.isForeground) { 10384 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10385 } 10386 if (r.startRequested) { 10387 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10388 } 10389 if (r.app != null && r.app.pid == MY_PID) { 10390 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10391 } 10392 if (r.app != null && r.app.persistent) { 10393 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10394 } 10395 10396 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 10397 for (int i=0; i<connl.size(); i++) { 10398 ConnectionRecord conn = connl.get(i); 10399 if (conn.clientLabel != 0) { 10400 info.clientPackage = conn.binding.client.info.packageName; 10401 info.clientLabel = conn.clientLabel; 10402 return info; 10403 } 10404 } 10405 } 10406 return info; 10407 } 10408 10409 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10410 int flags) { 10411 synchronized (this) { 10412 ArrayList<ActivityManager.RunningServiceInfo> res 10413 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10414 10415 if (mServices.size() > 0) { 10416 Iterator<ServiceRecord> it = mServices.values().iterator(); 10417 while (it.hasNext() && res.size() < maxNum) { 10418 res.add(makeRunningServiceInfoLocked(it.next())); 10419 } 10420 } 10421 10422 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10423 ServiceRecord r = mRestartingServices.get(i); 10424 ActivityManager.RunningServiceInfo info = 10425 makeRunningServiceInfoLocked(r); 10426 info.restarting = r.nextRestartTime; 10427 res.add(info); 10428 } 10429 10430 return res; 10431 } 10432 } 10433 10434 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10435 synchronized (this) { 10436 ServiceRecord r = mServices.get(name); 10437 if (r != null) { 10438 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 10439 for (int i=0; i<conn.size(); i++) { 10440 if (conn.get(i).clientIntent != null) { 10441 return conn.get(i).clientIntent; 10442 } 10443 } 10444 } 10445 } 10446 } 10447 return null; 10448 } 10449 10450 private final ServiceRecord findServiceLocked(ComponentName name, 10451 IBinder token) { 10452 ServiceRecord r = mServices.get(name); 10453 return r == token ? r : null; 10454 } 10455 10456 private final class ServiceLookupResult { 10457 final ServiceRecord record; 10458 final String permission; 10459 10460 ServiceLookupResult(ServiceRecord _record, String _permission) { 10461 record = _record; 10462 permission = _permission; 10463 } 10464 }; 10465 10466 private ServiceLookupResult findServiceLocked(Intent service, 10467 String resolvedType) { 10468 ServiceRecord r = null; 10469 if (service.getComponent() != null) { 10470 r = mServices.get(service.getComponent()); 10471 } 10472 if (r == null) { 10473 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10474 r = mServicesByIntent.get(filter); 10475 } 10476 10477 if (r == null) { 10478 try { 10479 ResolveInfo rInfo = 10480 AppGlobals.getPackageManager().resolveService( 10481 service, resolvedType, 0); 10482 ServiceInfo sInfo = 10483 rInfo != null ? rInfo.serviceInfo : null; 10484 if (sInfo == null) { 10485 return null; 10486 } 10487 10488 ComponentName name = new ComponentName( 10489 sInfo.applicationInfo.packageName, sInfo.name); 10490 r = mServices.get(name); 10491 } catch (RemoteException ex) { 10492 // pm is in same process, this will never happen. 10493 } 10494 } 10495 if (r != null) { 10496 int callingPid = Binder.getCallingPid(); 10497 int callingUid = Binder.getCallingUid(); 10498 if (checkComponentPermission(r.permission, 10499 callingPid, callingUid, r.appInfo.uid, r.exported) 10500 != PackageManager.PERMISSION_GRANTED) { 10501 if (!r.exported) { 10502 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10503 + " from pid=" + callingPid 10504 + ", uid=" + callingUid 10505 + " that is not exported from uid " + r.appInfo.uid); 10506 return new ServiceLookupResult(null, "not exported from uid " 10507 + r.appInfo.uid); 10508 } 10509 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10510 + " from pid=" + callingPid 10511 + ", uid=" + callingUid 10512 + " requires " + r.permission); 10513 return new ServiceLookupResult(null, r.permission); 10514 } 10515 return new ServiceLookupResult(r, null); 10516 } 10517 return null; 10518 } 10519 10520 private class ServiceRestarter implements Runnable { 10521 private ServiceRecord mService; 10522 10523 void setService(ServiceRecord service) { 10524 mService = service; 10525 } 10526 10527 public void run() { 10528 synchronized(ActivityManagerService.this) { 10529 performServiceRestartLocked(mService); 10530 } 10531 } 10532 } 10533 10534 private ServiceLookupResult retrieveServiceLocked(Intent service, 10535 String resolvedType, int callingPid, int callingUid) { 10536 ServiceRecord r = null; 10537 if (service.getComponent() != null) { 10538 r = mServices.get(service.getComponent()); 10539 } 10540 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10541 r = mServicesByIntent.get(filter); 10542 if (r == null) { 10543 try { 10544 ResolveInfo rInfo = 10545 AppGlobals.getPackageManager().resolveService( 10546 service, resolvedType, STOCK_PM_FLAGS); 10547 ServiceInfo sInfo = 10548 rInfo != null ? rInfo.serviceInfo : null; 10549 if (sInfo == null) { 10550 Slog.w(TAG, "Unable to start service " + service + 10551 ": not found"); 10552 return null; 10553 } 10554 10555 ComponentName name = new ComponentName( 10556 sInfo.applicationInfo.packageName, sInfo.name); 10557 r = mServices.get(name); 10558 if (r == null) { 10559 filter = new Intent.FilterComparison(service.cloneFilter()); 10560 ServiceRestarter res = new ServiceRestarter(); 10561 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10562 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10563 synchronized (stats) { 10564 ss = stats.getServiceStatsLocked( 10565 sInfo.applicationInfo.uid, sInfo.packageName, 10566 sInfo.name); 10567 } 10568 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 10569 res.setService(r); 10570 mServices.put(name, r); 10571 mServicesByIntent.put(filter, r); 10572 10573 // Make sure this component isn't in the pending list. 10574 int N = mPendingServices.size(); 10575 for (int i=0; i<N; i++) { 10576 ServiceRecord pr = mPendingServices.get(i); 10577 if (pr.name.equals(name)) { 10578 mPendingServices.remove(i); 10579 i--; 10580 N--; 10581 } 10582 } 10583 } 10584 } catch (RemoteException ex) { 10585 // pm is in same process, this will never happen. 10586 } 10587 } 10588 if (r != null) { 10589 if (checkComponentPermission(r.permission, 10590 callingPid, callingUid, r.appInfo.uid, r.exported) 10591 != PackageManager.PERMISSION_GRANTED) { 10592 if (!r.exported) { 10593 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10594 + " from pid=" + callingPid 10595 + ", uid=" + callingUid 10596 + " that is not exported from uid " + r.appInfo.uid); 10597 return new ServiceLookupResult(null, "not exported from uid " 10598 + r.appInfo.uid); 10599 } 10600 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10601 + " from pid=" + callingPid 10602 + ", uid=" + callingUid 10603 + " requires " + r.permission); 10604 return new ServiceLookupResult(null, r.permission); 10605 } 10606 return new ServiceLookupResult(r, null); 10607 } 10608 return null; 10609 } 10610 10611 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 10612 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 10613 + why + " of " + r + " in app " + r.app); 10614 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 10615 + why + " of " + r.shortName); 10616 long now = SystemClock.uptimeMillis(); 10617 if (r.executeNesting == 0 && r.app != null) { 10618 if (r.app.executingServices.size() == 0) { 10619 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10620 msg.obj = r.app; 10621 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10622 } 10623 r.app.executingServices.add(r); 10624 } 10625 r.executeNesting++; 10626 r.executingStart = now; 10627 } 10628 10629 private final void sendServiceArgsLocked(ServiceRecord r, 10630 boolean oomAdjusted) { 10631 final int N = r.pendingStarts.size(); 10632 if (N == 0) { 10633 return; 10634 } 10635 10636 while (r.pendingStarts.size() > 0) { 10637 try { 10638 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 10639 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 10640 + r + " " + r.intent + " args=" + si.intent); 10641 if (si.intent == null && N > 1) { 10642 // If somehow we got a dummy null intent in the middle, 10643 // then skip it. DO NOT skip a null intent when it is 10644 // the only one in the list -- this is to support the 10645 // onStartCommand(null) case. 10646 continue; 10647 } 10648 si.deliveredTime = SystemClock.uptimeMillis(); 10649 r.deliveredStarts.add(si); 10650 si.deliveryCount++; 10651 if (si.targetPermissionUid >= 0 && si.intent != null) { 10652 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid, 10653 r.packageName, si.intent, si.getUriPermissionsLocked()); 10654 } 10655 bumpServiceExecutingLocked(r, "start"); 10656 if (!oomAdjusted) { 10657 oomAdjusted = true; 10658 updateOomAdjLocked(r.app); 10659 } 10660 int flags = 0; 10661 if (si.deliveryCount > 0) { 10662 flags |= Service.START_FLAG_RETRY; 10663 } 10664 if (si.doneExecutingCount > 0) { 10665 flags |= Service.START_FLAG_REDELIVERY; 10666 } 10667 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 10668 } catch (RemoteException e) { 10669 // Remote process gone... we'll let the normal cleanup take 10670 // care of this. 10671 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 10672 break; 10673 } catch (Exception e) { 10674 Slog.w(TAG, "Unexpected exception", e); 10675 break; 10676 } 10677 } 10678 } 10679 10680 private final boolean requestServiceBindingLocked(ServiceRecord r, 10681 IntentBindRecord i, boolean rebind) { 10682 if (r.app == null || r.app.thread == null) { 10683 // If service is not currently running, can't yet bind. 10684 return false; 10685 } 10686 if ((!i.requested || rebind) && i.apps.size() > 0) { 10687 try { 10688 bumpServiceExecutingLocked(r, "bind"); 10689 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10690 if (!rebind) { 10691 i.requested = true; 10692 } 10693 i.hasBound = true; 10694 i.doRebind = false; 10695 } catch (RemoteException e) { 10696 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 10697 return false; 10698 } 10699 } 10700 return true; 10701 } 10702 10703 private final void requestServiceBindingsLocked(ServiceRecord r) { 10704 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10705 while (bindings.hasNext()) { 10706 IntentBindRecord i = bindings.next(); 10707 if (!requestServiceBindingLocked(r, i, false)) { 10708 break; 10709 } 10710 } 10711 } 10712 10713 private final void realStartServiceLocked(ServiceRecord r, 10714 ProcessRecord app) throws RemoteException { 10715 if (app.thread == null) { 10716 throw new RemoteException(); 10717 } 10718 10719 r.app = app; 10720 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10721 10722 app.services.add(r); 10723 bumpServiceExecutingLocked(r, "create"); 10724 updateLruProcessLocked(app, true, true); 10725 10726 boolean created = false; 10727 try { 10728 mStringBuilder.setLength(0); 10729 r.intent.getIntent().toShortString(mStringBuilder, true, false, true); 10730 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 10731 System.identityHashCode(r), r.shortName, 10732 mStringBuilder.toString(), r.app.pid); 10733 synchronized (r.stats.getBatteryStats()) { 10734 r.stats.startLaunchedLocked(); 10735 } 10736 ensurePackageDexOpt(r.serviceInfo.packageName); 10737 app.thread.scheduleCreateService(r, r.serviceInfo, 10738 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 10739 r.postNotification(); 10740 created = true; 10741 } finally { 10742 if (!created) { 10743 app.services.remove(r); 10744 scheduleServiceRestartLocked(r, false); 10745 } 10746 } 10747 10748 requestServiceBindingsLocked(r); 10749 10750 // If the service is in the started state, and there are no 10751 // pending arguments, then fake up one so its onStartCommand() will 10752 // be called. 10753 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10754 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 10755 null, -1)); 10756 } 10757 10758 sendServiceArgsLocked(r, true); 10759 } 10760 10761 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10762 boolean allowCancel) { 10763 boolean canceled = false; 10764 10765 final long now = SystemClock.uptimeMillis(); 10766 long minDuration = SERVICE_RESTART_DURATION; 10767 long resetTime = SERVICE_RESET_RUN_DURATION; 10768 10769 if ((r.serviceInfo.applicationInfo.flags 10770 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 10771 minDuration /= 4; 10772 } 10773 10774 // Any delivered but not yet finished starts should be put back 10775 // on the pending list. 10776 final int N = r.deliveredStarts.size(); 10777 if (N > 0) { 10778 for (int i=N-1; i>=0; i--) { 10779 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10780 si.removeUriPermissionsLocked(); 10781 if (si.intent == null) { 10782 // We'll generate this again if needed. 10783 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10784 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10785 r.pendingStarts.add(0, si); 10786 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10787 dur *= 2; 10788 if (minDuration < dur) minDuration = dur; 10789 if (resetTime < dur) resetTime = dur; 10790 } else { 10791 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 10792 + r.name); 10793 canceled = true; 10794 } 10795 } 10796 r.deliveredStarts.clear(); 10797 } 10798 10799 r.totalRestartCount++; 10800 if (r.restartDelay == 0) { 10801 r.restartCount++; 10802 r.restartDelay = minDuration; 10803 } else { 10804 // If it has been a "reasonably long time" since the service 10805 // was started, then reset our restart duration back to 10806 // the beginning, so we don't infinitely increase the duration 10807 // on a service that just occasionally gets killed (which is 10808 // a normal case, due to process being killed to reclaim memory). 10809 if (now > (r.restartTime+resetTime)) { 10810 r.restartCount = 1; 10811 r.restartDelay = minDuration; 10812 } else { 10813 if ((r.serviceInfo.applicationInfo.flags 10814 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 10815 // Services in peristent processes will restart much more 10816 // quickly, since they are pretty important. (Think SystemUI). 10817 r.restartDelay += minDuration/2; 10818 } else { 10819 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10820 if (r.restartDelay < minDuration) { 10821 r.restartDelay = minDuration; 10822 } 10823 } 10824 } 10825 } 10826 10827 r.nextRestartTime = now + r.restartDelay; 10828 10829 // Make sure that we don't end up restarting a bunch of services 10830 // all at the same time. 10831 boolean repeat; 10832 do { 10833 repeat = false; 10834 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10835 ServiceRecord r2 = mRestartingServices.get(i); 10836 if (r2 != r && r.nextRestartTime 10837 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10838 && r.nextRestartTime 10839 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10840 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10841 r.restartDelay = r.nextRestartTime - now; 10842 repeat = true; 10843 break; 10844 } 10845 } 10846 } while (repeat); 10847 10848 if (!mRestartingServices.contains(r)) { 10849 mRestartingServices.add(r); 10850 } 10851 10852 r.cancelNotification(); 10853 10854 mHandler.removeCallbacks(r.restarter); 10855 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10856 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10857 Slog.w(TAG, "Scheduling restart of crashed service " 10858 + r.shortName + " in " + r.restartDelay + "ms"); 10859 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 10860 r.shortName, r.restartDelay); 10861 10862 return canceled; 10863 } 10864 10865 final void performServiceRestartLocked(ServiceRecord r) { 10866 if (!mRestartingServices.contains(r)) { 10867 return; 10868 } 10869 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10870 } 10871 10872 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10873 if (r.restartDelay == 0) { 10874 return false; 10875 } 10876 r.resetRestartCounter(); 10877 mRestartingServices.remove(r); 10878 mHandler.removeCallbacks(r.restarter); 10879 return true; 10880 } 10881 10882 private final boolean bringUpServiceLocked(ServiceRecord r, 10883 int intentFlags, boolean whileRestarting) { 10884 //Slog.i(TAG, "Bring up service:"); 10885 //r.dump(" "); 10886 10887 if (r.app != null && r.app.thread != null) { 10888 sendServiceArgsLocked(r, false); 10889 return true; 10890 } 10891 10892 if (!whileRestarting && r.restartDelay > 0) { 10893 // If waiting for a restart, then do nothing. 10894 return true; 10895 } 10896 10897 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 10898 10899 // We are now bringing the service up, so no longer in the 10900 // restarting state. 10901 mRestartingServices.remove(r); 10902 10903 // Service is now being launched, its package can't be stopped. 10904 try { 10905 AppGlobals.getPackageManager().setPackageStoppedState( 10906 r.packageName, false); 10907 } catch (RemoteException e) { 10908 } catch (IllegalArgumentException e) { 10909 Slog.w(TAG, "Failed trying to unstop package " 10910 + r.packageName + ": " + e); 10911 } 10912 10913 final String appName = r.processName; 10914 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10915 if (app != null && app.thread != null) { 10916 try { 10917 app.addPackage(r.appInfo.packageName); 10918 realStartServiceLocked(r, app); 10919 return true; 10920 } catch (RemoteException e) { 10921 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 10922 } 10923 10924 // If a dead object exception was thrown -- fall through to 10925 // restart the application. 10926 } 10927 10928 // Not running -- get it started, and enqueue this service record 10929 // to be executed when the app comes up. 10930 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10931 "service", r.name, false) == null) { 10932 Slog.w(TAG, "Unable to launch app " 10933 + r.appInfo.packageName + "/" 10934 + r.appInfo.uid + " for service " 10935 + r.intent.getIntent() + ": process is bad"); 10936 bringDownServiceLocked(r, true); 10937 return false; 10938 } 10939 10940 if (!mPendingServices.contains(r)) { 10941 mPendingServices.add(r); 10942 } 10943 10944 return true; 10945 } 10946 10947 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10948 //Slog.i(TAG, "Bring down service:"); 10949 //r.dump(" "); 10950 10951 // Does it still need to run? 10952 if (!force && r.startRequested) { 10953 return; 10954 } 10955 if (r.connections.size() > 0) { 10956 if (!force) { 10957 // XXX should probably keep a count of the number of auto-create 10958 // connections directly in the service. 10959 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 10960 while (it.hasNext()) { 10961 ArrayList<ConnectionRecord> cr = it.next(); 10962 for (int i=0; i<cr.size(); i++) { 10963 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 10964 return; 10965 } 10966 } 10967 } 10968 } 10969 10970 // Report to all of the connections that the service is no longer 10971 // available. 10972 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 10973 while (it.hasNext()) { 10974 ArrayList<ConnectionRecord> c = it.next(); 10975 for (int i=0; i<c.size(); i++) { 10976 ConnectionRecord cr = c.get(i); 10977 // There is still a connection to the service that is 10978 // being brought down. Mark it as dead. 10979 cr.serviceDead = true; 10980 try { 10981 cr.conn.connected(r.name, null); 10982 } catch (Exception e) { 10983 Slog.w(TAG, "Failure disconnecting service " + r.name + 10984 " to connection " + c.get(i).conn.asBinder() + 10985 " (in " + c.get(i).binding.client.processName + ")", e); 10986 } 10987 } 10988 } 10989 } 10990 10991 // Tell the service that it has been unbound. 10992 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10993 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10994 while (it.hasNext()) { 10995 IntentBindRecord ibr = it.next(); 10996 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 10997 + ": hasBound=" + ibr.hasBound); 10998 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10999 try { 11000 bumpServiceExecutingLocked(r, "bring down unbind"); 11001 updateOomAdjLocked(r.app); 11002 ibr.hasBound = false; 11003 r.app.thread.scheduleUnbindService(r, 11004 ibr.intent.getIntent()); 11005 } catch (Exception e) { 11006 Slog.w(TAG, "Exception when unbinding service " 11007 + r.shortName, e); 11008 serviceDoneExecutingLocked(r, true); 11009 } 11010 } 11011 } 11012 } 11013 11014 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 11015 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 11016 System.identityHashCode(r), r.shortName, 11017 (r.app != null) ? r.app.pid : -1); 11018 11019 mServices.remove(r.name); 11020 mServicesByIntent.remove(r.intent); 11021 r.totalRestartCount = 0; 11022 unscheduleServiceRestartLocked(r); 11023 11024 // Also make sure it is not on the pending list. 11025 int N = mPendingServices.size(); 11026 for (int i=0; i<N; i++) { 11027 if (mPendingServices.get(i) == r) { 11028 mPendingServices.remove(i); 11029 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 11030 i--; 11031 N--; 11032 } 11033 } 11034 11035 r.cancelNotification(); 11036 r.isForeground = false; 11037 r.foregroundId = 0; 11038 r.foregroundNoti = null; 11039 11040 // Clear start entries. 11041 r.clearDeliveredStartsLocked(); 11042 r.pendingStarts.clear(); 11043 11044 if (r.app != null) { 11045 synchronized (r.stats.getBatteryStats()) { 11046 r.stats.stopLaunchedLocked(); 11047 } 11048 r.app.services.remove(r); 11049 if (r.app.thread != null) { 11050 try { 11051 bumpServiceExecutingLocked(r, "stop"); 11052 mStoppingServices.add(r); 11053 updateOomAdjLocked(r.app); 11054 r.app.thread.scheduleStopService(r); 11055 } catch (Exception e) { 11056 Slog.w(TAG, "Exception when stopping service " 11057 + r.shortName, e); 11058 serviceDoneExecutingLocked(r, true); 11059 } 11060 updateServiceForegroundLocked(r.app, false); 11061 } else { 11062 if (DEBUG_SERVICE) Slog.v( 11063 TAG, "Removed service that has no process: " + r); 11064 } 11065 } else { 11066 if (DEBUG_SERVICE) Slog.v( 11067 TAG, "Removed service that is not running: " + r); 11068 } 11069 11070 if (r.bindings.size() > 0) { 11071 r.bindings.clear(); 11072 } 11073 11074 if (r.restarter instanceof ServiceRestarter) { 11075 ((ServiceRestarter)r.restarter).setService(null); 11076 } 11077 } 11078 11079 ComponentName startServiceLocked(IApplicationThread caller, 11080 Intent service, String resolvedType, 11081 int callingPid, int callingUid) { 11082 synchronized(this) { 11083 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11084 + " type=" + resolvedType + " args=" + service.getExtras()); 11085 11086 if (caller != null) { 11087 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11088 if (callerApp == null) { 11089 throw new SecurityException( 11090 "Unable to find app for caller " + caller 11091 + " (pid=" + Binder.getCallingPid() 11092 + ") when starting service " + service); 11093 } 11094 } 11095 11096 ServiceLookupResult res = 11097 retrieveServiceLocked(service, resolvedType, 11098 callingPid, callingUid); 11099 if (res == null) { 11100 return null; 11101 } 11102 if (res.record == null) { 11103 return new ComponentName("!", res.permission != null 11104 ? res.permission : "private to package"); 11105 } 11106 ServiceRecord r = res.record; 11107 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked( 11108 callingUid, r.packageName, service); 11109 if (unscheduleServiceRestartLocked(r)) { 11110 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 11111 } 11112 r.startRequested = true; 11113 r.callStart = false; 11114 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11115 service, targetPermissionUid)); 11116 r.lastActivity = SystemClock.uptimeMillis(); 11117 synchronized (r.stats.getBatteryStats()) { 11118 r.stats.startRunningLocked(); 11119 } 11120 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11121 return new ComponentName("!", "Service process is bad"); 11122 } 11123 return r.name; 11124 } 11125 } 11126 11127 public ComponentName startService(IApplicationThread caller, Intent service, 11128 String resolvedType) { 11129 // Refuse possible leaked file descriptors 11130 if (service != null && service.hasFileDescriptors() == true) { 11131 throw new IllegalArgumentException("File descriptors passed in Intent"); 11132 } 11133 11134 synchronized(this) { 11135 final int callingPid = Binder.getCallingPid(); 11136 final int callingUid = Binder.getCallingUid(); 11137 final long origId = Binder.clearCallingIdentity(); 11138 ComponentName res = startServiceLocked(caller, service, 11139 resolvedType, callingPid, callingUid); 11140 Binder.restoreCallingIdentity(origId); 11141 return res; 11142 } 11143 } 11144 11145 ComponentName startServiceInPackage(int uid, 11146 Intent service, String resolvedType) { 11147 synchronized(this) { 11148 final long origId = Binder.clearCallingIdentity(); 11149 ComponentName res = startServiceLocked(null, service, 11150 resolvedType, -1, uid); 11151 Binder.restoreCallingIdentity(origId); 11152 return res; 11153 } 11154 } 11155 11156 private void stopServiceLocked(ServiceRecord service) { 11157 synchronized (service.stats.getBatteryStats()) { 11158 service.stats.stopRunningLocked(); 11159 } 11160 service.startRequested = false; 11161 service.callStart = false; 11162 bringDownServiceLocked(service, false); 11163 } 11164 11165 public int stopService(IApplicationThread caller, Intent service, 11166 String resolvedType) { 11167 // Refuse possible leaked file descriptors 11168 if (service != null && service.hasFileDescriptors() == true) { 11169 throw new IllegalArgumentException("File descriptors passed in Intent"); 11170 } 11171 11172 synchronized(this) { 11173 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11174 + " type=" + resolvedType); 11175 11176 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11177 if (caller != null && callerApp == null) { 11178 throw new SecurityException( 11179 "Unable to find app for caller " + caller 11180 + " (pid=" + Binder.getCallingPid() 11181 + ") when stopping service " + service); 11182 } 11183 11184 // If this service is active, make sure it is stopped. 11185 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11186 if (r != null) { 11187 if (r.record != null) { 11188 final long origId = Binder.clearCallingIdentity(); 11189 try { 11190 stopServiceLocked(r.record); 11191 } finally { 11192 Binder.restoreCallingIdentity(origId); 11193 } 11194 return 1; 11195 } 11196 return -1; 11197 } 11198 } 11199 11200 return 0; 11201 } 11202 11203 public IBinder peekService(Intent service, String resolvedType) { 11204 // Refuse possible leaked file descriptors 11205 if (service != null && service.hasFileDescriptors() == true) { 11206 throw new IllegalArgumentException("File descriptors passed in Intent"); 11207 } 11208 11209 IBinder ret = null; 11210 11211 synchronized(this) { 11212 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11213 11214 if (r != null) { 11215 // r.record is null if findServiceLocked() failed the caller permission check 11216 if (r.record == null) { 11217 throw new SecurityException( 11218 "Permission Denial: Accessing service " + r.record.name 11219 + " from pid=" + Binder.getCallingPid() 11220 + ", uid=" + Binder.getCallingUid() 11221 + " requires " + r.permission); 11222 } 11223 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11224 if (ib != null) { 11225 ret = ib.binder; 11226 } 11227 } 11228 } 11229 11230 return ret; 11231 } 11232 11233 public boolean stopServiceToken(ComponentName className, IBinder token, 11234 int startId) { 11235 synchronized(this) { 11236 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11237 + " " + token + " startId=" + startId); 11238 ServiceRecord r = findServiceLocked(className, token); 11239 if (r != null) { 11240 if (startId >= 0) { 11241 // Asked to only stop if done with all work. Note that 11242 // to avoid leaks, we will take this as dropping all 11243 // start items up to and including this one. 11244 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11245 if (si != null) { 11246 while (r.deliveredStarts.size() > 0) { 11247 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 11248 cur.removeUriPermissionsLocked(); 11249 if (cur == si) { 11250 break; 11251 } 11252 } 11253 } 11254 11255 if (r.getLastStartId() != startId) { 11256 return false; 11257 } 11258 11259 if (r.deliveredStarts.size() > 0) { 11260 Slog.w(TAG, "stopServiceToken startId " + startId 11261 + " is last, but have " + r.deliveredStarts.size() 11262 + " remaining args"); 11263 } 11264 } 11265 11266 synchronized (r.stats.getBatteryStats()) { 11267 r.stats.stopRunningLocked(); 11268 r.startRequested = false; 11269 r.callStart = false; 11270 } 11271 final long origId = Binder.clearCallingIdentity(); 11272 bringDownServiceLocked(r, false); 11273 Binder.restoreCallingIdentity(origId); 11274 return true; 11275 } 11276 } 11277 return false; 11278 } 11279 11280 public void setServiceForeground(ComponentName className, IBinder token, 11281 int id, Notification notification, boolean removeNotification) { 11282 final long origId = Binder.clearCallingIdentity(); 11283 try { 11284 synchronized(this) { 11285 ServiceRecord r = findServiceLocked(className, token); 11286 if (r != null) { 11287 if (id != 0) { 11288 if (notification == null) { 11289 throw new IllegalArgumentException("null notification"); 11290 } 11291 if (r.foregroundId != id) { 11292 r.cancelNotification(); 11293 r.foregroundId = id; 11294 } 11295 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11296 r.foregroundNoti = notification; 11297 r.isForeground = true; 11298 r.postNotification(); 11299 if (r.app != null) { 11300 updateServiceForegroundLocked(r.app, true); 11301 } 11302 } else { 11303 if (r.isForeground) { 11304 r.isForeground = false; 11305 if (r.app != null) { 11306 updateLruProcessLocked(r.app, false, true); 11307 updateServiceForegroundLocked(r.app, true); 11308 } 11309 } 11310 if (removeNotification) { 11311 r.cancelNotification(); 11312 r.foregroundId = 0; 11313 r.foregroundNoti = null; 11314 } 11315 } 11316 } 11317 } 11318 } finally { 11319 Binder.restoreCallingIdentity(origId); 11320 } 11321 } 11322 11323 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11324 boolean anyForeground = false; 11325 for (ServiceRecord sr : proc.services) { 11326 if (sr.isForeground) { 11327 anyForeground = true; 11328 break; 11329 } 11330 } 11331 if (anyForeground != proc.foregroundServices) { 11332 proc.foregroundServices = anyForeground; 11333 if (oomAdj) { 11334 updateOomAdjLocked(); 11335 } 11336 } 11337 } 11338 11339 public int bindService(IApplicationThread caller, IBinder token, 11340 Intent service, String resolvedType, 11341 IServiceConnection connection, int flags) { 11342 // Refuse possible leaked file descriptors 11343 if (service != null && service.hasFileDescriptors() == true) { 11344 throw new IllegalArgumentException("File descriptors passed in Intent"); 11345 } 11346 11347 synchronized(this) { 11348 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 11349 + " type=" + resolvedType + " conn=" + connection.asBinder() 11350 + " flags=0x" + Integer.toHexString(flags)); 11351 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11352 if (callerApp == null) { 11353 throw new SecurityException( 11354 "Unable to find app for caller " + caller 11355 + " (pid=" + Binder.getCallingPid() 11356 + ") when binding service " + service); 11357 } 11358 11359 ActivityRecord activity = null; 11360 if (token != null) { 11361 activity = mMainStack.isInStackLocked(token); 11362 if (activity == null) { 11363 Slog.w(TAG, "Binding with unknown activity: " + token); 11364 return 0; 11365 } 11366 } 11367 11368 int clientLabel = 0; 11369 PendingIntent clientIntent = null; 11370 11371 if (callerApp.info.uid == Process.SYSTEM_UID) { 11372 // Hacky kind of thing -- allow system stuff to tell us 11373 // what they are, so we can report this elsewhere for 11374 // others to know why certain services are running. 11375 try { 11376 clientIntent = (PendingIntent)service.getParcelableExtra( 11377 Intent.EXTRA_CLIENT_INTENT); 11378 } catch (RuntimeException e) { 11379 } 11380 if (clientIntent != null) { 11381 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11382 if (clientLabel != 0) { 11383 // There are no useful extras in the intent, trash them. 11384 // System code calling with this stuff just needs to know 11385 // this will happen. 11386 service = service.cloneFilter(); 11387 } 11388 } 11389 } 11390 11391 ServiceLookupResult res = 11392 retrieveServiceLocked(service, resolvedType, 11393 Binder.getCallingPid(), Binder.getCallingUid()); 11394 if (res == null) { 11395 return 0; 11396 } 11397 if (res.record == null) { 11398 return -1; 11399 } 11400 ServiceRecord s = res.record; 11401 11402 final long origId = Binder.clearCallingIdentity(); 11403 11404 if (unscheduleServiceRestartLocked(s)) { 11405 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11406 + s); 11407 } 11408 11409 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11410 ConnectionRecord c = new ConnectionRecord(b, activity, 11411 connection, flags, clientLabel, clientIntent); 11412 11413 IBinder binder = connection.asBinder(); 11414 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 11415 if (clist == null) { 11416 clist = new ArrayList<ConnectionRecord>(); 11417 s.connections.put(binder, clist); 11418 } 11419 clist.add(c); 11420 b.connections.add(c); 11421 if (activity != null) { 11422 if (activity.connections == null) { 11423 activity.connections = new HashSet<ConnectionRecord>(); 11424 } 11425 activity.connections.add(c); 11426 } 11427 b.client.connections.add(c); 11428 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 11429 b.client.hasAboveClient = true; 11430 } 11431 clist = mServiceConnections.get(binder); 11432 if (clist == null) { 11433 clist = new ArrayList<ConnectionRecord>(); 11434 mServiceConnections.put(binder, clist); 11435 } 11436 clist.add(c); 11437 11438 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11439 s.lastActivity = SystemClock.uptimeMillis(); 11440 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11441 return 0; 11442 } 11443 } 11444 11445 if (s.app != null) { 11446 // This could have made the service more important. 11447 updateOomAdjLocked(s.app); 11448 } 11449 11450 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 11451 + ": received=" + b.intent.received 11452 + " apps=" + b.intent.apps.size() 11453 + " doRebind=" + b.intent.doRebind); 11454 11455 if (s.app != null && b.intent.received) { 11456 // Service is already running, so we can immediately 11457 // publish the connection. 11458 try { 11459 c.conn.connected(s.name, b.intent.binder); 11460 } catch (Exception e) { 11461 Slog.w(TAG, "Failure sending service " + s.shortName 11462 + " to connection " + c.conn.asBinder() 11463 + " (in " + c.binding.client.processName + ")", e); 11464 } 11465 11466 // If this is the first app connected back to this binding, 11467 // and the service had previously asked to be told when 11468 // rebound, then do so. 11469 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11470 requestServiceBindingLocked(s, b.intent, true); 11471 } 11472 } else if (!b.intent.requested) { 11473 requestServiceBindingLocked(s, b.intent, false); 11474 } 11475 11476 Binder.restoreCallingIdentity(origId); 11477 } 11478 11479 return 1; 11480 } 11481 11482 void removeConnectionLocked( 11483 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 11484 IBinder binder = c.conn.asBinder(); 11485 AppBindRecord b = c.binding; 11486 ServiceRecord s = b.service; 11487 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 11488 if (clist != null) { 11489 clist.remove(c); 11490 if (clist.size() == 0) { 11491 s.connections.remove(binder); 11492 } 11493 } 11494 b.connections.remove(c); 11495 if (c.activity != null && c.activity != skipAct) { 11496 if (c.activity.connections != null) { 11497 c.activity.connections.remove(c); 11498 } 11499 } 11500 if (b.client != skipApp) { 11501 b.client.connections.remove(c); 11502 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 11503 b.client.updateHasAboveClientLocked(); 11504 } 11505 } 11506 clist = mServiceConnections.get(binder); 11507 if (clist != null) { 11508 clist.remove(c); 11509 if (clist.size() == 0) { 11510 mServiceConnections.remove(binder); 11511 } 11512 } 11513 11514 if (b.connections.size() == 0) { 11515 b.intent.apps.remove(b.client); 11516 } 11517 11518 if (!c.serviceDead) { 11519 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 11520 + ": shouldUnbind=" + b.intent.hasBound); 11521 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11522 && b.intent.hasBound) { 11523 try { 11524 bumpServiceExecutingLocked(s, "unbind"); 11525 updateOomAdjLocked(s.app); 11526 b.intent.hasBound = false; 11527 // Assume the client doesn't want to know about a rebind; 11528 // we will deal with that later if it asks for one. 11529 b.intent.doRebind = false; 11530 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11531 } catch (Exception e) { 11532 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 11533 serviceDoneExecutingLocked(s, true); 11534 } 11535 } 11536 11537 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11538 bringDownServiceLocked(s, false); 11539 } 11540 } 11541 } 11542 11543 public boolean unbindService(IServiceConnection connection) { 11544 synchronized (this) { 11545 IBinder binder = connection.asBinder(); 11546 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 11547 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 11548 if (clist == null) { 11549 Slog.w(TAG, "Unbind failed: could not find connection for " 11550 + connection.asBinder()); 11551 return false; 11552 } 11553 11554 final long origId = Binder.clearCallingIdentity(); 11555 11556 while (clist.size() > 0) { 11557 ConnectionRecord r = clist.get(0); 11558 removeConnectionLocked(r, null, null); 11559 11560 if (r.binding.service.app != null) { 11561 // This could have made the service less important. 11562 updateOomAdjLocked(r.binding.service.app); 11563 } 11564 } 11565 11566 Binder.restoreCallingIdentity(origId); 11567 } 11568 11569 return true; 11570 } 11571 11572 public void publishService(IBinder token, Intent intent, IBinder service) { 11573 // Refuse possible leaked file descriptors 11574 if (intent != null && intent.hasFileDescriptors() == true) { 11575 throw new IllegalArgumentException("File descriptors passed in Intent"); 11576 } 11577 11578 synchronized(this) { 11579 if (!(token instanceof ServiceRecord)) { 11580 throw new IllegalArgumentException("Invalid service token"); 11581 } 11582 ServiceRecord r = (ServiceRecord)token; 11583 11584 final long origId = Binder.clearCallingIdentity(); 11585 11586 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 11587 + " " + intent + ": " + service); 11588 if (r != null) { 11589 Intent.FilterComparison filter 11590 = new Intent.FilterComparison(intent); 11591 IntentBindRecord b = r.bindings.get(filter); 11592 if (b != null && !b.received) { 11593 b.binder = service; 11594 b.requested = true; 11595 b.received = true; 11596 if (r.connections.size() > 0) { 11597 Iterator<ArrayList<ConnectionRecord>> it 11598 = r.connections.values().iterator(); 11599 while (it.hasNext()) { 11600 ArrayList<ConnectionRecord> clist = it.next(); 11601 for (int i=0; i<clist.size(); i++) { 11602 ConnectionRecord c = clist.get(i); 11603 if (!filter.equals(c.binding.intent.intent)) { 11604 if (DEBUG_SERVICE) Slog.v( 11605 TAG, "Not publishing to: " + c); 11606 if (DEBUG_SERVICE) Slog.v( 11607 TAG, "Bound intent: " + c.binding.intent.intent); 11608 if (DEBUG_SERVICE) Slog.v( 11609 TAG, "Published intent: " + intent); 11610 continue; 11611 } 11612 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 11613 try { 11614 c.conn.connected(r.name, service); 11615 } catch (Exception e) { 11616 Slog.w(TAG, "Failure sending service " + r.name + 11617 " to connection " + c.conn.asBinder() + 11618 " (in " + c.binding.client.processName + ")", e); 11619 } 11620 } 11621 } 11622 } 11623 } 11624 11625 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11626 11627 Binder.restoreCallingIdentity(origId); 11628 } 11629 } 11630 } 11631 11632 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11633 // Refuse possible leaked file descriptors 11634 if (intent != null && intent.hasFileDescriptors() == true) { 11635 throw new IllegalArgumentException("File descriptors passed in Intent"); 11636 } 11637 11638 synchronized(this) { 11639 if (!(token instanceof ServiceRecord)) { 11640 throw new IllegalArgumentException("Invalid service token"); 11641 } 11642 ServiceRecord r = (ServiceRecord)token; 11643 11644 final long origId = Binder.clearCallingIdentity(); 11645 11646 if (r != null) { 11647 Intent.FilterComparison filter 11648 = new Intent.FilterComparison(intent); 11649 IntentBindRecord b = r.bindings.get(filter); 11650 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 11651 + " at " + b + ": apps=" 11652 + (b != null ? b.apps.size() : 0)); 11653 11654 boolean inStopping = mStoppingServices.contains(r); 11655 if (b != null) { 11656 if (b.apps.size() > 0 && !inStopping) { 11657 // Applications have already bound since the last 11658 // unbind, so just rebind right here. 11659 requestServiceBindingLocked(r, b, true); 11660 } else { 11661 // Note to tell the service the next time there is 11662 // a new client. 11663 b.doRebind = true; 11664 } 11665 } 11666 11667 serviceDoneExecutingLocked(r, inStopping); 11668 11669 Binder.restoreCallingIdentity(origId); 11670 } 11671 } 11672 } 11673 11674 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11675 synchronized(this) { 11676 if (!(token instanceof ServiceRecord)) { 11677 throw new IllegalArgumentException("Invalid service token"); 11678 } 11679 ServiceRecord r = (ServiceRecord)token; 11680 boolean inStopping = mStoppingServices.contains(token); 11681 if (r != null) { 11682 if (r != token) { 11683 Slog.w(TAG, "Done executing service " + r.name 11684 + " with incorrect token: given " + token 11685 + ", expected " + r); 11686 return; 11687 } 11688 11689 if (type == 1) { 11690 // This is a call from a service start... take care of 11691 // book-keeping. 11692 r.callStart = true; 11693 switch (res) { 11694 case Service.START_STICKY_COMPATIBILITY: 11695 case Service.START_STICKY: { 11696 // We are done with the associated start arguments. 11697 r.findDeliveredStart(startId, true); 11698 // Don't stop if killed. 11699 r.stopIfKilled = false; 11700 break; 11701 } 11702 case Service.START_NOT_STICKY: { 11703 // We are done with the associated start arguments. 11704 r.findDeliveredStart(startId, true); 11705 if (r.getLastStartId() == startId) { 11706 // There is no more work, and this service 11707 // doesn't want to hang around if killed. 11708 r.stopIfKilled = true; 11709 } 11710 break; 11711 } 11712 case Service.START_REDELIVER_INTENT: { 11713 // We'll keep this item until they explicitly 11714 // call stop for it, but keep track of the fact 11715 // that it was delivered. 11716 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11717 if (si != null) { 11718 si.deliveryCount = 0; 11719 si.doneExecutingCount++; 11720 // Don't stop if killed. 11721 r.stopIfKilled = true; 11722 } 11723 break; 11724 } 11725 case Service.START_TASK_REMOVED_COMPLETE: { 11726 // Special processing for onTaskRemoved(). Don't 11727 // impact normal onStartCommand() processing. 11728 r.findDeliveredStart(startId, true); 11729 break; 11730 } 11731 default: 11732 throw new IllegalArgumentException( 11733 "Unknown service start result: " + res); 11734 } 11735 if (res == Service.START_STICKY_COMPATIBILITY) { 11736 r.callStart = false; 11737 } 11738 } 11739 11740 final long origId = Binder.clearCallingIdentity(); 11741 serviceDoneExecutingLocked(r, inStopping); 11742 Binder.restoreCallingIdentity(origId); 11743 } else { 11744 Slog.w(TAG, "Done executing unknown service from pid " 11745 + Binder.getCallingPid()); 11746 } 11747 } 11748 } 11749 11750 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11751 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 11752 + ": nesting=" + r.executeNesting 11753 + ", inStopping=" + inStopping + ", app=" + r.app); 11754 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 11755 r.executeNesting--; 11756 if (r.executeNesting <= 0 && r.app != null) { 11757 if (DEBUG_SERVICE) Slog.v(TAG, 11758 "Nesting at 0 of " + r.shortName); 11759 r.app.executingServices.remove(r); 11760 if (r.app.executingServices.size() == 0) { 11761 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 11762 "No more executingServices of " + r.shortName); 11763 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11764 } 11765 if (inStopping) { 11766 if (DEBUG_SERVICE) Slog.v(TAG, 11767 "doneExecuting remove stopping " + r); 11768 mStoppingServices.remove(r); 11769 r.bindings.clear(); 11770 } 11771 updateOomAdjLocked(r.app); 11772 } 11773 } 11774 11775 void serviceTimeout(ProcessRecord proc) { 11776 String anrMessage = null; 11777 11778 synchronized(this) { 11779 if (proc.executingServices.size() == 0 || proc.thread == null) { 11780 return; 11781 } 11782 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11783 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11784 ServiceRecord timeout = null; 11785 long nextTime = 0; 11786 while (it.hasNext()) { 11787 ServiceRecord sr = it.next(); 11788 if (sr.executingStart < maxTime) { 11789 timeout = sr; 11790 break; 11791 } 11792 if (sr.executingStart > nextTime) { 11793 nextTime = sr.executingStart; 11794 } 11795 } 11796 if (timeout != null && mLruProcesses.contains(proc)) { 11797 Slog.w(TAG, "Timeout executing service: " + timeout); 11798 anrMessage = "Executing service " + timeout.shortName; 11799 } else { 11800 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11801 msg.obj = proc; 11802 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11803 } 11804 } 11805 11806 if (anrMessage != null) { 11807 appNotResponding(proc, null, null, anrMessage); 11808 } 11809 } 11810 11811 // ========================================================= 11812 // BACKUP AND RESTORE 11813 // ========================================================= 11814 11815 // Cause the target app to be launched if necessary and its backup agent 11816 // instantiated. The backup agent will invoke backupAgentCreated() on the 11817 // activity manager to announce its creation. 11818 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11819 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11820 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11821 11822 synchronized(this) { 11823 // !!! TODO: currently no check here that we're already bound 11824 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11825 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11826 synchronized (stats) { 11827 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11828 } 11829 11830 // Backup agent is now in use, its package can't be stopped. 11831 try { 11832 AppGlobals.getPackageManager().setPackageStoppedState( 11833 app.packageName, false); 11834 } catch (RemoteException e) { 11835 } catch (IllegalArgumentException e) { 11836 Slog.w(TAG, "Failed trying to unstop package " 11837 + app.packageName + ": " + e); 11838 } 11839 11840 BackupRecord r = new BackupRecord(ss, app, backupMode); 11841 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11842 ? new ComponentName(app.packageName, app.backupAgentName) 11843 : new ComponentName("android", "FullBackupAgent"); 11844 // startProcessLocked() returns existing proc's record if it's already running 11845 ProcessRecord proc = startProcessLocked(app.processName, app, 11846 false, 0, "backup", hostingName, false); 11847 if (proc == null) { 11848 Slog.e(TAG, "Unable to start backup agent process " + r); 11849 return false; 11850 } 11851 11852 r.app = proc; 11853 mBackupTarget = r; 11854 mBackupAppName = app.packageName; 11855 11856 // Try not to kill the process during backup 11857 updateOomAdjLocked(proc); 11858 11859 // If the process is already attached, schedule the creation of the backup agent now. 11860 // If it is not yet live, this will be done when it attaches to the framework. 11861 if (proc.thread != null) { 11862 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11863 try { 11864 proc.thread.scheduleCreateBackupAgent(app, 11865 compatibilityInfoForPackageLocked(app), backupMode); 11866 } catch (RemoteException e) { 11867 // Will time out on the backup manager side 11868 } 11869 } else { 11870 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11871 } 11872 // Invariants: at this point, the target app process exists and the application 11873 // is either already running or in the process of coming up. mBackupTarget and 11874 // mBackupAppName describe the app, so that when it binds back to the AM we 11875 // know that it's scheduled for a backup-agent operation. 11876 } 11877 11878 return true; 11879 } 11880 11881 // A backup agent has just come up 11882 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11883 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11884 + " = " + agent); 11885 11886 synchronized(this) { 11887 if (!agentPackageName.equals(mBackupAppName)) { 11888 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11889 return; 11890 } 11891 } 11892 11893 long oldIdent = Binder.clearCallingIdentity(); 11894 try { 11895 IBackupManager bm = IBackupManager.Stub.asInterface( 11896 ServiceManager.getService(Context.BACKUP_SERVICE)); 11897 bm.agentConnected(agentPackageName, agent); 11898 } catch (RemoteException e) { 11899 // can't happen; the backup manager service is local 11900 } catch (Exception e) { 11901 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11902 e.printStackTrace(); 11903 } finally { 11904 Binder.restoreCallingIdentity(oldIdent); 11905 } 11906 } 11907 11908 // done with this agent 11909 public void unbindBackupAgent(ApplicationInfo appInfo) { 11910 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11911 if (appInfo == null) { 11912 Slog.w(TAG, "unbind backup agent for null app"); 11913 return; 11914 } 11915 11916 synchronized(this) { 11917 if (mBackupAppName == null) { 11918 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11919 return; 11920 } 11921 11922 if (!mBackupAppName.equals(appInfo.packageName)) { 11923 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11924 return; 11925 } 11926 11927 ProcessRecord proc = mBackupTarget.app; 11928 mBackupTarget = null; 11929 mBackupAppName = null; 11930 11931 // Not backing this app up any more; reset its OOM adjustment 11932 updateOomAdjLocked(proc); 11933 11934 // If the app crashed during backup, 'thread' will be null here 11935 if (proc.thread != null) { 11936 try { 11937 proc.thread.scheduleDestroyBackupAgent(appInfo, 11938 compatibilityInfoForPackageLocked(appInfo)); 11939 } catch (Exception e) { 11940 Slog.e(TAG, "Exception when unbinding backup agent:"); 11941 e.printStackTrace(); 11942 } 11943 } 11944 } 11945 } 11946 // ========================================================= 11947 // BROADCASTS 11948 // ========================================================= 11949 11950 private final List getStickiesLocked(String action, IntentFilter filter, 11951 List cur) { 11952 final ContentResolver resolver = mContext.getContentResolver(); 11953 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11954 if (list == null) { 11955 return cur; 11956 } 11957 int N = list.size(); 11958 for (int i=0; i<N; i++) { 11959 Intent intent = list.get(i); 11960 if (filter.match(resolver, intent, true, TAG) >= 0) { 11961 if (cur == null) { 11962 cur = new ArrayList<Intent>(); 11963 } 11964 cur.add(intent); 11965 } 11966 } 11967 return cur; 11968 } 11969 11970 private final void scheduleBroadcastsLocked() { 11971 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current=" 11972 + mBroadcastsScheduled); 11973 11974 if (mBroadcastsScheduled) { 11975 return; 11976 } 11977 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11978 mBroadcastsScheduled = true; 11979 } 11980 11981 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11982 IIntentReceiver receiver, IntentFilter filter, String permission) { 11983 synchronized(this) { 11984 ProcessRecord callerApp = null; 11985 if (caller != null) { 11986 callerApp = getRecordForAppLocked(caller); 11987 if (callerApp == null) { 11988 throw new SecurityException( 11989 "Unable to find app for caller " + caller 11990 + " (pid=" + Binder.getCallingPid() 11991 + ") when registering receiver " + receiver); 11992 } 11993 if (callerApp.info.uid != Process.SYSTEM_UID && 11994 !callerApp.pkgList.contains(callerPackage)) { 11995 throw new SecurityException("Given caller package " + callerPackage 11996 + " is not running in process " + callerApp); 11997 } 11998 } else { 11999 callerPackage = null; 12000 } 12001 12002 List allSticky = null; 12003 12004 // Look for any matching sticky broadcasts... 12005 Iterator actions = filter.actionsIterator(); 12006 if (actions != null) { 12007 while (actions.hasNext()) { 12008 String action = (String)actions.next(); 12009 allSticky = getStickiesLocked(action, filter, allSticky); 12010 } 12011 } else { 12012 allSticky = getStickiesLocked(null, filter, allSticky); 12013 } 12014 12015 // The first sticky in the list is returned directly back to 12016 // the client. 12017 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12018 12019 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12020 + ": " + sticky); 12021 12022 if (receiver == null) { 12023 return sticky; 12024 } 12025 12026 ReceiverList rl 12027 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12028 if (rl == null) { 12029 rl = new ReceiverList(this, callerApp, 12030 Binder.getCallingPid(), 12031 Binder.getCallingUid(), receiver); 12032 if (rl.app != null) { 12033 rl.app.receivers.add(rl); 12034 } else { 12035 try { 12036 receiver.asBinder().linkToDeath(rl, 0); 12037 } catch (RemoteException e) { 12038 return sticky; 12039 } 12040 rl.linkedToDeath = true; 12041 } 12042 mRegisteredReceivers.put(receiver.asBinder(), rl); 12043 } 12044 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 12045 rl.add(bf); 12046 if (!bf.debugCheck()) { 12047 Slog.w(TAG, "==> For Dynamic broadast"); 12048 } 12049 mReceiverResolver.addFilter(bf); 12050 12051 // Enqueue broadcasts for all existing stickies that match 12052 // this filter. 12053 if (allSticky != null) { 12054 ArrayList receivers = new ArrayList(); 12055 receivers.add(bf); 12056 12057 int N = allSticky.size(); 12058 for (int i=0; i<N; i++) { 12059 Intent intent = (Intent)allSticky.get(i); 12060 BroadcastRecord r = new BroadcastRecord(intent, null, 12061 null, -1, -1, null, receivers, null, 0, null, null, 12062 false, true, true); 12063 if (mParallelBroadcasts.size() == 0) { 12064 scheduleBroadcastsLocked(); 12065 } 12066 mParallelBroadcasts.add(r); 12067 } 12068 } 12069 12070 return sticky; 12071 } 12072 } 12073 12074 public void unregisterReceiver(IIntentReceiver receiver) { 12075 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12076 12077 boolean doNext = false; 12078 12079 synchronized(this) { 12080 ReceiverList rl 12081 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12082 if (rl != null) { 12083 if (rl.curBroadcast != null) { 12084 BroadcastRecord r = rl.curBroadcast; 12085 doNext = finishReceiverLocked( 12086 receiver.asBinder(), r.resultCode, r.resultData, 12087 r.resultExtras, r.resultAbort, true); 12088 } 12089 12090 if (rl.app != null) { 12091 rl.app.receivers.remove(rl); 12092 } 12093 removeReceiverLocked(rl); 12094 if (rl.linkedToDeath) { 12095 rl.linkedToDeath = false; 12096 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12097 } 12098 } 12099 } 12100 12101 if (!doNext) { 12102 return; 12103 } 12104 12105 final long origId = Binder.clearCallingIdentity(); 12106 processNextBroadcast(false); 12107 trimApplications(); 12108 Binder.restoreCallingIdentity(origId); 12109 } 12110 12111 void removeReceiverLocked(ReceiverList rl) { 12112 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12113 int N = rl.size(); 12114 for (int i=0; i<N; i++) { 12115 mReceiverResolver.removeFilter(rl.get(i)); 12116 } 12117 } 12118 12119 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12120 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12121 ProcessRecord r = mLruProcesses.get(i); 12122 if (r.thread != null) { 12123 try { 12124 r.thread.dispatchPackageBroadcast(cmd, packages); 12125 } catch (RemoteException ex) { 12126 } 12127 } 12128 } 12129 } 12130 12131 private final int broadcastIntentLocked(ProcessRecord callerApp, 12132 String callerPackage, Intent intent, String resolvedType, 12133 IIntentReceiver resultTo, int resultCode, String resultData, 12134 Bundle map, String requiredPermission, 12135 boolean ordered, boolean sticky, int callingPid, int callingUid) { 12136 intent = new Intent(intent); 12137 12138 // By default broadcasts do not go to stopped apps. 12139 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 12140 12141 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12142 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12143 + " ordered=" + ordered); 12144 if ((resultTo != null) && !ordered) { 12145 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12146 } 12147 12148 // Handle special intents: if this broadcast is from the package 12149 // manager about a package being removed, we need to remove all of 12150 // its activities from the history stack. 12151 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 12152 intent.getAction()); 12153 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12154 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12155 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12156 || uidRemoved) { 12157 if (checkComponentPermission( 12158 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12159 callingPid, callingUid, -1, true) 12160 == PackageManager.PERMISSION_GRANTED) { 12161 if (uidRemoved) { 12162 final Bundle intentExtras = intent.getExtras(); 12163 final int uid = intentExtras != null 12164 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12165 if (uid >= 0) { 12166 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12167 synchronized (bs) { 12168 bs.removeUidStatsLocked(uid); 12169 } 12170 } 12171 } else { 12172 // If resources are unvailble just force stop all 12173 // those packages and flush the attribute cache as well. 12174 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12175 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12176 if (list != null && (list.length > 0)) { 12177 for (String pkg : list) { 12178 forceStopPackageLocked(pkg, -1, false, true, true, false); 12179 } 12180 sendPackageBroadcastLocked( 12181 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12182 } 12183 } else { 12184 Uri data = intent.getData(); 12185 String ssp; 12186 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12187 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12188 forceStopPackageLocked(ssp, 12189 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false); 12190 } 12191 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12192 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12193 new String[] {ssp}); 12194 } 12195 } 12196 } 12197 } 12198 } else { 12199 String msg = "Permission Denial: " + intent.getAction() 12200 + " broadcast from " + callerPackage + " (pid=" + callingPid 12201 + ", uid=" + callingUid + ")" 12202 + " requires " 12203 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12204 Slog.w(TAG, msg); 12205 throw new SecurityException(msg); 12206 } 12207 12208 // Special case for adding a package: by default turn on compatibility 12209 // mode. 12210 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12211 Uri data = intent.getData(); 12212 String ssp; 12213 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12214 mCompatModePackages.handlePackageAddedLocked(ssp, 12215 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12216 } 12217 } 12218 12219 /* 12220 * If this is the time zone changed action, queue up a message that will reset the timezone 12221 * of all currently running processes. This message will get queued up before the broadcast 12222 * happens. 12223 */ 12224 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12225 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12226 } 12227 12228 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12229 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12230 } 12231 12232 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12233 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12234 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12235 } 12236 12237 /* 12238 * Prevent non-system code (defined here to be non-persistent 12239 * processes) from sending protected broadcasts. 12240 */ 12241 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12242 || callingUid == Process.SHELL_UID || callingUid == 0) { 12243 // Always okay. 12244 } else if (callerApp == null || !callerApp.persistent) { 12245 try { 12246 if (AppGlobals.getPackageManager().isProtectedBroadcast( 12247 intent.getAction())) { 12248 String msg = "Permission Denial: not allowed to send broadcast " 12249 + intent.getAction() + " from pid=" 12250 + callingPid + ", uid=" + callingUid; 12251 Slog.w(TAG, msg); 12252 throw new SecurityException(msg); 12253 } 12254 } catch (RemoteException e) { 12255 Slog.w(TAG, "Remote exception", e); 12256 return BROADCAST_SUCCESS; 12257 } 12258 } 12259 12260 // Add to the sticky list if requested. 12261 if (sticky) { 12262 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12263 callingPid, callingUid) 12264 != PackageManager.PERMISSION_GRANTED) { 12265 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12266 + callingPid + ", uid=" + callingUid 12267 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12268 Slog.w(TAG, msg); 12269 throw new SecurityException(msg); 12270 } 12271 if (requiredPermission != null) { 12272 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12273 + " and enforce permission " + requiredPermission); 12274 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12275 } 12276 if (intent.getComponent() != null) { 12277 throw new SecurityException( 12278 "Sticky broadcasts can't target a specific component"); 12279 } 12280 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12281 if (list == null) { 12282 list = new ArrayList<Intent>(); 12283 mStickyBroadcasts.put(intent.getAction(), list); 12284 } 12285 int N = list.size(); 12286 int i; 12287 for (i=0; i<N; i++) { 12288 if (intent.filterEquals(list.get(i))) { 12289 // This sticky already exists, replace it. 12290 list.set(i, new Intent(intent)); 12291 break; 12292 } 12293 } 12294 if (i >= N) { 12295 list.add(new Intent(intent)); 12296 } 12297 } 12298 12299 // Figure out who all will receive this broadcast. 12300 List receivers = null; 12301 List<BroadcastFilter> registeredReceivers = null; 12302 try { 12303 if (intent.getComponent() != null) { 12304 // Broadcast is going to one specific receiver class... 12305 ActivityInfo ai = AppGlobals.getPackageManager(). 12306 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 12307 if (ai != null) { 12308 receivers = new ArrayList(); 12309 ResolveInfo ri = new ResolveInfo(); 12310 ri.activityInfo = ai; 12311 receivers.add(ri); 12312 } 12313 } else { 12314 // Need to resolve the intent to interested receivers... 12315 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12316 == 0) { 12317 receivers = 12318 AppGlobals.getPackageManager().queryIntentReceivers( 12319 intent, resolvedType, STOCK_PM_FLAGS); 12320 } 12321 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 12322 } 12323 } catch (RemoteException ex) { 12324 // pm is in same process, this will never happen. 12325 } 12326 12327 final boolean replacePending = 12328 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12329 12330 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 12331 + " replacePending=" + replacePending); 12332 12333 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12334 if (!ordered && NR > 0) { 12335 // If we are not serializing this broadcast, then send the 12336 // registered receivers separately so they don't wait for the 12337 // components to be launched. 12338 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12339 callerPackage, callingPid, callingUid, requiredPermission, 12340 registeredReceivers, resultTo, resultCode, resultData, map, 12341 ordered, sticky, false); 12342 if (DEBUG_BROADCAST) Slog.v( 12343 TAG, "Enqueueing parallel broadcast " + r 12344 + ": prev had " + mParallelBroadcasts.size()); 12345 boolean replaced = false; 12346 if (replacePending) { 12347 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 12348 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { 12349 if (DEBUG_BROADCAST) Slog.v(TAG, 12350 "***** DROPPING PARALLEL: " + intent); 12351 mParallelBroadcasts.set(i, r); 12352 replaced = true; 12353 break; 12354 } 12355 } 12356 } 12357 if (!replaced) { 12358 mParallelBroadcasts.add(r); 12359 scheduleBroadcastsLocked(); 12360 } 12361 registeredReceivers = null; 12362 NR = 0; 12363 } 12364 12365 // Merge into one list. 12366 int ir = 0; 12367 if (receivers != null) { 12368 // A special case for PACKAGE_ADDED: do not allow the package 12369 // being added to see this broadcast. This prevents them from 12370 // using this as a back door to get run as soon as they are 12371 // installed. Maybe in the future we want to have a special install 12372 // broadcast or such for apps, but we'd like to deliberately make 12373 // this decision. 12374 String skipPackages[] = null; 12375 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 12376 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 12377 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12378 Uri data = intent.getData(); 12379 if (data != null) { 12380 String pkgName = data.getSchemeSpecificPart(); 12381 if (pkgName != null) { 12382 skipPackages = new String[] { pkgName }; 12383 } 12384 } 12385 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 12386 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12387 } 12388 if (skipPackages != null && (skipPackages.length > 0)) { 12389 for (String skipPackage : skipPackages) { 12390 if (skipPackage != null) { 12391 int NT = receivers.size(); 12392 for (int it=0; it<NT; it++) { 12393 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12394 if (curt.activityInfo.packageName.equals(skipPackage)) { 12395 receivers.remove(it); 12396 it--; 12397 NT--; 12398 } 12399 } 12400 } 12401 } 12402 } 12403 12404 int NT = receivers != null ? receivers.size() : 0; 12405 int it = 0; 12406 ResolveInfo curt = null; 12407 BroadcastFilter curr = null; 12408 while (it < NT && ir < NR) { 12409 if (curt == null) { 12410 curt = (ResolveInfo)receivers.get(it); 12411 } 12412 if (curr == null) { 12413 curr = registeredReceivers.get(ir); 12414 } 12415 if (curr.getPriority() >= curt.priority) { 12416 // Insert this broadcast record into the final list. 12417 receivers.add(it, curr); 12418 ir++; 12419 curr = null; 12420 it++; 12421 NT++; 12422 } else { 12423 // Skip to the next ResolveInfo in the final list. 12424 it++; 12425 curt = null; 12426 } 12427 } 12428 } 12429 while (ir < NR) { 12430 if (receivers == null) { 12431 receivers = new ArrayList(); 12432 } 12433 receivers.add(registeredReceivers.get(ir)); 12434 ir++; 12435 } 12436 12437 if ((receivers != null && receivers.size() > 0) 12438 || resultTo != null) { 12439 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12440 callerPackage, callingPid, callingUid, requiredPermission, 12441 receivers, resultTo, resultCode, resultData, map, ordered, 12442 sticky, false); 12443 if (DEBUG_BROADCAST) Slog.v( 12444 TAG, "Enqueueing ordered broadcast " + r 12445 + ": prev had " + mOrderedBroadcasts.size()); 12446 if (DEBUG_BROADCAST) { 12447 int seq = r.intent.getIntExtra("seq", -1); 12448 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12449 } 12450 boolean replaced = false; 12451 if (replacePending) { 12452 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) { 12453 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { 12454 if (DEBUG_BROADCAST) Slog.v(TAG, 12455 "***** DROPPING ORDERED: " + intent); 12456 mOrderedBroadcasts.set(i, r); 12457 replaced = true; 12458 break; 12459 } 12460 } 12461 } 12462 if (!replaced) { 12463 mOrderedBroadcasts.add(r); 12464 scheduleBroadcastsLocked(); 12465 } 12466 } 12467 12468 return BROADCAST_SUCCESS; 12469 } 12470 12471 final Intent verifyBroadcastLocked(Intent intent) { 12472 // Refuse possible leaked file descriptors 12473 if (intent != null && intent.hasFileDescriptors() == true) { 12474 throw new IllegalArgumentException("File descriptors passed in Intent"); 12475 } 12476 12477 int flags = intent.getFlags(); 12478 12479 if (!mProcessesReady) { 12480 // if the caller really truly claims to know what they're doing, go 12481 // ahead and allow the broadcast without launching any receivers 12482 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12483 intent = new Intent(intent); 12484 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12485 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 12486 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12487 + " before boot completion"); 12488 throw new IllegalStateException("Cannot broadcast before boot completed"); 12489 } 12490 } 12491 12492 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12493 throw new IllegalArgumentException( 12494 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12495 } 12496 12497 return intent; 12498 } 12499 12500 public final int broadcastIntent(IApplicationThread caller, 12501 Intent intent, String resolvedType, IIntentReceiver resultTo, 12502 int resultCode, String resultData, Bundle map, 12503 String requiredPermission, boolean serialized, boolean sticky) { 12504 synchronized(this) { 12505 intent = verifyBroadcastLocked(intent); 12506 12507 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12508 final int callingPid = Binder.getCallingPid(); 12509 final int callingUid = Binder.getCallingUid(); 12510 final long origId = Binder.clearCallingIdentity(); 12511 int res = broadcastIntentLocked(callerApp, 12512 callerApp != null ? callerApp.info.packageName : null, 12513 intent, resolvedType, resultTo, 12514 resultCode, resultData, map, requiredPermission, serialized, 12515 sticky, callingPid, callingUid); 12516 Binder.restoreCallingIdentity(origId); 12517 return res; 12518 } 12519 } 12520 12521 int broadcastIntentInPackage(String packageName, int uid, 12522 Intent intent, String resolvedType, IIntentReceiver resultTo, 12523 int resultCode, String resultData, Bundle map, 12524 String requiredPermission, boolean serialized, boolean sticky) { 12525 synchronized(this) { 12526 intent = verifyBroadcastLocked(intent); 12527 12528 final long origId = Binder.clearCallingIdentity(); 12529 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12530 resultTo, resultCode, resultData, map, requiredPermission, 12531 serialized, sticky, -1, uid); 12532 Binder.restoreCallingIdentity(origId); 12533 return res; 12534 } 12535 } 12536 12537 public final void unbroadcastIntent(IApplicationThread caller, 12538 Intent intent) { 12539 // Refuse possible leaked file descriptors 12540 if (intent != null && intent.hasFileDescriptors() == true) { 12541 throw new IllegalArgumentException("File descriptors passed in Intent"); 12542 } 12543 12544 synchronized(this) { 12545 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12546 != PackageManager.PERMISSION_GRANTED) { 12547 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12548 + Binder.getCallingPid() 12549 + ", uid=" + Binder.getCallingUid() 12550 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12551 Slog.w(TAG, msg); 12552 throw new SecurityException(msg); 12553 } 12554 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12555 if (list != null) { 12556 int N = list.size(); 12557 int i; 12558 for (i=0; i<N; i++) { 12559 if (intent.filterEquals(list.get(i))) { 12560 list.remove(i); 12561 break; 12562 } 12563 } 12564 } 12565 } 12566 } 12567 12568 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12569 String resultData, Bundle resultExtras, boolean resultAbort, 12570 boolean explicit) { 12571 if (mOrderedBroadcasts.size() == 0) { 12572 if (explicit) { 12573 Slog.w(TAG, "finishReceiver called but no pending broadcasts"); 12574 } 12575 return false; 12576 } 12577 BroadcastRecord r = mOrderedBroadcasts.get(0); 12578 if (r.receiver == null) { 12579 if (explicit) { 12580 Slog.w(TAG, "finishReceiver called but none active"); 12581 } 12582 return false; 12583 } 12584 if (r.receiver != receiver) { 12585 Slog.w(TAG, "finishReceiver called but active receiver is different"); 12586 return false; 12587 } 12588 int state = r.state; 12589 r.state = BroadcastRecord.IDLE; 12590 if (state == BroadcastRecord.IDLE) { 12591 if (explicit) { 12592 Slog.w(TAG, "finishReceiver called but state is IDLE"); 12593 } 12594 } 12595 r.receiver = null; 12596 r.intent.setComponent(null); 12597 if (r.curApp != null) { 12598 r.curApp.curReceiver = null; 12599 } 12600 if (r.curFilter != null) { 12601 r.curFilter.receiverList.curBroadcast = null; 12602 } 12603 r.curFilter = null; 12604 r.curApp = null; 12605 r.curComponent = null; 12606 r.curReceiver = null; 12607 mPendingBroadcast = null; 12608 12609 r.resultCode = resultCode; 12610 r.resultData = resultData; 12611 r.resultExtras = resultExtras; 12612 r.resultAbort = resultAbort; 12613 12614 // We will process the next receiver right now if this is finishing 12615 // an app receiver (which is always asynchronous) or after we have 12616 // come back from calling a receiver. 12617 return state == BroadcastRecord.APP_RECEIVE 12618 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12619 } 12620 12621 public void finishReceiver(IBinder who, int resultCode, String resultData, 12622 Bundle resultExtras, boolean resultAbort) { 12623 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12624 12625 // Refuse possible leaked file descriptors 12626 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12627 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12628 } 12629 12630 boolean doNext; 12631 12632 final long origId = Binder.clearCallingIdentity(); 12633 12634 synchronized(this) { 12635 doNext = finishReceiverLocked( 12636 who, resultCode, resultData, resultExtras, resultAbort, true); 12637 } 12638 12639 if (doNext) { 12640 processNextBroadcast(false); 12641 } 12642 trimApplications(); 12643 12644 Binder.restoreCallingIdentity(origId); 12645 } 12646 12647 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) { 12648 if (r.nextReceiver > 0) { 12649 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12650 if (curReceiver instanceof BroadcastFilter) { 12651 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12652 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, 12653 System.identityHashCode(r), 12654 r.intent.getAction(), 12655 r.nextReceiver - 1, 12656 System.identityHashCode(bf)); 12657 } else { 12658 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12659 System.identityHashCode(r), 12660 r.intent.getAction(), 12661 r.nextReceiver - 1, 12662 ((ResolveInfo)curReceiver).toString()); 12663 } 12664 } else { 12665 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: " 12666 + r); 12667 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12668 System.identityHashCode(r), 12669 r.intent.getAction(), 12670 r.nextReceiver, 12671 "NONE"); 12672 } 12673 } 12674 12675 private final void setBroadcastTimeoutLocked(long timeoutTime) { 12676 if (! mPendingBroadcastTimeoutMessage) { 12677 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12678 mHandler.sendMessageAtTime(msg, timeoutTime); 12679 mPendingBroadcastTimeoutMessage = true; 12680 } 12681 } 12682 12683 private final void cancelBroadcastTimeoutLocked() { 12684 if (mPendingBroadcastTimeoutMessage) { 12685 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12686 mPendingBroadcastTimeoutMessage = false; 12687 } 12688 } 12689 12690 private final void broadcastTimeoutLocked(boolean fromMsg) { 12691 if (fromMsg) { 12692 mPendingBroadcastTimeoutMessage = false; 12693 } 12694 12695 if (mOrderedBroadcasts.size() == 0) { 12696 return; 12697 } 12698 12699 long now = SystemClock.uptimeMillis(); 12700 BroadcastRecord r = mOrderedBroadcasts.get(0); 12701 if (fromMsg) { 12702 if (mDidDexOpt) { 12703 // Delay timeouts until dexopt finishes. 12704 mDidDexOpt = false; 12705 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT; 12706 setBroadcastTimeoutLocked(timeoutTime); 12707 return; 12708 } 12709 if (! mProcessesReady) { 12710 // Only process broadcast timeouts if the system is ready. That way 12711 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended 12712 // to do heavy lifting for system up. 12713 return; 12714 } 12715 12716 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT; 12717 if (timeoutTime > now) { 12718 // We can observe premature timeouts because we do not cancel and reset the 12719 // broadcast timeout message after each receiver finishes. Instead, we set up 12720 // an initial timeout then kick it down the road a little further as needed 12721 // when it expires. 12722 if (DEBUG_BROADCAST) Slog.v(TAG, 12723 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12724 + timeoutTime); 12725 setBroadcastTimeoutLocked(timeoutTime); 12726 return; 12727 } 12728 } 12729 12730 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver 12731 + ", started " + (now - r.receiverTime) + "ms ago"); 12732 r.receiverTime = now; 12733 r.anrCount++; 12734 12735 // Current receiver has passed its expiration date. 12736 if (r.nextReceiver <= 0) { 12737 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12738 return; 12739 } 12740 12741 ProcessRecord app = null; 12742 String anrMessage = null; 12743 12744 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12745 Slog.w(TAG, "Receiver during timeout: " + curReceiver); 12746 logBroadcastReceiverDiscardLocked(r); 12747 if (curReceiver instanceof BroadcastFilter) { 12748 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12749 if (bf.receiverList.pid != 0 12750 && bf.receiverList.pid != MY_PID) { 12751 synchronized (this.mPidsSelfLocked) { 12752 app = this.mPidsSelfLocked.get( 12753 bf.receiverList.pid); 12754 } 12755 } 12756 } else { 12757 app = r.curApp; 12758 } 12759 12760 if (app != null) { 12761 anrMessage = "Broadcast of " + r.intent.toString(); 12762 } 12763 12764 if (mPendingBroadcast == r) { 12765 mPendingBroadcast = null; 12766 } 12767 12768 // Move on to the next receiver. 12769 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12770 r.resultExtras, r.resultAbort, true); 12771 scheduleBroadcastsLocked(); 12772 12773 if (anrMessage != null) { 12774 // Post the ANR to the handler since we do not want to process ANRs while 12775 // potentially holding our lock. 12776 mHandler.post(new AppNotResponding(app, anrMessage)); 12777 } 12778 } 12779 12780 private final void processCurBroadcastLocked(BroadcastRecord r, 12781 ProcessRecord app) throws RemoteException { 12782 if (DEBUG_BROADCAST) Slog.v(TAG, 12783 "Process cur broadcast " + r + " for app " + app); 12784 if (app.thread == null) { 12785 throw new RemoteException(); 12786 } 12787 r.receiver = app.thread.asBinder(); 12788 r.curApp = app; 12789 app.curReceiver = r; 12790 updateLruProcessLocked(app, true, true); 12791 12792 // Tell the application to launch this receiver. 12793 r.intent.setComponent(r.curComponent); 12794 12795 boolean started = false; 12796 try { 12797 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, 12798 "Delivering to component " + r.curComponent 12799 + ": " + r); 12800 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12801 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12802 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo), 12803 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12804 if (DEBUG_BROADCAST) Slog.v(TAG, 12805 "Process cur broadcast " + r + " DELIVERED for app " + app); 12806 started = true; 12807 } finally { 12808 if (!started) { 12809 if (DEBUG_BROADCAST) Slog.v(TAG, 12810 "Process cur broadcast " + r + ": NOT STARTED!"); 12811 r.receiver = null; 12812 r.curApp = null; 12813 app.curReceiver = null; 12814 } 12815 } 12816 12817 } 12818 12819 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, 12820 Intent intent, int resultCode, String data, Bundle extras, 12821 boolean ordered, boolean sticky) throws RemoteException { 12822 // Send the intent to the receiver asynchronously using one-way binder calls. 12823 if (app != null && app.thread != null) { 12824 // If we have an app thread, do the call through that so it is 12825 // correctly ordered with other one-way calls. 12826 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12827 data, extras, ordered, sticky); 12828 } else { 12829 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12830 } 12831 } 12832 12833 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r, 12834 BroadcastFilter filter, boolean ordered) { 12835 boolean skip = false; 12836 if (filter.requiredPermission != null) { 12837 int perm = checkComponentPermission(filter.requiredPermission, 12838 r.callingPid, r.callingUid, -1, true); 12839 if (perm != PackageManager.PERMISSION_GRANTED) { 12840 Slog.w(TAG, "Permission Denial: broadcasting " 12841 + r.intent.toString() 12842 + " from " + r.callerPackage + " (pid=" 12843 + r.callingPid + ", uid=" + r.callingUid + ")" 12844 + " requires " + filter.requiredPermission 12845 + " due to registered receiver " + filter); 12846 skip = true; 12847 } 12848 } 12849 if (r.requiredPermission != null) { 12850 int perm = checkComponentPermission(r.requiredPermission, 12851 filter.receiverList.pid, filter.receiverList.uid, -1, true); 12852 if (perm != PackageManager.PERMISSION_GRANTED) { 12853 Slog.w(TAG, "Permission Denial: receiving " 12854 + r.intent.toString() 12855 + " to " + filter.receiverList.app 12856 + " (pid=" + filter.receiverList.pid 12857 + ", uid=" + filter.receiverList.uid + ")" 12858 + " requires " + r.requiredPermission 12859 + " due to sender " + r.callerPackage 12860 + " (uid " + r.callingUid + ")"); 12861 skip = true; 12862 } 12863 } 12864 12865 if (!skip) { 12866 // If this is not being sent as an ordered broadcast, then we 12867 // don't want to touch the fields that keep track of the current 12868 // state of ordered broadcasts. 12869 if (ordered) { 12870 r.receiver = filter.receiverList.receiver.asBinder(); 12871 r.curFilter = filter; 12872 filter.receiverList.curBroadcast = r; 12873 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12874 if (filter.receiverList.app != null) { 12875 // Bump hosting application to no longer be in background 12876 // scheduling class. Note that we can't do that if there 12877 // isn't an app... but we can only be in that case for 12878 // things that directly call the IActivityManager API, which 12879 // are already core system stuff so don't matter for this. 12880 r.curApp = filter.receiverList.app; 12881 filter.receiverList.app.curReceiver = r; 12882 updateOomAdjLocked(); 12883 } 12884 } 12885 try { 12886 if (DEBUG_BROADCAST_LIGHT) { 12887 int seq = r.intent.getIntExtra("seq", -1); 12888 Slog.i(TAG, "Delivering to " + filter 12889 + " (seq=" + seq + "): " + r); 12890 } 12891 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, 12892 new Intent(r.intent), r.resultCode, 12893 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 12894 if (ordered) { 12895 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12896 } 12897 } catch (RemoteException e) { 12898 Slog.w(TAG, "Failure sending broadcast " + r.intent, e); 12899 if (ordered) { 12900 r.receiver = null; 12901 r.curFilter = null; 12902 filter.receiverList.curBroadcast = null; 12903 if (filter.receiverList.app != null) { 12904 filter.receiverList.app.curReceiver = null; 12905 } 12906 } 12907 } 12908 } 12909 } 12910 12911 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 12912 if (r.callingUid < 0) { 12913 // This was from a registerReceiver() call; ignore it. 12914 return; 12915 } 12916 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 12917 MAX_BROADCAST_HISTORY-1); 12918 r.finishTime = SystemClock.uptimeMillis(); 12919 mBroadcastHistory[0] = r; 12920 } 12921 12922 private final void processNextBroadcast(boolean fromMsg) { 12923 synchronized(this) { 12924 BroadcastRecord r; 12925 12926 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: " 12927 + mParallelBroadcasts.size() + " broadcasts, " 12928 + mOrderedBroadcasts.size() + " ordered broadcasts"); 12929 12930 updateCpuStats(); 12931 12932 if (fromMsg) { 12933 mBroadcastsScheduled = false; 12934 } 12935 12936 // First, deliver any non-serialized broadcasts right away. 12937 while (mParallelBroadcasts.size() > 0) { 12938 r = mParallelBroadcasts.remove(0); 12939 r.dispatchTime = SystemClock.uptimeMillis(); 12940 r.dispatchClockTime = System.currentTimeMillis(); 12941 final int N = r.receivers.size(); 12942 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast " 12943 + r); 12944 for (int i=0; i<N; i++) { 12945 Object target = r.receivers.get(i); 12946 if (DEBUG_BROADCAST) Slog.v(TAG, 12947 "Delivering non-ordered to registered " 12948 + target + ": " + r); 12949 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false); 12950 } 12951 addBroadcastToHistoryLocked(r); 12952 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast " 12953 + r); 12954 } 12955 12956 // Now take care of the next serialized one... 12957 12958 // If we are waiting for a process to come up to handle the next 12959 // broadcast, then do nothing at this point. Just in case, we 12960 // check that the process we're waiting for still exists. 12961 if (mPendingBroadcast != null) { 12962 if (DEBUG_BROADCAST_LIGHT) { 12963 Slog.v(TAG, "processNextBroadcast: waiting for " 12964 + mPendingBroadcast.curApp); 12965 } 12966 12967 boolean isDead; 12968 synchronized (mPidsSelfLocked) { 12969 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12970 } 12971 if (!isDead) { 12972 // It's still alive, so keep waiting 12973 return; 12974 } else { 12975 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp 12976 + " died before responding to broadcast"); 12977 mPendingBroadcast.state = BroadcastRecord.IDLE; 12978 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 12979 mPendingBroadcast = null; 12980 } 12981 } 12982 12983 boolean looped = false; 12984 12985 do { 12986 if (mOrderedBroadcasts.size() == 0) { 12987 // No more broadcasts pending, so all done! 12988 scheduleAppGcsLocked(); 12989 if (looped) { 12990 // If we had finished the last ordered broadcast, then 12991 // make sure all processes have correct oom and sched 12992 // adjustments. 12993 updateOomAdjLocked(); 12994 } 12995 return; 12996 } 12997 r = mOrderedBroadcasts.get(0); 12998 boolean forceReceive = false; 12999 13000 // Ensure that even if something goes awry with the timeout 13001 // detection, we catch "hung" broadcasts here, discard them, 13002 // and continue to make progress. 13003 // 13004 // This is only done if the system is ready so that PRE_BOOT_COMPLETED 13005 // receivers don't get executed with timeouts. They're intended for 13006 // one time heavy lifting after system upgrades and can take 13007 // significant amounts of time. 13008 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 13009 if (mProcessesReady && r.dispatchTime > 0) { 13010 long now = SystemClock.uptimeMillis(); 13011 if ((numReceivers > 0) && 13012 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 13013 Slog.w(TAG, "Hung broadcast discarded after timeout failure:" 13014 + " now=" + now 13015 + " dispatchTime=" + r.dispatchTime 13016 + " startTime=" + r.receiverTime 13017 + " intent=" + r.intent 13018 + " numReceivers=" + numReceivers 13019 + " nextReceiver=" + r.nextReceiver 13020 + " state=" + r.state); 13021 broadcastTimeoutLocked(false); // forcibly finish this broadcast 13022 forceReceive = true; 13023 r.state = BroadcastRecord.IDLE; 13024 } 13025 } 13026 13027 if (r.state != BroadcastRecord.IDLE) { 13028 if (DEBUG_BROADCAST) Slog.d(TAG, 13029 "processNextBroadcast() called when not idle (state=" 13030 + r.state + ")"); 13031 return; 13032 } 13033 13034 if (r.receivers == null || r.nextReceiver >= numReceivers 13035 || r.resultAbort || forceReceive) { 13036 // No more receivers for this broadcast! Send the final 13037 // result if requested... 13038 if (r.resultTo != null) { 13039 try { 13040 if (DEBUG_BROADCAST) { 13041 int seq = r.intent.getIntExtra("seq", -1); 13042 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction() 13043 + " seq=" + seq + " app=" + r.callerApp); 13044 } 13045 performReceiveLocked(r.callerApp, r.resultTo, 13046 new Intent(r.intent), r.resultCode, 13047 r.resultData, r.resultExtras, false, false); 13048 // Set this to null so that the reference 13049 // (local and remote) isnt kept in the mBroadcastHistory. 13050 r.resultTo = null; 13051 } catch (RemoteException e) { 13052 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e); 13053 } 13054 } 13055 13056 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 13057 cancelBroadcastTimeoutLocked(); 13058 13059 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast " 13060 + r); 13061 13062 // ... and on to the next... 13063 addBroadcastToHistoryLocked(r); 13064 mOrderedBroadcasts.remove(0); 13065 r = null; 13066 looped = true; 13067 continue; 13068 } 13069 } while (r == null); 13070 13071 // Get the next receiver... 13072 int recIdx = r.nextReceiver++; 13073 13074 // Keep track of when this receiver started, and make sure there 13075 // is a timeout message pending to kill it if need be. 13076 r.receiverTime = SystemClock.uptimeMillis(); 13077 if (recIdx == 0) { 13078 r.dispatchTime = r.receiverTime; 13079 r.dispatchClockTime = System.currentTimeMillis(); 13080 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast " 13081 + r); 13082 } 13083 if (! mPendingBroadcastTimeoutMessage) { 13084 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT; 13085 if (DEBUG_BROADCAST) Slog.v(TAG, 13086 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime); 13087 setBroadcastTimeoutLocked(timeoutTime); 13088 } 13089 13090 Object nextReceiver = r.receivers.get(recIdx); 13091 if (nextReceiver instanceof BroadcastFilter) { 13092 // Simple case: this is a registered receiver who gets 13093 // a direct call. 13094 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 13095 if (DEBUG_BROADCAST) Slog.v(TAG, 13096 "Delivering ordered to registered " 13097 + filter + ": " + r); 13098 deliverToRegisteredReceiverLocked(r, filter, r.ordered); 13099 if (r.receiver == null || !r.ordered) { 13100 // The receiver has already finished, so schedule to 13101 // process the next one. 13102 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered=" 13103 + r.ordered + " receiver=" + r.receiver); 13104 r.state = BroadcastRecord.IDLE; 13105 scheduleBroadcastsLocked(); 13106 } 13107 return; 13108 } 13109 13110 // Hard case: need to instantiate the receiver, possibly 13111 // starting its application process to host it. 13112 13113 ResolveInfo info = 13114 (ResolveInfo)nextReceiver; 13115 13116 boolean skip = false; 13117 int perm = checkComponentPermission(info.activityInfo.permission, 13118 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid, 13119 info.activityInfo.exported); 13120 if (perm != PackageManager.PERMISSION_GRANTED) { 13121 if (!info.activityInfo.exported) { 13122 Slog.w(TAG, "Permission Denial: broadcasting " 13123 + r.intent.toString() 13124 + " from " + r.callerPackage + " (pid=" + r.callingPid 13125 + ", uid=" + r.callingUid + ")" 13126 + " is not exported from uid " + info.activityInfo.applicationInfo.uid 13127 + " due to receiver " + info.activityInfo.packageName 13128 + "/" + info.activityInfo.name); 13129 } else { 13130 Slog.w(TAG, "Permission Denial: broadcasting " 13131 + r.intent.toString() 13132 + " from " + r.callerPackage + " (pid=" + r.callingPid 13133 + ", uid=" + r.callingUid + ")" 13134 + " requires " + info.activityInfo.permission 13135 + " due to receiver " + info.activityInfo.packageName 13136 + "/" + info.activityInfo.name); 13137 } 13138 skip = true; 13139 } 13140 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && 13141 r.requiredPermission != null) { 13142 try { 13143 perm = AppGlobals.getPackageManager(). 13144 checkPermission(r.requiredPermission, 13145 info.activityInfo.applicationInfo.packageName); 13146 } catch (RemoteException e) { 13147 perm = PackageManager.PERMISSION_DENIED; 13148 } 13149 if (perm != PackageManager.PERMISSION_GRANTED) { 13150 Slog.w(TAG, "Permission Denial: receiving " 13151 + r.intent + " to " 13152 + info.activityInfo.applicationInfo.packageName 13153 + " requires " + r.requiredPermission 13154 + " due to sender " + r.callerPackage 13155 + " (uid " + r.callingUid + ")"); 13156 skip = true; 13157 } 13158 } 13159 if (r.curApp != null && r.curApp.crashing) { 13160 // If the target process is crashing, just skip it. 13161 if (DEBUG_BROADCAST) Slog.v(TAG, 13162 "Skipping deliver ordered " + r + " to " + r.curApp 13163 + ": process crashing"); 13164 skip = true; 13165 } 13166 13167 if (skip) { 13168 if (DEBUG_BROADCAST) Slog.v(TAG, 13169 "Skipping delivery of ordered " + r + " for whatever reason"); 13170 r.receiver = null; 13171 r.curFilter = null; 13172 r.state = BroadcastRecord.IDLE; 13173 scheduleBroadcastsLocked(); 13174 return; 13175 } 13176 13177 r.state = BroadcastRecord.APP_RECEIVE; 13178 String targetProcess = info.activityInfo.processName; 13179 r.curComponent = new ComponentName( 13180 info.activityInfo.applicationInfo.packageName, 13181 info.activityInfo.name); 13182 r.curReceiver = info.activityInfo; 13183 13184 // Broadcast is being executed, its package can't be stopped. 13185 try { 13186 AppGlobals.getPackageManager().setPackageStoppedState( 13187 r.curComponent.getPackageName(), false); 13188 } catch (RemoteException e) { 13189 } catch (IllegalArgumentException e) { 13190 Slog.w(TAG, "Failed trying to unstop package " 13191 + r.curComponent.getPackageName() + ": " + e); 13192 } 13193 13194 // Is this receiver's application already running? 13195 ProcessRecord app = getProcessRecordLocked(targetProcess, 13196 info.activityInfo.applicationInfo.uid); 13197 if (app != null && app.thread != null) { 13198 try { 13199 app.addPackage(info.activityInfo.packageName); 13200 processCurBroadcastLocked(r, app); 13201 return; 13202 } catch (RemoteException e) { 13203 Slog.w(TAG, "Exception when sending broadcast to " 13204 + r.curComponent, e); 13205 } 13206 13207 // If a dead object exception was thrown -- fall through to 13208 // restart the application. 13209 } 13210 13211 // Not running -- get it started, to be executed when the app comes up. 13212 if (DEBUG_BROADCAST) Slog.v(TAG, 13213 "Need to start app " + targetProcess + " for broadcast " + r); 13214 if ((r.curApp=startProcessLocked(targetProcess, 13215 info.activityInfo.applicationInfo, true, 13216 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 13217 "broadcast", r.curComponent, 13218 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 13219 == null) { 13220 // Ah, this recipient is unavailable. Finish it if necessary, 13221 // and mark the broadcast record as ready for the next. 13222 Slog.w(TAG, "Unable to launch app " 13223 + info.activityInfo.applicationInfo.packageName + "/" 13224 + info.activityInfo.applicationInfo.uid + " for broadcast " 13225 + r.intent + ": process is bad"); 13226 logBroadcastReceiverDiscardLocked(r); 13227 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 13228 r.resultExtras, r.resultAbort, true); 13229 scheduleBroadcastsLocked(); 13230 r.state = BroadcastRecord.IDLE; 13231 return; 13232 } 13233 13234 mPendingBroadcast = r; 13235 mPendingBroadcastRecvIndex = recIdx; 13236 } 13237 } 13238 13239 // ========================================================= 13240 // INSTRUMENTATION 13241 // ========================================================= 13242 13243 public boolean startInstrumentation(ComponentName className, 13244 String profileFile, int flags, Bundle arguments, 13245 IInstrumentationWatcher watcher) { 13246 // Refuse possible leaked file descriptors 13247 if (arguments != null && arguments.hasFileDescriptors()) { 13248 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13249 } 13250 13251 synchronized(this) { 13252 InstrumentationInfo ii = null; 13253 ApplicationInfo ai = null; 13254 try { 13255 ii = mContext.getPackageManager().getInstrumentationInfo( 13256 className, STOCK_PM_FLAGS); 13257 ai = mContext.getPackageManager().getApplicationInfo( 13258 ii.targetPackage, STOCK_PM_FLAGS); 13259 } catch (PackageManager.NameNotFoundException e) { 13260 } 13261 if (ii == null) { 13262 reportStartInstrumentationFailure(watcher, className, 13263 "Unable to find instrumentation info for: " + className); 13264 return false; 13265 } 13266 if (ai == null) { 13267 reportStartInstrumentationFailure(watcher, className, 13268 "Unable to find instrumentation target package: " + ii.targetPackage); 13269 return false; 13270 } 13271 13272 int match = mContext.getPackageManager().checkSignatures( 13273 ii.targetPackage, ii.packageName); 13274 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13275 String msg = "Permission Denial: starting instrumentation " 13276 + className + " from pid=" 13277 + Binder.getCallingPid() 13278 + ", uid=" + Binder.getCallingPid() 13279 + " not allowed because package " + ii.packageName 13280 + " does not have a signature matching the target " 13281 + ii.targetPackage; 13282 reportStartInstrumentationFailure(watcher, className, msg); 13283 throw new SecurityException(msg); 13284 } 13285 13286 final long origId = Binder.clearCallingIdentity(); 13287 // Instrumentation can kill and relaunch even persistent processes 13288 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true); 13289 ProcessRecord app = addAppLocked(ai); 13290 app.instrumentationClass = className; 13291 app.instrumentationInfo = ai; 13292 app.instrumentationProfileFile = profileFile; 13293 app.instrumentationArguments = arguments; 13294 app.instrumentationWatcher = watcher; 13295 app.instrumentationResultClass = className; 13296 Binder.restoreCallingIdentity(origId); 13297 } 13298 13299 return true; 13300 } 13301 13302 /** 13303 * Report errors that occur while attempting to start Instrumentation. Always writes the 13304 * error to the logs, but if somebody is watching, send the report there too. This enables 13305 * the "am" command to report errors with more information. 13306 * 13307 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13308 * @param cn The component name of the instrumentation. 13309 * @param report The error report. 13310 */ 13311 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13312 ComponentName cn, String report) { 13313 Slog.w(TAG, report); 13314 try { 13315 if (watcher != null) { 13316 Bundle results = new Bundle(); 13317 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13318 results.putString("Error", report); 13319 watcher.instrumentationStatus(cn, -1, results); 13320 } 13321 } catch (RemoteException e) { 13322 Slog.w(TAG, e); 13323 } 13324 } 13325 13326 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13327 if (app.instrumentationWatcher != null) { 13328 try { 13329 // NOTE: IInstrumentationWatcher *must* be oneway here 13330 app.instrumentationWatcher.instrumentationFinished( 13331 app.instrumentationClass, 13332 resultCode, 13333 results); 13334 } catch (RemoteException e) { 13335 } 13336 } 13337 app.instrumentationWatcher = null; 13338 app.instrumentationClass = null; 13339 app.instrumentationInfo = null; 13340 app.instrumentationProfileFile = null; 13341 app.instrumentationArguments = null; 13342 13343 forceStopPackageLocked(app.processName, -1, false, false, true, true); 13344 } 13345 13346 public void finishInstrumentation(IApplicationThread target, 13347 int resultCode, Bundle results) { 13348 // Refuse possible leaked file descriptors 13349 if (results != null && results.hasFileDescriptors()) { 13350 throw new IllegalArgumentException("File descriptors passed in Intent"); 13351 } 13352 13353 synchronized(this) { 13354 ProcessRecord app = getRecordForAppLocked(target); 13355 if (app == null) { 13356 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13357 return; 13358 } 13359 final long origId = Binder.clearCallingIdentity(); 13360 finishInstrumentationLocked(app, resultCode, results); 13361 Binder.restoreCallingIdentity(origId); 13362 } 13363 } 13364 13365 // ========================================================= 13366 // CONFIGURATION 13367 // ========================================================= 13368 13369 public ConfigurationInfo getDeviceConfigurationInfo() { 13370 ConfigurationInfo config = new ConfigurationInfo(); 13371 synchronized (this) { 13372 config.reqTouchScreen = mConfiguration.touchscreen; 13373 config.reqKeyboardType = mConfiguration.keyboard; 13374 config.reqNavigation = mConfiguration.navigation; 13375 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13376 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13377 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13378 } 13379 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13380 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13381 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13382 } 13383 config.reqGlEsVersion = GL_ES_VERSION; 13384 } 13385 return config; 13386 } 13387 13388 public Configuration getConfiguration() { 13389 Configuration ci; 13390 synchronized(this) { 13391 ci = new Configuration(mConfiguration); 13392 } 13393 return ci; 13394 } 13395 13396 public void updatePersistentConfiguration(Configuration values) { 13397 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13398 "updateConfiguration()"); 13399 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13400 "updateConfiguration()"); 13401 if (values == null) { 13402 throw new NullPointerException("Configuration must not be null"); 13403 } 13404 13405 synchronized(this) { 13406 final long origId = Binder.clearCallingIdentity(); 13407 updateConfigurationLocked(values, null, true, false); 13408 Binder.restoreCallingIdentity(origId); 13409 } 13410 } 13411 13412 public void updateConfiguration(Configuration values) { 13413 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13414 "updateConfiguration()"); 13415 13416 synchronized(this) { 13417 if (values == null && mWindowManager != null) { 13418 // sentinel: fetch the current configuration from the window manager 13419 values = mWindowManager.computeNewConfiguration(); 13420 } 13421 13422 if (mWindowManager != null) { 13423 mProcessList.applyDisplaySize(mWindowManager); 13424 } 13425 13426 final long origId = Binder.clearCallingIdentity(); 13427 if (values != null) { 13428 Settings.System.clearConfiguration(values); 13429 } 13430 updateConfigurationLocked(values, null, false, false); 13431 Binder.restoreCallingIdentity(origId); 13432 } 13433 } 13434 13435 /** 13436 * Do either or both things: (1) change the current configuration, and (2) 13437 * make sure the given activity is running with the (now) current 13438 * configuration. Returns true if the activity has been left running, or 13439 * false if <var>starting</var> is being destroyed to match the new 13440 * configuration. 13441 * @param persistent TODO 13442 */ 13443 public boolean updateConfigurationLocked(Configuration values, 13444 ActivityRecord starting, boolean persistent, boolean initLocale) { 13445 int changes = 0; 13446 13447 boolean kept = true; 13448 13449 if (values != null) { 13450 Configuration newConfig = new Configuration(mConfiguration); 13451 changes = newConfig.updateFrom(values); 13452 if (changes != 0) { 13453 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13454 Slog.i(TAG, "Updating configuration to: " + values); 13455 } 13456 13457 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13458 13459 if (values.locale != null && !initLocale) { 13460 saveLocaleLocked(values.locale, 13461 !values.locale.equals(mConfiguration.locale), 13462 values.userSetLocale); 13463 } 13464 13465 mConfigurationSeq++; 13466 if (mConfigurationSeq <= 0) { 13467 mConfigurationSeq = 1; 13468 } 13469 newConfig.seq = mConfigurationSeq; 13470 mConfiguration = newConfig; 13471 Slog.i(TAG, "Config changed: " + newConfig); 13472 13473 final Configuration configCopy = new Configuration(mConfiguration); 13474 13475 AttributeCache ac = AttributeCache.instance(); 13476 if (ac != null) { 13477 ac.updateConfiguration(configCopy); 13478 } 13479 13480 // Make sure all resources in our process are updated 13481 // right now, so that anyone who is going to retrieve 13482 // resource values after we return will be sure to get 13483 // the new ones. This is especially important during 13484 // boot, where the first config change needs to guarantee 13485 // all resources have that config before following boot 13486 // code is executed. 13487 mSystemThread.applyConfigurationToResources(configCopy); 13488 13489 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13490 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13491 msg.obj = new Configuration(configCopy); 13492 mHandler.sendMessage(msg); 13493 } 13494 13495 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13496 ProcessRecord app = mLruProcesses.get(i); 13497 try { 13498 if (app.thread != null) { 13499 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13500 + app.processName + " new config " + mConfiguration); 13501 app.thread.scheduleConfigurationChanged(configCopy); 13502 } 13503 } catch (Exception e) { 13504 } 13505 } 13506 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13507 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13508 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13509 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13510 null, false, false, MY_PID, Process.SYSTEM_UID); 13511 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13512 broadcastIntentLocked(null, null, 13513 new Intent(Intent.ACTION_LOCALE_CHANGED), 13514 null, null, 0, null, null, 13515 null, false, false, MY_PID, Process.SYSTEM_UID); 13516 } 13517 } 13518 } 13519 13520 if (changes != 0 && starting == null) { 13521 // If the configuration changed, and the caller is not already 13522 // in the process of starting an activity, then find the top 13523 // activity to check if its configuration needs to change. 13524 starting = mMainStack.topRunningActivityLocked(null); 13525 } 13526 13527 if (starting != null) { 13528 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 13529 // And we need to make sure at this point that all other activities 13530 // are made visible with the correct configuration. 13531 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 13532 } 13533 13534 if (values != null && mWindowManager != null) { 13535 mWindowManager.setNewConfiguration(mConfiguration); 13536 } 13537 13538 return kept; 13539 } 13540 13541 /** 13542 * Save the locale. You must be inside a synchronized (this) block. 13543 */ 13544 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13545 if(isDiff) { 13546 SystemProperties.set("user.language", l.getLanguage()); 13547 SystemProperties.set("user.region", l.getCountry()); 13548 } 13549 13550 if(isPersist) { 13551 SystemProperties.set("persist.sys.language", l.getLanguage()); 13552 SystemProperties.set("persist.sys.country", l.getCountry()); 13553 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13554 } 13555 } 13556 13557 // ========================================================= 13558 // LIFETIME MANAGEMENT 13559 // ========================================================= 13560 13561 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13562 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 13563 if (mAdjSeq == app.adjSeq) { 13564 // This adjustment has already been computed. If we are calling 13565 // from the top, we may have already computed our adjustment with 13566 // an earlier hidden adjustment that isn't really for us... if 13567 // so, use the new hidden adjustment. 13568 if (!recursed && app.hidden) { 13569 app.curAdj = app.curRawAdj = hiddenAdj; 13570 } 13571 return app.curRawAdj; 13572 } 13573 13574 if (app.thread == null) { 13575 app.adjSeq = mAdjSeq; 13576 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13577 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 13578 } 13579 13580 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13581 app.adjSource = null; 13582 app.adjTarget = null; 13583 app.empty = false; 13584 app.hidden = false; 13585 13586 final int activitiesSize = app.activities.size(); 13587 13588 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13589 // The max adjustment doesn't allow this app to be anything 13590 // below foreground, so it is not worth doing work for it. 13591 app.adjType = "fixed"; 13592 app.adjSeq = mAdjSeq; 13593 app.curRawAdj = app.maxAdj; 13594 app.foregroundActivities = false; 13595 app.keeping = true; 13596 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13597 // System process can do UI, and when they do we want to have 13598 // them trim their memory after the user leaves the UI. To 13599 // facilitate this, here we need to determine whether or not it 13600 // is currently showing UI. 13601 app.systemNoUi = true; 13602 if (app == TOP_APP) { 13603 app.systemNoUi = false; 13604 } else if (activitiesSize > 0) { 13605 for (int j = 0; j < activitiesSize; j++) { 13606 final ActivityRecord r = app.activities.get(j); 13607 if (r.visible) { 13608 app.systemNoUi = false; 13609 break; 13610 } 13611 } 13612 } 13613 return (app.curAdj=app.maxAdj); 13614 } 13615 13616 final boolean hadForegroundActivities = app.foregroundActivities; 13617 13618 app.foregroundActivities = false; 13619 app.keeping = false; 13620 app.systemNoUi = false; 13621 13622 // Determine the importance of the process, starting with most 13623 // important to least, and assign an appropriate OOM adjustment. 13624 int adj; 13625 int schedGroup; 13626 if (app == TOP_APP) { 13627 // The last app on the list is the foreground app. 13628 adj = ProcessList.FOREGROUND_APP_ADJ; 13629 schedGroup = Process.THREAD_GROUP_DEFAULT; 13630 app.adjType = "top-activity"; 13631 app.foregroundActivities = true; 13632 } else if (app.instrumentationClass != null) { 13633 // Don't want to kill running instrumentation. 13634 adj = ProcessList.FOREGROUND_APP_ADJ; 13635 schedGroup = Process.THREAD_GROUP_DEFAULT; 13636 app.adjType = "instrumentation"; 13637 } else if (app.curReceiver != null || 13638 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13639 // An app that is currently receiving a broadcast also 13640 // counts as being in the foreground. 13641 adj = ProcessList.FOREGROUND_APP_ADJ; 13642 schedGroup = Process.THREAD_GROUP_DEFAULT; 13643 app.adjType = "broadcast"; 13644 } else if (app.executingServices.size() > 0) { 13645 // An app that is currently executing a service callback also 13646 // counts as being in the foreground. 13647 adj = ProcessList.FOREGROUND_APP_ADJ; 13648 schedGroup = Process.THREAD_GROUP_DEFAULT; 13649 app.adjType = "exec-service"; 13650 } else if (activitiesSize > 0) { 13651 // This app is in the background with paused activities. 13652 // We inspect activities to potentially upgrade adjustment further below. 13653 adj = hiddenAdj; 13654 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13655 app.hidden = true; 13656 app.adjType = "bg-activities"; 13657 } else { 13658 // A very not-needed process. If this is lower in the lru list, 13659 // we will push it in to the empty bucket. 13660 adj = hiddenAdj; 13661 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13662 app.hidden = true; 13663 app.empty = true; 13664 app.adjType = "bg-empty"; 13665 } 13666 13667 // Examine all activities if not already foreground. 13668 if (!app.foregroundActivities && activitiesSize > 0) { 13669 for (int j = 0; j < activitiesSize; j++) { 13670 final ActivityRecord r = app.activities.get(j); 13671 if (r.visible) { 13672 // App has a visible activity; only upgrade adjustment. 13673 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13674 adj = ProcessList.VISIBLE_APP_ADJ; 13675 app.adjType = "visible"; 13676 } 13677 schedGroup = Process.THREAD_GROUP_DEFAULT; 13678 app.hidden = false; 13679 app.foregroundActivities = true; 13680 break; 13681 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED 13682 || r.state == ActivityState.STOPPING) { 13683 // Only upgrade adjustment. 13684 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13685 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13686 app.adjType = "stopping"; 13687 } 13688 app.hidden = false; 13689 app.foregroundActivities = true; 13690 } 13691 } 13692 } 13693 13694 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13695 if (app.foregroundServices) { 13696 // The user is aware of this app, so make it visible. 13697 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13698 app.hidden = false; 13699 app.adjType = "foreground-service"; 13700 schedGroup = Process.THREAD_GROUP_DEFAULT; 13701 } else if (app.forcingToForeground != null) { 13702 // The user is aware of this app, so make it visible. 13703 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13704 app.hidden = false; 13705 app.adjType = "force-foreground"; 13706 app.adjSource = app.forcingToForeground; 13707 schedGroup = Process.THREAD_GROUP_DEFAULT; 13708 } 13709 } 13710 13711 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13712 // We don't want to kill the current heavy-weight process. 13713 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13714 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13715 app.hidden = false; 13716 app.adjType = "heavy"; 13717 } 13718 13719 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13720 // This process is hosting what we currently consider to be the 13721 // home app, so we don't want to let it go into the background. 13722 adj = ProcessList.HOME_APP_ADJ; 13723 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13724 app.hidden = false; 13725 app.adjType = "home"; 13726 } 13727 13728 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13729 && app.activities.size() > 0) { 13730 // This was the previous process that showed UI to the user. 13731 // We want to try to keep it around more aggressively, to give 13732 // a good experience around switching between two apps. 13733 adj = ProcessList.PREVIOUS_APP_ADJ; 13734 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13735 app.hidden = false; 13736 app.adjType = "previous"; 13737 } 13738 13739 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13740 + " reason=" + app.adjType); 13741 13742 // By default, we use the computed adjustment. It may be changed if 13743 // there are applications dependent on our services or providers, but 13744 // this gives us a baseline and makes sure we don't get into an 13745 // infinite recursion. 13746 app.adjSeq = mAdjSeq; 13747 app.curRawAdj = adj; 13748 13749 if (mBackupTarget != null && app == mBackupTarget.app) { 13750 // If possible we want to avoid killing apps while they're being backed up 13751 if (adj > ProcessList.BACKUP_APP_ADJ) { 13752 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13753 adj = ProcessList.BACKUP_APP_ADJ; 13754 app.adjType = "backup"; 13755 app.hidden = false; 13756 } 13757 } 13758 13759 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13760 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13761 final long now = SystemClock.uptimeMillis(); 13762 // This process is more important if the top activity is 13763 // bound to the service. 13764 Iterator<ServiceRecord> jt = app.services.iterator(); 13765 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13766 ServiceRecord s = jt.next(); 13767 if (s.startRequested) { 13768 if (app.hasShownUi && app != mHomeProcess) { 13769 // If this process has shown some UI, let it immediately 13770 // go to the LRU list because it may be pretty heavy with 13771 // UI stuff. We'll tag it with a label just to help 13772 // debug and understand what is going on. 13773 if (adj > ProcessList.SERVICE_ADJ) { 13774 app.adjType = "started-bg-ui-services"; 13775 } 13776 } else { 13777 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13778 // This service has seen some activity within 13779 // recent memory, so we will keep its process ahead 13780 // of the background processes. 13781 if (adj > ProcessList.SERVICE_ADJ) { 13782 adj = ProcessList.SERVICE_ADJ; 13783 app.adjType = "started-services"; 13784 app.hidden = false; 13785 } 13786 } 13787 // If we have let the service slide into the background 13788 // state, still have some text describing what it is doing 13789 // even though the service no longer has an impact. 13790 if (adj > ProcessList.SERVICE_ADJ) { 13791 app.adjType = "started-bg-services"; 13792 } 13793 } 13794 // Don't kill this process because it is doing work; it 13795 // has said it is doing work. 13796 app.keeping = true; 13797 } 13798 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13799 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13800 Iterator<ArrayList<ConnectionRecord>> kt 13801 = s.connections.values().iterator(); 13802 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13803 ArrayList<ConnectionRecord> clist = kt.next(); 13804 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 13805 // XXX should compute this based on the max of 13806 // all connected clients. 13807 ConnectionRecord cr = clist.get(i); 13808 if (cr.binding.client == app) { 13809 // Binding to ourself is not interesting. 13810 continue; 13811 } 13812 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 13813 ProcessRecord client = cr.binding.client; 13814 int clientAdj = adj; 13815 int myHiddenAdj = hiddenAdj; 13816 if (myHiddenAdj > client.hiddenAdj) { 13817 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 13818 myHiddenAdj = client.hiddenAdj; 13819 } else { 13820 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 13821 } 13822 } 13823 clientAdj = computeOomAdjLocked( 13824 client, myHiddenAdj, TOP_APP, true, doingAll); 13825 String adjType = null; 13826 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 13827 // Not doing bind OOM management, so treat 13828 // this guy more like a started service. 13829 if (app.hasShownUi && app != mHomeProcess) { 13830 // If this process has shown some UI, let it immediately 13831 // go to the LRU list because it may be pretty heavy with 13832 // UI stuff. We'll tag it with a label just to help 13833 // debug and understand what is going on. 13834 if (adj > clientAdj) { 13835 adjType = "bound-bg-ui-services"; 13836 } 13837 app.hidden = false; 13838 clientAdj = adj; 13839 } else { 13840 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13841 // This service has not seen activity within 13842 // recent memory, so allow it to drop to the 13843 // LRU list if there is no other reason to keep 13844 // it around. We'll also tag it with a label just 13845 // to help debug and undertand what is going on. 13846 if (adj > clientAdj) { 13847 adjType = "bound-bg-services"; 13848 } 13849 clientAdj = adj; 13850 } 13851 } 13852 } 13853 if (adj > clientAdj) { 13854 // If this process has recently shown UI, and 13855 // the process that is binding to it is less 13856 // important than being visible, then we don't 13857 // care about the binding as much as we care 13858 // about letting this process get into the LRU 13859 // list to be killed and restarted if needed for 13860 // memory. 13861 if (app.hasShownUi && app != mHomeProcess 13862 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13863 adjType = "bound-bg-ui-services"; 13864 } else { 13865 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 13866 |Context.BIND_IMPORTANT)) != 0) { 13867 adj = clientAdj; 13868 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 13869 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 13870 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13871 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13872 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 13873 adj = clientAdj; 13874 } else { 13875 app.pendingUiClean = true; 13876 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13877 adj = ProcessList.VISIBLE_APP_ADJ; 13878 } 13879 } 13880 if (!client.hidden) { 13881 app.hidden = false; 13882 } 13883 if (client.keeping) { 13884 app.keeping = true; 13885 } 13886 adjType = "service"; 13887 } 13888 } 13889 if (adjType != null) { 13890 app.adjType = adjType; 13891 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13892 .REASON_SERVICE_IN_USE; 13893 app.adjSource = cr.binding.client; 13894 app.adjSourceOom = clientAdj; 13895 app.adjTarget = s.name; 13896 } 13897 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13898 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13899 schedGroup = Process.THREAD_GROUP_DEFAULT; 13900 } 13901 } 13902 } 13903 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 13904 ActivityRecord a = cr.activity; 13905 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 13906 (a.visible || a.state == ActivityState.RESUMED 13907 || a.state == ActivityState.PAUSING)) { 13908 adj = ProcessList.FOREGROUND_APP_ADJ; 13909 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13910 schedGroup = Process.THREAD_GROUP_DEFAULT; 13911 } 13912 app.hidden = false; 13913 app.adjType = "service"; 13914 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13915 .REASON_SERVICE_IN_USE; 13916 app.adjSource = a; 13917 app.adjSourceOom = adj; 13918 app.adjTarget = s.name; 13919 } 13920 } 13921 } 13922 } 13923 } 13924 } 13925 13926 // Finally, if this process has active services running in it, we 13927 // would like to avoid killing it unless it would prevent the current 13928 // application from running. By default we put the process in 13929 // with the rest of the background processes; as we scan through 13930 // its services we may bump it up from there. 13931 if (adj > hiddenAdj) { 13932 adj = hiddenAdj; 13933 app.hidden = false; 13934 app.adjType = "bg-services"; 13935 } 13936 } 13937 13938 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13939 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13940 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13941 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13942 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13943 ContentProviderRecord cpr = jt.next(); 13944 if (cpr.clients.size() != 0) { 13945 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13946 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13947 ProcessRecord client = kt.next(); 13948 if (client == app) { 13949 // Being our own client is not interesting. 13950 continue; 13951 } 13952 int myHiddenAdj = hiddenAdj; 13953 if (myHiddenAdj > client.hiddenAdj) { 13954 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13955 myHiddenAdj = client.hiddenAdj; 13956 } else { 13957 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13958 } 13959 } 13960 int clientAdj = computeOomAdjLocked( 13961 client, myHiddenAdj, TOP_APP, true, doingAll); 13962 if (adj > clientAdj) { 13963 if (app.hasShownUi && app != mHomeProcess 13964 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13965 app.adjType = "bg-ui-provider"; 13966 } else { 13967 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13968 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13969 app.adjType = "provider"; 13970 } 13971 if (!client.hidden) { 13972 app.hidden = false; 13973 } 13974 if (client.keeping) { 13975 app.keeping = true; 13976 } 13977 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13978 .REASON_PROVIDER_IN_USE; 13979 app.adjSource = client; 13980 app.adjSourceOom = clientAdj; 13981 app.adjTarget = cpr.name; 13982 } 13983 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13984 schedGroup = Process.THREAD_GROUP_DEFAULT; 13985 } 13986 } 13987 } 13988 // If the provider has external (non-framework) process 13989 // dependencies, ensure that its adjustment is at least 13990 // FOREGROUND_APP_ADJ. 13991 if (cpr.externals != 0) { 13992 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13993 adj = ProcessList.FOREGROUND_APP_ADJ; 13994 schedGroup = Process.THREAD_GROUP_DEFAULT; 13995 app.hidden = false; 13996 app.keeping = true; 13997 app.adjType = "provider"; 13998 app.adjTarget = cpr.name; 13999 } 14000 } 14001 } 14002 } 14003 14004 app.curRawAdj = adj; 14005 14006 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14007 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14008 if (adj > app.maxAdj) { 14009 adj = app.maxAdj; 14010 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14011 schedGroup = Process.THREAD_GROUP_DEFAULT; 14012 } 14013 } 14014 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14015 app.keeping = true; 14016 } 14017 14018 if (app.hasAboveClient) { 14019 // If this process has bound to any services with BIND_ABOVE_CLIENT, 14020 // then we need to drop its adjustment to be lower than the service's 14021 // in order to honor the request. We want to drop it by one adjustment 14022 // level... but there is special meaning applied to various levels so 14023 // we will skip some of them. 14024 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 14025 // System process will not get dropped, ever 14026 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 14027 adj = ProcessList.VISIBLE_APP_ADJ; 14028 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 14029 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14030 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14031 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 14032 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 14033 adj++; 14034 } 14035 } 14036 14037 if (adj == ProcessList.SERVICE_ADJ) { 14038 if (doingAll) { 14039 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 14040 mNewNumServiceProcs++; 14041 } 14042 if (app.serviceb) { 14043 adj = ProcessList.SERVICE_B_ADJ; 14044 } 14045 } else { 14046 app.serviceb = false; 14047 } 14048 14049 app.curAdj = adj; 14050 app.curSchedGroup = schedGroup; 14051 14052 if (hadForegroundActivities != app.foregroundActivities) { 14053 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid, 14054 app.foregroundActivities).sendToTarget(); 14055 } 14056 14057 return app.curRawAdj; 14058 } 14059 14060 /** 14061 * Ask a given process to GC right now. 14062 */ 14063 final void performAppGcLocked(ProcessRecord app) { 14064 try { 14065 app.lastRequestedGc = SystemClock.uptimeMillis(); 14066 if (app.thread != null) { 14067 if (app.reportLowMemory) { 14068 app.reportLowMemory = false; 14069 app.thread.scheduleLowMemory(); 14070 } else { 14071 app.thread.processInBackground(); 14072 } 14073 } 14074 } catch (Exception e) { 14075 // whatever. 14076 } 14077 } 14078 14079 /** 14080 * Returns true if things are idle enough to perform GCs. 14081 */ 14082 private final boolean canGcNowLocked() { 14083 return mParallelBroadcasts.size() == 0 14084 && mOrderedBroadcasts.size() == 0 14085 && (mSleeping || (mMainStack.mResumedActivity != null && 14086 mMainStack.mResumedActivity.idle)); 14087 } 14088 14089 /** 14090 * Perform GCs on all processes that are waiting for it, but only 14091 * if things are idle. 14092 */ 14093 final void performAppGcsLocked() { 14094 final int N = mProcessesToGc.size(); 14095 if (N <= 0) { 14096 return; 14097 } 14098 if (canGcNowLocked()) { 14099 while (mProcessesToGc.size() > 0) { 14100 ProcessRecord proc = mProcessesToGc.remove(0); 14101 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14102 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14103 <= SystemClock.uptimeMillis()) { 14104 // To avoid spamming the system, we will GC processes one 14105 // at a time, waiting a few seconds between each. 14106 performAppGcLocked(proc); 14107 scheduleAppGcsLocked(); 14108 return; 14109 } else { 14110 // It hasn't been long enough since we last GCed this 14111 // process... put it in the list to wait for its time. 14112 addProcessToGcListLocked(proc); 14113 break; 14114 } 14115 } 14116 } 14117 14118 scheduleAppGcsLocked(); 14119 } 14120 } 14121 14122 /** 14123 * If all looks good, perform GCs on all processes waiting for them. 14124 */ 14125 final void performAppGcsIfAppropriateLocked() { 14126 if (canGcNowLocked()) { 14127 performAppGcsLocked(); 14128 return; 14129 } 14130 // Still not idle, wait some more. 14131 scheduleAppGcsLocked(); 14132 } 14133 14134 /** 14135 * Schedule the execution of all pending app GCs. 14136 */ 14137 final void scheduleAppGcsLocked() { 14138 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14139 14140 if (mProcessesToGc.size() > 0) { 14141 // Schedule a GC for the time to the next process. 14142 ProcessRecord proc = mProcessesToGc.get(0); 14143 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14144 14145 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14146 long now = SystemClock.uptimeMillis(); 14147 if (when < (now+GC_TIMEOUT)) { 14148 when = now + GC_TIMEOUT; 14149 } 14150 mHandler.sendMessageAtTime(msg, when); 14151 } 14152 } 14153 14154 /** 14155 * Add a process to the array of processes waiting to be GCed. Keeps the 14156 * list in sorted order by the last GC time. The process can't already be 14157 * on the list. 14158 */ 14159 final void addProcessToGcListLocked(ProcessRecord proc) { 14160 boolean added = false; 14161 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14162 if (mProcessesToGc.get(i).lastRequestedGc < 14163 proc.lastRequestedGc) { 14164 added = true; 14165 mProcessesToGc.add(i+1, proc); 14166 break; 14167 } 14168 } 14169 if (!added) { 14170 mProcessesToGc.add(0, proc); 14171 } 14172 } 14173 14174 /** 14175 * Set up to ask a process to GC itself. This will either do it 14176 * immediately, or put it on the list of processes to gc the next 14177 * time things are idle. 14178 */ 14179 final void scheduleAppGcLocked(ProcessRecord app) { 14180 long now = SystemClock.uptimeMillis(); 14181 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14182 return; 14183 } 14184 if (!mProcessesToGc.contains(app)) { 14185 addProcessToGcListLocked(app); 14186 scheduleAppGcsLocked(); 14187 } 14188 } 14189 14190 final void checkExcessivePowerUsageLocked(boolean doKills) { 14191 updateCpuStatsNow(); 14192 14193 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14194 boolean doWakeKills = doKills; 14195 boolean doCpuKills = doKills; 14196 if (mLastPowerCheckRealtime == 0) { 14197 doWakeKills = false; 14198 } 14199 if (mLastPowerCheckUptime == 0) { 14200 doCpuKills = false; 14201 } 14202 if (stats.isScreenOn()) { 14203 doWakeKills = false; 14204 } 14205 final long curRealtime = SystemClock.elapsedRealtime(); 14206 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14207 final long curUptime = SystemClock.uptimeMillis(); 14208 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14209 mLastPowerCheckRealtime = curRealtime; 14210 mLastPowerCheckUptime = curUptime; 14211 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14212 doWakeKills = false; 14213 } 14214 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14215 doCpuKills = false; 14216 } 14217 int i = mLruProcesses.size(); 14218 while (i > 0) { 14219 i--; 14220 ProcessRecord app = mLruProcesses.get(i); 14221 if (!app.keeping) { 14222 long wtime; 14223 synchronized (stats) { 14224 wtime = stats.getProcessWakeTime(app.info.uid, 14225 app.pid, curRealtime); 14226 } 14227 long wtimeUsed = wtime - app.lastWakeTime; 14228 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14229 if (DEBUG_POWER) { 14230 StringBuilder sb = new StringBuilder(128); 14231 sb.append("Wake for "); 14232 app.toShortString(sb); 14233 sb.append(": over "); 14234 TimeUtils.formatDuration(realtimeSince, sb); 14235 sb.append(" used "); 14236 TimeUtils.formatDuration(wtimeUsed, sb); 14237 sb.append(" ("); 14238 sb.append((wtimeUsed*100)/realtimeSince); 14239 sb.append("%)"); 14240 Slog.i(TAG, sb.toString()); 14241 sb.setLength(0); 14242 sb.append("CPU for "); 14243 app.toShortString(sb); 14244 sb.append(": over "); 14245 TimeUtils.formatDuration(uptimeSince, sb); 14246 sb.append(" used "); 14247 TimeUtils.formatDuration(cputimeUsed, sb); 14248 sb.append(" ("); 14249 sb.append((cputimeUsed*100)/uptimeSince); 14250 sb.append("%)"); 14251 Slog.i(TAG, sb.toString()); 14252 } 14253 // If a process has held a wake lock for more 14254 // than 50% of the time during this period, 14255 // that sounds pad. Kill! 14256 if (doWakeKills && realtimeSince > 0 14257 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14258 synchronized (stats) { 14259 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14260 realtimeSince, wtimeUsed); 14261 } 14262 Slog.w(TAG, "Excessive wake lock in " + app.processName 14263 + " (pid " + app.pid + "): held " + wtimeUsed 14264 + " during " + realtimeSince); 14265 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14266 app.processName, app.setAdj, "excessive wake lock"); 14267 Process.killProcessQuiet(app.pid); 14268 } else if (doCpuKills && uptimeSince > 0 14269 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14270 synchronized (stats) { 14271 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 14272 uptimeSince, cputimeUsed); 14273 } 14274 Slog.w(TAG, "Excessive CPU in " + app.processName 14275 + " (pid " + app.pid + "): used " + cputimeUsed 14276 + " during " + uptimeSince); 14277 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14278 app.processName, app.setAdj, "excessive cpu"); 14279 Process.killProcessQuiet(app.pid); 14280 } else { 14281 app.lastWakeTime = wtime; 14282 app.lastCpuTime = app.curCpuTime; 14283 } 14284 } 14285 } 14286 } 14287 14288 private final boolean updateOomAdjLocked( 14289 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 14290 app.hiddenAdj = hiddenAdj; 14291 14292 if (app.thread == null) { 14293 return false; 14294 } 14295 14296 final boolean wasKeeping = app.keeping; 14297 14298 boolean success = true; 14299 14300 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 14301 14302 if (app.curRawAdj != app.setRawAdj) { 14303 if (false) { 14304 // Removing for now. Forcing GCs is not so useful anymore 14305 // with Dalvik, and the new memory level hint facility is 14306 // better for what we need to do these days. 14307 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ 14308 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14309 // If this app is transitioning from foreground to 14310 // non-foreground, have it do a gc. 14311 scheduleAppGcLocked(app); 14312 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14313 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14314 // Likewise do a gc when an app is moving in to the 14315 // background (such as a service stopping). 14316 scheduleAppGcLocked(app); 14317 } 14318 } 14319 14320 if (wasKeeping && !app.keeping) { 14321 // This app is no longer something we want to keep. Note 14322 // its current wake lock time to later know to kill it if 14323 // it is not behaving well. 14324 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14325 synchronized (stats) { 14326 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 14327 app.pid, SystemClock.elapsedRealtime()); 14328 } 14329 app.lastCpuTime = app.curCpuTime; 14330 } 14331 14332 app.setRawAdj = app.curRawAdj; 14333 } 14334 14335 if (app.curAdj != app.setAdj) { 14336 if (Process.setOomAdj(app.pid, app.curAdj)) { 14337 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 14338 TAG, "Set " + app.pid + " " + app.processName + 14339 " adj " + app.curAdj + ": " + app.adjType); 14340 app.setAdj = app.curAdj; 14341 } else { 14342 success = false; 14343 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 14344 } 14345 } 14346 if (app.setSchedGroup != app.curSchedGroup) { 14347 app.setSchedGroup = app.curSchedGroup; 14348 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 14349 "Setting process group of " + app.processName 14350 + " to " + app.curSchedGroup); 14351 if (app.waitingToKill != null && 14352 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 14353 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 14354 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14355 app.processName, app.setAdj, app.waitingToKill); 14356 Process.killProcessQuiet(app.pid); 14357 success = false; 14358 } else { 14359 if (true) { 14360 long oldId = Binder.clearCallingIdentity(); 14361 try { 14362 Process.setProcessGroup(app.pid, app.curSchedGroup); 14363 } catch (Exception e) { 14364 Slog.w(TAG, "Failed setting process group of " + app.pid 14365 + " to " + app.curSchedGroup); 14366 e.printStackTrace(); 14367 } finally { 14368 Binder.restoreCallingIdentity(oldId); 14369 } 14370 } else { 14371 if (app.thread != null) { 14372 try { 14373 app.thread.setSchedulingGroup(app.curSchedGroup); 14374 } catch (RemoteException e) { 14375 } 14376 } 14377 } 14378 } 14379 } 14380 return success; 14381 } 14382 14383 private final ActivityRecord resumedAppLocked() { 14384 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 14385 if (resumedActivity == null || resumedActivity.app == null) { 14386 resumedActivity = mMainStack.mPausingActivity; 14387 if (resumedActivity == null || resumedActivity.app == null) { 14388 resumedActivity = mMainStack.topRunningActivityLocked(null); 14389 } 14390 } 14391 return resumedActivity; 14392 } 14393 14394 private final boolean updateOomAdjLocked(ProcessRecord app) { 14395 final ActivityRecord TOP_ACT = resumedAppLocked(); 14396 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14397 int curAdj = app.curAdj; 14398 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14399 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14400 14401 mAdjSeq++; 14402 14403 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 14404 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14405 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14406 if (nowHidden != wasHidden) { 14407 // Changed to/from hidden state, so apps after it in the LRU 14408 // list may also be changed. 14409 updateOomAdjLocked(); 14410 } 14411 return success; 14412 } 14413 14414 final void updateOomAdjLocked() { 14415 final ActivityRecord TOP_ACT = resumedAppLocked(); 14416 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14417 14418 if (false) { 14419 RuntimeException e = new RuntimeException(); 14420 e.fillInStackTrace(); 14421 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 14422 } 14423 14424 mAdjSeq++; 14425 mNewNumServiceProcs = 0; 14426 14427 // Let's determine how many processes we have running vs. 14428 // how many slots we have for background processes; we may want 14429 // to put multiple processes in a slot of there are enough of 14430 // them. 14431 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 14432 int factor = (mLruProcesses.size()-4)/numSlots; 14433 if (factor < 1) factor = 1; 14434 int step = 0; 14435 int numHidden = 0; 14436 14437 // First update the OOM adjustment for each of the 14438 // application processes based on their current state. 14439 int i = mLruProcesses.size(); 14440 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 14441 while (i > 0) { 14442 i--; 14443 ProcessRecord app = mLruProcesses.get(i); 14444 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 14445 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 14446 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 14447 && app.curAdj == curHiddenAdj) { 14448 step++; 14449 if (step >= factor) { 14450 step = 0; 14451 curHiddenAdj++; 14452 } 14453 } 14454 if (!app.killedBackground) { 14455 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14456 numHidden++; 14457 if (numHidden > mProcessLimit) { 14458 Slog.i(TAG, "No longer want " + app.processName 14459 + " (pid " + app.pid + "): hidden #" + numHidden); 14460 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14461 app.processName, app.setAdj, "too many background"); 14462 app.killedBackground = true; 14463 Process.killProcessQuiet(app.pid); 14464 } 14465 } 14466 } 14467 } 14468 14469 mNumServiceProcs = mNewNumServiceProcs; 14470 14471 // Now determine the memory trimming level of background processes. 14472 // Unfortunately we need to start at the back of the list to do this 14473 // properly. We only do this if the number of background apps we 14474 // are managing to keep around is less than half the maximum we desire; 14475 // if we are keeping a good number around, we'll let them use whatever 14476 // memory they want. 14477 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 14478 final int N = mLruProcesses.size(); 14479 factor = numHidden/3; 14480 int minFactor = 2; 14481 if (mHomeProcess != null) minFactor++; 14482 if (mPreviousProcess != null) minFactor++; 14483 if (factor < minFactor) factor = minFactor; 14484 step = 0; 14485 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14486 for (i=0; i<N; i++) { 14487 ProcessRecord app = mLruProcesses.get(i); 14488 if (app.curAdj >= ProcessList.HOME_APP_ADJ 14489 && app.curAdj != ProcessList.SERVICE_B_ADJ 14490 && !app.killedBackground) { 14491 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14492 try { 14493 app.thread.scheduleTrimMemory(curLevel); 14494 } catch (RemoteException e) { 14495 } 14496 if (false) { 14497 // For now we won't do this; our memory trimming seems 14498 // to be good enough at this point that destroying 14499 // activities causes more harm than good. 14500 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14501 && app != mHomeProcess && app != mPreviousProcess) { 14502 // For these apps we will also finish their activities 14503 // to help them free memory. 14504 mMainStack.destroyActivitiesLocked(app, false, "trim"); 14505 } 14506 } 14507 } 14508 app.trimMemoryLevel = curLevel; 14509 step++; 14510 if (step >= factor) { 14511 switch (curLevel) { 14512 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14513 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14514 break; 14515 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14516 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14517 break; 14518 } 14519 } 14520 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14521 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14522 && app.thread != null) { 14523 try { 14524 app.thread.scheduleTrimMemory( 14525 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14526 } catch (RemoteException e) { 14527 } 14528 } 14529 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14530 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14531 && app.pendingUiClean) { 14532 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14533 && app.thread != null) { 14534 try { 14535 app.thread.scheduleTrimMemory( 14536 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14537 } catch (RemoteException e) { 14538 } 14539 } 14540 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14541 app.pendingUiClean = false; 14542 } else { 14543 app.trimMemoryLevel = 0; 14544 } 14545 } 14546 } else { 14547 final int N = mLruProcesses.size(); 14548 for (i=0; i<N; i++) { 14549 ProcessRecord app = mLruProcesses.get(i); 14550 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14551 && app.pendingUiClean) { 14552 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14553 && app.thread != null) { 14554 try { 14555 app.thread.scheduleTrimMemory( 14556 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14557 } catch (RemoteException e) { 14558 } 14559 } 14560 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14561 app.pendingUiClean = false; 14562 } else { 14563 app.trimMemoryLevel = 0; 14564 } 14565 } 14566 } 14567 14568 if (mAlwaysFinishActivities) { 14569 mMainStack.destroyActivitiesLocked(null, false, "always-finish"); 14570 } 14571 } 14572 14573 final void trimApplications() { 14574 synchronized (this) { 14575 int i; 14576 14577 // First remove any unused application processes whose package 14578 // has been removed. 14579 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14580 final ProcessRecord app = mRemovedProcesses.get(i); 14581 if (app.activities.size() == 0 14582 && app.curReceiver == null && app.services.size() == 0) { 14583 Slog.i( 14584 TAG, "Exiting empty application process " 14585 + app.processName + " (" 14586 + (app.thread != null ? app.thread.asBinder() : null) 14587 + ")\n"); 14588 if (app.pid > 0 && app.pid != MY_PID) { 14589 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14590 app.processName, app.setAdj, "empty"); 14591 Process.killProcessQuiet(app.pid); 14592 } else { 14593 try { 14594 app.thread.scheduleExit(); 14595 } catch (Exception e) { 14596 // Ignore exceptions. 14597 } 14598 } 14599 cleanUpApplicationRecordLocked(app, false, true, -1); 14600 mRemovedProcesses.remove(i); 14601 14602 if (app.persistent) { 14603 if (app.persistent) { 14604 addAppLocked(app.info); 14605 } 14606 } 14607 } 14608 } 14609 14610 // Now update the oom adj for all processes. 14611 updateOomAdjLocked(); 14612 } 14613 } 14614 14615 /** This method sends the specified signal to each of the persistent apps */ 14616 public void signalPersistentProcesses(int sig) throws RemoteException { 14617 if (sig != Process.SIGNAL_USR1) { 14618 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14619 } 14620 14621 synchronized (this) { 14622 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14623 != PackageManager.PERMISSION_GRANTED) { 14624 throw new SecurityException("Requires permission " 14625 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14626 } 14627 14628 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14629 ProcessRecord r = mLruProcesses.get(i); 14630 if (r.thread != null && r.persistent) { 14631 Process.sendSignal(r.pid, sig); 14632 } 14633 } 14634 } 14635 } 14636 14637 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14638 if (proc == null || proc == mProfileProc) { 14639 proc = mProfileProc; 14640 path = mProfileFile; 14641 profileType = mProfileType; 14642 clearProfilerLocked(); 14643 } 14644 if (proc == null) { 14645 return; 14646 } 14647 try { 14648 proc.thread.profilerControl(false, path, null, profileType); 14649 } catch (RemoteException e) { 14650 throw new IllegalStateException("Process disappeared"); 14651 } 14652 } 14653 14654 private void clearProfilerLocked() { 14655 if (mProfileFd != null) { 14656 try { 14657 mProfileFd.close(); 14658 } catch (IOException e) { 14659 } 14660 } 14661 mProfileApp = null; 14662 mProfileProc = null; 14663 mProfileFile = null; 14664 mProfileType = 0; 14665 mAutoStopProfiler = false; 14666 } 14667 14668 public boolean profileControl(String process, boolean start, 14669 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14670 14671 try { 14672 synchronized (this) { 14673 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14674 // its own permission. 14675 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14676 != PackageManager.PERMISSION_GRANTED) { 14677 throw new SecurityException("Requires permission " 14678 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14679 } 14680 14681 if (start && fd == null) { 14682 throw new IllegalArgumentException("null fd"); 14683 } 14684 14685 ProcessRecord proc = null; 14686 if (process != null) { 14687 try { 14688 int pid = Integer.parseInt(process); 14689 synchronized (mPidsSelfLocked) { 14690 proc = mPidsSelfLocked.get(pid); 14691 } 14692 } catch (NumberFormatException e) { 14693 } 14694 14695 if (proc == null) { 14696 HashMap<String, SparseArray<ProcessRecord>> all 14697 = mProcessNames.getMap(); 14698 SparseArray<ProcessRecord> procs = all.get(process); 14699 if (procs != null && procs.size() > 0) { 14700 proc = procs.valueAt(0); 14701 } 14702 } 14703 } 14704 14705 if (start && (proc == null || proc.thread == null)) { 14706 throw new IllegalArgumentException("Unknown process: " + process); 14707 } 14708 14709 if (start) { 14710 stopProfilerLocked(null, null, 0); 14711 setProfileApp(proc.info, proc.processName, path, fd, false); 14712 mProfileProc = proc; 14713 mProfileType = profileType; 14714 try { 14715 fd = fd.dup(); 14716 } catch (IOException e) { 14717 fd = null; 14718 } 14719 proc.thread.profilerControl(start, path, fd, profileType); 14720 fd = null; 14721 mProfileFd = null; 14722 } else { 14723 stopProfilerLocked(proc, path, profileType); 14724 if (fd != null) { 14725 try { 14726 fd.close(); 14727 } catch (IOException e) { 14728 } 14729 } 14730 } 14731 14732 return true; 14733 } 14734 } catch (RemoteException e) { 14735 throw new IllegalStateException("Process disappeared"); 14736 } finally { 14737 if (fd != null) { 14738 try { 14739 fd.close(); 14740 } catch (IOException e) { 14741 } 14742 } 14743 } 14744 } 14745 14746 public boolean dumpHeap(String process, boolean managed, 14747 String path, ParcelFileDescriptor fd) throws RemoteException { 14748 14749 try { 14750 synchronized (this) { 14751 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14752 // its own permission (same as profileControl). 14753 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14754 != PackageManager.PERMISSION_GRANTED) { 14755 throw new SecurityException("Requires permission " 14756 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14757 } 14758 14759 if (fd == null) { 14760 throw new IllegalArgumentException("null fd"); 14761 } 14762 14763 ProcessRecord proc = null; 14764 try { 14765 int pid = Integer.parseInt(process); 14766 synchronized (mPidsSelfLocked) { 14767 proc = mPidsSelfLocked.get(pid); 14768 } 14769 } catch (NumberFormatException e) { 14770 } 14771 14772 if (proc == null) { 14773 HashMap<String, SparseArray<ProcessRecord>> all 14774 = mProcessNames.getMap(); 14775 SparseArray<ProcessRecord> procs = all.get(process); 14776 if (procs != null && procs.size() > 0) { 14777 proc = procs.valueAt(0); 14778 } 14779 } 14780 14781 if (proc == null || proc.thread == null) { 14782 throw new IllegalArgumentException("Unknown process: " + process); 14783 } 14784 14785 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14786 if (!isDebuggable) { 14787 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14788 throw new SecurityException("Process not debuggable: " + proc); 14789 } 14790 } 14791 14792 proc.thread.dumpHeap(managed, path, fd); 14793 fd = null; 14794 return true; 14795 } 14796 } catch (RemoteException e) { 14797 throw new IllegalStateException("Process disappeared"); 14798 } finally { 14799 if (fd != null) { 14800 try { 14801 fd.close(); 14802 } catch (IOException e) { 14803 } 14804 } 14805 } 14806 } 14807 14808 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14809 public void monitor() { 14810 synchronized (this) { } 14811 } 14812 14813 public void onCoreSettingsChange(Bundle settings) { 14814 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14815 ProcessRecord processRecord = mLruProcesses.get(i); 14816 try { 14817 if (processRecord.thread != null) { 14818 processRecord.thread.setCoreSettings(settings); 14819 } 14820 } catch (RemoteException re) { 14821 /* ignore */ 14822 } 14823 } 14824 } 14825 14826 // Multi-user methods 14827 14828 public boolean switchUser(int userid) { 14829 // TODO 14830 return true; 14831 } 14832 } 14833