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.util.EventLog; 109 import android.util.Pair; 110 import android.util.Slog; 111 import android.util.Log; 112 import android.util.PrintWriterPrinter; 113 import android.util.SparseArray; 114 import android.util.TimeUtils; 115 import android.view.Gravity; 116 import android.view.LayoutInflater; 117 import android.view.View; 118 import android.view.WindowManager; 119 import android.view.WindowManagerPolicy; 120 121 import java.io.BufferedInputStream; 122 import java.io.BufferedOutputStream; 123 import java.io.BufferedReader; 124 import java.io.DataInputStream; 125 import java.io.DataOutputStream; 126 import java.io.File; 127 import java.io.FileDescriptor; 128 import java.io.FileInputStream; 129 import java.io.FileNotFoundException; 130 import java.io.FileOutputStream; 131 import java.io.IOException; 132 import java.io.InputStreamReader; 133 import java.io.PrintWriter; 134 import java.io.StringWriter; 135 import java.lang.IllegalStateException; 136 import java.lang.ref.WeakReference; 137 import java.util.ArrayList; 138 import java.util.Collections; 139 import java.util.Comparator; 140 import java.util.HashMap; 141 import java.util.HashSet; 142 import java.util.Iterator; 143 import java.util.List; 144 import java.util.Locale; 145 import java.util.Map; 146 import java.util.Set; 147 import java.util.concurrent.atomic.AtomicBoolean; 148 import java.util.concurrent.atomic.AtomicLong; 149 150 public final class ActivityManagerService extends ActivityManagerNative 151 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 152 static final String TAG = "ActivityManager"; 153 static final boolean DEBUG = false; 154 static final boolean localLOGV = DEBUG; 155 static final boolean DEBUG_SWITCH = localLOGV || false; 156 static final boolean DEBUG_TASKS = localLOGV || false; 157 static final boolean DEBUG_PAUSE = localLOGV || false; 158 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 159 static final boolean DEBUG_TRANSITION = localLOGV || false; 160 static final boolean DEBUG_BROADCAST = localLOGV || false; 161 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 162 static final boolean DEBUG_SERVICE = localLOGV || false; 163 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 164 static final boolean DEBUG_VISBILITY = localLOGV || false; 165 static final boolean DEBUG_PROCESSES = localLOGV || false; 166 static final boolean DEBUG_PROVIDER = localLOGV || false; 167 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 168 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 169 static final boolean DEBUG_RESULTS = localLOGV || false; 170 static final boolean DEBUG_BACKUP = localLOGV || false; 171 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 172 static final boolean DEBUG_POWER = localLOGV || false; 173 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 174 static final boolean VALIDATE_TOKENS = false; 175 static final boolean SHOW_ACTIVITY_START_TIME = true; 176 177 // Control over CPU and battery monitoring. 178 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 179 static final boolean MONITOR_CPU_USAGE = true; 180 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 181 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 182 static final boolean MONITOR_THREAD_CPU_USAGE = false; 183 184 // The flags that are set for all calls we make to the package manager. 185 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 186 187 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 188 189 // Maximum number of recent tasks that we can remember. 190 static final int MAX_RECENT_TASKS = 20; 191 192 // Amount of time after a call to stopAppSwitches() during which we will 193 // prevent further untrusted switches from happening. 194 static final long APP_SWITCH_DELAY_TIME = 5*1000; 195 196 // How long we wait for a launched process to attach to the activity manager 197 // before we decide it's never going to come up for real. 198 static final int PROC_START_TIMEOUT = 10*1000; 199 200 // How long we wait for a launched process to attach to the activity manager 201 // before we decide it's never going to come up for real, when the process was 202 // started with a wrapper for instrumentation (such as Valgrind) because it 203 // could take much longer than usual. 204 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 205 206 // How long to wait after going idle before forcing apps to GC. 207 static final int GC_TIMEOUT = 5*1000; 208 209 // The minimum amount of time between successive GC requests for a process. 210 static final int GC_MIN_INTERVAL = 60*1000; 211 212 // The rate at which we check for apps using excessive power -- 15 mins. 213 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 214 215 // The minimum sample duration we will allow before deciding we have 216 // enough data on wake locks to start killing things. 217 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 218 219 // The minimum sample duration we will allow before deciding we have 220 // enough data on CPU usage to start killing things. 221 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 222 223 // How long we allow a receiver to run before giving up on it. 224 static final int BROADCAST_TIMEOUT = 10*1000; 225 226 // How long we wait for a service to finish executing. 227 static final int SERVICE_TIMEOUT = 20*1000; 228 229 // How long a service needs to be running until restarting its process 230 // is no longer considered to be a relaunch of the service. 231 static final int SERVICE_RESTART_DURATION = 5*1000; 232 233 // How long a service needs to be running until it will start back at 234 // SERVICE_RESTART_DURATION after being killed. 235 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 236 237 // Multiplying factor to increase restart duration time by, for each time 238 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 239 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 240 241 // The minimum amount of time between restarting services that we allow. 242 // That is, when multiple services are restarting, we won't allow each 243 // to restart less than this amount of time from the last one. 244 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 245 246 // Maximum amount of time for there to be no activity on a service before 247 // we consider it non-essential and allow its process to go on the 248 // LRU background list. 249 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 250 251 // How long we wait until we timeout on key dispatching. 252 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 253 254 // How long we wait until we timeout on key dispatching during instrumentation. 255 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 256 257 static final int MY_PID = Process.myPid(); 258 259 static final String[] EMPTY_STRING_ARRAY = new String[0]; 260 261 public ActivityStack mMainStack; 262 263 /** 264 * Description of a request to start a new activity, which has been held 265 * due to app switches being disabled. 266 */ 267 static class PendingActivityLaunch { 268 ActivityRecord r; 269 ActivityRecord sourceRecord; 270 Uri[] grantedUriPermissions; 271 int grantedMode; 272 boolean onlyIfNeeded; 273 } 274 275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 276 = new ArrayList<PendingActivityLaunch>(); 277 278 /** 279 * List of all active broadcasts that are to be executed immediately 280 * (without waiting for another broadcast to finish). Currently this only 281 * contains broadcasts to registered receivers, to avoid spinning up 282 * a bunch of processes to execute IntentReceiver components. 283 */ 284 final ArrayList<BroadcastRecord> mParallelBroadcasts 285 = new ArrayList<BroadcastRecord>(); 286 287 /** 288 * List of all active broadcasts that are to be executed one at a time. 289 * The object at the top of the list is the currently activity broadcasts; 290 * those after it are waiting for the top to finish.. 291 */ 292 final ArrayList<BroadcastRecord> mOrderedBroadcasts 293 = new ArrayList<BroadcastRecord>(); 294 295 /** 296 * Historical data of past broadcasts, for debugging. 297 */ 298 static final int MAX_BROADCAST_HISTORY = 25; 299 final BroadcastRecord[] mBroadcastHistory 300 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 301 302 /** 303 * Set when we current have a BROADCAST_INTENT_MSG in flight. 304 */ 305 boolean mBroadcastsScheduled = false; 306 307 /** 308 * Activity we have told the window manager to have key focus. 309 */ 310 ActivityRecord mFocusedActivity = null; 311 /** 312 * List of intents that were used to start the most recent tasks. 313 */ 314 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 315 316 /** 317 * Process management. 318 */ 319 final ProcessList mProcessList = new ProcessList(); 320 321 /** 322 * All of the applications we currently have running organized by name. 323 * The keys are strings of the application package name (as 324 * returned by the package manager), and the keys are ApplicationRecord 325 * objects. 326 */ 327 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 328 329 /** 330 * The currently running heavy-weight process, if any. 331 */ 332 ProcessRecord mHeavyWeightProcess = null; 333 334 /** 335 * The last time that various processes have crashed. 336 */ 337 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 338 339 /** 340 * Set of applications that we consider to be bad, and will reject 341 * incoming broadcasts from (which the user has no control over). 342 * Processes are added to this set when they have crashed twice within 343 * a minimum amount of time; they are removed from it when they are 344 * later restarted (hopefully due to some user action). The value is the 345 * time it was added to the list. 346 */ 347 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 348 349 /** 350 * All of the processes we currently have running organized by pid. 351 * The keys are the pid running the application. 352 * 353 * <p>NOTE: This object is protected by its own lock, NOT the global 354 * activity manager lock! 355 */ 356 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 357 358 /** 359 * All of the processes that have been forced to be foreground. The key 360 * is the pid of the caller who requested it (we hold a death 361 * link on it). 362 */ 363 abstract class ForegroundToken implements IBinder.DeathRecipient { 364 int pid; 365 IBinder token; 366 } 367 final SparseArray<ForegroundToken> mForegroundProcesses 368 = new SparseArray<ForegroundToken>(); 369 370 /** 371 * List of records for processes that someone had tried to start before the 372 * system was ready. We don't start them at that point, but ensure they 373 * are started by the time booting is complete. 374 */ 375 final ArrayList<ProcessRecord> mProcessesOnHold 376 = new ArrayList<ProcessRecord>(); 377 378 /** 379 * List of persistent applications that are in the process 380 * of being started. 381 */ 382 final ArrayList<ProcessRecord> mPersistentStartingProcesses 383 = new ArrayList<ProcessRecord>(); 384 385 /** 386 * Processes that are being forcibly torn down. 387 */ 388 final ArrayList<ProcessRecord> mRemovedProcesses 389 = new ArrayList<ProcessRecord>(); 390 391 /** 392 * List of running applications, sorted by recent usage. 393 * The first entry in the list is the least recently used. 394 * It contains ApplicationRecord objects. This list does NOT include 395 * any persistent application records (since we never want to exit them). 396 */ 397 final ArrayList<ProcessRecord> mLruProcesses 398 = new ArrayList<ProcessRecord>(); 399 400 /** 401 * List of processes that should gc as soon as things are idle. 402 */ 403 final ArrayList<ProcessRecord> mProcessesToGc 404 = new ArrayList<ProcessRecord>(); 405 406 /** 407 * This is the process holding what we currently consider to be 408 * the "home" activity. 409 */ 410 ProcessRecord mHomeProcess; 411 412 /** 413 * This is the process holding the activity the user last visited that 414 * is in a different process from the one they are currently in. 415 */ 416 ProcessRecord mPreviousProcess; 417 418 /** 419 * The time at which the previous process was last visible. 420 */ 421 long mPreviousProcessVisibleTime; 422 423 /** 424 * Packages that the user has asked to have run in screen size 425 * compatibility mode instead of filling the screen. 426 */ 427 final CompatModePackages mCompatModePackages; 428 429 /** 430 * Set of PendingResultRecord objects that are currently active. 431 */ 432 final HashSet mPendingResultRecords = new HashSet(); 433 434 /** 435 * Set of IntentSenderRecord objects that are currently active. 436 */ 437 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 438 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 439 440 /** 441 * Fingerprints (hashCode()) of stack traces that we've 442 * already logged DropBox entries for. Guarded by itself. If 443 * something (rogue user app) forces this over 444 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 445 */ 446 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 447 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 448 449 /** 450 * Strict Mode background batched logging state. 451 * 452 * The string buffer is guarded by itself, and its lock is also 453 * used to determine if another batched write is already 454 * in-flight. 455 */ 456 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 457 458 /** 459 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler. 460 */ 461 private boolean mPendingBroadcastTimeoutMessage; 462 463 /** 464 * Intent broadcast that we have tried to start, but are 465 * waiting for its application's process to be created. We only 466 * need one (instead of a list) because we always process broadcasts 467 * one at a time, so no others can be started while waiting for this 468 * one. 469 */ 470 BroadcastRecord mPendingBroadcast = null; 471 472 /** 473 * The receiver index that is pending, to restart the broadcast if needed. 474 */ 475 int mPendingBroadcastRecvIndex; 476 477 /** 478 * Keeps track of all IIntentReceivers that have been registered for 479 * broadcasts. Hash keys are the receiver IBinder, hash value is 480 * a ReceiverList. 481 */ 482 final HashMap mRegisteredReceivers = new HashMap(); 483 484 /** 485 * Resolver for broadcast intents to registered receivers. 486 * Holds BroadcastFilter (subclass of IntentFilter). 487 */ 488 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 489 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 490 @Override 491 protected boolean allowFilterResult( 492 BroadcastFilter filter, List<BroadcastFilter> dest) { 493 IBinder target = filter.receiverList.receiver.asBinder(); 494 for (int i=dest.size()-1; i>=0; i--) { 495 if (dest.get(i).receiverList.receiver.asBinder() == target) { 496 return false; 497 } 498 } 499 return true; 500 } 501 502 @Override 503 protected String packageForFilter(BroadcastFilter filter) { 504 return filter.packageName; 505 } 506 }; 507 508 /** 509 * State of all active sticky broadcasts. Keys are the action of the 510 * sticky Intent, values are an ArrayList of all broadcasted intents with 511 * that action (which should usually be one). 512 */ 513 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 514 new HashMap<String, ArrayList<Intent>>(); 515 516 /** 517 * All currently running services. 518 */ 519 final HashMap<ComponentName, ServiceRecord> mServices = 520 new HashMap<ComponentName, ServiceRecord>(); 521 522 /** 523 * All currently running services indexed by the Intent used to start them. 524 */ 525 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 526 new HashMap<Intent.FilterComparison, ServiceRecord>(); 527 528 /** 529 * All currently bound service connections. Keys are the IBinder of 530 * the client's IServiceConnection. 531 */ 532 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections 533 = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); 534 535 /** 536 * List of services that we have been asked to start, 537 * but haven't yet been able to. It is used to hold start requests 538 * while waiting for their corresponding application thread to get 539 * going. 540 */ 541 final ArrayList<ServiceRecord> mPendingServices 542 = new ArrayList<ServiceRecord>(); 543 544 /** 545 * List of services that are scheduled to restart following a crash. 546 */ 547 final ArrayList<ServiceRecord> mRestartingServices 548 = new ArrayList<ServiceRecord>(); 549 550 /** 551 * List of services that are in the process of being stopped. 552 */ 553 final ArrayList<ServiceRecord> mStoppingServices 554 = new ArrayList<ServiceRecord>(); 555 556 /** 557 * Backup/restore process management 558 */ 559 String mBackupAppName = null; 560 BackupRecord mBackupTarget = null; 561 562 /** 563 * List of PendingThumbnailsRecord objects of clients who are still 564 * waiting to receive all of the thumbnails for a task. 565 */ 566 final ArrayList mPendingThumbnails = new ArrayList(); 567 568 /** 569 * List of HistoryRecord objects that have been finished and must 570 * still report back to a pending thumbnail receiver. 571 */ 572 final ArrayList mCancelledThumbnails = new ArrayList(); 573 574 /** 575 * All of the currently running global content providers. Keys are a 576 * string containing the provider name and values are a 577 * ContentProviderRecord object containing the data about it. Note 578 * that a single provider may be published under multiple names, so 579 * there may be multiple entries here for a single one in mProvidersByClass. 580 */ 581 final HashMap<String, ContentProviderRecord> mProvidersByName 582 = new HashMap<String, ContentProviderRecord>(); 583 584 /** 585 * All of the currently running global content providers. Keys are a 586 * string containing the provider's implementation class and values are a 587 * ContentProviderRecord object containing the data about it. 588 */ 589 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass 590 = new HashMap<ComponentName, ContentProviderRecord>(); 591 592 /** 593 * List of content providers who have clients waiting for them. The 594 * application is currently being launched and the provider will be 595 * removed from this list once it is published. 596 */ 597 final ArrayList<ContentProviderRecord> mLaunchingProviders 598 = new ArrayList<ContentProviderRecord>(); 599 600 /** 601 * Global set of specific Uri permissions that have been granted. 602 */ 603 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 604 = new SparseArray<HashMap<Uri, UriPermission>>(); 605 606 CoreSettingsObserver mCoreSettingsObserver; 607 608 /** 609 * Thread-local storage used to carry caller permissions over through 610 * indirect content-provider access. 611 * @see #ActivityManagerService.openContentUri() 612 */ 613 private class Identity { 614 public int pid; 615 public int uid; 616 617 Identity(int _pid, int _uid) { 618 pid = _pid; 619 uid = _uid; 620 } 621 } 622 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 623 624 /** 625 * All information we have collected about the runtime performance of 626 * any user id that can impact battery performance. 627 */ 628 final BatteryStatsService mBatteryStatsService; 629 630 /** 631 * information about component usage 632 */ 633 final UsageStatsService mUsageStatsService; 634 635 /** 636 * Current configuration information. HistoryRecord objects are given 637 * a reference to this object to indicate which configuration they are 638 * currently running in, so this object must be kept immutable. 639 */ 640 Configuration mConfiguration = new Configuration(); 641 642 /** 643 * Current sequencing integer of the configuration, for skipping old 644 * configurations. 645 */ 646 int mConfigurationSeq = 0; 647 648 /** 649 * Hardware-reported OpenGLES version. 650 */ 651 final int GL_ES_VERSION; 652 653 /** 654 * List of initialization arguments to pass to all processes when binding applications to them. 655 * For example, references to the commonly used services. 656 */ 657 HashMap<String, IBinder> mAppBindArgs; 658 659 /** 660 * Temporary to avoid allocations. Protected by main lock. 661 */ 662 final StringBuilder mStringBuilder = new StringBuilder(256); 663 664 /** 665 * Used to control how we initialize the service. 666 */ 667 boolean mStartRunning = false; 668 ComponentName mTopComponent; 669 String mTopAction; 670 String mTopData; 671 boolean mProcessesReady = false; 672 boolean mSystemReady = false; 673 boolean mBooting = false; 674 boolean mWaitingUpdate = false; 675 boolean mDidUpdate = false; 676 boolean mOnBattery = false; 677 boolean mLaunchWarningShown = false; 678 679 Context mContext; 680 681 int mFactoryTest; 682 683 boolean mCheckedForSetup; 684 685 /** 686 * The time at which we will allow normal application switches again, 687 * after a call to {@link #stopAppSwitches()}. 688 */ 689 long mAppSwitchesAllowedTime; 690 691 /** 692 * This is set to true after the first switch after mAppSwitchesAllowedTime 693 * is set; any switches after that will clear the time. 694 */ 695 boolean mDidAppSwitch; 696 697 /** 698 * Last time (in realtime) at which we checked for power usage. 699 */ 700 long mLastPowerCheckRealtime; 701 702 /** 703 * Last time (in uptime) at which we checked for power usage. 704 */ 705 long mLastPowerCheckUptime; 706 707 /** 708 * Set while we are wanting to sleep, to prevent any 709 * activities from being started/resumed. 710 */ 711 boolean mSleeping = false; 712 713 /** 714 * Set if we are shutting down the system, similar to sleeping. 715 */ 716 boolean mShuttingDown = false; 717 718 /** 719 * Task identifier that activities are currently being started 720 * in. Incremented each time a new task is created. 721 * todo: Replace this with a TokenSpace class that generates non-repeating 722 * integers that won't wrap. 723 */ 724 int mCurTask = 1; 725 726 /** 727 * Current sequence id for oom_adj computation traversal. 728 */ 729 int mAdjSeq = 0; 730 731 /** 732 * Current sequence id for process LRU updating. 733 */ 734 int mLruSeq = 0; 735 736 /** 737 * Keep track of the number of service processes we last found, to 738 * determine on the next iteration which should be B services. 739 */ 740 int mNumServiceProcs = 0; 741 int mNewNumServiceProcs = 0; 742 743 /** 744 * System monitoring: number of processes that died since the last 745 * N procs were started. 746 */ 747 int[] mProcDeaths = new int[20]; 748 749 /** 750 * This is set if we had to do a delayed dexopt of an app before launching 751 * it, to increasing the ANR timeouts in that case. 752 */ 753 boolean mDidDexOpt; 754 755 String mDebugApp = null; 756 boolean mWaitForDebugger = false; 757 boolean mDebugTransient = false; 758 String mOrigDebugApp = null; 759 boolean mOrigWaitForDebugger = false; 760 boolean mAlwaysFinishActivities = false; 761 IActivityController mController = null; 762 String mProfileApp = null; 763 ProcessRecord mProfileProc = null; 764 String mProfileFile; 765 ParcelFileDescriptor mProfileFd; 766 int mProfileType = 0; 767 boolean mAutoStopProfiler = false; 768 769 final RemoteCallbackList<IActivityWatcher> mWatchers 770 = new RemoteCallbackList<IActivityWatcher>(); 771 772 final RemoteCallbackList<IProcessObserver> mProcessObservers 773 = new RemoteCallbackList<IProcessObserver>(); 774 775 /** 776 * Callback of last caller to {@link #requestPss}. 777 */ 778 Runnable mRequestPssCallback; 779 780 /** 781 * Remaining processes for which we are waiting results from the last 782 * call to {@link #requestPss}. 783 */ 784 final ArrayList<ProcessRecord> mRequestPssList 785 = new ArrayList<ProcessRecord>(); 786 787 /** 788 * Runtime statistics collection thread. This object's lock is used to 789 * protect all related state. 790 */ 791 final Thread mProcessStatsThread; 792 793 /** 794 * Used to collect process stats when showing not responding dialog. 795 * Protected by mProcessStatsThread. 796 */ 797 final ProcessStats mProcessStats = new ProcessStats( 798 MONITOR_THREAD_CPU_USAGE); 799 final AtomicLong mLastCpuTime = new AtomicLong(0); 800 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 801 802 long mLastWriteTime = 0; 803 804 /** 805 * Set to true after the system has finished booting. 806 */ 807 boolean mBooted = false; 808 809 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 810 int mProcessLimitOverride = -1; 811 812 WindowManagerService mWindowManager; 813 814 static ActivityManagerService mSelf; 815 static ActivityThread mSystemThread; 816 817 private final class AppDeathRecipient implements IBinder.DeathRecipient { 818 final ProcessRecord mApp; 819 final int mPid; 820 final IApplicationThread mAppThread; 821 822 AppDeathRecipient(ProcessRecord app, int pid, 823 IApplicationThread thread) { 824 if (localLOGV) Slog.v( 825 TAG, "New death recipient " + this 826 + " for thread " + thread.asBinder()); 827 mApp = app; 828 mPid = pid; 829 mAppThread = thread; 830 } 831 832 public void binderDied() { 833 if (localLOGV) Slog.v( 834 TAG, "Death received in " + this 835 + " for thread " + mAppThread.asBinder()); 836 synchronized(ActivityManagerService.this) { 837 appDiedLocked(mApp, mPid, mAppThread); 838 } 839 } 840 } 841 842 static final int SHOW_ERROR_MSG = 1; 843 static final int SHOW_NOT_RESPONDING_MSG = 2; 844 static final int SHOW_FACTORY_ERROR_MSG = 3; 845 static final int UPDATE_CONFIGURATION_MSG = 4; 846 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 847 static final int WAIT_FOR_DEBUGGER_MSG = 6; 848 static final int BROADCAST_INTENT_MSG = 7; 849 static final int BROADCAST_TIMEOUT_MSG = 8; 850 static final int SERVICE_TIMEOUT_MSG = 12; 851 static final int UPDATE_TIME_ZONE = 13; 852 static final int SHOW_UID_ERROR_MSG = 14; 853 static final int IM_FEELING_LUCKY_MSG = 15; 854 static final int PROC_START_TIMEOUT_MSG = 20; 855 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 856 static final int KILL_APPLICATION_MSG = 22; 857 static final int FINALIZE_PENDING_INTENT_MSG = 23; 858 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 859 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 860 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 861 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 862 static final int CLEAR_DNS_CACHE = 28; 863 static final int UPDATE_HTTP_PROXY = 29; 864 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 865 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31; 866 static final int DISPATCH_PROCESS_DIED = 32; 867 static final int REPORT_MEM_USAGE = 33; 868 869 AlertDialog mUidAlert; 870 CompatModeDialog mCompatModeDialog; 871 long mLastMemUsageReportTime = 0; 872 873 final Handler mHandler = new Handler() { 874 //public Handler() { 875 // if (localLOGV) Slog.v(TAG, "Handler started!"); 876 //} 877 878 public void handleMessage(Message msg) { 879 switch (msg.what) { 880 case SHOW_ERROR_MSG: { 881 HashMap data = (HashMap) msg.obj; 882 synchronized (ActivityManagerService.this) { 883 ProcessRecord proc = (ProcessRecord)data.get("app"); 884 if (proc != null && proc.crashDialog != null) { 885 Slog.e(TAG, "App already has crash dialog: " + proc); 886 return; 887 } 888 AppErrorResult res = (AppErrorResult) data.get("result"); 889 if (!mSleeping && !mShuttingDown) { 890 Dialog d = new AppErrorDialog(mContext, res, proc); 891 d.show(); 892 proc.crashDialog = d; 893 } else { 894 // The device is asleep, so just pretend that the user 895 // saw a crash dialog and hit "force quit". 896 res.set(0); 897 } 898 } 899 900 ensureBootCompleted(); 901 } break; 902 case SHOW_NOT_RESPONDING_MSG: { 903 synchronized (ActivityManagerService.this) { 904 HashMap data = (HashMap) msg.obj; 905 ProcessRecord proc = (ProcessRecord)data.get("app"); 906 if (proc != null && proc.anrDialog != null) { 907 Slog.e(TAG, "App already has anr dialog: " + proc); 908 return; 909 } 910 911 Intent intent = new Intent("android.intent.action.ANR"); 912 if (!mProcessesReady) { 913 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 914 } 915 broadcastIntentLocked(null, null, intent, 916 null, null, 0, null, null, null, 917 false, false, MY_PID, Process.SYSTEM_UID); 918 919 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 920 mContext, proc, (ActivityRecord)data.get("activity")); 921 d.show(); 922 proc.anrDialog = d; 923 } 924 925 ensureBootCompleted(); 926 } break; 927 case SHOW_STRICT_MODE_VIOLATION_MSG: { 928 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 929 synchronized (ActivityManagerService.this) { 930 ProcessRecord proc = (ProcessRecord) data.get("app"); 931 if (proc == null) { 932 Slog.e(TAG, "App not found when showing strict mode dialog."); 933 break; 934 } 935 if (proc.crashDialog != null) { 936 Slog.e(TAG, "App already has strict mode dialog: " + proc); 937 return; 938 } 939 AppErrorResult res = (AppErrorResult) data.get("result"); 940 if (!mSleeping && !mShuttingDown) { 941 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 942 d.show(); 943 proc.crashDialog = d; 944 } else { 945 // The device is asleep, so just pretend that the user 946 // saw a crash dialog and hit "force quit". 947 res.set(0); 948 } 949 } 950 ensureBootCompleted(); 951 } break; 952 case SHOW_FACTORY_ERROR_MSG: { 953 Dialog d = new FactoryErrorDialog( 954 mContext, msg.getData().getCharSequence("msg")); 955 d.show(); 956 ensureBootCompleted(); 957 } break; 958 case UPDATE_CONFIGURATION_MSG: { 959 final ContentResolver resolver = mContext.getContentResolver(); 960 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 961 } break; 962 case GC_BACKGROUND_PROCESSES_MSG: { 963 synchronized (ActivityManagerService.this) { 964 performAppGcsIfAppropriateLocked(); 965 } 966 } break; 967 case WAIT_FOR_DEBUGGER_MSG: { 968 synchronized (ActivityManagerService.this) { 969 ProcessRecord app = (ProcessRecord)msg.obj; 970 if (msg.arg1 != 0) { 971 if (!app.waitedForDebugger) { 972 Dialog d = new AppWaitingForDebuggerDialog( 973 ActivityManagerService.this, 974 mContext, app); 975 app.waitDialog = d; 976 app.waitedForDebugger = true; 977 d.show(); 978 } 979 } else { 980 if (app.waitDialog != null) { 981 app.waitDialog.dismiss(); 982 app.waitDialog = null; 983 } 984 } 985 } 986 } break; 987 case BROADCAST_INTENT_MSG: { 988 if (DEBUG_BROADCAST) Slog.v( 989 TAG, "Received BROADCAST_INTENT_MSG"); 990 processNextBroadcast(true); 991 } break; 992 case BROADCAST_TIMEOUT_MSG: { 993 synchronized (ActivityManagerService.this) { 994 broadcastTimeoutLocked(true); 995 } 996 } break; 997 case SERVICE_TIMEOUT_MSG: { 998 if (mDidDexOpt) { 999 mDidDexOpt = false; 1000 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1001 nmsg.obj = msg.obj; 1002 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1003 return; 1004 } 1005 serviceTimeout((ProcessRecord)msg.obj); 1006 } break; 1007 case UPDATE_TIME_ZONE: { 1008 synchronized (ActivityManagerService.this) { 1009 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1010 ProcessRecord r = mLruProcesses.get(i); 1011 if (r.thread != null) { 1012 try { 1013 r.thread.updateTimeZone(); 1014 } catch (RemoteException ex) { 1015 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1016 } 1017 } 1018 } 1019 } 1020 } break; 1021 case CLEAR_DNS_CACHE: { 1022 synchronized (ActivityManagerService.this) { 1023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1024 ProcessRecord r = mLruProcesses.get(i); 1025 if (r.thread != null) { 1026 try { 1027 r.thread.clearDnsCache(); 1028 } catch (RemoteException ex) { 1029 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1030 } 1031 } 1032 } 1033 } 1034 } break; 1035 case UPDATE_HTTP_PROXY: { 1036 ProxyProperties proxy = (ProxyProperties)msg.obj; 1037 String host = ""; 1038 String port = ""; 1039 String exclList = ""; 1040 if (proxy != null) { 1041 host = proxy.getHost(); 1042 port = Integer.toString(proxy.getPort()); 1043 exclList = proxy.getExclusionList(); 1044 } 1045 synchronized (ActivityManagerService.this) { 1046 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1047 ProcessRecord r = mLruProcesses.get(i); 1048 if (r.thread != null) { 1049 try { 1050 r.thread.setHttpProxy(host, port, exclList); 1051 } catch (RemoteException ex) { 1052 Slog.w(TAG, "Failed to update http proxy for: " + 1053 r.info.processName); 1054 } 1055 } 1056 } 1057 } 1058 } break; 1059 case SHOW_UID_ERROR_MSG: { 1060 // XXX This is a temporary dialog, no need to localize. 1061 AlertDialog d = new BaseErrorDialog(mContext); 1062 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1063 d.setCancelable(false); 1064 d.setTitle("System UIDs Inconsistent"); 1065 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1066 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1067 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1068 mUidAlert = d; 1069 d.show(); 1070 } break; 1071 case IM_FEELING_LUCKY_MSG: { 1072 if (mUidAlert != null) { 1073 mUidAlert.dismiss(); 1074 mUidAlert = null; 1075 } 1076 } break; 1077 case PROC_START_TIMEOUT_MSG: { 1078 if (mDidDexOpt) { 1079 mDidDexOpt = false; 1080 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1081 nmsg.obj = msg.obj; 1082 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1083 return; 1084 } 1085 ProcessRecord app = (ProcessRecord)msg.obj; 1086 synchronized (ActivityManagerService.this) { 1087 processStartTimedOutLocked(app); 1088 } 1089 } break; 1090 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1091 synchronized (ActivityManagerService.this) { 1092 doPendingActivityLaunchesLocked(true); 1093 } 1094 } break; 1095 case KILL_APPLICATION_MSG: { 1096 synchronized (ActivityManagerService.this) { 1097 int uid = msg.arg1; 1098 boolean restart = (msg.arg2 == 1); 1099 String pkg = (String) msg.obj; 1100 forceStopPackageLocked(pkg, uid, restart, false, true, false); 1101 } 1102 } break; 1103 case FINALIZE_PENDING_INTENT_MSG: { 1104 ((PendingIntentRecord)msg.obj).completeFinalize(); 1105 } break; 1106 case POST_HEAVY_NOTIFICATION_MSG: { 1107 INotificationManager inm = NotificationManager.getService(); 1108 if (inm == null) { 1109 return; 1110 } 1111 1112 ActivityRecord root = (ActivityRecord)msg.obj; 1113 ProcessRecord process = root.app; 1114 if (process == null) { 1115 return; 1116 } 1117 1118 try { 1119 Context context = mContext.createPackageContext(process.info.packageName, 0); 1120 String text = mContext.getString(R.string.heavy_weight_notification, 1121 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1122 Notification notification = new Notification(); 1123 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1124 notification.when = 0; 1125 notification.flags = Notification.FLAG_ONGOING_EVENT; 1126 notification.tickerText = text; 1127 notification.defaults = 0; // please be quiet 1128 notification.sound = null; 1129 notification.vibrate = null; 1130 notification.setLatestEventInfo(context, text, 1131 mContext.getText(R.string.heavy_weight_notification_detail), 1132 PendingIntent.getActivity(mContext, 0, root.intent, 1133 PendingIntent.FLAG_CANCEL_CURRENT)); 1134 1135 try { 1136 int[] outId = new int[1]; 1137 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1138 notification, outId); 1139 } catch (RuntimeException e) { 1140 Slog.w(ActivityManagerService.TAG, 1141 "Error showing notification for heavy-weight app", e); 1142 } catch (RemoteException e) { 1143 } 1144 } catch (NameNotFoundException e) { 1145 Slog.w(TAG, "Unable to create context for heavy notification", e); 1146 } 1147 } break; 1148 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1149 INotificationManager inm = NotificationManager.getService(); 1150 if (inm == null) { 1151 return; 1152 } 1153 try { 1154 inm.cancelNotification("android", 1155 R.string.heavy_weight_notification); 1156 } catch (RuntimeException e) { 1157 Slog.w(ActivityManagerService.TAG, 1158 "Error canceling notification for service", e); 1159 } catch (RemoteException e) { 1160 } 1161 } break; 1162 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1163 synchronized (ActivityManagerService.this) { 1164 checkExcessivePowerUsageLocked(true); 1165 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1166 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1167 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1168 } 1169 } break; 1170 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1171 synchronized (ActivityManagerService.this) { 1172 ActivityRecord ar = (ActivityRecord)msg.obj; 1173 if (mCompatModeDialog != null) { 1174 if (mCompatModeDialog.mAppInfo.packageName.equals( 1175 ar.info.applicationInfo.packageName)) { 1176 return; 1177 } 1178 mCompatModeDialog.dismiss(); 1179 mCompatModeDialog = null; 1180 } 1181 if (ar != null && false) { 1182 if (mCompatModePackages.getPackageAskCompatModeLocked( 1183 ar.packageName)) { 1184 int mode = mCompatModePackages.computeCompatModeLocked( 1185 ar.info.applicationInfo); 1186 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1187 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1188 mCompatModeDialog = new CompatModeDialog( 1189 ActivityManagerService.this, mContext, 1190 ar.info.applicationInfo); 1191 mCompatModeDialog.show(); 1192 } 1193 } 1194 } 1195 } 1196 break; 1197 } 1198 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: { 1199 final int pid = msg.arg1; 1200 final int uid = msg.arg2; 1201 final boolean foregroundActivities = (Boolean) msg.obj; 1202 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities); 1203 break; 1204 } 1205 case DISPATCH_PROCESS_DIED: { 1206 final int pid = msg.arg1; 1207 final int uid = msg.arg2; 1208 dispatchProcessDied(pid, uid); 1209 break; 1210 } 1211 case REPORT_MEM_USAGE: { 1212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1213 if (!isDebuggable) { 1214 return; 1215 } 1216 synchronized (ActivityManagerService.this) { 1217 long now = SystemClock.uptimeMillis(); 1218 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1219 // Don't report more than every 5 minutes to somewhat 1220 // avoid spamming. 1221 return; 1222 } 1223 mLastMemUsageReportTime = now; 1224 } 1225 Thread thread = new Thread() { 1226 @Override public void run() { 1227 StringBuilder dropBuilder = new StringBuilder(1024); 1228 StringBuilder logBuilder = new StringBuilder(1024); 1229 StringWriter oomSw = new StringWriter(); 1230 PrintWriter oomPw = new PrintWriter(oomSw); 1231 StringWriter catSw = new StringWriter(); 1232 PrintWriter catPw = new PrintWriter(catSw); 1233 String[] emptyArgs = new String[] { }; 1234 StringBuilder tag = new StringBuilder(128); 1235 StringBuilder stack = new StringBuilder(128); 1236 tag.append("Low on memory -- "); 1237 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1238 tag, stack); 1239 dropBuilder.append(stack); 1240 dropBuilder.append('\n'); 1241 dropBuilder.append('\n'); 1242 String oomString = oomSw.toString(); 1243 dropBuilder.append(oomString); 1244 dropBuilder.append('\n'); 1245 logBuilder.append(oomString); 1246 try { 1247 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1248 "procrank", }); 1249 final InputStreamReader converter = new InputStreamReader( 1250 proc.getInputStream()); 1251 BufferedReader in = new BufferedReader(converter); 1252 String line; 1253 while (true) { 1254 line = in.readLine(); 1255 if (line == null) { 1256 break; 1257 } 1258 if (line.length() > 0) { 1259 logBuilder.append(line); 1260 logBuilder.append('\n'); 1261 } 1262 dropBuilder.append(line); 1263 dropBuilder.append('\n'); 1264 } 1265 converter.close(); 1266 } catch (IOException e) { 1267 } 1268 synchronized (ActivityManagerService.this) { 1269 catPw.println(); 1270 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1271 catPw.println(); 1272 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null); 1273 catPw.println(); 1274 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1275 } 1276 dropBuilder.append(catSw.toString()); 1277 addErrorToDropBox("lowmem", null, "system_server", null, 1278 null, tag.toString(), dropBuilder.toString(), null, null); 1279 Slog.i(TAG, logBuilder.toString()); 1280 synchronized (ActivityManagerService.this) { 1281 long now = SystemClock.uptimeMillis(); 1282 if (mLastMemUsageReportTime < now) { 1283 mLastMemUsageReportTime = now; 1284 } 1285 } 1286 } 1287 }; 1288 thread.start(); 1289 break; 1290 } 1291 } 1292 } 1293 }; 1294 1295 public static void setSystemProcess() { 1296 try { 1297 ActivityManagerService m = mSelf; 1298 1299 ServiceManager.addService("activity", m); 1300 ServiceManager.addService("meminfo", new MemBinder(m)); 1301 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1302 if (MONITOR_CPU_USAGE) { 1303 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1304 } 1305 ServiceManager.addService("permission", new PermissionController(m)); 1306 1307 ApplicationInfo info = 1308 mSelf.mContext.getPackageManager().getApplicationInfo( 1309 "android", STOCK_PM_FLAGS); 1310 mSystemThread.installSystemApplicationInfo(info); 1311 1312 synchronized (mSelf) { 1313 ProcessRecord app = mSelf.newProcessRecordLocked( 1314 mSystemThread.getApplicationThread(), info, 1315 info.processName); 1316 app.persistent = true; 1317 app.pid = MY_PID; 1318 app.maxAdj = ProcessList.SYSTEM_ADJ; 1319 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1320 synchronized (mSelf.mPidsSelfLocked) { 1321 mSelf.mPidsSelfLocked.put(app.pid, app); 1322 } 1323 mSelf.updateLruProcessLocked(app, true, true); 1324 } 1325 } catch (PackageManager.NameNotFoundException e) { 1326 throw new RuntimeException( 1327 "Unable to find android system package", e); 1328 } 1329 } 1330 1331 public void setWindowManager(WindowManagerService wm) { 1332 mWindowManager = wm; 1333 } 1334 1335 public static final Context main(int factoryTest) { 1336 AThread thr = new AThread(); 1337 thr.start(); 1338 1339 synchronized (thr) { 1340 while (thr.mService == null) { 1341 try { 1342 thr.wait(); 1343 } catch (InterruptedException e) { 1344 } 1345 } 1346 } 1347 1348 ActivityManagerService m = thr.mService; 1349 mSelf = m; 1350 ActivityThread at = ActivityThread.systemMain(); 1351 mSystemThread = at; 1352 Context context = at.getSystemContext(); 1353 context.setTheme(android.R.style.Theme_Holo); 1354 m.mContext = context; 1355 m.mFactoryTest = factoryTest; 1356 m.mMainStack = new ActivityStack(m, context, true); 1357 1358 m.mBatteryStatsService.publish(context); 1359 m.mUsageStatsService.publish(context); 1360 1361 synchronized (thr) { 1362 thr.mReady = true; 1363 thr.notifyAll(); 1364 } 1365 1366 m.startRunning(null, null, null, null); 1367 1368 return context; 1369 } 1370 1371 public static ActivityManagerService self() { 1372 return mSelf; 1373 } 1374 1375 static class AThread extends Thread { 1376 ActivityManagerService mService; 1377 boolean mReady = false; 1378 1379 public AThread() { 1380 super("ActivityManager"); 1381 } 1382 1383 public void run() { 1384 Looper.prepare(); 1385 1386 android.os.Process.setThreadPriority( 1387 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1388 android.os.Process.setCanSelfBackground(false); 1389 1390 ActivityManagerService m = new ActivityManagerService(); 1391 1392 synchronized (this) { 1393 mService = m; 1394 notifyAll(); 1395 } 1396 1397 synchronized (this) { 1398 while (!mReady) { 1399 try { 1400 wait(); 1401 } catch (InterruptedException e) { 1402 } 1403 } 1404 } 1405 1406 // For debug builds, log event loop stalls to dropbox for analysis. 1407 if (StrictMode.conditionallyEnableDebugLogging()) { 1408 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1409 } 1410 1411 Looper.loop(); 1412 } 1413 } 1414 1415 static class MemBinder extends Binder { 1416 ActivityManagerService mActivityManagerService; 1417 MemBinder(ActivityManagerService activityManagerService) { 1418 mActivityManagerService = activityManagerService; 1419 } 1420 1421 @Override 1422 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1423 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1424 != PackageManager.PERMISSION_GRANTED) { 1425 pw.println("Permission Denial: can't dump meminfo from from pid=" 1426 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1427 + " without permission " + android.Manifest.permission.DUMP); 1428 return; 1429 } 1430 1431 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1432 false, null, null, null); 1433 } 1434 } 1435 1436 static class GraphicsBinder extends Binder { 1437 ActivityManagerService mActivityManagerService; 1438 GraphicsBinder(ActivityManagerService activityManagerService) { 1439 mActivityManagerService = activityManagerService; 1440 } 1441 1442 @Override 1443 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1444 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1445 != PackageManager.PERMISSION_GRANTED) { 1446 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1447 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1448 + " without permission " + android.Manifest.permission.DUMP); 1449 return; 1450 } 1451 1452 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1453 } 1454 } 1455 1456 static class CpuBinder extends Binder { 1457 ActivityManagerService mActivityManagerService; 1458 CpuBinder(ActivityManagerService activityManagerService) { 1459 mActivityManagerService = activityManagerService; 1460 } 1461 1462 @Override 1463 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1464 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1465 != PackageManager.PERMISSION_GRANTED) { 1466 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1467 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1468 + " without permission " + android.Manifest.permission.DUMP); 1469 return; 1470 } 1471 1472 synchronized (mActivityManagerService.mProcessStatsThread) { 1473 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1474 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1475 SystemClock.uptimeMillis())); 1476 } 1477 } 1478 } 1479 1480 private ActivityManagerService() { 1481 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1482 1483 File dataDir = Environment.getDataDirectory(); 1484 File systemDir = new File(dataDir, "system"); 1485 systemDir.mkdirs(); 1486 mBatteryStatsService = new BatteryStatsService(new File( 1487 systemDir, "batterystats.bin").toString()); 1488 mBatteryStatsService.getActiveStatistics().readLocked(); 1489 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1490 mOnBattery = DEBUG_POWER ? true 1491 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1492 mBatteryStatsService.getActiveStatistics().setCallback(this); 1493 1494 mUsageStatsService = new UsageStatsService(new File( 1495 systemDir, "usagestats").toString()); 1496 1497 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1498 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1499 1500 mConfiguration.setToDefaults(); 1501 mConfiguration.locale = Locale.getDefault(); 1502 mConfigurationSeq = mConfiguration.seq = 1; 1503 mProcessStats.init(); 1504 1505 mCompatModePackages = new CompatModePackages(this, systemDir); 1506 1507 // Add ourself to the Watchdog monitors. 1508 Watchdog.getInstance().addMonitor(this); 1509 1510 mProcessStatsThread = new Thread("ProcessStats") { 1511 public void run() { 1512 while (true) { 1513 try { 1514 try { 1515 synchronized(this) { 1516 final long now = SystemClock.uptimeMillis(); 1517 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1518 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1519 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1520 // + ", write delay=" + nextWriteDelay); 1521 if (nextWriteDelay < nextCpuDelay) { 1522 nextCpuDelay = nextWriteDelay; 1523 } 1524 if (nextCpuDelay > 0) { 1525 mProcessStatsMutexFree.set(true); 1526 this.wait(nextCpuDelay); 1527 } 1528 } 1529 } catch (InterruptedException e) { 1530 } 1531 updateCpuStatsNow(); 1532 } catch (Exception e) { 1533 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1534 } 1535 } 1536 } 1537 }; 1538 mProcessStatsThread.start(); 1539 } 1540 1541 @Override 1542 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1543 throws RemoteException { 1544 try { 1545 return super.onTransact(code, data, reply, flags); 1546 } catch (RuntimeException e) { 1547 // The activity manager only throws security exceptions, so let's 1548 // log all others. 1549 if (!(e instanceof SecurityException)) { 1550 Slog.e(TAG, "Activity Manager Crash", e); 1551 } 1552 throw e; 1553 } 1554 } 1555 1556 void updateCpuStats() { 1557 final long now = SystemClock.uptimeMillis(); 1558 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1559 return; 1560 } 1561 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1562 synchronized (mProcessStatsThread) { 1563 mProcessStatsThread.notify(); 1564 } 1565 } 1566 } 1567 1568 void updateCpuStatsNow() { 1569 synchronized (mProcessStatsThread) { 1570 mProcessStatsMutexFree.set(false); 1571 final long now = SystemClock.uptimeMillis(); 1572 boolean haveNewCpuStats = false; 1573 1574 if (MONITOR_CPU_USAGE && 1575 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1576 mLastCpuTime.set(now); 1577 haveNewCpuStats = true; 1578 mProcessStats.update(); 1579 //Slog.i(TAG, mProcessStats.printCurrentState()); 1580 //Slog.i(TAG, "Total CPU usage: " 1581 // + mProcessStats.getTotalCpuPercent() + "%"); 1582 1583 // Slog the cpu usage if the property is set. 1584 if ("true".equals(SystemProperties.get("events.cpu"))) { 1585 int user = mProcessStats.getLastUserTime(); 1586 int system = mProcessStats.getLastSystemTime(); 1587 int iowait = mProcessStats.getLastIoWaitTime(); 1588 int irq = mProcessStats.getLastIrqTime(); 1589 int softIrq = mProcessStats.getLastSoftIrqTime(); 1590 int idle = mProcessStats.getLastIdleTime(); 1591 1592 int total = user + system + iowait + irq + softIrq + idle; 1593 if (total == 0) total = 1; 1594 1595 EventLog.writeEvent(EventLogTags.CPU, 1596 ((user+system+iowait+irq+softIrq) * 100) / total, 1597 (user * 100) / total, 1598 (system * 100) / total, 1599 (iowait * 100) / total, 1600 (irq * 100) / total, 1601 (softIrq * 100) / total); 1602 } 1603 } 1604 1605 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1606 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1607 synchronized(bstats) { 1608 synchronized(mPidsSelfLocked) { 1609 if (haveNewCpuStats) { 1610 if (mOnBattery) { 1611 int perc = bstats.startAddingCpuLocked(); 1612 int totalUTime = 0; 1613 int totalSTime = 0; 1614 final int N = mProcessStats.countStats(); 1615 for (int i=0; i<N; i++) { 1616 ProcessStats.Stats st = mProcessStats.getStats(i); 1617 if (!st.working) { 1618 continue; 1619 } 1620 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1621 int otherUTime = (st.rel_utime*perc)/100; 1622 int otherSTime = (st.rel_stime*perc)/100; 1623 totalUTime += otherUTime; 1624 totalSTime += otherSTime; 1625 if (pr != null) { 1626 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1627 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1628 st.rel_stime-otherSTime); 1629 ps.addSpeedStepTimes(cpuSpeedTimes); 1630 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1631 } else { 1632 BatteryStatsImpl.Uid.Proc ps = 1633 bstats.getProcessStatsLocked(st.name, st.pid); 1634 if (ps != null) { 1635 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1636 st.rel_stime-otherSTime); 1637 ps.addSpeedStepTimes(cpuSpeedTimes); 1638 } 1639 } 1640 } 1641 bstats.finishAddingCpuLocked(perc, totalUTime, 1642 totalSTime, cpuSpeedTimes); 1643 } 1644 } 1645 } 1646 1647 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1648 mLastWriteTime = now; 1649 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1650 } 1651 } 1652 } 1653 } 1654 1655 @Override 1656 public void batteryNeedsCpuUpdate() { 1657 updateCpuStatsNow(); 1658 } 1659 1660 @Override 1661 public void batteryPowerChanged(boolean onBattery) { 1662 // When plugging in, update the CPU stats first before changing 1663 // the plug state. 1664 updateCpuStatsNow(); 1665 synchronized (this) { 1666 synchronized(mPidsSelfLocked) { 1667 mOnBattery = DEBUG_POWER ? true : onBattery; 1668 } 1669 } 1670 } 1671 1672 /** 1673 * Initialize the application bind args. These are passed to each 1674 * process when the bindApplication() IPC is sent to the process. They're 1675 * lazily setup to make sure the services are running when they're asked for. 1676 */ 1677 private HashMap<String, IBinder> getCommonServicesLocked() { 1678 if (mAppBindArgs == null) { 1679 mAppBindArgs = new HashMap<String, IBinder>(); 1680 1681 // Setup the application init args 1682 mAppBindArgs.put("package", ServiceManager.getService("package")); 1683 mAppBindArgs.put("window", ServiceManager.getService("window")); 1684 mAppBindArgs.put(Context.ALARM_SERVICE, 1685 ServiceManager.getService(Context.ALARM_SERVICE)); 1686 } 1687 return mAppBindArgs; 1688 } 1689 1690 final void setFocusedActivityLocked(ActivityRecord r) { 1691 if (mFocusedActivity != r) { 1692 mFocusedActivity = r; 1693 if (r != null) { 1694 mWindowManager.setFocusedApp(r.appToken, true); 1695 } 1696 } 1697 } 1698 1699 private final void updateLruProcessInternalLocked(ProcessRecord app, 1700 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1701 // put it on the LRU to keep track of when it should be exited. 1702 int lrui = mLruProcesses.indexOf(app); 1703 if (lrui >= 0) mLruProcesses.remove(lrui); 1704 1705 int i = mLruProcesses.size()-1; 1706 int skipTop = 0; 1707 1708 app.lruSeq = mLruSeq; 1709 1710 // compute the new weight for this process. 1711 if (updateActivityTime) { 1712 app.lastActivityTime = SystemClock.uptimeMillis(); 1713 } 1714 if (app.activities.size() > 0) { 1715 // If this process has activities, we more strongly want to keep 1716 // it around. 1717 app.lruWeight = app.lastActivityTime; 1718 } else if (app.pubProviders.size() > 0) { 1719 // If this process contains content providers, we want to keep 1720 // it a little more strongly. 1721 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1722 // Also don't let it kick out the first few "real" hidden processes. 1723 skipTop = ProcessList.MIN_HIDDEN_APPS; 1724 } else { 1725 // If this process doesn't have activities, we less strongly 1726 // want to keep it around, and generally want to avoid getting 1727 // in front of any very recently used activities. 1728 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1729 // Also don't let it kick out the first few "real" hidden processes. 1730 skipTop = ProcessList.MIN_HIDDEN_APPS; 1731 } 1732 1733 while (i >= 0) { 1734 ProcessRecord p = mLruProcesses.get(i); 1735 // If this app shouldn't be in front of the first N background 1736 // apps, then skip over that many that are currently hidden. 1737 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1738 skipTop--; 1739 } 1740 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1741 mLruProcesses.add(i+1, app); 1742 break; 1743 } 1744 i--; 1745 } 1746 if (i < 0) { 1747 mLruProcesses.add(0, app); 1748 } 1749 1750 // If the app is currently using a content provider or service, 1751 // bump those processes as well. 1752 if (app.connections.size() > 0) { 1753 for (ConnectionRecord cr : app.connections) { 1754 if (cr.binding != null && cr.binding.service != null 1755 && cr.binding.service.app != null 1756 && cr.binding.service.app.lruSeq != mLruSeq) { 1757 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, 1758 updateActivityTime, i+1); 1759 } 1760 } 1761 } 1762 if (app.conProviders.size() > 0) { 1763 for (ContentProviderRecord cpr : app.conProviders.keySet()) { 1764 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1765 updateLruProcessInternalLocked(cpr.proc, oomAdj, 1766 updateActivityTime, i+1); 1767 } 1768 } 1769 } 1770 1771 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1772 if (oomAdj) { 1773 updateOomAdjLocked(); 1774 } 1775 } 1776 1777 final void updateLruProcessLocked(ProcessRecord app, 1778 boolean oomAdj, boolean updateActivityTime) { 1779 mLruSeq++; 1780 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1781 } 1782 1783 final ProcessRecord getProcessRecordLocked( 1784 String processName, int uid) { 1785 if (uid == Process.SYSTEM_UID) { 1786 // The system gets to run in any process. If there are multiple 1787 // processes with the same uid, just pick the first (this 1788 // should never happen). 1789 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1790 processName); 1791 return procs != null ? procs.valueAt(0) : null; 1792 } 1793 ProcessRecord proc = mProcessNames.get(processName, uid); 1794 return proc; 1795 } 1796 1797 void ensurePackageDexOpt(String packageName) { 1798 IPackageManager pm = AppGlobals.getPackageManager(); 1799 try { 1800 if (pm.performDexOpt(packageName)) { 1801 mDidDexOpt = true; 1802 } 1803 } catch (RemoteException e) { 1804 } 1805 } 1806 1807 boolean isNextTransitionForward() { 1808 int transit = mWindowManager.getPendingAppTransition(); 1809 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1810 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1811 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1812 } 1813 1814 final ProcessRecord startProcessLocked(String processName, 1815 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1816 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1817 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1818 // We don't have to do anything more if: 1819 // (1) There is an existing application record; and 1820 // (2) The caller doesn't think it is dead, OR there is no thread 1821 // object attached to it so we know it couldn't have crashed; and 1822 // (3) There is a pid assigned to it, so it is either starting or 1823 // already running. 1824 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1825 + " app=" + app + " knownToBeDead=" + knownToBeDead 1826 + " thread=" + (app != null ? app.thread : null) 1827 + " pid=" + (app != null ? app.pid : -1)); 1828 if (app != null && app.pid > 0) { 1829 if (!knownToBeDead || app.thread == null) { 1830 // We already have the app running, or are waiting for it to 1831 // come up (we have a pid but not yet its thread), so keep it. 1832 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1833 // If this is a new package in the process, add the package to the list 1834 app.addPackage(info.packageName); 1835 return app; 1836 } else { 1837 // An application record is attached to a previous process, 1838 // clean it up now. 1839 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1840 handleAppDiedLocked(app, true, true); 1841 } 1842 } 1843 1844 String hostingNameStr = hostingName != null 1845 ? hostingName.flattenToShortString() : null; 1846 1847 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1848 // If we are in the background, then check to see if this process 1849 // is bad. If so, we will just silently fail. 1850 if (mBadProcesses.get(info.processName, info.uid) != null) { 1851 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1852 + "/" + info.processName); 1853 return null; 1854 } 1855 } else { 1856 // When the user is explicitly starting a process, then clear its 1857 // crash count so that we won't make it bad until they see at 1858 // least one crash dialog again, and make the process good again 1859 // if it had been bad. 1860 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1861 + "/" + info.processName); 1862 mProcessCrashTimes.remove(info.processName, info.uid); 1863 if (mBadProcesses.get(info.processName, info.uid) != null) { 1864 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1865 info.processName); 1866 mBadProcesses.remove(info.processName, info.uid); 1867 if (app != null) { 1868 app.bad = false; 1869 } 1870 } 1871 } 1872 1873 if (app == null) { 1874 app = newProcessRecordLocked(null, info, processName); 1875 mProcessNames.put(processName, info.uid, app); 1876 } else { 1877 // If this is a new package in the process, add the package to the list 1878 app.addPackage(info.packageName); 1879 } 1880 1881 // If the system is not ready yet, then hold off on starting this 1882 // process until it is. 1883 if (!mProcessesReady 1884 && !isAllowedWhileBooting(info) 1885 && !allowWhileBooting) { 1886 if (!mProcessesOnHold.contains(app)) { 1887 mProcessesOnHold.add(app); 1888 } 1889 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1890 return app; 1891 } 1892 1893 startProcessLocked(app, hostingType, hostingNameStr); 1894 return (app.pid != 0) ? app : null; 1895 } 1896 1897 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1898 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1899 } 1900 1901 private final void startProcessLocked(ProcessRecord app, 1902 String hostingType, String hostingNameStr) { 1903 if (app.pid > 0 && app.pid != MY_PID) { 1904 synchronized (mPidsSelfLocked) { 1905 mPidsSelfLocked.remove(app.pid); 1906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1907 } 1908 app.pid = 0; 1909 } 1910 1911 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1912 "startProcessLocked removing on hold: " + app); 1913 mProcessesOnHold.remove(app); 1914 1915 updateCpuStats(); 1916 1917 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1918 mProcDeaths[0] = 0; 1919 1920 try { 1921 int uid = app.info.uid; 1922 int[] gids = null; 1923 try { 1924 gids = mContext.getPackageManager().getPackageGids( 1925 app.info.packageName); 1926 } catch (PackageManager.NameNotFoundException e) { 1927 Slog.w(TAG, "Unable to retrieve gids", e); 1928 } 1929 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1930 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1931 && mTopComponent != null 1932 && app.processName.equals(mTopComponent.getPackageName())) { 1933 uid = 0; 1934 } 1935 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1936 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1937 uid = 0; 1938 } 1939 } 1940 int debugFlags = 0; 1941 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1942 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1943 // Also turn on CheckJNI for debuggable apps. It's quite 1944 // awkward to turn on otherwise. 1945 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1946 } 1947 // Run the app in safe mode if its manifest requests so or the 1948 // system is booted in safe mode. 1949 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 1950 Zygote.systemInSafeMode == true) { 1951 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1952 } 1953 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1954 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1955 } 1956 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1957 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1958 } 1959 if ("1".equals(SystemProperties.get("debug.assert"))) { 1960 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1961 } 1962 1963 // Start the process. It will either succeed and return a result containing 1964 // the PID of the new process, or else throw a RuntimeException. 1965 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 1966 app.processName, uid, uid, gids, debugFlags, 1967 app.info.targetSdkVersion, null); 1968 1969 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 1970 synchronized (bs) { 1971 if (bs.isOnBattery()) { 1972 app.batteryStats.incStartsLocked(); 1973 } 1974 } 1975 1976 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 1977 app.processName, hostingType, 1978 hostingNameStr != null ? hostingNameStr : ""); 1979 1980 if (app.persistent) { 1981 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 1982 } 1983 1984 StringBuilder buf = mStringBuilder; 1985 buf.setLength(0); 1986 buf.append("Start proc "); 1987 buf.append(app.processName); 1988 buf.append(" for "); 1989 buf.append(hostingType); 1990 if (hostingNameStr != null) { 1991 buf.append(" "); 1992 buf.append(hostingNameStr); 1993 } 1994 buf.append(": pid="); 1995 buf.append(startResult.pid); 1996 buf.append(" uid="); 1997 buf.append(uid); 1998 buf.append(" gids={"); 1999 if (gids != null) { 2000 for (int gi=0; gi<gids.length; gi++) { 2001 if (gi != 0) buf.append(", "); 2002 buf.append(gids[gi]); 2003 2004 } 2005 } 2006 buf.append("}"); 2007 Slog.i(TAG, buf.toString()); 2008 app.pid = startResult.pid; 2009 app.usingWrapper = startResult.usingWrapper; 2010 app.removed = false; 2011 synchronized (mPidsSelfLocked) { 2012 this.mPidsSelfLocked.put(startResult.pid, app); 2013 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2014 msg.obj = app; 2015 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2016 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2017 } 2018 } catch (RuntimeException e) { 2019 // XXX do better error recovery. 2020 app.pid = 0; 2021 Slog.e(TAG, "Failure starting process " + app.processName, e); 2022 } 2023 } 2024 2025 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2026 if (resumed) { 2027 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2028 } else { 2029 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2030 } 2031 } 2032 2033 boolean startHomeActivityLocked() { 2034 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2035 && mTopAction == null) { 2036 // We are running in factory test mode, but unable to find 2037 // the factory test app, so just sit around displaying the 2038 // error message and don't try to start anything. 2039 return false; 2040 } 2041 Intent intent = new Intent( 2042 mTopAction, 2043 mTopData != null ? Uri.parse(mTopData) : null); 2044 intent.setComponent(mTopComponent); 2045 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2046 intent.addCategory(Intent.CATEGORY_HOME); 2047 } 2048 ActivityInfo aInfo = 2049 intent.resolveActivityInfo(mContext.getPackageManager(), 2050 STOCK_PM_FLAGS); 2051 if (aInfo != null) { 2052 intent.setComponent(new ComponentName( 2053 aInfo.applicationInfo.packageName, aInfo.name)); 2054 // Don't do this if the home app is currently being 2055 // instrumented. 2056 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2057 aInfo.applicationInfo.uid); 2058 if (app == null || app.instrumentationClass == null) { 2059 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2060 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo, 2061 null, null, 0, 0, 0, false, false, null); 2062 } 2063 } 2064 2065 2066 return true; 2067 } 2068 2069 /** 2070 * Starts the "new version setup screen" if appropriate. 2071 */ 2072 void startSetupActivityLocked() { 2073 // Only do this once per boot. 2074 if (mCheckedForSetup) { 2075 return; 2076 } 2077 2078 // We will show this screen if the current one is a different 2079 // version than the last one shown, and we are not running in 2080 // low-level factory test mode. 2081 final ContentResolver resolver = mContext.getContentResolver(); 2082 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2083 Settings.Secure.getInt(resolver, 2084 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2085 mCheckedForSetup = true; 2086 2087 // See if we should be showing the platform update setup UI. 2088 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2089 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2090 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2091 2092 // We don't allow third party apps to replace this. 2093 ResolveInfo ri = null; 2094 for (int i=0; ris != null && i<ris.size(); i++) { 2095 if ((ris.get(i).activityInfo.applicationInfo.flags 2096 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2097 ri = ris.get(i); 2098 break; 2099 } 2100 } 2101 2102 if (ri != null) { 2103 String vers = ri.activityInfo.metaData != null 2104 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2105 : null; 2106 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2107 vers = ri.activityInfo.applicationInfo.metaData.getString( 2108 Intent.METADATA_SETUP_VERSION); 2109 } 2110 String lastVers = Settings.Secure.getString( 2111 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2112 if (vers != null && !vers.equals(lastVers)) { 2113 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2114 intent.setComponent(new ComponentName( 2115 ri.activityInfo.packageName, ri.activityInfo.name)); 2116 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2117 null, null, 0, 0, 0, false, false, null); 2118 } 2119 } 2120 } 2121 } 2122 2123 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2124 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2125 } 2126 2127 public int getFrontActivityScreenCompatMode() { 2128 synchronized (this) { 2129 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2130 } 2131 } 2132 2133 public void setFrontActivityScreenCompatMode(int mode) { 2134 synchronized (this) { 2135 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2136 } 2137 } 2138 2139 public int getPackageScreenCompatMode(String packageName) { 2140 synchronized (this) { 2141 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2142 } 2143 } 2144 2145 public void setPackageScreenCompatMode(String packageName, int mode) { 2146 synchronized (this) { 2147 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2148 } 2149 } 2150 2151 public boolean getPackageAskScreenCompat(String packageName) { 2152 synchronized (this) { 2153 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2154 } 2155 } 2156 2157 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2158 synchronized (this) { 2159 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2160 } 2161 } 2162 2163 void reportResumedActivityLocked(ActivityRecord r) { 2164 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2165 2166 final int identHash = System.identityHashCode(r); 2167 updateUsageStats(r, true); 2168 2169 int i = mWatchers.beginBroadcast(); 2170 while (i > 0) { 2171 i--; 2172 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2173 if (w != null) { 2174 try { 2175 w.activityResuming(identHash); 2176 } catch (RemoteException e) { 2177 } 2178 } 2179 } 2180 mWatchers.finishBroadcast(); 2181 } 2182 2183 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 2184 int i = mProcessObservers.beginBroadcast(); 2185 while (i > 0) { 2186 i--; 2187 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2188 if (observer != null) { 2189 try { 2190 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities); 2191 } catch (RemoteException e) { 2192 } 2193 } 2194 } 2195 mProcessObservers.finishBroadcast(); 2196 } 2197 2198 private void dispatchProcessDied(int pid, int uid) { 2199 int i = mProcessObservers.beginBroadcast(); 2200 while (i > 0) { 2201 i--; 2202 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2203 if (observer != null) { 2204 try { 2205 observer.onProcessDied(pid, uid); 2206 } catch (RemoteException e) { 2207 } 2208 } 2209 } 2210 mProcessObservers.finishBroadcast(); 2211 } 2212 2213 final void doPendingActivityLaunchesLocked(boolean doResume) { 2214 final int N = mPendingActivityLaunches.size(); 2215 if (N <= 0) { 2216 return; 2217 } 2218 for (int i=0; i<N; i++) { 2219 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2220 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2221 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 2222 doResume && i == (N-1)); 2223 } 2224 mPendingActivityLaunches.clear(); 2225 } 2226 2227 public final int startActivity(IApplicationThread caller, 2228 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2229 int grantedMode, IBinder resultTo, 2230 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, 2231 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 2232 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2233 grantedUriPermissions, grantedMode, resultTo, resultWho, 2234 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, 2235 null, null); 2236 } 2237 2238 public final WaitResult startActivityAndWait(IApplicationThread caller, 2239 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2240 int grantedMode, IBinder resultTo, 2241 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, 2242 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 2243 WaitResult res = new WaitResult(); 2244 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2245 grantedUriPermissions, grantedMode, resultTo, resultWho, 2246 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, 2247 res, null); 2248 return res; 2249 } 2250 2251 public final int startActivityWithConfig(IApplicationThread caller, 2252 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2253 int grantedMode, IBinder resultTo, 2254 String resultWho, int requestCode, boolean onlyIfNeeded, 2255 boolean debug, Configuration config) { 2256 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2257 grantedUriPermissions, grantedMode, resultTo, resultWho, 2258 requestCode, onlyIfNeeded, debug, null, null, false, null, config); 2259 } 2260 2261 public int startActivityIntentSender(IApplicationThread caller, 2262 IntentSender intent, Intent fillInIntent, String resolvedType, 2263 IBinder resultTo, String resultWho, int requestCode, 2264 int flagsMask, int flagsValues) { 2265 // Refuse possible leaked file descriptors 2266 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2267 throw new IllegalArgumentException("File descriptors passed in Intent"); 2268 } 2269 2270 IIntentSender sender = intent.getTarget(); 2271 if (!(sender instanceof PendingIntentRecord)) { 2272 throw new IllegalArgumentException("Bad PendingIntent object"); 2273 } 2274 2275 PendingIntentRecord pir = (PendingIntentRecord)sender; 2276 2277 synchronized (this) { 2278 // If this is coming from the currently resumed activity, it is 2279 // effectively saying that app switches are allowed at this point. 2280 if (mMainStack.mResumedActivity != null 2281 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2282 Binder.getCallingUid()) { 2283 mAppSwitchesAllowedTime = 0; 2284 } 2285 } 2286 2287 return pir.sendInner(0, fillInIntent, resolvedType, null, 2288 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 2289 } 2290 2291 public boolean startNextMatchingActivity(IBinder callingActivity, 2292 Intent intent) { 2293 // Refuse possible leaked file descriptors 2294 if (intent != null && intent.hasFileDescriptors() == true) { 2295 throw new IllegalArgumentException("File descriptors passed in Intent"); 2296 } 2297 2298 synchronized (this) { 2299 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2300 if (r == null) { 2301 return false; 2302 } 2303 if (r.app == null || r.app.thread == null) { 2304 // The caller is not running... d'oh! 2305 return false; 2306 } 2307 intent = new Intent(intent); 2308 // The caller is not allowed to change the data. 2309 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2310 // And we are resetting to find the next component... 2311 intent.setComponent(null); 2312 2313 ActivityInfo aInfo = null; 2314 try { 2315 List<ResolveInfo> resolves = 2316 AppGlobals.getPackageManager().queryIntentActivities( 2317 intent, r.resolvedType, 2318 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 2319 2320 // Look for the original activity in the list... 2321 final int N = resolves != null ? resolves.size() : 0; 2322 for (int i=0; i<N; i++) { 2323 ResolveInfo rInfo = resolves.get(i); 2324 if (rInfo.activityInfo.packageName.equals(r.packageName) 2325 && rInfo.activityInfo.name.equals(r.info.name)) { 2326 // We found the current one... the next matching is 2327 // after it. 2328 i++; 2329 if (i<N) { 2330 aInfo = resolves.get(i).activityInfo; 2331 } 2332 break; 2333 } 2334 } 2335 } catch (RemoteException e) { 2336 } 2337 2338 if (aInfo == null) { 2339 // Nobody who is next! 2340 return false; 2341 } 2342 2343 intent.setComponent(new ComponentName( 2344 aInfo.applicationInfo.packageName, aInfo.name)); 2345 intent.setFlags(intent.getFlags()&~( 2346 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2347 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2348 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2349 Intent.FLAG_ACTIVITY_NEW_TASK)); 2350 2351 // Okay now we need to start the new activity, replacing the 2352 // currently running activity. This is a little tricky because 2353 // we want to start the new one as if the current one is finished, 2354 // but not finish the current one first so that there is no flicker. 2355 // And thus... 2356 final boolean wasFinishing = r.finishing; 2357 r.finishing = true; 2358 2359 // Propagate reply information over to the new activity. 2360 final ActivityRecord resultTo = r.resultTo; 2361 final String resultWho = r.resultWho; 2362 final int requestCode = r.requestCode; 2363 r.resultTo = null; 2364 if (resultTo != null) { 2365 resultTo.removeResultsLocked(r, resultWho, requestCode); 2366 } 2367 2368 final long origId = Binder.clearCallingIdentity(); 2369 // XXX we are not dealing with propagating grantedUriPermissions... 2370 // those are not yet exposed to user code, so there is no need. 2371 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2372 r.resolvedType, null, 0, aInfo, 2373 resultTo != null ? resultTo.appToken : null, resultWho, 2374 requestCode, -1, r.launchedFromUid, false, false, null); 2375 Binder.restoreCallingIdentity(origId); 2376 2377 r.finishing = wasFinishing; 2378 if (res != START_SUCCESS) { 2379 return false; 2380 } 2381 return true; 2382 } 2383 } 2384 2385 public final int startActivityInPackage(int uid, 2386 Intent intent, String resolvedType, IBinder resultTo, 2387 String resultWho, int requestCode, boolean onlyIfNeeded) { 2388 2389 // This is so super not safe, that only the system (or okay root) 2390 // can do it. 2391 final int callingUid = Binder.getCallingUid(); 2392 if (callingUid != 0 && callingUid != Process.myUid()) { 2393 throw new SecurityException( 2394 "startActivityInPackage only available to the system"); 2395 } 2396 2397 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2398 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, 2399 null, null, false, null, null); 2400 } 2401 2402 public final int startActivities(IApplicationThread caller, 2403 Intent[] intents, String[] resolvedTypes, IBinder resultTo) { 2404 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo); 2405 } 2406 2407 public final int startActivitiesInPackage(int uid, 2408 Intent[] intents, String[] resolvedTypes, IBinder resultTo) { 2409 2410 // This is so super not safe, that only the system (or okay root) 2411 // can do it. 2412 final int callingUid = Binder.getCallingUid(); 2413 if (callingUid != 0 && callingUid != Process.myUid()) { 2414 throw new SecurityException( 2415 "startActivityInPackage only available to the system"); 2416 } 2417 2418 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo); 2419 } 2420 2421 final void addRecentTaskLocked(TaskRecord task) { 2422 int N = mRecentTasks.size(); 2423 // Quick case: check if the top-most recent task is the same. 2424 if (N > 0 && mRecentTasks.get(0) == task) { 2425 return; 2426 } 2427 // Remove any existing entries that are the same kind of task. 2428 for (int i=0; i<N; i++) { 2429 TaskRecord tr = mRecentTasks.get(i); 2430 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 2431 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 2432 mRecentTasks.remove(i); 2433 i--; 2434 N--; 2435 if (task.intent == null) { 2436 // If the new recent task we are adding is not fully 2437 // specified, then replace it with the existing recent task. 2438 task = tr; 2439 } 2440 } 2441 } 2442 if (N >= MAX_RECENT_TASKS) { 2443 mRecentTasks.remove(N-1); 2444 } 2445 mRecentTasks.add(0, task); 2446 } 2447 2448 public void setRequestedOrientation(IBinder token, 2449 int requestedOrientation) { 2450 synchronized (this) { 2451 ActivityRecord r = mMainStack.isInStackLocked(token); 2452 if (r == null) { 2453 return; 2454 } 2455 final long origId = Binder.clearCallingIdentity(); 2456 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2457 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2458 mConfiguration, 2459 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2460 if (config != null) { 2461 r.frozenBeforeDestroy = true; 2462 if (!updateConfigurationLocked(config, r, false, false)) { 2463 mMainStack.resumeTopActivityLocked(null); 2464 } 2465 } 2466 Binder.restoreCallingIdentity(origId); 2467 } 2468 } 2469 2470 public int getRequestedOrientation(IBinder token) { 2471 synchronized (this) { 2472 ActivityRecord r = mMainStack.isInStackLocked(token); 2473 if (r == null) { 2474 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2475 } 2476 return mWindowManager.getAppOrientation(r.appToken); 2477 } 2478 } 2479 2480 /** 2481 * This is the internal entry point for handling Activity.finish(). 2482 * 2483 * @param token The Binder token referencing the Activity we want to finish. 2484 * @param resultCode Result code, if any, from this Activity. 2485 * @param resultData Result data (Intent), if any, from this Activity. 2486 * 2487 * @return Returns true if the activity successfully finished, or false if it is still running. 2488 */ 2489 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2490 // Refuse possible leaked file descriptors 2491 if (resultData != null && resultData.hasFileDescriptors() == true) { 2492 throw new IllegalArgumentException("File descriptors passed in Intent"); 2493 } 2494 2495 synchronized(this) { 2496 if (mController != null) { 2497 // Find the first activity that is not finishing. 2498 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2499 if (next != null) { 2500 // ask watcher if this is allowed 2501 boolean resumeOK = true; 2502 try { 2503 resumeOK = mController.activityResuming(next.packageName); 2504 } catch (RemoteException e) { 2505 mController = null; 2506 } 2507 2508 if (!resumeOK) { 2509 return false; 2510 } 2511 } 2512 } 2513 final long origId = Binder.clearCallingIdentity(); 2514 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2515 resultData, "app-request"); 2516 Binder.restoreCallingIdentity(origId); 2517 return res; 2518 } 2519 } 2520 2521 public final void finishHeavyWeightApp() { 2522 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2523 != PackageManager.PERMISSION_GRANTED) { 2524 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2525 + Binder.getCallingPid() 2526 + ", uid=" + Binder.getCallingUid() 2527 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2528 Slog.w(TAG, msg); 2529 throw new SecurityException(msg); 2530 } 2531 2532 synchronized(this) { 2533 if (mHeavyWeightProcess == null) { 2534 return; 2535 } 2536 2537 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2538 mHeavyWeightProcess.activities); 2539 for (int i=0; i<activities.size(); i++) { 2540 ActivityRecord r = activities.get(i); 2541 if (!r.finishing) { 2542 int index = mMainStack.indexOfTokenLocked(r.appToken); 2543 if (index >= 0) { 2544 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2545 null, "finish-heavy"); 2546 } 2547 } 2548 } 2549 2550 mHeavyWeightProcess = null; 2551 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2552 } 2553 } 2554 2555 public void crashApplication(int uid, int initialPid, String packageName, 2556 String message) { 2557 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2558 != PackageManager.PERMISSION_GRANTED) { 2559 String msg = "Permission Denial: crashApplication() from pid=" 2560 + Binder.getCallingPid() 2561 + ", uid=" + Binder.getCallingUid() 2562 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2563 Slog.w(TAG, msg); 2564 throw new SecurityException(msg); 2565 } 2566 2567 synchronized(this) { 2568 ProcessRecord proc = null; 2569 2570 // Figure out which process to kill. We don't trust that initialPid 2571 // still has any relation to current pids, so must scan through the 2572 // list. 2573 synchronized (mPidsSelfLocked) { 2574 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2575 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2576 if (p.info.uid != uid) { 2577 continue; 2578 } 2579 if (p.pid == initialPid) { 2580 proc = p; 2581 break; 2582 } 2583 for (String str : p.pkgList) { 2584 if (str.equals(packageName)) { 2585 proc = p; 2586 } 2587 } 2588 } 2589 } 2590 2591 if (proc == null) { 2592 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2593 + " initialPid=" + initialPid 2594 + " packageName=" + packageName); 2595 return; 2596 } 2597 2598 if (proc.thread != null) { 2599 if (proc.pid == Process.myPid()) { 2600 Log.w(TAG, "crashApplication: trying to crash self!"); 2601 return; 2602 } 2603 long ident = Binder.clearCallingIdentity(); 2604 try { 2605 proc.thread.scheduleCrash(message); 2606 } catch (RemoteException e) { 2607 } 2608 Binder.restoreCallingIdentity(ident); 2609 } 2610 } 2611 } 2612 2613 public final void finishSubActivity(IBinder token, String resultWho, 2614 int requestCode) { 2615 synchronized(this) { 2616 ActivityRecord self = mMainStack.isInStackLocked(token); 2617 if (self == null) { 2618 return; 2619 } 2620 2621 final long origId = Binder.clearCallingIdentity(); 2622 2623 int i; 2624 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2625 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2626 if (r.resultTo == self && r.requestCode == requestCode) { 2627 if ((r.resultWho == null && resultWho == null) || 2628 (r.resultWho != null && r.resultWho.equals(resultWho))) { 2629 mMainStack.finishActivityLocked(r, i, 2630 Activity.RESULT_CANCELED, null, "request-sub"); 2631 } 2632 } 2633 } 2634 2635 Binder.restoreCallingIdentity(origId); 2636 } 2637 } 2638 2639 public boolean willActivityBeVisible(IBinder token) { 2640 synchronized(this) { 2641 int i; 2642 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2643 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2644 if (r.appToken == token) { 2645 return true; 2646 } 2647 if (r.fullscreen && !r.finishing) { 2648 return false; 2649 } 2650 } 2651 return true; 2652 } 2653 } 2654 2655 public void overridePendingTransition(IBinder token, String packageName, 2656 int enterAnim, int exitAnim) { 2657 synchronized(this) { 2658 ActivityRecord self = mMainStack.isInStackLocked(token); 2659 if (self == null) { 2660 return; 2661 } 2662 2663 final long origId = Binder.clearCallingIdentity(); 2664 2665 if (self.state == ActivityState.RESUMED 2666 || self.state == ActivityState.PAUSING) { 2667 mWindowManager.overridePendingAppTransition(packageName, 2668 enterAnim, exitAnim); 2669 } 2670 2671 Binder.restoreCallingIdentity(origId); 2672 } 2673 } 2674 2675 /** 2676 * Main function for removing an existing process from the activity manager 2677 * as a result of that process going away. Clears out all connections 2678 * to the process. 2679 */ 2680 private final void handleAppDiedLocked(ProcessRecord app, 2681 boolean restarting, boolean allowRestart) { 2682 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2683 if (!restarting) { 2684 mLruProcesses.remove(app); 2685 } 2686 2687 if (mProfileProc == app) { 2688 clearProfilerLocked(); 2689 } 2690 2691 // Just in case... 2692 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2693 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2694 mMainStack.mPausingActivity = null; 2695 } 2696 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2697 mMainStack.mLastPausedActivity = null; 2698 } 2699 2700 // Remove this application's activities from active lists. 2701 mMainStack.removeHistoryRecordsForAppLocked(app); 2702 2703 boolean atTop = true; 2704 boolean hasVisibleActivities = false; 2705 2706 // Clean out the history list. 2707 int i = mMainStack.mHistory.size(); 2708 if (localLOGV) Slog.v( 2709 TAG, "Removing app " + app + " from history with " + i + " entries"); 2710 while (i > 0) { 2711 i--; 2712 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2713 if (localLOGV) Slog.v( 2714 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2715 if (r.app == app) { 2716 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2717 if (ActivityStack.DEBUG_ADD_REMOVE) { 2718 RuntimeException here = new RuntimeException("here"); 2719 here.fillInStackTrace(); 2720 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2721 + ": haveState=" + r.haveState 2722 + " stateNotNeeded=" + r.stateNotNeeded 2723 + " finishing=" + r.finishing 2724 + " state=" + r.state, here); 2725 } 2726 if (!r.finishing) { 2727 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2728 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2729 System.identityHashCode(r), 2730 r.task.taskId, r.shortComponentName, 2731 "proc died without state saved"); 2732 } 2733 r.makeFinishing(); 2734 mMainStack.mHistory.remove(i); 2735 r.takeFromHistory(); 2736 mWindowManager.removeAppToken(r.appToken); 2737 if (VALIDATE_TOKENS) { 2738 mMainStack.validateAppTokensLocked(); 2739 } 2740 r.removeUriPermissionsLocked(); 2741 2742 } else { 2743 // We have the current state for this activity, so 2744 // it can be restarted later when needed. 2745 if (localLOGV) Slog.v( 2746 TAG, "Keeping entry, setting app to null"); 2747 if (r.visible) { 2748 hasVisibleActivities = true; 2749 } 2750 r.app = null; 2751 r.nowVisible = false; 2752 if (!r.haveState) { 2753 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2754 "App died, clearing saved state of " + r); 2755 r.icicle = null; 2756 } 2757 } 2758 2759 r.stack.cleanUpActivityLocked(r, true, true); 2760 } 2761 atTop = false; 2762 } 2763 2764 app.activities.clear(); 2765 2766 if (app.instrumentationClass != null) { 2767 Slog.w(TAG, "Crash of app " + app.processName 2768 + " running instrumentation " + app.instrumentationClass); 2769 Bundle info = new Bundle(); 2770 info.putString("shortMsg", "Process crashed."); 2771 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2772 } 2773 2774 if (!restarting) { 2775 if (!mMainStack.resumeTopActivityLocked(null)) { 2776 // If there was nothing to resume, and we are not already 2777 // restarting this process, but there is a visible activity that 2778 // is hosted by the process... then make sure all visible 2779 // activities are running, taking care of restarting this 2780 // process. 2781 if (hasVisibleActivities) { 2782 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2783 } 2784 } 2785 } 2786 } 2787 2788 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2789 IBinder threadBinder = thread.asBinder(); 2790 2791 // Find the application record. 2792 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2793 ProcessRecord rec = mLruProcesses.get(i); 2794 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2795 return i; 2796 } 2797 } 2798 return -1; 2799 } 2800 2801 final ProcessRecord getRecordForAppLocked( 2802 IApplicationThread thread) { 2803 if (thread == null) { 2804 return null; 2805 } 2806 2807 int appIndex = getLRURecordIndexForAppLocked(thread); 2808 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2809 } 2810 2811 final void appDiedLocked(ProcessRecord app, int pid, 2812 IApplicationThread thread) { 2813 2814 mProcDeaths[0]++; 2815 2816 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2817 synchronized (stats) { 2818 stats.noteProcessDiedLocked(app.info.uid, pid); 2819 } 2820 2821 // Clean up already done if the process has been re-started. 2822 if (app.pid == pid && app.thread != null && 2823 app.thread.asBinder() == thread.asBinder()) { 2824 if (!app.killedBackground) { 2825 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2826 + ") has died."); 2827 } 2828 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2829 if (localLOGV) Slog.v( 2830 TAG, "Dying app: " + app + ", pid: " + pid 2831 + ", thread: " + thread.asBinder()); 2832 boolean doLowMem = app.instrumentationClass == null; 2833 handleAppDiedLocked(app, false, true); 2834 2835 if (doLowMem) { 2836 // If there are no longer any background processes running, 2837 // and the app that died was not running instrumentation, 2838 // then tell everyone we are now low on memory. 2839 boolean haveBg = false; 2840 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2841 ProcessRecord rec = mLruProcesses.get(i); 2842 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2843 haveBg = true; 2844 break; 2845 } 2846 } 2847 2848 if (!haveBg) { 2849 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2850 long now = SystemClock.uptimeMillis(); 2851 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2852 ProcessRecord rec = mLruProcesses.get(i); 2853 if (rec != app && rec.thread != null && 2854 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2855 // The low memory report is overriding any current 2856 // state for a GC request. Make sure to do 2857 // heavy/important/visible/foreground processes first. 2858 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2859 rec.lastRequestedGc = 0; 2860 } else { 2861 rec.lastRequestedGc = rec.lastLowMemory; 2862 } 2863 rec.reportLowMemory = true; 2864 rec.lastLowMemory = now; 2865 mProcessesToGc.remove(rec); 2866 addProcessToGcListLocked(rec); 2867 } 2868 } 2869 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 2870 scheduleAppGcsLocked(); 2871 } 2872 } 2873 } else if (app.pid != pid) { 2874 // A new process has already been started. 2875 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2876 + ") has died and restarted (pid " + app.pid + ")."); 2877 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2878 } else if (DEBUG_PROCESSES) { 2879 Slog.d(TAG, "Received spurious death notification for thread " 2880 + thread.asBinder()); 2881 } 2882 } 2883 2884 /** 2885 * If a stack trace dump file is configured, dump process stack traces. 2886 * @param clearTraces causes the dump file to be erased prior to the new 2887 * traces being written, if true; when false, the new traces will be 2888 * appended to any existing file content. 2889 * @param firstPids of dalvik VM processes to dump stack traces for first 2890 * @param lastPids of dalvik VM processes to dump stack traces for last 2891 * @return file containing stack traces, or null if no dump file is configured 2892 */ 2893 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 2894 ProcessStats processStats, SparseArray<Boolean> lastPids) { 2895 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 2896 if (tracesPath == null || tracesPath.length() == 0) { 2897 return null; 2898 } 2899 2900 File tracesFile = new File(tracesPath); 2901 try { 2902 File tracesDir = tracesFile.getParentFile(); 2903 if (!tracesDir.exists()) tracesFile.mkdirs(); 2904 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 2905 2906 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 2907 tracesFile.createNewFile(); 2908 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 2909 } catch (IOException e) { 2910 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 2911 return null; 2912 } 2913 2914 // Use a FileObserver to detect when traces finish writing. 2915 // The order of traces is considered important to maintain for legibility. 2916 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 2917 public synchronized void onEvent(int event, String path) { notify(); } 2918 }; 2919 2920 try { 2921 observer.startWatching(); 2922 2923 // First collect all of the stacks of the most important pids. 2924 try { 2925 int num = firstPids.size(); 2926 for (int i = 0; i < num; i++) { 2927 synchronized (observer) { 2928 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 2929 observer.wait(200); // Wait for write-close, give up after 200msec 2930 } 2931 } 2932 } catch (InterruptedException e) { 2933 Log.wtf(TAG, e); 2934 } 2935 2936 // Next measure CPU usage. 2937 if (processStats != null) { 2938 processStats.init(); 2939 System.gc(); 2940 processStats.update(); 2941 try { 2942 synchronized (processStats) { 2943 processStats.wait(500); // measure over 1/2 second. 2944 } 2945 } catch (InterruptedException e) { 2946 } 2947 processStats.update(); 2948 2949 // We'll take the stack crawls of just the top apps using CPU. 2950 final int N = processStats.countWorkingStats(); 2951 int numProcs = 0; 2952 for (int i=0; i<N && numProcs<5; i++) { 2953 ProcessStats.Stats stats = processStats.getWorkingStats(i); 2954 if (lastPids.indexOfKey(stats.pid) >= 0) { 2955 numProcs++; 2956 try { 2957 synchronized (observer) { 2958 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 2959 observer.wait(200); // Wait for write-close, give up after 200msec 2960 } 2961 } catch (InterruptedException e) { 2962 Log.wtf(TAG, e); 2963 } 2964 2965 } 2966 } 2967 } 2968 2969 return tracesFile; 2970 2971 } finally { 2972 observer.stopWatching(); 2973 } 2974 } 2975 2976 private final class AppNotResponding implements Runnable { 2977 private final ProcessRecord mApp; 2978 private final String mAnnotation; 2979 2980 public AppNotResponding(ProcessRecord app, String annotation) { 2981 mApp = app; 2982 mAnnotation = annotation; 2983 } 2984 2985 @Override 2986 public void run() { 2987 appNotResponding(mApp, null, null, mAnnotation); 2988 } 2989 } 2990 2991 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 2992 ActivityRecord parent, final String annotation) { 2993 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 2994 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 2995 2996 if (mController != null) { 2997 try { 2998 // 0 == continue, -1 = kill process immediately 2999 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3000 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3001 } catch (RemoteException e) { 3002 mController = null; 3003 } 3004 } 3005 3006 long anrTime = SystemClock.uptimeMillis(); 3007 if (MONITOR_CPU_USAGE) { 3008 updateCpuStatsNow(); 3009 } 3010 3011 synchronized (this) { 3012 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3013 if (mShuttingDown) { 3014 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3015 return; 3016 } else if (app.notResponding) { 3017 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3018 return; 3019 } else if (app.crashing) { 3020 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3021 return; 3022 } 3023 3024 // In case we come through here for the same app before completing 3025 // this one, mark as anring now so we will bail out. 3026 app.notResponding = true; 3027 3028 // Log the ANR to the event log. 3029 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3030 annotation); 3031 3032 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3033 firstPids.add(app.pid); 3034 3035 int parentPid = app.pid; 3036 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3037 if (parentPid != app.pid) firstPids.add(parentPid); 3038 3039 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3040 3041 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3042 ProcessRecord r = mLruProcesses.get(i); 3043 if (r != null && r.thread != null) { 3044 int pid = r.pid; 3045 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3046 if (r.persistent) { 3047 firstPids.add(pid); 3048 } else { 3049 lastPids.put(pid, Boolean.TRUE); 3050 } 3051 } 3052 } 3053 } 3054 } 3055 3056 // Log the ANR to the main log. 3057 StringBuilder info = mStringBuilder; 3058 info.setLength(0); 3059 info.append("ANR in ").append(app.processName); 3060 if (activity != null && activity.shortComponentName != null) { 3061 info.append(" (").append(activity.shortComponentName).append(")"); 3062 } 3063 info.append("\n"); 3064 if (annotation != null) { 3065 info.append("Reason: ").append(annotation).append("\n"); 3066 } 3067 if (parent != null && parent != activity) { 3068 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3069 } 3070 3071 final ProcessStats processStats = new ProcessStats(true); 3072 3073 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids); 3074 3075 String cpuInfo = null; 3076 if (MONITOR_CPU_USAGE) { 3077 updateCpuStatsNow(); 3078 synchronized (mProcessStatsThread) { 3079 cpuInfo = mProcessStats.printCurrentState(anrTime); 3080 } 3081 info.append(processStats.printCurrentLoad()); 3082 info.append(cpuInfo); 3083 } 3084 3085 info.append(processStats.printCurrentState(anrTime)); 3086 3087 Slog.e(TAG, info.toString()); 3088 if (tracesFile == null) { 3089 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3090 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3091 } 3092 3093 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3094 cpuInfo, tracesFile, null); 3095 3096 if (mController != null) { 3097 try { 3098 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3099 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3100 if (res != 0) { 3101 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3102 return; 3103 } 3104 } catch (RemoteException e) { 3105 mController = null; 3106 } 3107 } 3108 3109 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3110 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3111 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3112 3113 synchronized (this) { 3114 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3115 Slog.w(TAG, "Killing " + app + ": background ANR"); 3116 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3117 app.processName, app.setAdj, "background ANR"); 3118 Process.killProcessQuiet(app.pid); 3119 return; 3120 } 3121 3122 // Set the app's notResponding state, and look up the errorReportReceiver 3123 makeAppNotRespondingLocked(app, 3124 activity != null ? activity.shortComponentName : null, 3125 annotation != null ? "ANR " + annotation : "ANR", 3126 info.toString()); 3127 3128 // Bring up the infamous App Not Responding dialog 3129 Message msg = Message.obtain(); 3130 HashMap map = new HashMap(); 3131 msg.what = SHOW_NOT_RESPONDING_MSG; 3132 msg.obj = map; 3133 map.put("app", app); 3134 if (activity != null) { 3135 map.put("activity", activity); 3136 } 3137 3138 mHandler.sendMessage(msg); 3139 } 3140 } 3141 3142 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3143 if (!mLaunchWarningShown) { 3144 mLaunchWarningShown = true; 3145 mHandler.post(new Runnable() { 3146 @Override 3147 public void run() { 3148 synchronized (ActivityManagerService.this) { 3149 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3150 d.show(); 3151 mHandler.postDelayed(new Runnable() { 3152 @Override 3153 public void run() { 3154 synchronized (ActivityManagerService.this) { 3155 d.dismiss(); 3156 mLaunchWarningShown = false; 3157 } 3158 } 3159 }, 4000); 3160 } 3161 } 3162 }); 3163 } 3164 } 3165 3166 public boolean clearApplicationUserData(final String packageName, 3167 final IPackageDataObserver observer) { 3168 int uid = Binder.getCallingUid(); 3169 int pid = Binder.getCallingPid(); 3170 long callingId = Binder.clearCallingIdentity(); 3171 try { 3172 IPackageManager pm = AppGlobals.getPackageManager(); 3173 int pkgUid = -1; 3174 synchronized(this) { 3175 try { 3176 pkgUid = pm.getPackageUid(packageName); 3177 } catch (RemoteException e) { 3178 } 3179 if (pkgUid == -1) { 3180 Slog.w(TAG, "Invalid packageName:" + packageName); 3181 return false; 3182 } 3183 if (uid == pkgUid || checkComponentPermission( 3184 android.Manifest.permission.CLEAR_APP_USER_DATA, 3185 pid, uid, -1, true) 3186 == PackageManager.PERMISSION_GRANTED) { 3187 forceStopPackageLocked(packageName, pkgUid); 3188 } else { 3189 throw new SecurityException(pid+" does not have permission:"+ 3190 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3191 "for process:"+packageName); 3192 } 3193 } 3194 3195 try { 3196 //clear application user data 3197 pm.clearApplicationUserData(packageName, observer); 3198 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3199 Uri.fromParts("package", packageName, null)); 3200 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3201 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3202 null, null, 0, null, null, null, false, false); 3203 } catch (RemoteException e) { 3204 } 3205 } finally { 3206 Binder.restoreCallingIdentity(callingId); 3207 } 3208 return true; 3209 } 3210 3211 public void killBackgroundProcesses(final String packageName) { 3212 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3213 != PackageManager.PERMISSION_GRANTED && 3214 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3215 != PackageManager.PERMISSION_GRANTED) { 3216 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3217 + Binder.getCallingPid() 3218 + ", uid=" + Binder.getCallingUid() 3219 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3220 Slog.w(TAG, msg); 3221 throw new SecurityException(msg); 3222 } 3223 3224 long callingId = Binder.clearCallingIdentity(); 3225 try { 3226 IPackageManager pm = AppGlobals.getPackageManager(); 3227 int pkgUid = -1; 3228 synchronized(this) { 3229 try { 3230 pkgUid = pm.getPackageUid(packageName); 3231 } catch (RemoteException e) { 3232 } 3233 if (pkgUid == -1) { 3234 Slog.w(TAG, "Invalid packageName: " + packageName); 3235 return; 3236 } 3237 killPackageProcessesLocked(packageName, pkgUid, 3238 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3239 } 3240 } finally { 3241 Binder.restoreCallingIdentity(callingId); 3242 } 3243 } 3244 3245 public void killAllBackgroundProcesses() { 3246 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3247 != PackageManager.PERMISSION_GRANTED) { 3248 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3249 + Binder.getCallingPid() 3250 + ", uid=" + Binder.getCallingUid() 3251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3252 Slog.w(TAG, msg); 3253 throw new SecurityException(msg); 3254 } 3255 3256 long callingId = Binder.clearCallingIdentity(); 3257 try { 3258 synchronized(this) { 3259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3260 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3261 final int NA = apps.size(); 3262 for (int ia=0; ia<NA; ia++) { 3263 ProcessRecord app = apps.valueAt(ia); 3264 if (app.persistent) { 3265 // we don't kill persistent processes 3266 continue; 3267 } 3268 if (app.removed) { 3269 procs.add(app); 3270 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3271 app.removed = true; 3272 procs.add(app); 3273 } 3274 } 3275 } 3276 3277 int N = procs.size(); 3278 for (int i=0; i<N; i++) { 3279 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3280 } 3281 } 3282 } finally { 3283 Binder.restoreCallingIdentity(callingId); 3284 } 3285 } 3286 3287 public void forceStopPackage(final String packageName) { 3288 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3289 != PackageManager.PERMISSION_GRANTED) { 3290 String msg = "Permission Denial: forceStopPackage() from pid=" 3291 + Binder.getCallingPid() 3292 + ", uid=" + Binder.getCallingUid() 3293 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 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 forceStopPackageLocked(packageName, pkgUid); 3312 try { 3313 pm.setPackageStoppedState(packageName, true); 3314 } catch (RemoteException e) { 3315 } catch (IllegalArgumentException e) { 3316 Slog.w(TAG, "Failed trying to unstop package " 3317 + packageName + ": " + e); 3318 } 3319 } 3320 } finally { 3321 Binder.restoreCallingIdentity(callingId); 3322 } 3323 } 3324 3325 /* 3326 * The pkg name and uid have to be specified. 3327 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3328 */ 3329 public void killApplicationWithUid(String pkg, int uid) { 3330 if (pkg == null) { 3331 return; 3332 } 3333 // Make sure the uid is valid. 3334 if (uid < 0) { 3335 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3336 return; 3337 } 3338 int callerUid = Binder.getCallingUid(); 3339 // Only the system server can kill an application 3340 if (callerUid == Process.SYSTEM_UID) { 3341 // Post an aysnc message to kill the application 3342 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3343 msg.arg1 = uid; 3344 msg.arg2 = 0; 3345 msg.obj = pkg; 3346 mHandler.sendMessage(msg); 3347 } else { 3348 throw new SecurityException(callerUid + " cannot kill pkg: " + 3349 pkg); 3350 } 3351 } 3352 3353 public void closeSystemDialogs(String reason) { 3354 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3355 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3356 if (reason != null) { 3357 intent.putExtra("reason", reason); 3358 } 3359 3360 final int uid = Binder.getCallingUid(); 3361 final long origId = Binder.clearCallingIdentity(); 3362 synchronized (this) { 3363 int i = mWatchers.beginBroadcast(); 3364 while (i > 0) { 3365 i--; 3366 IActivityWatcher w = mWatchers.getBroadcastItem(i); 3367 if (w != null) { 3368 try { 3369 w.closingSystemDialogs(reason); 3370 } catch (RemoteException e) { 3371 } 3372 } 3373 } 3374 mWatchers.finishBroadcast(); 3375 3376 mWindowManager.closeSystemDialogs(reason); 3377 3378 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 3379 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3380 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3381 r.stack.finishActivityLocked(r, i, 3382 Activity.RESULT_CANCELED, null, "close-sys"); 3383 } 3384 } 3385 3386 broadcastIntentLocked(null, null, intent, null, 3387 null, 0, null, null, null, false, false, -1, uid); 3388 } 3389 Binder.restoreCallingIdentity(origId); 3390 } 3391 3392 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3393 throws RemoteException { 3394 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3395 for (int i=pids.length-1; i>=0; i--) { 3396 infos[i] = new Debug.MemoryInfo(); 3397 Debug.getMemoryInfo(pids[i], infos[i]); 3398 } 3399 return infos; 3400 } 3401 3402 public long[] getProcessPss(int[] pids) throws RemoteException { 3403 long[] pss = new long[pids.length]; 3404 for (int i=pids.length-1; i>=0; i--) { 3405 pss[i] = Debug.getPss(pids[i]); 3406 } 3407 return pss; 3408 } 3409 3410 public void killApplicationProcess(String processName, int uid) { 3411 if (processName == null) { 3412 return; 3413 } 3414 3415 int callerUid = Binder.getCallingUid(); 3416 // Only the system server can kill an application 3417 if (callerUid == Process.SYSTEM_UID) { 3418 synchronized (this) { 3419 ProcessRecord app = getProcessRecordLocked(processName, uid); 3420 if (app != null && app.thread != null) { 3421 try { 3422 app.thread.scheduleSuicide(); 3423 } catch (RemoteException e) { 3424 // If the other end already died, then our work here is done. 3425 } 3426 } else { 3427 Slog.w(TAG, "Process/uid not found attempting kill of " 3428 + processName + " / " + uid); 3429 } 3430 } 3431 } else { 3432 throw new SecurityException(callerUid + " cannot kill app process: " + 3433 processName); 3434 } 3435 } 3436 3437 private void forceStopPackageLocked(final String packageName, int uid) { 3438 forceStopPackageLocked(packageName, uid, false, false, true, false); 3439 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3440 Uri.fromParts("package", packageName, null)); 3441 if (!mProcessesReady) { 3442 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3443 } 3444 intent.putExtra(Intent.EXTRA_UID, uid); 3445 broadcastIntentLocked(null, null, intent, 3446 null, null, 0, null, null, null, 3447 false, false, MY_PID, Process.SYSTEM_UID); 3448 } 3449 3450 private final boolean killPackageProcessesLocked(String packageName, int uid, 3451 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3452 boolean evenPersistent, String reason) { 3453 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3454 3455 // Remove all processes this package may have touched: all with the 3456 // same UID (except for the system or root user), and all whose name 3457 // matches the package name. 3458 final String procNamePrefix = packageName + ":"; 3459 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3460 final int NA = apps.size(); 3461 for (int ia=0; ia<NA; ia++) { 3462 ProcessRecord app = apps.valueAt(ia); 3463 if (app.persistent && !evenPersistent) { 3464 // we don't kill persistent processes 3465 continue; 3466 } 3467 if (app.removed) { 3468 if (doit) { 3469 procs.add(app); 3470 } 3471 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3472 || app.processName.equals(packageName) 3473 || app.processName.startsWith(procNamePrefix)) { 3474 if (app.setAdj >= minOomAdj) { 3475 if (!doit) { 3476 return true; 3477 } 3478 app.removed = true; 3479 procs.add(app); 3480 } 3481 } 3482 } 3483 } 3484 3485 int N = procs.size(); 3486 for (int i=0; i<N; i++) { 3487 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3488 } 3489 return N > 0; 3490 } 3491 3492 private final boolean forceStopPackageLocked(String name, int uid, 3493 boolean callerWillRestart, boolean purgeCache, boolean doit, 3494 boolean evenPersistent) { 3495 int i; 3496 int N; 3497 3498 if (uid < 0) { 3499 try { 3500 uid = AppGlobals.getPackageManager().getPackageUid(name); 3501 } catch (RemoteException e) { 3502 } 3503 } 3504 3505 if (doit) { 3506 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3507 3508 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3509 while (badApps.hasNext()) { 3510 SparseArray<Long> ba = badApps.next(); 3511 if (ba.get(uid) != null) { 3512 badApps.remove(); 3513 } 3514 } 3515 } 3516 3517 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3518 callerWillRestart, false, doit, evenPersistent, "force stop"); 3519 3520 TaskRecord lastTask = null; 3521 for (i=0; i<mMainStack.mHistory.size(); i++) { 3522 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3523 final boolean samePackage = r.packageName.equals(name); 3524 if ((samePackage || r.task == lastTask) 3525 && (r.app == null || evenPersistent || !r.app.persistent)) { 3526 if (!doit) { 3527 if (r.finishing) { 3528 // If this activity is just finishing, then it is not 3529 // interesting as far as something to stop. 3530 continue; 3531 } 3532 return true; 3533 } 3534 didSomething = true; 3535 Slog.i(TAG, " Force finishing activity " + r); 3536 if (samePackage) { 3537 if (r.app != null) { 3538 r.app.removed = true; 3539 } 3540 r.app = null; 3541 } 3542 lastTask = r.task; 3543 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3544 null, "force-stop")) { 3545 i--; 3546 } 3547 } 3548 } 3549 3550 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 3551 for (ServiceRecord service : mServices.values()) { 3552 if (service.packageName.equals(name) 3553 && (service.app == null || evenPersistent || !service.app.persistent)) { 3554 if (!doit) { 3555 return true; 3556 } 3557 didSomething = true; 3558 Slog.i(TAG, " Force stopping service " + service); 3559 if (service.app != null) { 3560 service.app.removed = true; 3561 } 3562 service.app = null; 3563 services.add(service); 3564 } 3565 } 3566 3567 N = services.size(); 3568 for (i=0; i<N; i++) { 3569 bringDownServiceLocked(services.get(i), true); 3570 } 3571 3572 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3573 for (ContentProviderRecord provider : mProvidersByClass.values()) { 3574 if (provider.info.packageName.equals(name) 3575 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3576 if (!doit) { 3577 return true; 3578 } 3579 didSomething = true; 3580 providers.add(provider); 3581 } 3582 } 3583 3584 N = providers.size(); 3585 for (i=0; i<N; i++) { 3586 removeDyingProviderLocked(null, providers.get(i)); 3587 } 3588 3589 if (doit) { 3590 if (purgeCache) { 3591 AttributeCache ac = AttributeCache.instance(); 3592 if (ac != null) { 3593 ac.removePackage(name); 3594 } 3595 } 3596 if (mBooted) { 3597 mMainStack.resumeTopActivityLocked(null); 3598 mMainStack.scheduleIdleLocked(); 3599 } 3600 } 3601 3602 return didSomething; 3603 } 3604 3605 private final boolean removeProcessLocked(ProcessRecord app, 3606 boolean callerWillRestart, boolean allowRestart, String reason) { 3607 final String name = app.processName; 3608 final int uid = app.info.uid; 3609 if (DEBUG_PROCESSES) Slog.d( 3610 TAG, "Force removing proc " + app.toShortString() + " (" + name 3611 + "/" + uid + ")"); 3612 3613 mProcessNames.remove(name, uid); 3614 if (mHeavyWeightProcess == app) { 3615 mHeavyWeightProcess = null; 3616 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3617 } 3618 boolean needRestart = false; 3619 if (app.pid > 0 && app.pid != MY_PID) { 3620 int pid = app.pid; 3621 synchronized (mPidsSelfLocked) { 3622 mPidsSelfLocked.remove(pid); 3623 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3624 } 3625 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3626 handleAppDiedLocked(app, true, allowRestart); 3627 mLruProcesses.remove(app); 3628 Process.killProcessQuiet(pid); 3629 3630 if (app.persistent) { 3631 if (!callerWillRestart) { 3632 addAppLocked(app.info); 3633 } else { 3634 needRestart = true; 3635 } 3636 } 3637 } else { 3638 mRemovedProcesses.add(app); 3639 } 3640 3641 return needRestart; 3642 } 3643 3644 private final void processStartTimedOutLocked(ProcessRecord app) { 3645 final int pid = app.pid; 3646 boolean gone = false; 3647 synchronized (mPidsSelfLocked) { 3648 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3649 if (knownApp != null && knownApp.thread == null) { 3650 mPidsSelfLocked.remove(pid); 3651 gone = true; 3652 } 3653 } 3654 3655 if (gone) { 3656 Slog.w(TAG, "Process " + app + " failed to attach"); 3657 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 3658 app.processName); 3659 mProcessNames.remove(app.processName, app.info.uid); 3660 if (mHeavyWeightProcess == app) { 3661 mHeavyWeightProcess = null; 3662 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3663 } 3664 // Take care of any launching providers waiting for this process. 3665 checkAppInLaunchingProvidersLocked(app, true); 3666 // Take care of any services that are waiting for the process. 3667 for (int i=0; i<mPendingServices.size(); i++) { 3668 ServiceRecord sr = mPendingServices.get(i); 3669 if (app.info.uid == sr.appInfo.uid 3670 && app.processName.equals(sr.processName)) { 3671 Slog.w(TAG, "Forcing bringing down service: " + sr); 3672 mPendingServices.remove(i); 3673 i--; 3674 bringDownServiceLocked(sr, true); 3675 } 3676 } 3677 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3678 app.processName, app.setAdj, "start timeout"); 3679 Process.killProcessQuiet(pid); 3680 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3681 Slog.w(TAG, "Unattached app died before backup, skipping"); 3682 try { 3683 IBackupManager bm = IBackupManager.Stub.asInterface( 3684 ServiceManager.getService(Context.BACKUP_SERVICE)); 3685 bm.agentDisconnected(app.info.packageName); 3686 } catch (RemoteException e) { 3687 // Can't happen; the backup manager is local 3688 } 3689 } 3690 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 3691 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3692 mPendingBroadcast.state = BroadcastRecord.IDLE; 3693 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 3694 mPendingBroadcast = null; 3695 scheduleBroadcastsLocked(); 3696 } 3697 } else { 3698 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3699 } 3700 } 3701 3702 private final boolean attachApplicationLocked(IApplicationThread thread, 3703 int pid) { 3704 3705 // Find the application record that is being attached... either via 3706 // the pid if we are running in multiple processes, or just pull the 3707 // next app record if we are emulating process with anonymous threads. 3708 ProcessRecord app; 3709 if (pid != MY_PID && pid >= 0) { 3710 synchronized (mPidsSelfLocked) { 3711 app = mPidsSelfLocked.get(pid); 3712 } 3713 } else { 3714 app = null; 3715 } 3716 3717 if (app == null) { 3718 Slog.w(TAG, "No pending application record for pid " + pid 3719 + " (IApplicationThread " + thread + "); dropping process"); 3720 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3721 if (pid > 0 && pid != MY_PID) { 3722 Process.killProcessQuiet(pid); 3723 } else { 3724 try { 3725 thread.scheduleExit(); 3726 } catch (Exception e) { 3727 // Ignore exceptions. 3728 } 3729 } 3730 return false; 3731 } 3732 3733 // If this application record is still attached to a previous 3734 // process, clean it up now. 3735 if (app.thread != null) { 3736 handleAppDiedLocked(app, true, true); 3737 } 3738 3739 // Tell the process all about itself. 3740 3741 if (localLOGV) Slog.v( 3742 TAG, "Binding process pid " + pid + " to record " + app); 3743 3744 String processName = app.processName; 3745 try { 3746 AppDeathRecipient adr = new AppDeathRecipient( 3747 app, pid, thread); 3748 thread.asBinder().linkToDeath(adr, 0); 3749 app.deathRecipient = adr; 3750 } catch (RemoteException e) { 3751 app.resetPackageList(); 3752 startProcessLocked(app, "link fail", processName); 3753 return false; 3754 } 3755 3756 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3757 3758 app.thread = thread; 3759 app.curAdj = app.setAdj = -100; 3760 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3761 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3762 app.forcingToForeground = null; 3763 app.foregroundServices = false; 3764 app.hasShownUi = false; 3765 app.debugging = false; 3766 3767 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3768 3769 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3770 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3771 3772 if (!normalMode) { 3773 Slog.i(TAG, "Launching preboot mode app: " + app); 3774 } 3775 3776 if (localLOGV) Slog.v( 3777 TAG, "New app record " + app 3778 + " thread=" + thread.asBinder() + " pid=" + pid); 3779 try { 3780 int testMode = IApplicationThread.DEBUG_OFF; 3781 if (mDebugApp != null && mDebugApp.equals(processName)) { 3782 testMode = mWaitForDebugger 3783 ? IApplicationThread.DEBUG_WAIT 3784 : IApplicationThread.DEBUG_ON; 3785 app.debugging = true; 3786 if (mDebugTransient) { 3787 mDebugApp = mOrigDebugApp; 3788 mWaitForDebugger = mOrigWaitForDebugger; 3789 } 3790 } 3791 String profileFile = app.instrumentationProfileFile; 3792 ParcelFileDescriptor profileFd = null; 3793 boolean profileAutoStop = false; 3794 if (mProfileApp != null && mProfileApp.equals(processName)) { 3795 mProfileProc = app; 3796 profileFile = mProfileFile; 3797 profileFd = mProfileFd; 3798 profileAutoStop = mAutoStopProfiler; 3799 } 3800 3801 // If the app is being launched for restore or full backup, set it up specially 3802 boolean isRestrictedBackupMode = false; 3803 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3804 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3805 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3806 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3807 } 3808 3809 ensurePackageDexOpt(app.instrumentationInfo != null 3810 ? app.instrumentationInfo.packageName 3811 : app.info.packageName); 3812 if (app.instrumentationClass != null) { 3813 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3814 } 3815 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3816 + processName + " with config " + mConfiguration); 3817 ApplicationInfo appInfo = app.instrumentationInfo != null 3818 ? app.instrumentationInfo : app.info; 3819 app.compat = compatibilityInfoForPackageLocked(appInfo); 3820 if (profileFd != null) { 3821 profileFd = profileFd.dup(); 3822 } 3823 thread.bindApplication(processName, appInfo, providers, 3824 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 3825 app.instrumentationArguments, app.instrumentationWatcher, testMode, 3826 isRestrictedBackupMode || !normalMode, app.persistent, 3827 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 3828 mCoreSettingsObserver.getCoreSettingsLocked()); 3829 updateLruProcessLocked(app, false, true); 3830 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 3831 } catch (Exception e) { 3832 // todo: Yikes! What should we do? For now we will try to 3833 // start another process, but that could easily get us in 3834 // an infinite loop of restarting processes... 3835 Slog.w(TAG, "Exception thrown during bind!", e); 3836 3837 app.resetPackageList(); 3838 app.unlinkDeathRecipient(); 3839 startProcessLocked(app, "bind fail", processName); 3840 return false; 3841 } 3842 3843 // Remove this record from the list of starting applications. 3844 mPersistentStartingProcesses.remove(app); 3845 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3846 "Attach application locked removing on hold: " + app); 3847 mProcessesOnHold.remove(app); 3848 3849 boolean badApp = false; 3850 boolean didSomething = false; 3851 3852 // See if the top visible activity is waiting to run in this process... 3853 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 3854 if (hr != null && normalMode) { 3855 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 3856 && processName.equals(hr.processName)) { 3857 try { 3858 if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 3859 didSomething = true; 3860 } 3861 } catch (Exception e) { 3862 Slog.w(TAG, "Exception in new application when starting activity " 3863 + hr.intent.getComponent().flattenToShortString(), e); 3864 badApp = true; 3865 } 3866 } else { 3867 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 3868 } 3869 } 3870 3871 // Find any services that should be running in this process... 3872 if (!badApp && mPendingServices.size() > 0) { 3873 ServiceRecord sr = null; 3874 try { 3875 for (int i=0; i<mPendingServices.size(); i++) { 3876 sr = mPendingServices.get(i); 3877 if (app.info.uid != sr.appInfo.uid 3878 || !processName.equals(sr.processName)) { 3879 continue; 3880 } 3881 3882 mPendingServices.remove(i); 3883 i--; 3884 realStartServiceLocked(sr, app); 3885 didSomething = true; 3886 } 3887 } catch (Exception e) { 3888 Slog.w(TAG, "Exception in new application when starting service " 3889 + sr.shortName, e); 3890 badApp = true; 3891 } 3892 } 3893 3894 // Check if the next broadcast receiver is in this process... 3895 BroadcastRecord br = mPendingBroadcast; 3896 if (!badApp && br != null && br.curApp == app) { 3897 try { 3898 mPendingBroadcast = null; 3899 processCurBroadcastLocked(br, app); 3900 didSomething = true; 3901 } catch (Exception e) { 3902 Slog.w(TAG, "Exception in new application when starting receiver " 3903 + br.curComponent.flattenToShortString(), e); 3904 badApp = true; 3905 logBroadcastReceiverDiscardLocked(br); 3906 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 3907 br.resultExtras, br.resultAbort, true); 3908 scheduleBroadcastsLocked(); 3909 // We need to reset the state if we fails to start the receiver. 3910 br.state = BroadcastRecord.IDLE; 3911 } 3912 } 3913 3914 // Check whether the next backup agent is in this process... 3915 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 3916 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 3917 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 3918 try { 3919 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 3920 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 3921 mBackupTarget.backupMode); 3922 } catch (Exception e) { 3923 Slog.w(TAG, "Exception scheduling backup agent creation: "); 3924 e.printStackTrace(); 3925 } 3926 } 3927 3928 if (badApp) { 3929 // todo: Also need to kill application to deal with all 3930 // kinds of exceptions. 3931 handleAppDiedLocked(app, false, true); 3932 return false; 3933 } 3934 3935 if (!didSomething) { 3936 updateOomAdjLocked(); 3937 } 3938 3939 return true; 3940 } 3941 3942 public final void attachApplication(IApplicationThread thread) { 3943 synchronized (this) { 3944 int callingPid = Binder.getCallingPid(); 3945 final long origId = Binder.clearCallingIdentity(); 3946 attachApplicationLocked(thread, callingPid); 3947 Binder.restoreCallingIdentity(origId); 3948 } 3949 } 3950 3951 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 3952 final long origId = Binder.clearCallingIdentity(); 3953 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 3954 if (stopProfiling) { 3955 synchronized (this) { 3956 if (mProfileProc == r.app) { 3957 if (mProfileFd != null) { 3958 try { 3959 mProfileFd.close(); 3960 } catch (IOException e) { 3961 } 3962 clearProfilerLocked(); 3963 } 3964 } 3965 } 3966 } 3967 Binder.restoreCallingIdentity(origId); 3968 } 3969 3970 void enableScreenAfterBoot() { 3971 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 3972 SystemClock.uptimeMillis()); 3973 mWindowManager.enableScreenAfterBoot(); 3974 } 3975 3976 public void showBootMessage(final CharSequence msg, final boolean always) { 3977 mWindowManager.showBootMessage(msg, always); 3978 } 3979 3980 public void dismissKeyguardOnNextActivity() { 3981 synchronized (this) { 3982 mMainStack.dismissKeyguardOnNextActivityLocked(); 3983 } 3984 } 3985 3986 final void finishBooting() { 3987 IntentFilter pkgFilter = new IntentFilter(); 3988 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 3989 pkgFilter.addDataScheme("package"); 3990 mContext.registerReceiver(new BroadcastReceiver() { 3991 @Override 3992 public void onReceive(Context context, Intent intent) { 3993 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 3994 if (pkgs != null) { 3995 for (String pkg : pkgs) { 3996 synchronized (ActivityManagerService.this) { 3997 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) { 3998 setResultCode(Activity.RESULT_OK); 3999 return; 4000 } 4001 } 4002 } 4003 } 4004 } 4005 }, pkgFilter); 4006 4007 synchronized (this) { 4008 // Ensure that any processes we had put on hold are now started 4009 // up. 4010 final int NP = mProcessesOnHold.size(); 4011 if (NP > 0) { 4012 ArrayList<ProcessRecord> procs = 4013 new ArrayList<ProcessRecord>(mProcessesOnHold); 4014 for (int ip=0; ip<NP; ip++) { 4015 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4016 + procs.get(ip)); 4017 startProcessLocked(procs.get(ip), "on-hold", null); 4018 } 4019 } 4020 4021 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4022 // Start looking for apps that are abusing wake locks. 4023 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4024 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4025 // Tell anyone interested that we are done booting! 4026 SystemProperties.set("sys.boot_completed", "1"); 4027 broadcastIntentLocked(null, null, 4028 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4029 null, null, 0, null, null, 4030 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4031 false, false, MY_PID, Process.SYSTEM_UID); 4032 } 4033 } 4034 } 4035 4036 final void ensureBootCompleted() { 4037 boolean booting; 4038 boolean enableScreen; 4039 synchronized (this) { 4040 booting = mBooting; 4041 mBooting = false; 4042 enableScreen = !mBooted; 4043 mBooted = true; 4044 } 4045 4046 if (booting) { 4047 finishBooting(); 4048 } 4049 4050 if (enableScreen) { 4051 enableScreenAfterBoot(); 4052 } 4053 } 4054 4055 public final void activityPaused(IBinder token) { 4056 final long origId = Binder.clearCallingIdentity(); 4057 mMainStack.activityPaused(token, false); 4058 Binder.restoreCallingIdentity(origId); 4059 } 4060 4061 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4062 CharSequence description) { 4063 if (localLOGV) Slog.v( 4064 TAG, "Activity stopped: token=" + token); 4065 4066 // Refuse possible leaked file descriptors 4067 if (icicle != null && icicle.hasFileDescriptors()) { 4068 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4069 } 4070 4071 ActivityRecord r = null; 4072 4073 final long origId = Binder.clearCallingIdentity(); 4074 4075 synchronized (this) { 4076 r = mMainStack.isInStackLocked(token); 4077 if (r != null) { 4078 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4079 } 4080 } 4081 4082 if (r != null) { 4083 sendPendingThumbnail(r, null, null, null, false); 4084 } 4085 4086 trimApplications(); 4087 4088 Binder.restoreCallingIdentity(origId); 4089 } 4090 4091 public final void activityDestroyed(IBinder token) { 4092 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4093 mMainStack.activityDestroyed(token); 4094 } 4095 4096 public String getCallingPackage(IBinder token) { 4097 synchronized (this) { 4098 ActivityRecord r = getCallingRecordLocked(token); 4099 return r != null && r.app != null ? r.info.packageName : null; 4100 } 4101 } 4102 4103 public ComponentName getCallingActivity(IBinder token) { 4104 synchronized (this) { 4105 ActivityRecord r = getCallingRecordLocked(token); 4106 return r != null ? r.intent.getComponent() : null; 4107 } 4108 } 4109 4110 private ActivityRecord getCallingRecordLocked(IBinder token) { 4111 ActivityRecord r = mMainStack.isInStackLocked(token); 4112 if (r == null) { 4113 return null; 4114 } 4115 return r.resultTo; 4116 } 4117 4118 public ComponentName getActivityClassForToken(IBinder token) { 4119 synchronized(this) { 4120 ActivityRecord r = mMainStack.isInStackLocked(token); 4121 if (r == null) { 4122 return null; 4123 } 4124 return r.intent.getComponent(); 4125 } 4126 } 4127 4128 public String getPackageForToken(IBinder token) { 4129 synchronized(this) { 4130 ActivityRecord r = mMainStack.isInStackLocked(token); 4131 if (r == null) { 4132 return null; 4133 } 4134 return r.packageName; 4135 } 4136 } 4137 4138 public IIntentSender getIntentSender(int type, 4139 String packageName, IBinder token, String resultWho, 4140 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) { 4141 // Refuse possible leaked file descriptors 4142 if (intents != null) { 4143 if (intents.length < 1) { 4144 throw new IllegalArgumentException("Intents array length must be >= 1"); 4145 } 4146 for (int i=0; i<intents.length; i++) { 4147 Intent intent = intents[i]; 4148 if (intent != null) { 4149 if (intent.hasFileDescriptors()) { 4150 throw new IllegalArgumentException("File descriptors passed in Intent"); 4151 } 4152 if (type == INTENT_SENDER_BROADCAST && 4153 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4154 throw new IllegalArgumentException( 4155 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4156 } 4157 intents[i] = new Intent(intent); 4158 } 4159 } 4160 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4161 throw new IllegalArgumentException( 4162 "Intent array length does not match resolvedTypes length"); 4163 } 4164 } 4165 4166 synchronized(this) { 4167 int callingUid = Binder.getCallingUid(); 4168 try { 4169 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4170 int uid = AppGlobals.getPackageManager() 4171 .getPackageUid(packageName); 4172 if (uid != Binder.getCallingUid()) { 4173 String msg = "Permission Denial: getIntentSender() from pid=" 4174 + Binder.getCallingPid() 4175 + ", uid=" + Binder.getCallingUid() 4176 + ", (need uid=" + uid + ")" 4177 + " is not allowed to send as package " + packageName; 4178 Slog.w(TAG, msg); 4179 throw new SecurityException(msg); 4180 } 4181 } 4182 4183 return getIntentSenderLocked(type, packageName, callingUid, 4184 token, resultWho, requestCode, intents, resolvedTypes, flags); 4185 4186 } catch (RemoteException e) { 4187 throw new SecurityException(e); 4188 } 4189 } 4190 } 4191 4192 IIntentSender getIntentSenderLocked(int type, 4193 String packageName, int callingUid, IBinder token, String resultWho, 4194 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) { 4195 ActivityRecord activity = null; 4196 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 4197 activity = mMainStack.isInStackLocked(token); 4198 if (activity == null) { 4199 return null; 4200 } 4201 if (activity.finishing) { 4202 return null; 4203 } 4204 } 4205 4206 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4207 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4208 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4209 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4210 |PendingIntent.FLAG_UPDATE_CURRENT); 4211 4212 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4213 type, packageName, activity, resultWho, 4214 requestCode, intents, resolvedTypes, flags); 4215 WeakReference<PendingIntentRecord> ref; 4216 ref = mIntentSenderRecords.get(key); 4217 PendingIntentRecord rec = ref != null ? ref.get() : null; 4218 if (rec != null) { 4219 if (!cancelCurrent) { 4220 if (updateCurrent) { 4221 if (rec.key.requestIntent != null) { 4222 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null); 4223 } 4224 if (intents != null) { 4225 intents[intents.length-1] = rec.key.requestIntent; 4226 rec.key.allIntents = intents; 4227 rec.key.allResolvedTypes = resolvedTypes; 4228 } else { 4229 rec.key.allIntents = null; 4230 rec.key.allResolvedTypes = null; 4231 } 4232 } 4233 return rec; 4234 } 4235 rec.canceled = true; 4236 mIntentSenderRecords.remove(key); 4237 } 4238 if (noCreate) { 4239 return rec; 4240 } 4241 rec = new PendingIntentRecord(this, key, callingUid); 4242 mIntentSenderRecords.put(key, rec.ref); 4243 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 4244 if (activity.pendingResults == null) { 4245 activity.pendingResults 4246 = new HashSet<WeakReference<PendingIntentRecord>>(); 4247 } 4248 activity.pendingResults.add(rec.ref); 4249 } 4250 return rec; 4251 } 4252 4253 public void cancelIntentSender(IIntentSender sender) { 4254 if (!(sender instanceof PendingIntentRecord)) { 4255 return; 4256 } 4257 synchronized(this) { 4258 PendingIntentRecord rec = (PendingIntentRecord)sender; 4259 try { 4260 int uid = AppGlobals.getPackageManager() 4261 .getPackageUid(rec.key.packageName); 4262 if (uid != Binder.getCallingUid()) { 4263 String msg = "Permission Denial: cancelIntentSender() from pid=" 4264 + Binder.getCallingPid() 4265 + ", uid=" + Binder.getCallingUid() 4266 + " is not allowed to cancel packges " 4267 + rec.key.packageName; 4268 Slog.w(TAG, msg); 4269 throw new SecurityException(msg); 4270 } 4271 } catch (RemoteException e) { 4272 throw new SecurityException(e); 4273 } 4274 cancelIntentSenderLocked(rec, true); 4275 } 4276 } 4277 4278 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4279 rec.canceled = true; 4280 mIntentSenderRecords.remove(rec.key); 4281 if (cleanActivity && rec.key.activity != null) { 4282 rec.key.activity.pendingResults.remove(rec.ref); 4283 } 4284 } 4285 4286 public String getPackageForIntentSender(IIntentSender pendingResult) { 4287 if (!(pendingResult instanceof PendingIntentRecord)) { 4288 return null; 4289 } 4290 try { 4291 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4292 return res.key.packageName; 4293 } catch (ClassCastException e) { 4294 } 4295 return null; 4296 } 4297 4298 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4299 if (!(pendingResult instanceof PendingIntentRecord)) { 4300 return false; 4301 } 4302 try { 4303 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4304 if (res.key.allIntents == null) { 4305 return false; 4306 } 4307 for (int i=0; i<res.key.allIntents.length; i++) { 4308 Intent intent = res.key.allIntents[i]; 4309 if (intent.getPackage() != null && intent.getComponent() != null) { 4310 return false; 4311 } 4312 } 4313 return true; 4314 } catch (ClassCastException e) { 4315 } 4316 return false; 4317 } 4318 4319 public void setProcessLimit(int max) { 4320 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4321 "setProcessLimit()"); 4322 synchronized (this) { 4323 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4324 mProcessLimitOverride = max; 4325 } 4326 trimApplications(); 4327 } 4328 4329 public int getProcessLimit() { 4330 synchronized (this) { 4331 return mProcessLimitOverride; 4332 } 4333 } 4334 4335 void foregroundTokenDied(ForegroundToken token) { 4336 synchronized (ActivityManagerService.this) { 4337 synchronized (mPidsSelfLocked) { 4338 ForegroundToken cur 4339 = mForegroundProcesses.get(token.pid); 4340 if (cur != token) { 4341 return; 4342 } 4343 mForegroundProcesses.remove(token.pid); 4344 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4345 if (pr == null) { 4346 return; 4347 } 4348 pr.forcingToForeground = null; 4349 pr.foregroundServices = false; 4350 } 4351 updateOomAdjLocked(); 4352 } 4353 } 4354 4355 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4356 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4357 "setProcessForeground()"); 4358 synchronized(this) { 4359 boolean changed = false; 4360 4361 synchronized (mPidsSelfLocked) { 4362 ProcessRecord pr = mPidsSelfLocked.get(pid); 4363 if (pr == null) { 4364 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4365 return; 4366 } 4367 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4368 if (oldToken != null) { 4369 oldToken.token.unlinkToDeath(oldToken, 0); 4370 mForegroundProcesses.remove(pid); 4371 pr.forcingToForeground = null; 4372 changed = true; 4373 } 4374 if (isForeground && token != null) { 4375 ForegroundToken newToken = new ForegroundToken() { 4376 public void binderDied() { 4377 foregroundTokenDied(this); 4378 } 4379 }; 4380 newToken.pid = pid; 4381 newToken.token = token; 4382 try { 4383 token.linkToDeath(newToken, 0); 4384 mForegroundProcesses.put(pid, newToken); 4385 pr.forcingToForeground = token; 4386 changed = true; 4387 } catch (RemoteException e) { 4388 // If the process died while doing this, we will later 4389 // do the cleanup with the process death link. 4390 } 4391 } 4392 } 4393 4394 if (changed) { 4395 updateOomAdjLocked(); 4396 } 4397 } 4398 } 4399 4400 // ========================================================= 4401 // PERMISSIONS 4402 // ========================================================= 4403 4404 static class PermissionController extends IPermissionController.Stub { 4405 ActivityManagerService mActivityManagerService; 4406 PermissionController(ActivityManagerService activityManagerService) { 4407 mActivityManagerService = activityManagerService; 4408 } 4409 4410 public boolean checkPermission(String permission, int pid, int uid) { 4411 return mActivityManagerService.checkPermission(permission, pid, 4412 uid) == PackageManager.PERMISSION_GRANTED; 4413 } 4414 } 4415 4416 /** 4417 * This can be called with or without the global lock held. 4418 */ 4419 int checkComponentPermission(String permission, int pid, int uid, 4420 int owningUid, boolean exported) { 4421 // We might be performing an operation on behalf of an indirect binder 4422 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4423 // client identity accordingly before proceeding. 4424 Identity tlsIdentity = sCallerIdentity.get(); 4425 if (tlsIdentity != null) { 4426 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4427 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4428 uid = tlsIdentity.uid; 4429 pid = tlsIdentity.pid; 4430 } 4431 4432 // Root, system server and our own process get to do everything. 4433 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) { 4434 return PackageManager.PERMISSION_GRANTED; 4435 } 4436 // If there is a uid that owns whatever is being accessed, it has 4437 // blanket access to it regardless of the permissions it requires. 4438 if (owningUid >= 0 && uid == owningUid) { 4439 return PackageManager.PERMISSION_GRANTED; 4440 } 4441 // If the target is not exported, then nobody else can get to it. 4442 if (!exported) { 4443 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid); 4444 return PackageManager.PERMISSION_DENIED; 4445 } 4446 if (permission == null) { 4447 return PackageManager.PERMISSION_GRANTED; 4448 } 4449 try { 4450 return AppGlobals.getPackageManager() 4451 .checkUidPermission(permission, uid); 4452 } catch (RemoteException e) { 4453 // Should never happen, but if it does... deny! 4454 Slog.e(TAG, "PackageManager is dead?!?", e); 4455 } 4456 return PackageManager.PERMISSION_DENIED; 4457 } 4458 4459 /** 4460 * As the only public entry point for permissions checking, this method 4461 * can enforce the semantic that requesting a check on a null global 4462 * permission is automatically denied. (Internally a null permission 4463 * string is used when calling {@link #checkComponentPermission} in cases 4464 * when only uid-based security is needed.) 4465 * 4466 * This can be called with or without the global lock held. 4467 */ 4468 public int checkPermission(String permission, int pid, int uid) { 4469 if (permission == null) { 4470 return PackageManager.PERMISSION_DENIED; 4471 } 4472 return checkComponentPermission(permission, pid, uid, -1, true); 4473 } 4474 4475 /** 4476 * Binder IPC calls go through the public entry point. 4477 * This can be called with or without the global lock held. 4478 */ 4479 int checkCallingPermission(String permission) { 4480 return checkPermission(permission, 4481 Binder.getCallingPid(), 4482 Binder.getCallingUid()); 4483 } 4484 4485 /** 4486 * This can be called with or without the global lock held. 4487 */ 4488 void enforceCallingPermission(String permission, String func) { 4489 if (checkCallingPermission(permission) 4490 == PackageManager.PERMISSION_GRANTED) { 4491 return; 4492 } 4493 4494 String msg = "Permission Denial: " + func + " from pid=" 4495 + Binder.getCallingPid() 4496 + ", uid=" + Binder.getCallingUid() 4497 + " requires " + permission; 4498 Slog.w(TAG, msg); 4499 throw new SecurityException(msg); 4500 } 4501 4502 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 4503 ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4504 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4505 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4506 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4507 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4508 try { 4509 // Is the component private from the target uid? 4510 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid; 4511 4512 // Acceptable if the there is no read permission needed from the 4513 // target or the target is holding the read permission. 4514 if (!readPerm) { 4515 if ((!prv && pi.readPermission == null) || 4516 (pm.checkUidPermission(pi.readPermission, uid) 4517 == PackageManager.PERMISSION_GRANTED)) { 4518 readPerm = true; 4519 } 4520 } 4521 4522 // Acceptable if the there is no write permission needed from the 4523 // target or the target is holding the read permission. 4524 if (!writePerm) { 4525 if (!prv && (pi.writePermission == null) || 4526 (pm.checkUidPermission(pi.writePermission, uid) 4527 == PackageManager.PERMISSION_GRANTED)) { 4528 writePerm = true; 4529 } 4530 } 4531 4532 // Acceptable if there is a path permission matching the URI that 4533 // the target holds the permission on. 4534 PathPermission[] pps = pi.pathPermissions; 4535 if (pps != null && (!readPerm || !writePerm)) { 4536 final String path = uri.getPath(); 4537 int i = pps.length; 4538 while (i > 0 && (!readPerm || !writePerm)) { 4539 i--; 4540 PathPermission pp = pps[i]; 4541 if (!readPerm) { 4542 final String pprperm = pp.getReadPermission(); 4543 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4544 + pprperm + " for " + pp.getPath() 4545 + ": match=" + pp.match(path) 4546 + " check=" + pm.checkUidPermission(pprperm, uid)); 4547 if (pprperm != null && pp.match(path) && 4548 (pm.checkUidPermission(pprperm, uid) 4549 == PackageManager.PERMISSION_GRANTED)) { 4550 readPerm = true; 4551 } 4552 } 4553 if (!writePerm) { 4554 final String ppwperm = pp.getWritePermission(); 4555 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4556 + ppwperm + " for " + pp.getPath() 4557 + ": match=" + pp.match(path) 4558 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4559 if (ppwperm != null && pp.match(path) && 4560 (pm.checkUidPermission(ppwperm, uid) 4561 == PackageManager.PERMISSION_GRANTED)) { 4562 writePerm = true; 4563 } 4564 } 4565 } 4566 } 4567 } catch (RemoteException e) { 4568 return false; 4569 } 4570 4571 return readPerm && writePerm; 4572 } 4573 4574 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4575 int modeFlags) { 4576 // Root gets to do everything. 4577 if (uid == 0) { 4578 return true; 4579 } 4580 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4581 if (perms == null) return false; 4582 UriPermission perm = perms.get(uri); 4583 if (perm == null) return false; 4584 return (modeFlags&perm.modeFlags) == modeFlags; 4585 } 4586 4587 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4588 // Another redirected-binder-call permissions check as in 4589 // {@link checkComponentPermission}. 4590 Identity tlsIdentity = sCallerIdentity.get(); 4591 if (tlsIdentity != null) { 4592 uid = tlsIdentity.uid; 4593 pid = tlsIdentity.pid; 4594 } 4595 4596 // Our own process gets to do everything. 4597 if (pid == MY_PID) { 4598 return PackageManager.PERMISSION_GRANTED; 4599 } 4600 synchronized(this) { 4601 return checkUriPermissionLocked(uri, uid, modeFlags) 4602 ? PackageManager.PERMISSION_GRANTED 4603 : PackageManager.PERMISSION_DENIED; 4604 } 4605 } 4606 4607 /** 4608 * Check if the targetPkg can be granted permission to access uri by 4609 * the callingUid using the given modeFlags. Throws a security exception 4610 * if callingUid is not allowed to do this. Returns the uid of the target 4611 * if the URI permission grant should be performed; returns -1 if it is not 4612 * needed (for example targetPkg already has permission to access the URI). 4613 */ 4614 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4615 Uri uri, int modeFlags) { 4616 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4617 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4618 if (modeFlags == 0) { 4619 return -1; 4620 } 4621 4622 if (targetPkg != null) { 4623 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4624 "Checking grant " + targetPkg + " permission to " + uri); 4625 } 4626 4627 final IPackageManager pm = AppGlobals.getPackageManager(); 4628 4629 // If this is not a content: uri, we can't do anything with it. 4630 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4631 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4632 "Can't grant URI permission for non-content URI: " + uri); 4633 return -1; 4634 } 4635 4636 String name = uri.getAuthority(); 4637 ProviderInfo pi = null; 4638 ContentProviderRecord cpr = mProvidersByName.get(name); 4639 if (cpr != null) { 4640 pi = cpr.info; 4641 } else { 4642 try { 4643 pi = pm.resolveContentProvider(name, 4644 PackageManager.GET_URI_PERMISSION_PATTERNS); 4645 } catch (RemoteException ex) { 4646 } 4647 } 4648 if (pi == null) { 4649 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4650 return -1; 4651 } 4652 4653 int targetUid; 4654 if (targetPkg != null) { 4655 try { 4656 targetUid = pm.getPackageUid(targetPkg); 4657 if (targetUid < 0) { 4658 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4659 "Can't grant URI permission no uid for: " + targetPkg); 4660 return -1; 4661 } 4662 } catch (RemoteException ex) { 4663 return -1; 4664 } 4665 } else { 4666 targetUid = -1; 4667 } 4668 4669 if (targetUid >= 0) { 4670 // First... does the target actually need this permission? 4671 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4672 // No need to grant the target this permission. 4673 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4674 "Target " + targetPkg + " already has full permission to " + uri); 4675 return -1; 4676 } 4677 } else { 4678 // First... there is no target package, so can anyone access it? 4679 boolean allowed = pi.exported; 4680 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4681 if (pi.readPermission != null) { 4682 allowed = false; 4683 } 4684 } 4685 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4686 if (pi.writePermission != null) { 4687 allowed = false; 4688 } 4689 } 4690 if (allowed) { 4691 return -1; 4692 } 4693 } 4694 4695 // Second... is the provider allowing granting of URI permissions? 4696 if (!pi.grantUriPermissions) { 4697 throw new SecurityException("Provider " + pi.packageName 4698 + "/" + pi.name 4699 + " does not allow granting of Uri permissions (uri " 4700 + uri + ")"); 4701 } 4702 if (pi.uriPermissionPatterns != null) { 4703 final int N = pi.uriPermissionPatterns.length; 4704 boolean allowed = false; 4705 for (int i=0; i<N; i++) { 4706 if (pi.uriPermissionPatterns[i] != null 4707 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4708 allowed = true; 4709 break; 4710 } 4711 } 4712 if (!allowed) { 4713 throw new SecurityException("Provider " + pi.packageName 4714 + "/" + pi.name 4715 + " does not allow granting of permission to path of Uri " 4716 + uri); 4717 } 4718 } 4719 4720 // Third... does the caller itself have permission to access 4721 // this uri? 4722 if (callingUid != Process.myUid()) { 4723 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4724 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4725 throw new SecurityException("Uid " + callingUid 4726 + " does not have permission to uri " + uri); 4727 } 4728 } 4729 } 4730 4731 return targetUid; 4732 } 4733 4734 public int checkGrantUriPermission(int callingUid, String targetPkg, 4735 Uri uri, int modeFlags) { 4736 synchronized(this) { 4737 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); 4738 } 4739 } 4740 4741 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4742 Uri uri, int modeFlags, UriPermissionOwner owner) { 4743 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4744 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4745 if (modeFlags == 0) { 4746 return; 4747 } 4748 4749 // So here we are: the caller has the assumed permission 4750 // to the uri, and the target doesn't. Let's now give this to 4751 // the target. 4752 4753 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4754 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4755 4756 HashMap<Uri, UriPermission> targetUris 4757 = mGrantedUriPermissions.get(targetUid); 4758 if (targetUris == null) { 4759 targetUris = new HashMap<Uri, UriPermission>(); 4760 mGrantedUriPermissions.put(targetUid, targetUris); 4761 } 4762 4763 UriPermission perm = targetUris.get(uri); 4764 if (perm == null) { 4765 perm = new UriPermission(targetUid, uri); 4766 targetUris.put(uri, perm); 4767 } 4768 4769 perm.modeFlags |= modeFlags; 4770 if (owner == null) { 4771 perm.globalModeFlags |= modeFlags; 4772 } else { 4773 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4774 perm.readOwners.add(owner); 4775 owner.addReadPermission(perm); 4776 } 4777 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4778 perm.writeOwners.add(owner); 4779 owner.addWritePermission(perm); 4780 } 4781 } 4782 } 4783 4784 void grantUriPermissionLocked(int callingUid, 4785 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 4786 if (targetPkg == null) { 4787 throw new NullPointerException("targetPkg"); 4788 } 4789 4790 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); 4791 if (targetUid < 0) { 4792 return; 4793 } 4794 4795 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 4796 } 4797 4798 /** 4799 * Like checkGrantUriPermissionLocked, but takes an Intent. 4800 */ 4801 int checkGrantUriPermissionFromIntentLocked(int callingUid, 4802 String targetPkg, Intent intent) { 4803 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4804 "Checking URI perm to " + (intent != null ? intent.getData() : null) 4805 + " from " + intent + "; flags=0x" 4806 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 4807 4808 if (targetPkg == null) { 4809 throw new NullPointerException("targetPkg"); 4810 } 4811 4812 if (intent == null) { 4813 return -1; 4814 } 4815 Uri data = intent.getData(); 4816 if (data == null) { 4817 return -1; 4818 } 4819 return checkGrantUriPermissionLocked(callingUid, targetPkg, data, 4820 intent.getFlags()); 4821 } 4822 4823 /** 4824 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 4825 */ 4826 void grantUriPermissionUncheckedFromIntentLocked(int targetUid, 4827 String targetPkg, Intent intent, UriPermissionOwner owner) { 4828 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(), 4829 intent.getFlags(), owner); 4830 } 4831 4832 void grantUriPermissionFromIntentLocked(int callingUid, 4833 String targetPkg, Intent intent, UriPermissionOwner owner) { 4834 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent); 4835 if (targetUid < 0) { 4836 return; 4837 } 4838 4839 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner); 4840 } 4841 4842 public void grantUriPermission(IApplicationThread caller, String targetPkg, 4843 Uri uri, int modeFlags) { 4844 synchronized(this) { 4845 final ProcessRecord r = getRecordForAppLocked(caller); 4846 if (r == null) { 4847 throw new SecurityException("Unable to find app for caller " 4848 + caller 4849 + " when granting permission to uri " + uri); 4850 } 4851 if (targetPkg == null) { 4852 throw new IllegalArgumentException("null target"); 4853 } 4854 if (uri == null) { 4855 throw new IllegalArgumentException("null uri"); 4856 } 4857 4858 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 4859 null); 4860 } 4861 } 4862 4863 void removeUriPermissionIfNeededLocked(UriPermission perm) { 4864 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 4865 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 4866 HashMap<Uri, UriPermission> perms 4867 = mGrantedUriPermissions.get(perm.uid); 4868 if (perms != null) { 4869 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4870 "Removing " + perm.uid + " permission to " + perm.uri); 4871 perms.remove(perm.uri); 4872 if (perms.size() == 0) { 4873 mGrantedUriPermissions.remove(perm.uid); 4874 } 4875 } 4876 } 4877 } 4878 4879 private void revokeUriPermissionLocked(int callingUid, Uri uri, 4880 int modeFlags) { 4881 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4882 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4883 if (modeFlags == 0) { 4884 return; 4885 } 4886 4887 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4888 "Revoking all granted permissions to " + uri); 4889 4890 final IPackageManager pm = AppGlobals.getPackageManager(); 4891 4892 final String authority = uri.getAuthority(); 4893 ProviderInfo pi = null; 4894 ContentProviderRecord cpr = mProvidersByName.get(authority); 4895 if (cpr != null) { 4896 pi = cpr.info; 4897 } else { 4898 try { 4899 pi = pm.resolveContentProvider(authority, 4900 PackageManager.GET_URI_PERMISSION_PATTERNS); 4901 } catch (RemoteException ex) { 4902 } 4903 } 4904 if (pi == null) { 4905 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 4906 return; 4907 } 4908 4909 // Does the caller have this permission on the URI? 4910 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4911 // Right now, if you are not the original owner of the permission, 4912 // you are not allowed to revoke it. 4913 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4914 throw new SecurityException("Uid " + callingUid 4915 + " does not have permission to uri " + uri); 4916 //} 4917 } 4918 4919 // Go through all of the permissions and remove any that match. 4920 final List<String> SEGMENTS = uri.getPathSegments(); 4921 if (SEGMENTS != null) { 4922 final int NS = SEGMENTS.size(); 4923 int N = mGrantedUriPermissions.size(); 4924 for (int i=0; i<N; i++) { 4925 HashMap<Uri, UriPermission> perms 4926 = mGrantedUriPermissions.valueAt(i); 4927 Iterator<UriPermission> it = perms.values().iterator(); 4928 toploop: 4929 while (it.hasNext()) { 4930 UriPermission perm = it.next(); 4931 Uri targetUri = perm.uri; 4932 if (!authority.equals(targetUri.getAuthority())) { 4933 continue; 4934 } 4935 List<String> targetSegments = targetUri.getPathSegments(); 4936 if (targetSegments == null) { 4937 continue; 4938 } 4939 if (targetSegments.size() < NS) { 4940 continue; 4941 } 4942 for (int j=0; j<NS; j++) { 4943 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 4944 continue toploop; 4945 } 4946 } 4947 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4948 "Revoking " + perm.uid + " permission to " + perm.uri); 4949 perm.clearModes(modeFlags); 4950 if (perm.modeFlags == 0) { 4951 it.remove(); 4952 } 4953 } 4954 if (perms.size() == 0) { 4955 mGrantedUriPermissions.remove( 4956 mGrantedUriPermissions.keyAt(i)); 4957 N--; 4958 i--; 4959 } 4960 } 4961 } 4962 } 4963 4964 public void revokeUriPermission(IApplicationThread caller, Uri uri, 4965 int modeFlags) { 4966 synchronized(this) { 4967 final ProcessRecord r = getRecordForAppLocked(caller); 4968 if (r == null) { 4969 throw new SecurityException("Unable to find app for caller " 4970 + caller 4971 + " when revoking permission to uri " + uri); 4972 } 4973 if (uri == null) { 4974 Slog.w(TAG, "revokeUriPermission: null uri"); 4975 return; 4976 } 4977 4978 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4979 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4980 if (modeFlags == 0) { 4981 return; 4982 } 4983 4984 final IPackageManager pm = AppGlobals.getPackageManager(); 4985 4986 final String authority = uri.getAuthority(); 4987 ProviderInfo pi = null; 4988 ContentProviderRecord cpr = mProvidersByName.get(authority); 4989 if (cpr != null) { 4990 pi = cpr.info; 4991 } else { 4992 try { 4993 pi = pm.resolveContentProvider(authority, 4994 PackageManager.GET_URI_PERMISSION_PATTERNS); 4995 } catch (RemoteException ex) { 4996 } 4997 } 4998 if (pi == null) { 4999 Slog.w(TAG, "No content provider found for permission revoke: " 5000 + uri.toSafeString()); 5001 return; 5002 } 5003 5004 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 5005 } 5006 } 5007 5008 @Override 5009 public IBinder newUriPermissionOwner(String name) { 5010 synchronized(this) { 5011 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5012 return owner.getExternalTokenLocked(); 5013 } 5014 } 5015 5016 @Override 5017 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5018 Uri uri, int modeFlags) { 5019 synchronized(this) { 5020 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5021 if (owner == null) { 5022 throw new IllegalArgumentException("Unknown owner: " + token); 5023 } 5024 if (fromUid != Binder.getCallingUid()) { 5025 if (Binder.getCallingUid() != Process.myUid()) { 5026 // Only system code can grant URI permissions on behalf 5027 // of other users. 5028 throw new SecurityException("nice try"); 5029 } 5030 } 5031 if (targetPkg == null) { 5032 throw new IllegalArgumentException("null target"); 5033 } 5034 if (uri == null) { 5035 throw new IllegalArgumentException("null uri"); 5036 } 5037 5038 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5039 } 5040 } 5041 5042 @Override 5043 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5044 synchronized(this) { 5045 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5046 if (owner == null) { 5047 throw new IllegalArgumentException("Unknown owner: " + token); 5048 } 5049 5050 if (uri == null) { 5051 owner.removeUriPermissionsLocked(mode); 5052 } else { 5053 owner.removeUriPermissionLocked(uri, mode); 5054 } 5055 } 5056 } 5057 5058 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5059 synchronized (this) { 5060 ProcessRecord app = 5061 who != null ? getRecordForAppLocked(who) : null; 5062 if (app == null) return; 5063 5064 Message msg = Message.obtain(); 5065 msg.what = WAIT_FOR_DEBUGGER_MSG; 5066 msg.obj = app; 5067 msg.arg1 = waiting ? 1 : 0; 5068 mHandler.sendMessage(msg); 5069 } 5070 } 5071 5072 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5073 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5074 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5075 outInfo.availMem = Process.getFreeMemory(); 5076 outInfo.threshold = homeAppMem; 5077 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5078 outInfo.hiddenAppThreshold = hiddenAppMem; 5079 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5080 ProcessList.SERVICE_ADJ); 5081 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5082 ProcessList.VISIBLE_APP_ADJ); 5083 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5084 ProcessList.FOREGROUND_APP_ADJ); 5085 } 5086 5087 // ========================================================= 5088 // TASK MANAGEMENT 5089 // ========================================================= 5090 5091 public List getTasks(int maxNum, int flags, 5092 IThumbnailReceiver receiver) { 5093 ArrayList list = new ArrayList(); 5094 5095 PendingThumbnailsRecord pending = null; 5096 IApplicationThread topThumbnail = null; 5097 ActivityRecord topRecord = null; 5098 5099 synchronized(this) { 5100 if (localLOGV) Slog.v( 5101 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5102 + ", receiver=" + receiver); 5103 5104 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5105 != PackageManager.PERMISSION_GRANTED) { 5106 if (receiver != null) { 5107 // If the caller wants to wait for pending thumbnails, 5108 // it ain't gonna get them. 5109 try { 5110 receiver.finished(); 5111 } catch (RemoteException ex) { 5112 } 5113 } 5114 String msg = "Permission Denial: getTasks() from pid=" 5115 + Binder.getCallingPid() 5116 + ", uid=" + Binder.getCallingUid() 5117 + " requires " + android.Manifest.permission.GET_TASKS; 5118 Slog.w(TAG, msg); 5119 throw new SecurityException(msg); 5120 } 5121 5122 int pos = mMainStack.mHistory.size()-1; 5123 ActivityRecord next = 5124 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5125 ActivityRecord top = null; 5126 TaskRecord curTask = null; 5127 int numActivities = 0; 5128 int numRunning = 0; 5129 while (pos >= 0 && maxNum > 0) { 5130 final ActivityRecord r = next; 5131 pos--; 5132 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5133 5134 // Initialize state for next task if needed. 5135 if (top == null || 5136 (top.state == ActivityState.INITIALIZING 5137 && top.task == r.task)) { 5138 top = r; 5139 curTask = r.task; 5140 numActivities = numRunning = 0; 5141 } 5142 5143 // Add 'r' into the current task. 5144 numActivities++; 5145 if (r.app != null && r.app.thread != null) { 5146 numRunning++; 5147 } 5148 5149 if (localLOGV) Slog.v( 5150 TAG, r.intent.getComponent().flattenToShortString() 5151 + ": task=" + r.task); 5152 5153 // If the next one is a different task, generate a new 5154 // TaskInfo entry for what we have. 5155 if (next == null || next.task != curTask) { 5156 ActivityManager.RunningTaskInfo ci 5157 = new ActivityManager.RunningTaskInfo(); 5158 ci.id = curTask.taskId; 5159 ci.baseActivity = r.intent.getComponent(); 5160 ci.topActivity = top.intent.getComponent(); 5161 if (top.thumbHolder != null) { 5162 ci.description = top.thumbHolder.lastDescription; 5163 } 5164 ci.numActivities = numActivities; 5165 ci.numRunning = numRunning; 5166 //System.out.println( 5167 // "#" + maxNum + ": " + " descr=" + ci.description); 5168 if (ci.thumbnail == null && receiver != null) { 5169 if (localLOGV) Slog.v( 5170 TAG, "State=" + top.state + "Idle=" + top.idle 5171 + " app=" + top.app 5172 + " thr=" + (top.app != null ? top.app.thread : null)); 5173 if (top.state == ActivityState.RESUMED 5174 || top.state == ActivityState.PAUSING) { 5175 if (top.idle && top.app != null 5176 && top.app.thread != null) { 5177 topRecord = top; 5178 topThumbnail = top.app.thread; 5179 } else { 5180 top.thumbnailNeeded = true; 5181 } 5182 } 5183 if (pending == null) { 5184 pending = new PendingThumbnailsRecord(receiver); 5185 } 5186 pending.pendingRecords.add(top); 5187 } 5188 list.add(ci); 5189 maxNum--; 5190 top = null; 5191 } 5192 } 5193 5194 if (pending != null) { 5195 mPendingThumbnails.add(pending); 5196 } 5197 } 5198 5199 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5200 5201 if (topThumbnail != null) { 5202 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5203 try { 5204 topThumbnail.requestThumbnail(topRecord.appToken); 5205 } catch (Exception e) { 5206 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5207 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5208 } 5209 } 5210 5211 if (pending == null && receiver != null) { 5212 // In this case all thumbnails were available and the client 5213 // is being asked to be told when the remaining ones come in... 5214 // which is unusually, since the top-most currently running 5215 // activity should never have a canned thumbnail! Oh well. 5216 try { 5217 receiver.finished(); 5218 } catch (RemoteException ex) { 5219 } 5220 } 5221 5222 return list; 5223 } 5224 5225 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5226 int flags) { 5227 synchronized (this) { 5228 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5229 "getRecentTasks()"); 5230 5231 IPackageManager pm = AppGlobals.getPackageManager(); 5232 5233 final int N = mRecentTasks.size(); 5234 ArrayList<ActivityManager.RecentTaskInfo> res 5235 = new ArrayList<ActivityManager.RecentTaskInfo>( 5236 maxNum < N ? maxNum : N); 5237 for (int i=0; i<N && maxNum > 0; i++) { 5238 TaskRecord tr = mRecentTasks.get(i); 5239 // Return the entry if desired by the caller. We always return 5240 // the first entry, because callers always expect this to be the 5241 // forground app. We may filter others if the caller has 5242 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5243 // we should exclude the entry. 5244 if (i == 0 5245 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5246 || (tr.intent == null) 5247 || ((tr.intent.getFlags() 5248 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5249 ActivityManager.RecentTaskInfo rti 5250 = new ActivityManager.RecentTaskInfo(); 5251 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5252 rti.persistentId = tr.taskId; 5253 rti.baseIntent = new Intent( 5254 tr.intent != null ? tr.intent : tr.affinityIntent); 5255 rti.origActivity = tr.origActivity; 5256 rti.description = tr.lastDescription; 5257 5258 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5259 // Check whether this activity is currently available. 5260 try { 5261 if (rti.origActivity != null) { 5262 if (pm.getActivityInfo(rti.origActivity, 0) == null) { 5263 continue; 5264 } 5265 } else if (rti.baseIntent != null) { 5266 if (pm.queryIntentActivities(rti.baseIntent, 5267 null, 0) == null) { 5268 continue; 5269 } 5270 } 5271 } catch (RemoteException e) { 5272 // Will never happen. 5273 } 5274 } 5275 5276 res.add(rti); 5277 maxNum--; 5278 } 5279 } 5280 return res; 5281 } 5282 } 5283 5284 private TaskRecord taskForIdLocked(int id) { 5285 final int N = mRecentTasks.size(); 5286 for (int i=0; i<N; i++) { 5287 TaskRecord tr = mRecentTasks.get(i); 5288 if (tr.taskId == id) { 5289 return tr; 5290 } 5291 } 5292 return null; 5293 } 5294 5295 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5296 synchronized (this) { 5297 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5298 "getTaskThumbnails()"); 5299 TaskRecord tr = taskForIdLocked(id); 5300 if (tr != null) { 5301 return mMainStack.getTaskThumbnailsLocked(tr); 5302 } 5303 } 5304 return null; 5305 } 5306 5307 public boolean removeSubTask(int taskId, int subTaskIndex) { 5308 synchronized (this) { 5309 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5310 "removeSubTask()"); 5311 long ident = Binder.clearCallingIdentity(); 5312 try { 5313 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null; 5314 } finally { 5315 Binder.restoreCallingIdentity(ident); 5316 } 5317 } 5318 } 5319 5320 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) { 5321 TaskRecord tr = root.task; 5322 Intent baseIntent = new Intent( 5323 tr.intent != null ? tr.intent : tr.affinityIntent); 5324 ComponentName component = baseIntent.getComponent(); 5325 if (component == null) { 5326 Slog.w(TAG, "Now component for base intent of task: " + tr); 5327 return; 5328 } 5329 5330 // Find any running services associated with this app. 5331 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5332 for (ServiceRecord sr : mServices.values()) { 5333 if (sr.packageName.equals(component.getPackageName())) { 5334 services.add(sr); 5335 } 5336 } 5337 5338 // Take care of any running services associated with the app. 5339 for (int i=0; i<services.size(); i++) { 5340 ServiceRecord sr = services.get(i); 5341 if (sr.startRequested) { 5342 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { 5343 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); 5344 stopServiceLocked(sr); 5345 } else { 5346 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, 5347 sr.makeNextStartId(), baseIntent, -1)); 5348 if (sr.app != null && sr.app.thread != null) { 5349 sendServiceArgsLocked(sr, false); 5350 } 5351 } 5352 } 5353 } 5354 5355 if (killProcesses) { 5356 // Find any running processes associated with this app. 5357 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5358 SparseArray<ProcessRecord> appProcs 5359 = mProcessNames.getMap().get(component.getPackageName()); 5360 if (appProcs != null) { 5361 for (int i=0; i<appProcs.size(); i++) { 5362 procs.add(appProcs.valueAt(i)); 5363 } 5364 } 5365 5366 // Kill the running processes. 5367 for (int i=0; i<procs.size(); i++) { 5368 ProcessRecord pr = procs.get(i); 5369 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5370 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5371 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5372 pr.processName, pr.setAdj, "remove task"); 5373 Process.killProcessQuiet(pr.pid); 5374 } else { 5375 pr.waitingToKill = "remove task"; 5376 } 5377 } 5378 } 5379 } 5380 5381 public boolean removeTask(int taskId, int flags) { 5382 synchronized (this) { 5383 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5384 "removeTask()"); 5385 long ident = Binder.clearCallingIdentity(); 5386 try { 5387 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1); 5388 if (r != null) { 5389 mRecentTasks.remove(r.task); 5390 cleanUpRemovedTaskLocked(r, 5391 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0); 5392 return true; 5393 } else { 5394 TaskRecord tr = null; 5395 int i=0; 5396 while (i < mRecentTasks.size()) { 5397 TaskRecord t = mRecentTasks.get(i); 5398 if (t.taskId == taskId) { 5399 tr = t; 5400 break; 5401 } 5402 i++; 5403 } 5404 if (tr != null) { 5405 if (tr.numActivities <= 0) { 5406 // Caller is just removing a recent task that is 5407 // not actively running. That is easy! 5408 mRecentTasks.remove(i); 5409 } else { 5410 Slog.w(TAG, "removeTask: task " + taskId 5411 + " does not have activities to remove, " 5412 + " but numActivities=" + tr.numActivities 5413 + ": " + tr); 5414 } 5415 } 5416 } 5417 } finally { 5418 Binder.restoreCallingIdentity(ident); 5419 } 5420 } 5421 return false; 5422 } 5423 5424 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5425 int j; 5426 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5427 TaskRecord jt = startTask; 5428 5429 // First look backwards 5430 for (j=startIndex-1; j>=0; j--) { 5431 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5432 if (r.task != jt) { 5433 jt = r.task; 5434 if (affinity.equals(jt.affinity)) { 5435 return j; 5436 } 5437 } 5438 } 5439 5440 // Now look forwards 5441 final int N = mMainStack.mHistory.size(); 5442 jt = startTask; 5443 for (j=startIndex+1; j<N; j++) { 5444 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5445 if (r.task != jt) { 5446 if (affinity.equals(jt.affinity)) { 5447 return j; 5448 } 5449 jt = r.task; 5450 } 5451 } 5452 5453 // Might it be at the top? 5454 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5455 return N-1; 5456 } 5457 5458 return -1; 5459 } 5460 5461 /** 5462 * TODO: Add mController hook 5463 */ 5464 public void moveTaskToFront(int task, int flags) { 5465 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5466 "moveTaskToFront()"); 5467 5468 synchronized(this) { 5469 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5470 Binder.getCallingUid(), "Task to front")) { 5471 return; 5472 } 5473 final long origId = Binder.clearCallingIdentity(); 5474 try { 5475 TaskRecord tr = taskForIdLocked(task); 5476 if (tr != null) { 5477 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5478 mMainStack.mUserLeaving = true; 5479 } 5480 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5481 // Caller wants the home activity moved with it. To accomplish this, 5482 // we'll just move the home task to the top first. 5483 mMainStack.moveHomeToFrontLocked(); 5484 } 5485 mMainStack.moveTaskToFrontLocked(tr, null); 5486 return; 5487 } 5488 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5489 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5490 if (hr.task.taskId == task) { 5491 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5492 mMainStack.mUserLeaving = true; 5493 } 5494 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5495 // Caller wants the home activity moved with it. To accomplish this, 5496 // we'll just move the home task to the top first. 5497 mMainStack.moveHomeToFrontLocked(); 5498 } 5499 mMainStack.moveTaskToFrontLocked(hr.task, null); 5500 return; 5501 } 5502 } 5503 } finally { 5504 Binder.restoreCallingIdentity(origId); 5505 } 5506 } 5507 } 5508 5509 public void moveTaskToBack(int task) { 5510 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5511 "moveTaskToBack()"); 5512 5513 synchronized(this) { 5514 if (mMainStack.mResumedActivity != null 5515 && mMainStack.mResumedActivity.task.taskId == task) { 5516 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5517 Binder.getCallingUid(), "Task to back")) { 5518 return; 5519 } 5520 } 5521 final long origId = Binder.clearCallingIdentity(); 5522 mMainStack.moveTaskToBackLocked(task, null); 5523 Binder.restoreCallingIdentity(origId); 5524 } 5525 } 5526 5527 /** 5528 * Moves an activity, and all of the other activities within the same task, to the bottom 5529 * of the history stack. The activity's order within the task is unchanged. 5530 * 5531 * @param token A reference to the activity we wish to move 5532 * @param nonRoot If false then this only works if the activity is the root 5533 * of a task; if true it will work for any activity in a task. 5534 * @return Returns true if the move completed, false if not. 5535 */ 5536 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5537 synchronized(this) { 5538 final long origId = Binder.clearCallingIdentity(); 5539 int taskId = getTaskForActivityLocked(token, !nonRoot); 5540 if (taskId >= 0) { 5541 return mMainStack.moveTaskToBackLocked(taskId, null); 5542 } 5543 Binder.restoreCallingIdentity(origId); 5544 } 5545 return false; 5546 } 5547 5548 public void moveTaskBackwards(int task) { 5549 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5550 "moveTaskBackwards()"); 5551 5552 synchronized(this) { 5553 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5554 Binder.getCallingUid(), "Task backwards")) { 5555 return; 5556 } 5557 final long origId = Binder.clearCallingIdentity(); 5558 moveTaskBackwardsLocked(task); 5559 Binder.restoreCallingIdentity(origId); 5560 } 5561 } 5562 5563 private final void moveTaskBackwardsLocked(int task) { 5564 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5565 } 5566 5567 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5568 synchronized(this) { 5569 return getTaskForActivityLocked(token, onlyRoot); 5570 } 5571 } 5572 5573 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5574 final int N = mMainStack.mHistory.size(); 5575 TaskRecord lastTask = null; 5576 for (int i=0; i<N; i++) { 5577 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5578 if (r.appToken == token) { 5579 if (!onlyRoot || lastTask != r.task) { 5580 return r.task.taskId; 5581 } 5582 return -1; 5583 } 5584 lastTask = r.task; 5585 } 5586 5587 return -1; 5588 } 5589 5590 public void finishOtherInstances(IBinder token, ComponentName className) { 5591 synchronized(this) { 5592 final long origId = Binder.clearCallingIdentity(); 5593 5594 int N = mMainStack.mHistory.size(); 5595 TaskRecord lastTask = null; 5596 for (int i=0; i<N; i++) { 5597 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5598 if (r.realActivity.equals(className) 5599 && r.appToken != token && lastTask != r.task) { 5600 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 5601 null, "others")) { 5602 i--; 5603 N--; 5604 } 5605 } 5606 lastTask = r.task; 5607 } 5608 5609 Binder.restoreCallingIdentity(origId); 5610 } 5611 } 5612 5613 // ========================================================= 5614 // THUMBNAILS 5615 // ========================================================= 5616 5617 public void reportThumbnail(IBinder token, 5618 Bitmap thumbnail, CharSequence description) { 5619 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5620 final long origId = Binder.clearCallingIdentity(); 5621 sendPendingThumbnail(null, token, thumbnail, description, true); 5622 Binder.restoreCallingIdentity(origId); 5623 } 5624 5625 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5626 Bitmap thumbnail, CharSequence description, boolean always) { 5627 TaskRecord task = null; 5628 ArrayList receivers = null; 5629 5630 //System.out.println("Send pending thumbnail: " + r); 5631 5632 synchronized(this) { 5633 if (r == null) { 5634 r = mMainStack.isInStackLocked(token); 5635 if (r == null) { 5636 return; 5637 } 5638 } 5639 if (thumbnail == null && r.thumbHolder != null) { 5640 thumbnail = r.thumbHolder.lastThumbnail; 5641 description = r.thumbHolder.lastDescription; 5642 } 5643 if (thumbnail == null && !always) { 5644 // If there is no thumbnail, and this entry is not actually 5645 // going away, then abort for now and pick up the next 5646 // thumbnail we get. 5647 return; 5648 } 5649 task = r.task; 5650 5651 int N = mPendingThumbnails.size(); 5652 int i=0; 5653 while (i<N) { 5654 PendingThumbnailsRecord pr = 5655 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5656 //System.out.println("Looking in " + pr.pendingRecords); 5657 if (pr.pendingRecords.remove(r)) { 5658 if (receivers == null) { 5659 receivers = new ArrayList(); 5660 } 5661 receivers.add(pr); 5662 if (pr.pendingRecords.size() == 0) { 5663 pr.finished = true; 5664 mPendingThumbnails.remove(i); 5665 N--; 5666 continue; 5667 } 5668 } 5669 i++; 5670 } 5671 } 5672 5673 if (receivers != null) { 5674 final int N = receivers.size(); 5675 for (int i=0; i<N; i++) { 5676 try { 5677 PendingThumbnailsRecord pr = 5678 (PendingThumbnailsRecord)receivers.get(i); 5679 pr.receiver.newThumbnail( 5680 task != null ? task.taskId : -1, thumbnail, description); 5681 if (pr.finished) { 5682 pr.receiver.finished(); 5683 } 5684 } catch (Exception e) { 5685 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5686 } 5687 } 5688 } 5689 } 5690 5691 // ========================================================= 5692 // CONTENT PROVIDERS 5693 // ========================================================= 5694 5695 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5696 List<ProviderInfo> providers = null; 5697 try { 5698 providers = AppGlobals.getPackageManager(). 5699 queryContentProviders(app.processName, app.info.uid, 5700 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5701 } catch (RemoteException ex) { 5702 } 5703 if (providers != null) { 5704 final int N = providers.size(); 5705 for (int i=0; i<N; i++) { 5706 ProviderInfo cpi = 5707 (ProviderInfo)providers.get(i); 5708 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5709 ContentProviderRecord cpr = mProvidersByClass.get(comp); 5710 if (cpr == null) { 5711 cpr = new ContentProviderRecord(cpi, app.info, comp); 5712 mProvidersByClass.put(comp, cpr); 5713 } 5714 app.pubProviders.put(cpi.name, cpr); 5715 app.addPackage(cpi.applicationInfo.packageName); 5716 ensurePackageDexOpt(cpi.applicationInfo.packageName); 5717 } 5718 } 5719 return providers; 5720 } 5721 5722 private final String checkContentProviderPermissionLocked( 5723 ProviderInfo cpi, ProcessRecord r) { 5724 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 5725 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 5726 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 5727 cpi.applicationInfo.uid, cpi.exported) 5728 == PackageManager.PERMISSION_GRANTED) { 5729 return null; 5730 } 5731 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 5732 cpi.applicationInfo.uid, cpi.exported) 5733 == PackageManager.PERMISSION_GRANTED) { 5734 return null; 5735 } 5736 5737 PathPermission[] pps = cpi.pathPermissions; 5738 if (pps != null) { 5739 int i = pps.length; 5740 while (i > 0) { 5741 i--; 5742 PathPermission pp = pps[i]; 5743 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 5744 cpi.applicationInfo.uid, cpi.exported) 5745 == PackageManager.PERMISSION_GRANTED) { 5746 return null; 5747 } 5748 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 5749 cpi.applicationInfo.uid, cpi.exported) 5750 == PackageManager.PERMISSION_GRANTED) { 5751 return null; 5752 } 5753 } 5754 } 5755 5756 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 5757 if (perms != null) { 5758 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 5759 if (uri.getKey().getAuthority().equals(cpi.authority)) { 5760 return null; 5761 } 5762 } 5763 } 5764 5765 String msg; 5766 if (!cpi.exported) { 5767 msg = "Permission Denial: opening provider " + cpi.name 5768 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 5769 + ", uid=" + callingUid + ") that is not exported from uid " 5770 + cpi.applicationInfo.uid; 5771 } else { 5772 msg = "Permission Denial: opening provider " + cpi.name 5773 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 5774 + ", uid=" + callingUid + ") requires " 5775 + cpi.readPermission + " or " + cpi.writePermission; 5776 } 5777 Slog.w(TAG, msg); 5778 return msg; 5779 } 5780 5781 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) { 5782 if (r != null) { 5783 Integer cnt = r.conProviders.get(cpr); 5784 if (DEBUG_PROVIDER) Slog.v(TAG, 5785 "Adding provider requested by " 5786 + r.processName + " from process " 5787 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 5788 + " cnt=" + (cnt == null ? 1 : cnt)); 5789 if (cnt == null) { 5790 cpr.clients.add(r); 5791 r.conProviders.put(cpr, new Integer(1)); 5792 return true; 5793 } else { 5794 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 5795 } 5796 } else { 5797 cpr.externals++; 5798 } 5799 return false; 5800 } 5801 5802 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) { 5803 if (r != null) { 5804 Integer cnt = r.conProviders.get(cpr); 5805 if (DEBUG_PROVIDER) Slog.v(TAG, 5806 "Removing provider requested by " 5807 + r.processName + " from process " 5808 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 5809 + " cnt=" + cnt); 5810 if (cnt == null || cnt.intValue() <= 1) { 5811 cpr.clients.remove(r); 5812 r.conProviders.remove(cpr); 5813 return true; 5814 } else { 5815 r.conProviders.put(cpr, new Integer(cnt.intValue()-1)); 5816 } 5817 } else { 5818 cpr.externals++; 5819 } 5820 return false; 5821 } 5822 5823 private final ContentProviderHolder getContentProviderImpl( 5824 IApplicationThread caller, String name) { 5825 ContentProviderRecord cpr; 5826 ProviderInfo cpi = null; 5827 5828 synchronized(this) { 5829 ProcessRecord r = null; 5830 if (caller != null) { 5831 r = getRecordForAppLocked(caller); 5832 if (r == null) { 5833 throw new SecurityException( 5834 "Unable to find app for caller " + caller 5835 + " (pid=" + Binder.getCallingPid() 5836 + ") when getting content provider " + name); 5837 } 5838 } 5839 5840 // First check if this content provider has been published... 5841 cpr = mProvidersByName.get(name); 5842 boolean providerRunning = cpr != null; 5843 if (providerRunning) { 5844 cpi = cpr.info; 5845 String msg; 5846 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 5847 throw new SecurityException(msg); 5848 } 5849 5850 if (r != null && cpr.canRunHere(r)) { 5851 // This provider has been published or is in the process 5852 // of being published... but it is also allowed to run 5853 // in the caller's process, so don't make a connection 5854 // and just let the caller instantiate its own instance. 5855 if (cpr.provider != null) { 5856 // don't give caller the provider object, it needs 5857 // to make its own. 5858 cpr = new ContentProviderRecord(cpr); 5859 } 5860 return cpr; 5861 } 5862 5863 final long origId = Binder.clearCallingIdentity(); 5864 5865 // In this case the provider instance already exists, so we can 5866 // return it right away. 5867 final boolean countChanged = incProviderCount(r, cpr); 5868 if (countChanged) { 5869 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 5870 // If this is a perceptible app accessing the provider, 5871 // make sure to count it as being accessed and thus 5872 // back up on the LRU list. This is good because 5873 // content providers are often expensive to start. 5874 updateLruProcessLocked(cpr.proc, false, true); 5875 } 5876 } 5877 5878 if (cpr.proc != null) { 5879 if (false) { 5880 if (cpr.name.flattenToShortString().equals( 5881 "com.android.providers.calendar/.CalendarProvider2")) { 5882 Slog.v(TAG, "****************** KILLING " 5883 + cpr.name.flattenToShortString()); 5884 Process.killProcess(cpr.proc.pid); 5885 } 5886 } 5887 boolean success = updateOomAdjLocked(cpr.proc); 5888 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 5889 // NOTE: there is still a race here where a signal could be 5890 // pending on the process even though we managed to update its 5891 // adj level. Not sure what to do about this, but at least 5892 // the race is now smaller. 5893 if (!success) { 5894 // Uh oh... it looks like the provider's process 5895 // has been killed on us. We need to wait for a new 5896 // process to be started, and make sure its death 5897 // doesn't kill our process. 5898 Slog.i(TAG, 5899 "Existing provider " + cpr.name.flattenToShortString() 5900 + " is crashing; detaching " + r); 5901 boolean lastRef = decProviderCount(r, cpr); 5902 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 5903 if (!lastRef) { 5904 // This wasn't the last ref our process had on 5905 // the provider... we have now been killed, bail. 5906 return null; 5907 } 5908 providerRunning = false; 5909 } 5910 } 5911 5912 Binder.restoreCallingIdentity(origId); 5913 } 5914 5915 if (!providerRunning) { 5916 try { 5917 cpi = AppGlobals.getPackageManager(). 5918 resolveContentProvider(name, 5919 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5920 } catch (RemoteException ex) { 5921 } 5922 if (cpi == null) { 5923 return null; 5924 } 5925 5926 String msg; 5927 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 5928 throw new SecurityException(msg); 5929 } 5930 5931 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 5932 && !cpi.processName.equals("system")) { 5933 // If this content provider does not run in the system 5934 // process, and the system is not yet ready to run other 5935 // processes, then fail fast instead of hanging. 5936 throw new IllegalArgumentException( 5937 "Attempt to launch content provider before system ready"); 5938 } 5939 5940 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5941 cpr = mProvidersByClass.get(comp); 5942 final boolean firstClass = cpr == null; 5943 if (firstClass) { 5944 try { 5945 ApplicationInfo ai = 5946 AppGlobals.getPackageManager(). 5947 getApplicationInfo( 5948 cpi.applicationInfo.packageName, 5949 STOCK_PM_FLAGS); 5950 if (ai == null) { 5951 Slog.w(TAG, "No package info for content provider " 5952 + cpi.name); 5953 return null; 5954 } 5955 cpr = new ContentProviderRecord(cpi, ai, comp); 5956 } catch (RemoteException ex) { 5957 // pm is in same process, this will never happen. 5958 } 5959 } 5960 5961 if (r != null && cpr.canRunHere(r)) { 5962 // If this is a multiprocess provider, then just return its 5963 // info and allow the caller to instantiate it. Only do 5964 // this if the provider is the same user as the caller's 5965 // process, or can run as root (so can be in any process). 5966 return cpr; 5967 } 5968 5969 if (DEBUG_PROVIDER) { 5970 RuntimeException e = new RuntimeException("here"); 5971 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 5972 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 5973 } 5974 5975 // This is single process, and our app is now connecting to it. 5976 // See if we are already in the process of launching this 5977 // provider. 5978 final int N = mLaunchingProviders.size(); 5979 int i; 5980 for (i=0; i<N; i++) { 5981 if (mLaunchingProviders.get(i) == cpr) { 5982 break; 5983 } 5984 } 5985 5986 // If the provider is not already being launched, then get it 5987 // started. 5988 if (i >= N) { 5989 final long origId = Binder.clearCallingIdentity(); 5990 5991 try { 5992 // Content provider is now in use, its package can't be stopped. 5993 try { 5994 AppGlobals.getPackageManager().setPackageStoppedState( 5995 cpr.appInfo.packageName, false); 5996 } catch (RemoteException e) { 5997 } catch (IllegalArgumentException e) { 5998 Slog.w(TAG, "Failed trying to unstop package " 5999 + cpr.appInfo.packageName + ": " + e); 6000 } 6001 6002 ProcessRecord proc = startProcessLocked(cpi.processName, 6003 cpr.appInfo, false, 0, "content provider", 6004 new ComponentName(cpi.applicationInfo.packageName, 6005 cpi.name), false); 6006 if (proc == null) { 6007 Slog.w(TAG, "Unable to launch app " 6008 + cpi.applicationInfo.packageName + "/" 6009 + cpi.applicationInfo.uid + " for provider " 6010 + name + ": process is bad"); 6011 return null; 6012 } 6013 cpr.launchingApp = proc; 6014 mLaunchingProviders.add(cpr); 6015 } finally { 6016 Binder.restoreCallingIdentity(origId); 6017 } 6018 } 6019 6020 // Make sure the provider is published (the same provider class 6021 // may be published under multiple names). 6022 if (firstClass) { 6023 mProvidersByClass.put(comp, cpr); 6024 } 6025 mProvidersByName.put(name, cpr); 6026 incProviderCount(r, cpr); 6027 } 6028 } 6029 6030 // Wait for the provider to be published... 6031 synchronized (cpr) { 6032 while (cpr.provider == null) { 6033 if (cpr.launchingApp == null) { 6034 Slog.w(TAG, "Unable to launch app " 6035 + cpi.applicationInfo.packageName + "/" 6036 + cpi.applicationInfo.uid + " for provider " 6037 + name + ": launching app became null"); 6038 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6039 cpi.applicationInfo.packageName, 6040 cpi.applicationInfo.uid, name); 6041 return null; 6042 } 6043 try { 6044 cpr.wait(); 6045 } catch (InterruptedException ex) { 6046 } 6047 } 6048 } 6049 return cpr; 6050 } 6051 6052 public final ContentProviderHolder getContentProvider( 6053 IApplicationThread caller, String name) { 6054 if (caller == null) { 6055 String msg = "null IApplicationThread when getting content provider " 6056 + name; 6057 Slog.w(TAG, msg); 6058 throw new SecurityException(msg); 6059 } 6060 6061 return getContentProviderImpl(caller, name); 6062 } 6063 6064 private ContentProviderHolder getContentProviderExternal(String name) { 6065 return getContentProviderImpl(null, name); 6066 } 6067 6068 /** 6069 * Drop a content provider from a ProcessRecord's bookkeeping 6070 * @param cpr 6071 */ 6072 public void removeContentProvider(IApplicationThread caller, String name) { 6073 synchronized (this) { 6074 ContentProviderRecord cpr = mProvidersByName.get(name); 6075 if(cpr == null) { 6076 // remove from mProvidersByClass 6077 if (DEBUG_PROVIDER) Slog.v(TAG, name + 6078 " provider not found in providers list"); 6079 return; 6080 } 6081 final ProcessRecord r = getRecordForAppLocked(caller); 6082 if (r == null) { 6083 throw new SecurityException( 6084 "Unable to find app for caller " + caller + 6085 " when removing content provider " + name); 6086 } 6087 //update content provider record entry info 6088 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6089 ContentProviderRecord localCpr = mProvidersByClass.get(comp); 6090 if (localCpr.proc == r) { 6091 //should not happen. taken care of as a local provider 6092 Slog.w(TAG, "removeContentProvider called on local provider: " 6093 + cpr.info.name + " in process " + r.processName); 6094 return; 6095 } else { 6096 if (decProviderCount(r, localCpr)) { 6097 updateOomAdjLocked(); 6098 } 6099 } 6100 } 6101 } 6102 6103 private void removeContentProviderExternal(String name) { 6104 synchronized (this) { 6105 ContentProviderRecord cpr = mProvidersByName.get(name); 6106 if(cpr == null) { 6107 //remove from mProvidersByClass 6108 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6109 return; 6110 } 6111 6112 //update content provider record entry info 6113 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6114 ContentProviderRecord localCpr = mProvidersByClass.get(comp); 6115 localCpr.externals--; 6116 if (localCpr.externals < 0) { 6117 Slog.e(TAG, "Externals < 0 for content provider " + localCpr); 6118 } 6119 updateOomAdjLocked(); 6120 } 6121 } 6122 6123 public final void publishContentProviders(IApplicationThread caller, 6124 List<ContentProviderHolder> providers) { 6125 if (providers == null) { 6126 return; 6127 } 6128 6129 synchronized(this) { 6130 final ProcessRecord r = getRecordForAppLocked(caller); 6131 if (r == null) { 6132 throw new SecurityException( 6133 "Unable to find app for caller " + caller 6134 + " (pid=" + Binder.getCallingPid() 6135 + ") when publishing content providers"); 6136 } 6137 6138 final long origId = Binder.clearCallingIdentity(); 6139 6140 final int N = providers.size(); 6141 for (int i=0; i<N; i++) { 6142 ContentProviderHolder src = providers.get(i); 6143 if (src == null || src.info == null || src.provider == null) { 6144 continue; 6145 } 6146 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6147 if (dst != null) { 6148 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6149 mProvidersByClass.put(comp, dst); 6150 String names[] = dst.info.authority.split(";"); 6151 for (int j = 0; j < names.length; j++) { 6152 mProvidersByName.put(names[j], dst); 6153 } 6154 6155 int NL = mLaunchingProviders.size(); 6156 int j; 6157 for (j=0; j<NL; j++) { 6158 if (mLaunchingProviders.get(j) == dst) { 6159 mLaunchingProviders.remove(j); 6160 j--; 6161 NL--; 6162 } 6163 } 6164 synchronized (dst) { 6165 dst.provider = src.provider; 6166 dst.proc = r; 6167 dst.notifyAll(); 6168 } 6169 updateOomAdjLocked(r); 6170 } 6171 } 6172 6173 Binder.restoreCallingIdentity(origId); 6174 } 6175 } 6176 6177 public static final void installSystemProviders() { 6178 List<ProviderInfo> providers; 6179 synchronized (mSelf) { 6180 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6181 providers = mSelf.generateApplicationProvidersLocked(app); 6182 if (providers != null) { 6183 for (int i=providers.size()-1; i>=0; i--) { 6184 ProviderInfo pi = (ProviderInfo)providers.get(i); 6185 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6186 Slog.w(TAG, "Not installing system proc provider " + pi.name 6187 + ": not system .apk"); 6188 providers.remove(i); 6189 } 6190 } 6191 } 6192 } 6193 if (providers != null) { 6194 mSystemThread.installSystemProviders(providers); 6195 } 6196 6197 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6198 6199 mSelf.mUsageStatsService.monitorPackages(); 6200 } 6201 6202 /** 6203 * Allows app to retrieve the MIME type of a URI without having permission 6204 * to access its content provider. 6205 * 6206 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6207 * 6208 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6209 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6210 */ 6211 public String getProviderMimeType(Uri uri) { 6212 final String name = uri.getAuthority(); 6213 final long ident = Binder.clearCallingIdentity(); 6214 ContentProviderHolder holder = null; 6215 6216 try { 6217 holder = getContentProviderExternal(name); 6218 if (holder != null) { 6219 return holder.provider.getType(uri); 6220 } 6221 } catch (RemoteException e) { 6222 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6223 return null; 6224 } finally { 6225 if (holder != null) { 6226 removeContentProviderExternal(name); 6227 } 6228 Binder.restoreCallingIdentity(ident); 6229 } 6230 6231 return null; 6232 } 6233 6234 // ========================================================= 6235 // GLOBAL MANAGEMENT 6236 // ========================================================= 6237 6238 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6239 ApplicationInfo info, String customProcess) { 6240 String proc = customProcess != null ? customProcess : info.processName; 6241 BatteryStatsImpl.Uid.Proc ps = null; 6242 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6243 synchronized (stats) { 6244 ps = stats.getProcessStatsLocked(info.uid, proc); 6245 } 6246 return new ProcessRecord(ps, thread, info, proc); 6247 } 6248 6249 final ProcessRecord addAppLocked(ApplicationInfo info) { 6250 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 6251 6252 if (app == null) { 6253 app = newProcessRecordLocked(null, info, null); 6254 mProcessNames.put(info.processName, info.uid, app); 6255 updateLruProcessLocked(app, true, true); 6256 } 6257 6258 // This package really, really can not be stopped. 6259 try { 6260 AppGlobals.getPackageManager().setPackageStoppedState( 6261 info.packageName, false); 6262 } catch (RemoteException e) { 6263 } catch (IllegalArgumentException e) { 6264 Slog.w(TAG, "Failed trying to unstop package " 6265 + info.packageName + ": " + e); 6266 } 6267 6268 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6269 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6270 app.persistent = true; 6271 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6272 } 6273 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6274 mPersistentStartingProcesses.add(app); 6275 startProcessLocked(app, "added application", app.processName); 6276 } 6277 6278 return app; 6279 } 6280 6281 public void unhandledBack() { 6282 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6283 "unhandledBack()"); 6284 6285 synchronized(this) { 6286 int count = mMainStack.mHistory.size(); 6287 if (DEBUG_SWITCH) Slog.d( 6288 TAG, "Performing unhandledBack(): stack size = " + count); 6289 if (count > 1) { 6290 final long origId = Binder.clearCallingIdentity(); 6291 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6292 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6293 Binder.restoreCallingIdentity(origId); 6294 } 6295 } 6296 } 6297 6298 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6299 String name = uri.getAuthority(); 6300 ContentProviderHolder cph = getContentProviderExternal(name); 6301 ParcelFileDescriptor pfd = null; 6302 if (cph != null) { 6303 // We record the binder invoker's uid in thread-local storage before 6304 // going to the content provider to open the file. Later, in the code 6305 // that handles all permissions checks, we look for this uid and use 6306 // that rather than the Activity Manager's own uid. The effect is that 6307 // we do the check against the caller's permissions even though it looks 6308 // to the content provider like the Activity Manager itself is making 6309 // the request. 6310 sCallerIdentity.set(new Identity( 6311 Binder.getCallingPid(), Binder.getCallingUid())); 6312 try { 6313 pfd = cph.provider.openFile(uri, "r"); 6314 } catch (FileNotFoundException e) { 6315 // do nothing; pfd will be returned null 6316 } finally { 6317 // Ensure that whatever happens, we clean up the identity state 6318 sCallerIdentity.remove(); 6319 } 6320 6321 // We've got the fd now, so we're done with the provider. 6322 removeContentProviderExternal(name); 6323 } else { 6324 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6325 } 6326 return pfd; 6327 } 6328 6329 // Actually is sleeping or shutting down or whatever else in the future 6330 // is an inactive state. 6331 public boolean isSleeping() { 6332 return mSleeping || mShuttingDown; 6333 } 6334 6335 public void goingToSleep() { 6336 synchronized(this) { 6337 mSleeping = true; 6338 mWindowManager.setEventDispatching(false); 6339 6340 mMainStack.stopIfSleepingLocked(); 6341 6342 // Initialize the wake times of all processes. 6343 checkExcessivePowerUsageLocked(false); 6344 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6345 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6346 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6347 } 6348 } 6349 6350 public boolean shutdown(int timeout) { 6351 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6352 != PackageManager.PERMISSION_GRANTED) { 6353 throw new SecurityException("Requires permission " 6354 + android.Manifest.permission.SHUTDOWN); 6355 } 6356 6357 boolean timedout = false; 6358 6359 synchronized(this) { 6360 mShuttingDown = true; 6361 mWindowManager.setEventDispatching(false); 6362 6363 if (mMainStack.mResumedActivity != null) { 6364 mMainStack.stopIfSleepingLocked(); 6365 final long endTime = System.currentTimeMillis() + timeout; 6366 while (mMainStack.mResumedActivity != null 6367 || mMainStack.mPausingActivity != null) { 6368 long delay = endTime - System.currentTimeMillis(); 6369 if (delay <= 0) { 6370 Slog.w(TAG, "Activity manager shutdown timed out"); 6371 timedout = true; 6372 break; 6373 } 6374 try { 6375 this.wait(); 6376 } catch (InterruptedException e) { 6377 } 6378 } 6379 } 6380 } 6381 6382 mUsageStatsService.shutdown(); 6383 mBatteryStatsService.shutdown(); 6384 6385 return timedout; 6386 } 6387 6388 public final void activitySlept(IBinder token) { 6389 if (localLOGV) Slog.v( 6390 TAG, "Activity slept: token=" + token); 6391 6392 ActivityRecord r = null; 6393 6394 final long origId = Binder.clearCallingIdentity(); 6395 6396 synchronized (this) { 6397 r = mMainStack.isInStackLocked(token); 6398 if (r != null) { 6399 mMainStack.activitySleptLocked(r); 6400 } 6401 } 6402 6403 Binder.restoreCallingIdentity(origId); 6404 } 6405 6406 public void wakingUp() { 6407 synchronized(this) { 6408 mWindowManager.setEventDispatching(true); 6409 mSleeping = false; 6410 mMainStack.awakeFromSleepingLocked(); 6411 mMainStack.resumeTopActivityLocked(null); 6412 } 6413 } 6414 6415 public void stopAppSwitches() { 6416 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6417 != PackageManager.PERMISSION_GRANTED) { 6418 throw new SecurityException("Requires permission " 6419 + android.Manifest.permission.STOP_APP_SWITCHES); 6420 } 6421 6422 synchronized(this) { 6423 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6424 + APP_SWITCH_DELAY_TIME; 6425 mDidAppSwitch = false; 6426 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6427 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6428 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6429 } 6430 } 6431 6432 public void resumeAppSwitches() { 6433 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6434 != PackageManager.PERMISSION_GRANTED) { 6435 throw new SecurityException("Requires permission " 6436 + android.Manifest.permission.STOP_APP_SWITCHES); 6437 } 6438 6439 synchronized(this) { 6440 // Note that we don't execute any pending app switches... we will 6441 // let those wait until either the timeout, or the next start 6442 // activity request. 6443 mAppSwitchesAllowedTime = 0; 6444 } 6445 } 6446 6447 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6448 String name) { 6449 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6450 return true; 6451 } 6452 6453 final int perm = checkComponentPermission( 6454 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6455 callingUid, -1, true); 6456 if (perm == PackageManager.PERMISSION_GRANTED) { 6457 return true; 6458 } 6459 6460 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6461 return false; 6462 } 6463 6464 public void setDebugApp(String packageName, boolean waitForDebugger, 6465 boolean persistent) { 6466 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 6467 "setDebugApp()"); 6468 6469 // Note that this is not really thread safe if there are multiple 6470 // callers into it at the same time, but that's not a situation we 6471 // care about. 6472 if (persistent) { 6473 final ContentResolver resolver = mContext.getContentResolver(); 6474 Settings.System.putString( 6475 resolver, Settings.System.DEBUG_APP, 6476 packageName); 6477 Settings.System.putInt( 6478 resolver, Settings.System.WAIT_FOR_DEBUGGER, 6479 waitForDebugger ? 1 : 0); 6480 } 6481 6482 synchronized (this) { 6483 if (!persistent) { 6484 mOrigDebugApp = mDebugApp; 6485 mOrigWaitForDebugger = mWaitForDebugger; 6486 } 6487 mDebugApp = packageName; 6488 mWaitForDebugger = waitForDebugger; 6489 mDebugTransient = !persistent; 6490 if (packageName != null) { 6491 final long origId = Binder.clearCallingIdentity(); 6492 forceStopPackageLocked(packageName, -1, false, false, true, true); 6493 Binder.restoreCallingIdentity(origId); 6494 } 6495 } 6496 } 6497 6498 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 6499 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 6500 synchronized (this) { 6501 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6502 if (!isDebuggable) { 6503 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 6504 throw new SecurityException("Process not debuggable: " + app.packageName); 6505 } 6506 } 6507 mProfileApp = processName; 6508 mProfileFile = profileFile; 6509 if (mProfileFd != null) { 6510 try { 6511 mProfileFd.close(); 6512 } catch (IOException e) { 6513 } 6514 mProfileFd = null; 6515 } 6516 mProfileFd = profileFd; 6517 mProfileType = 0; 6518 mAutoStopProfiler = autoStopProfiler; 6519 } 6520 } 6521 6522 public void setAlwaysFinish(boolean enabled) { 6523 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 6524 "setAlwaysFinish()"); 6525 6526 Settings.System.putInt( 6527 mContext.getContentResolver(), 6528 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 6529 6530 synchronized (this) { 6531 mAlwaysFinishActivities = enabled; 6532 } 6533 } 6534 6535 public void setActivityController(IActivityController controller) { 6536 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 6537 "setActivityController()"); 6538 synchronized (this) { 6539 mController = controller; 6540 } 6541 } 6542 6543 public boolean isUserAMonkey() { 6544 // For now the fact that there is a controller implies 6545 // we have a monkey. 6546 synchronized (this) { 6547 return mController != null; 6548 } 6549 } 6550 6551 public void registerActivityWatcher(IActivityWatcher watcher) { 6552 synchronized (this) { 6553 mWatchers.register(watcher); 6554 } 6555 } 6556 6557 public void unregisterActivityWatcher(IActivityWatcher watcher) { 6558 synchronized (this) { 6559 mWatchers.unregister(watcher); 6560 } 6561 } 6562 6563 public void registerProcessObserver(IProcessObserver observer) { 6564 mProcessObservers.register(observer); 6565 } 6566 6567 public void unregisterProcessObserver(IProcessObserver observer) { 6568 mProcessObservers.unregister(observer); 6569 } 6570 6571 public void setImmersive(IBinder token, boolean immersive) { 6572 synchronized(this) { 6573 ActivityRecord r = mMainStack.isInStackLocked(token); 6574 if (r == null) { 6575 throw new IllegalArgumentException(); 6576 } 6577 r.immersive = immersive; 6578 } 6579 } 6580 6581 public boolean isImmersive(IBinder token) { 6582 synchronized (this) { 6583 ActivityRecord r = mMainStack.isInStackLocked(token); 6584 if (r == null) { 6585 throw new IllegalArgumentException(); 6586 } 6587 return r.immersive; 6588 } 6589 } 6590 6591 public boolean isTopActivityImmersive() { 6592 synchronized (this) { 6593 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 6594 return (r != null) ? r.immersive : false; 6595 } 6596 } 6597 6598 public final void enterSafeMode() { 6599 synchronized(this) { 6600 // It only makes sense to do this before the system is ready 6601 // and started launching other packages. 6602 if (!mSystemReady) { 6603 try { 6604 AppGlobals.getPackageManager().enterSafeMode(); 6605 } catch (RemoteException e) { 6606 } 6607 } 6608 } 6609 } 6610 6611 public final void showSafeModeOverlay() { 6612 View v = LayoutInflater.from(mContext).inflate( 6613 com.android.internal.R.layout.safe_mode, null); 6614 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 6615 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 6616 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 6617 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 6618 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 6619 lp.format = v.getBackground().getOpacity(); 6620 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 6621 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 6622 ((WindowManager)mContext.getSystemService( 6623 Context.WINDOW_SERVICE)).addView(v, lp); 6624 } 6625 6626 public void noteWakeupAlarm(IIntentSender sender) { 6627 if (!(sender instanceof PendingIntentRecord)) { 6628 return; 6629 } 6630 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6631 synchronized (stats) { 6632 if (mBatteryStatsService.isOnBattery()) { 6633 mBatteryStatsService.enforceCallingPermission(); 6634 PendingIntentRecord rec = (PendingIntentRecord)sender; 6635 int MY_UID = Binder.getCallingUid(); 6636 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 6637 BatteryStatsImpl.Uid.Pkg pkg = 6638 stats.getPackageStatsLocked(uid, rec.key.packageName); 6639 pkg.incWakeupsLocked(); 6640 } 6641 } 6642 } 6643 6644 public boolean killPids(int[] pids, String pReason, boolean secure) { 6645 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6646 throw new SecurityException("killPids only available to the system"); 6647 } 6648 String reason = (pReason == null) ? "Unknown" : pReason; 6649 // XXX Note: don't acquire main activity lock here, because the window 6650 // manager calls in with its locks held. 6651 6652 boolean killed = false; 6653 synchronized (mPidsSelfLocked) { 6654 int[] types = new int[pids.length]; 6655 int worstType = 0; 6656 for (int i=0; i<pids.length; i++) { 6657 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 6658 if (proc != null) { 6659 int type = proc.setAdj; 6660 types[i] = type; 6661 if (type > worstType) { 6662 worstType = type; 6663 } 6664 } 6665 } 6666 6667 // If the worst oom_adj is somewhere in the hidden proc LRU range, 6668 // then constrain it so we will kill all hidden procs. 6669 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 6670 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 6671 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 6672 } 6673 6674 // If this is not a secure call, don't let it kill processes that 6675 // are important. 6676 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 6677 worstType = ProcessList.SERVICE_ADJ; 6678 } 6679 6680 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 6681 for (int i=0; i<pids.length; i++) { 6682 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 6683 if (proc == null) { 6684 continue; 6685 } 6686 int adj = proc.setAdj; 6687 if (adj >= worstType && !proc.killedBackground) { 6688 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 6689 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 6690 proc.processName, adj, reason); 6691 killed = true; 6692 proc.killedBackground = true; 6693 Process.killProcessQuiet(pids[i]); 6694 } 6695 } 6696 } 6697 return killed; 6698 } 6699 6700 public final void startRunning(String pkg, String cls, String action, 6701 String data) { 6702 synchronized(this) { 6703 if (mStartRunning) { 6704 return; 6705 } 6706 mStartRunning = true; 6707 mTopComponent = pkg != null && cls != null 6708 ? new ComponentName(pkg, cls) : null; 6709 mTopAction = action != null ? action : Intent.ACTION_MAIN; 6710 mTopData = data; 6711 if (!mSystemReady) { 6712 return; 6713 } 6714 } 6715 6716 systemReady(null); 6717 } 6718 6719 private void retrieveSettings() { 6720 final ContentResolver resolver = mContext.getContentResolver(); 6721 String debugApp = Settings.System.getString( 6722 resolver, Settings.System.DEBUG_APP); 6723 boolean waitForDebugger = Settings.System.getInt( 6724 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 6725 boolean alwaysFinishActivities = Settings.System.getInt( 6726 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 6727 6728 Configuration configuration = new Configuration(); 6729 Settings.System.getConfiguration(resolver, configuration); 6730 6731 synchronized (this) { 6732 mDebugApp = mOrigDebugApp = debugApp; 6733 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 6734 mAlwaysFinishActivities = alwaysFinishActivities; 6735 // This happens before any activities are started, so we can 6736 // change mConfiguration in-place. 6737 updateConfigurationLocked(configuration, null, false, true); 6738 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 6739 } 6740 } 6741 6742 public boolean testIsSystemReady() { 6743 // no need to synchronize(this) just to read & return the value 6744 return mSystemReady; 6745 } 6746 6747 private static File getCalledPreBootReceiversFile() { 6748 File dataDir = Environment.getDataDirectory(); 6749 File systemDir = new File(dataDir, "system"); 6750 File fname = new File(systemDir, "called_pre_boots.dat"); 6751 return fname; 6752 } 6753 6754 static final int LAST_DONE_VERSION = 10000; 6755 6756 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 6757 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 6758 File file = getCalledPreBootReceiversFile(); 6759 FileInputStream fis = null; 6760 try { 6761 fis = new FileInputStream(file); 6762 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 6763 int fvers = dis.readInt(); 6764 if (fvers == LAST_DONE_VERSION) { 6765 String vers = dis.readUTF(); 6766 String codename = dis.readUTF(); 6767 String build = dis.readUTF(); 6768 if (android.os.Build.VERSION.RELEASE.equals(vers) 6769 && android.os.Build.VERSION.CODENAME.equals(codename) 6770 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 6771 int num = dis.readInt(); 6772 while (num > 0) { 6773 num--; 6774 String pkg = dis.readUTF(); 6775 String cls = dis.readUTF(); 6776 lastDoneReceivers.add(new ComponentName(pkg, cls)); 6777 } 6778 } 6779 } 6780 } catch (FileNotFoundException e) { 6781 } catch (IOException e) { 6782 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 6783 } finally { 6784 if (fis != null) { 6785 try { 6786 fis.close(); 6787 } catch (IOException e) { 6788 } 6789 } 6790 } 6791 return lastDoneReceivers; 6792 } 6793 6794 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 6795 File file = getCalledPreBootReceiversFile(); 6796 FileOutputStream fos = null; 6797 DataOutputStream dos = null; 6798 try { 6799 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 6800 fos = new FileOutputStream(file); 6801 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 6802 dos.writeInt(LAST_DONE_VERSION); 6803 dos.writeUTF(android.os.Build.VERSION.RELEASE); 6804 dos.writeUTF(android.os.Build.VERSION.CODENAME); 6805 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 6806 dos.writeInt(list.size()); 6807 for (int i=0; i<list.size(); i++) { 6808 dos.writeUTF(list.get(i).getPackageName()); 6809 dos.writeUTF(list.get(i).getClassName()); 6810 } 6811 } catch (IOException e) { 6812 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 6813 file.delete(); 6814 } finally { 6815 FileUtils.sync(fos); 6816 if (dos != null) { 6817 try { 6818 dos.close(); 6819 } catch (IOException e) { 6820 // TODO Auto-generated catch block 6821 e.printStackTrace(); 6822 } 6823 } 6824 } 6825 } 6826 6827 public void systemReady(final Runnable goingCallback) { 6828 synchronized(this) { 6829 if (mSystemReady) { 6830 if (goingCallback != null) goingCallback.run(); 6831 return; 6832 } 6833 6834 // Check to see if there are any update receivers to run. 6835 if (!mDidUpdate) { 6836 if (mWaitingUpdate) { 6837 return; 6838 } 6839 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 6840 List<ResolveInfo> ris = null; 6841 try { 6842 ris = AppGlobals.getPackageManager().queryIntentReceivers( 6843 intent, null, 0); 6844 } catch (RemoteException e) { 6845 } 6846 if (ris != null) { 6847 for (int i=ris.size()-1; i>=0; i--) { 6848 if ((ris.get(i).activityInfo.applicationInfo.flags 6849 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6850 ris.remove(i); 6851 } 6852 } 6853 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 6854 6855 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 6856 6857 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 6858 for (int i=0; i<ris.size(); i++) { 6859 ActivityInfo ai = ris.get(i).activityInfo; 6860 ComponentName comp = new ComponentName(ai.packageName, ai.name); 6861 if (lastDoneReceivers.contains(comp)) { 6862 ris.remove(i); 6863 i--; 6864 } 6865 } 6866 6867 for (int i=0; i<ris.size(); i++) { 6868 ActivityInfo ai = ris.get(i).activityInfo; 6869 ComponentName comp = new ComponentName(ai.packageName, ai.name); 6870 doneReceivers.add(comp); 6871 intent.setComponent(comp); 6872 IIntentReceiver finisher = null; 6873 if (i == ris.size()-1) { 6874 finisher = new IIntentReceiver.Stub() { 6875 public void performReceive(Intent intent, int resultCode, 6876 String data, Bundle extras, boolean ordered, 6877 boolean sticky) { 6878 // The raw IIntentReceiver interface is called 6879 // with the AM lock held, so redispatch to 6880 // execute our code without the lock. 6881 mHandler.post(new Runnable() { 6882 public void run() { 6883 synchronized (ActivityManagerService.this) { 6884 mDidUpdate = true; 6885 } 6886 writeLastDonePreBootReceivers(doneReceivers); 6887 showBootMessage(mContext.getText( 6888 R.string.android_upgrading_complete), 6889 false); 6890 systemReady(goingCallback); 6891 } 6892 }); 6893 } 6894 }; 6895 } 6896 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 6897 broadcastIntentLocked(null, null, intent, null, finisher, 6898 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 6899 if (finisher != null) { 6900 mWaitingUpdate = true; 6901 } 6902 } 6903 } 6904 if (mWaitingUpdate) { 6905 return; 6906 } 6907 mDidUpdate = true; 6908 } 6909 6910 mSystemReady = true; 6911 if (!mStartRunning) { 6912 return; 6913 } 6914 } 6915 6916 ArrayList<ProcessRecord> procsToKill = null; 6917 synchronized(mPidsSelfLocked) { 6918 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 6919 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 6920 if (!isAllowedWhileBooting(proc.info)){ 6921 if (procsToKill == null) { 6922 procsToKill = new ArrayList<ProcessRecord>(); 6923 } 6924 procsToKill.add(proc); 6925 } 6926 } 6927 } 6928 6929 synchronized(this) { 6930 if (procsToKill != null) { 6931 for (int i=procsToKill.size()-1; i>=0; i--) { 6932 ProcessRecord proc = procsToKill.get(i); 6933 Slog.i(TAG, "Removing system update proc: " + proc); 6934 removeProcessLocked(proc, true, false, "system update done"); 6935 } 6936 } 6937 6938 // Now that we have cleaned up any update processes, we 6939 // are ready to start launching real processes and know that 6940 // we won't trample on them any more. 6941 mProcessesReady = true; 6942 } 6943 6944 Slog.i(TAG, "System now ready"); 6945 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 6946 SystemClock.uptimeMillis()); 6947 6948 synchronized(this) { 6949 // Make sure we have no pre-ready processes sitting around. 6950 6951 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 6952 ResolveInfo ri = mContext.getPackageManager() 6953 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 6954 STOCK_PM_FLAGS); 6955 CharSequence errorMsg = null; 6956 if (ri != null) { 6957 ActivityInfo ai = ri.activityInfo; 6958 ApplicationInfo app = ai.applicationInfo; 6959 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6960 mTopAction = Intent.ACTION_FACTORY_TEST; 6961 mTopData = null; 6962 mTopComponent = new ComponentName(app.packageName, 6963 ai.name); 6964 } else { 6965 errorMsg = mContext.getResources().getText( 6966 com.android.internal.R.string.factorytest_not_system); 6967 } 6968 } else { 6969 errorMsg = mContext.getResources().getText( 6970 com.android.internal.R.string.factorytest_no_action); 6971 } 6972 if (errorMsg != null) { 6973 mTopAction = null; 6974 mTopData = null; 6975 mTopComponent = null; 6976 Message msg = Message.obtain(); 6977 msg.what = SHOW_FACTORY_ERROR_MSG; 6978 msg.getData().putCharSequence("msg", errorMsg); 6979 mHandler.sendMessage(msg); 6980 } 6981 } 6982 } 6983 6984 retrieveSettings(); 6985 6986 if (goingCallback != null) goingCallback.run(); 6987 6988 synchronized (this) { 6989 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 6990 try { 6991 List apps = AppGlobals.getPackageManager(). 6992 getPersistentApplications(STOCK_PM_FLAGS); 6993 if (apps != null) { 6994 int N = apps.size(); 6995 int i; 6996 for (i=0; i<N; i++) { 6997 ApplicationInfo info 6998 = (ApplicationInfo)apps.get(i); 6999 if (info != null && 7000 !info.packageName.equals("android")) { 7001 addAppLocked(info); 7002 } 7003 } 7004 } 7005 } catch (RemoteException ex) { 7006 // pm is in same process, this will never happen. 7007 } 7008 } 7009 7010 // Start up initial activity. 7011 mBooting = true; 7012 7013 try { 7014 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7015 Message msg = Message.obtain(); 7016 msg.what = SHOW_UID_ERROR_MSG; 7017 mHandler.sendMessage(msg); 7018 } 7019 } catch (RemoteException e) { 7020 } 7021 7022 mMainStack.resumeTopActivityLocked(null); 7023 } 7024 } 7025 7026 private boolean makeAppCrashingLocked(ProcessRecord app, 7027 String shortMsg, String longMsg, String stackTrace) { 7028 app.crashing = true; 7029 app.crashingReport = generateProcessError(app, 7030 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7031 startAppProblemLocked(app); 7032 app.stopFreezingAllLocked(); 7033 return handleAppCrashLocked(app); 7034 } 7035 7036 private void makeAppNotRespondingLocked(ProcessRecord app, 7037 String activity, String shortMsg, String longMsg) { 7038 app.notResponding = true; 7039 app.notRespondingReport = generateProcessError(app, 7040 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7041 activity, shortMsg, longMsg, null); 7042 startAppProblemLocked(app); 7043 app.stopFreezingAllLocked(); 7044 } 7045 7046 /** 7047 * Generate a process error record, suitable for attachment to a ProcessRecord. 7048 * 7049 * @param app The ProcessRecord in which the error occurred. 7050 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7051 * ActivityManager.AppErrorStateInfo 7052 * @param activity The activity associated with the crash, if known. 7053 * @param shortMsg Short message describing the crash. 7054 * @param longMsg Long message describing the crash. 7055 * @param stackTrace Full crash stack trace, may be null. 7056 * 7057 * @return Returns a fully-formed AppErrorStateInfo record. 7058 */ 7059 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7060 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7061 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7062 7063 report.condition = condition; 7064 report.processName = app.processName; 7065 report.pid = app.pid; 7066 report.uid = app.info.uid; 7067 report.tag = activity; 7068 report.shortMsg = shortMsg; 7069 report.longMsg = longMsg; 7070 report.stackTrace = stackTrace; 7071 7072 return report; 7073 } 7074 7075 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7076 synchronized (this) { 7077 app.crashing = false; 7078 app.crashingReport = null; 7079 app.notResponding = false; 7080 app.notRespondingReport = null; 7081 if (app.anrDialog == fromDialog) { 7082 app.anrDialog = null; 7083 } 7084 if (app.waitDialog == fromDialog) { 7085 app.waitDialog = null; 7086 } 7087 if (app.pid > 0 && app.pid != MY_PID) { 7088 handleAppCrashLocked(app); 7089 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7090 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7091 app.processName, app.setAdj, "user's request after error"); 7092 Process.killProcessQuiet(app.pid); 7093 } 7094 } 7095 } 7096 7097 private boolean handleAppCrashLocked(ProcessRecord app) { 7098 long now = SystemClock.uptimeMillis(); 7099 7100 Long crashTime = mProcessCrashTimes.get(app.info.processName, 7101 app.info.uid); 7102 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7103 // This process loses! 7104 Slog.w(TAG, "Process " + app.info.processName 7105 + " has crashed too many times: killing!"); 7106 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7107 app.info.processName, app.info.uid); 7108 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7109 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7110 if (r.app == app) { 7111 Slog.w(TAG, " Force finishing activity " 7112 + r.intent.getComponent().flattenToShortString()); 7113 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7114 } 7115 } 7116 if (!app.persistent) { 7117 // We don't want to start this process again until the user 7118 // explicitly does so... but for persistent process, we really 7119 // need to keep it running. If a persistent process is actually 7120 // repeatedly crashing, then badness for everyone. 7121 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid, 7122 app.info.processName); 7123 mBadProcesses.put(app.info.processName, app.info.uid, now); 7124 app.bad = true; 7125 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 7126 app.removed = true; 7127 // Don't let services in this process be restarted and potentially 7128 // annoy the user repeatedly. Unless it is persistent, since those 7129 // processes run critical code. 7130 removeProcessLocked(app, false, false, "crash"); 7131 mMainStack.resumeTopActivityLocked(null); 7132 return false; 7133 } 7134 mMainStack.resumeTopActivityLocked(null); 7135 } else { 7136 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7137 if (r.app == app) { 7138 // If the top running activity is from this crashing 7139 // process, then terminate it to avoid getting in a loop. 7140 Slog.w(TAG, " Force finishing activity " 7141 + r.intent.getComponent().flattenToShortString()); 7142 int index = mMainStack.indexOfActivityLocked(r); 7143 r.stack.finishActivityLocked(r, index, 7144 Activity.RESULT_CANCELED, null, "crashed"); 7145 // Also terminate any activities below it that aren't yet 7146 // stopped, to avoid a situation where one will get 7147 // re-start our crashing activity once it gets resumed again. 7148 index--; 7149 if (index >= 0) { 7150 r = (ActivityRecord)mMainStack.mHistory.get(index); 7151 if (r.state == ActivityState.RESUMED 7152 || r.state == ActivityState.PAUSING 7153 || r.state == ActivityState.PAUSED) { 7154 if (!r.isHomeActivity || mHomeProcess != r.app) { 7155 Slog.w(TAG, " Force finishing activity " 7156 + r.intent.getComponent().flattenToShortString()); 7157 r.stack.finishActivityLocked(r, index, 7158 Activity.RESULT_CANCELED, null, "crashed"); 7159 } 7160 } 7161 } 7162 } 7163 } 7164 7165 // Bump up the crash count of any services currently running in the proc. 7166 if (app.services.size() != 0) { 7167 // Any services running in the application need to be placed 7168 // back in the pending list. 7169 Iterator<ServiceRecord> it = app.services.iterator(); 7170 while (it.hasNext()) { 7171 ServiceRecord sr = it.next(); 7172 sr.crashCount++; 7173 } 7174 } 7175 7176 // If the crashing process is what we consider to be the "home process" and it has been 7177 // replaced by a third-party app, clear the package preferred activities from packages 7178 // with a home activity running in the process to prevent a repeatedly crashing app 7179 // from blocking the user to manually clear the list. 7180 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7181 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7182 Iterator it = mHomeProcess.activities.iterator(); 7183 while (it.hasNext()) { 7184 ActivityRecord r = (ActivityRecord)it.next(); 7185 if (r.isHomeActivity) { 7186 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7187 try { 7188 ActivityThread.getPackageManager() 7189 .clearPackagePreferredActivities(r.packageName); 7190 } catch (RemoteException c) { 7191 // pm is in same process, this will never happen. 7192 } 7193 } 7194 } 7195 } 7196 7197 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 7198 return true; 7199 } 7200 7201 void startAppProblemLocked(ProcessRecord app) { 7202 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7203 mContext, app.info.packageName, app.info.flags); 7204 skipCurrentReceiverLocked(app); 7205 } 7206 7207 void skipCurrentReceiverLocked(ProcessRecord app) { 7208 boolean reschedule = false; 7209 BroadcastRecord r = app.curReceiver; 7210 if (r != null) { 7211 // The current broadcast is waiting for this app's receiver 7212 // to be finished. Looks like that's not going to happen, so 7213 // let the broadcast continue. 7214 logBroadcastReceiverDiscardLocked(r); 7215 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 7216 r.resultExtras, r.resultAbort, true); 7217 reschedule = true; 7218 } 7219 r = mPendingBroadcast; 7220 if (r != null && r.curApp == app) { 7221 if (DEBUG_BROADCAST) Slog.v(TAG, 7222 "skip & discard pending app " + r); 7223 logBroadcastReceiverDiscardLocked(r); 7224 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 7225 r.resultExtras, r.resultAbort, true); 7226 reschedule = true; 7227 } 7228 if (reschedule) { 7229 scheduleBroadcastsLocked(); 7230 } 7231 } 7232 7233 /** 7234 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7235 * The application process will exit immediately after this call returns. 7236 * @param app object of the crashing app, null for the system server 7237 * @param crashInfo describing the exception 7238 */ 7239 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7240 ProcessRecord r = findAppProcess(app, "Crash"); 7241 final String processName = app == null ? "system_server" 7242 : (r == null ? "unknown" : r.processName); 7243 7244 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7245 processName, 7246 r == null ? -1 : r.info.flags, 7247 crashInfo.exceptionClassName, 7248 crashInfo.exceptionMessage, 7249 crashInfo.throwFileName, 7250 crashInfo.throwLineNumber); 7251 7252 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7253 7254 crashApplication(r, crashInfo); 7255 } 7256 7257 public void handleApplicationStrictModeViolation( 7258 IBinder app, 7259 int violationMask, 7260 StrictMode.ViolationInfo info) { 7261 ProcessRecord r = findAppProcess(app, "StrictMode"); 7262 if (r == null) { 7263 return; 7264 } 7265 7266 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7267 Integer stackFingerprint = info.hashCode(); 7268 boolean logIt = true; 7269 synchronized (mAlreadyLoggedViolatedStacks) { 7270 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7271 logIt = false; 7272 // TODO: sub-sample into EventLog for these, with 7273 // the info.durationMillis? Then we'd get 7274 // the relative pain numbers, without logging all 7275 // the stack traces repeatedly. We'd want to do 7276 // likewise in the client code, which also does 7277 // dup suppression, before the Binder call. 7278 } else { 7279 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7280 mAlreadyLoggedViolatedStacks.clear(); 7281 } 7282 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7283 } 7284 } 7285 if (logIt) { 7286 logStrictModeViolationToDropBox(r, info); 7287 } 7288 } 7289 7290 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7291 AppErrorResult result = new AppErrorResult(); 7292 synchronized (this) { 7293 final long origId = Binder.clearCallingIdentity(); 7294 7295 Message msg = Message.obtain(); 7296 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7297 HashMap<String, Object> data = new HashMap<String, Object>(); 7298 data.put("result", result); 7299 data.put("app", r); 7300 data.put("violationMask", violationMask); 7301 data.put("info", info); 7302 msg.obj = data; 7303 mHandler.sendMessage(msg); 7304 7305 Binder.restoreCallingIdentity(origId); 7306 } 7307 int res = result.get(); 7308 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7309 } 7310 } 7311 7312 // Depending on the policy in effect, there could be a bunch of 7313 // these in quick succession so we try to batch these together to 7314 // minimize disk writes, number of dropbox entries, and maximize 7315 // compression, by having more fewer, larger records. 7316 private void logStrictModeViolationToDropBox( 7317 ProcessRecord process, 7318 StrictMode.ViolationInfo info) { 7319 if (info == null) { 7320 return; 7321 } 7322 final boolean isSystemApp = process == null || 7323 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7324 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7325 final String processName = process == null ? "unknown" : process.processName; 7326 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7327 final DropBoxManager dbox = (DropBoxManager) 7328 mContext.getSystemService(Context.DROPBOX_SERVICE); 7329 7330 // Exit early if the dropbox isn't configured to accept this report type. 7331 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7332 7333 boolean bufferWasEmpty; 7334 boolean needsFlush; 7335 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7336 synchronized (sb) { 7337 bufferWasEmpty = sb.length() == 0; 7338 appendDropBoxProcessHeaders(process, processName, sb); 7339 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7340 sb.append("System-App: ").append(isSystemApp).append("\n"); 7341 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7342 if (info.violationNumThisLoop != 0) { 7343 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7344 } 7345 if (info.numAnimationsRunning != 0) { 7346 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7347 } 7348 if (info.broadcastIntentAction != null) { 7349 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7350 } 7351 if (info.durationMillis != -1) { 7352 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7353 } 7354 if (info.numInstances != -1) { 7355 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7356 } 7357 if (info.tags != null) { 7358 for (String tag : info.tags) { 7359 sb.append("Span-Tag: ").append(tag).append("\n"); 7360 } 7361 } 7362 sb.append("\n"); 7363 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7364 sb.append(info.crashInfo.stackTrace); 7365 } 7366 sb.append("\n"); 7367 7368 // Only buffer up to ~64k. Various logging bits truncate 7369 // things at 128k. 7370 needsFlush = (sb.length() > 64 * 1024); 7371 } 7372 7373 // Flush immediately if the buffer's grown too large, or this 7374 // is a non-system app. Non-system apps are isolated with a 7375 // different tag & policy and not batched. 7376 // 7377 // Batching is useful during internal testing with 7378 // StrictMode settings turned up high. Without batching, 7379 // thousands of separate files could be created on boot. 7380 if (!isSystemApp || needsFlush) { 7381 new Thread("Error dump: " + dropboxTag) { 7382 @Override 7383 public void run() { 7384 String report; 7385 synchronized (sb) { 7386 report = sb.toString(); 7387 sb.delete(0, sb.length()); 7388 sb.trimToSize(); 7389 } 7390 if (report.length() != 0) { 7391 dbox.addText(dropboxTag, report); 7392 } 7393 } 7394 }.start(); 7395 return; 7396 } 7397 7398 // System app batching: 7399 if (!bufferWasEmpty) { 7400 // An existing dropbox-writing thread is outstanding, so 7401 // we don't need to start it up. The existing thread will 7402 // catch the buffer appends we just did. 7403 return; 7404 } 7405 7406 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7407 // (After this point, we shouldn't access AMS internal data structures.) 7408 new Thread("Error dump: " + dropboxTag) { 7409 @Override 7410 public void run() { 7411 // 5 second sleep to let stacks arrive and be batched together 7412 try { 7413 Thread.sleep(5000); // 5 seconds 7414 } catch (InterruptedException e) {} 7415 7416 String errorReport; 7417 synchronized (mStrictModeBuffer) { 7418 errorReport = mStrictModeBuffer.toString(); 7419 if (errorReport.length() == 0) { 7420 return; 7421 } 7422 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 7423 mStrictModeBuffer.trimToSize(); 7424 } 7425 dbox.addText(dropboxTag, errorReport); 7426 } 7427 }.start(); 7428 } 7429 7430 /** 7431 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 7432 * @param app object of the crashing app, null for the system server 7433 * @param tag reported by the caller 7434 * @param crashInfo describing the context of the error 7435 * @return true if the process should exit immediately (WTF is fatal) 7436 */ 7437 public boolean handleApplicationWtf(IBinder app, String tag, 7438 ApplicationErrorReport.CrashInfo crashInfo) { 7439 ProcessRecord r = findAppProcess(app, "WTF"); 7440 final String processName = app == null ? "system_server" 7441 : (r == null ? "unknown" : r.processName); 7442 7443 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 7444 processName, 7445 r == null ? -1 : r.info.flags, 7446 tag, crashInfo.exceptionMessage); 7447 7448 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 7449 7450 if (r != null && r.pid != Process.myPid() && 7451 Settings.Secure.getInt(mContext.getContentResolver(), 7452 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 7453 crashApplication(r, crashInfo); 7454 return true; 7455 } else { 7456 return false; 7457 } 7458 } 7459 7460 /** 7461 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 7462 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 7463 */ 7464 private ProcessRecord findAppProcess(IBinder app, String reason) { 7465 if (app == null) { 7466 return null; 7467 } 7468 7469 synchronized (this) { 7470 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 7471 final int NA = apps.size(); 7472 for (int ia=0; ia<NA; ia++) { 7473 ProcessRecord p = apps.valueAt(ia); 7474 if (p.thread != null && p.thread.asBinder() == app) { 7475 return p; 7476 } 7477 } 7478 } 7479 7480 Slog.w(TAG, "Can't find mystery application for " + reason 7481 + " from pid=" + Binder.getCallingPid() 7482 + " uid=" + Binder.getCallingUid() + ": " + app); 7483 return null; 7484 } 7485 } 7486 7487 /** 7488 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 7489 * to append various headers to the dropbox log text. 7490 */ 7491 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 7492 StringBuilder sb) { 7493 // Watchdog thread ends up invoking this function (with 7494 // a null ProcessRecord) to add the stack file to dropbox. 7495 // Do not acquire a lock on this (am) in such cases, as it 7496 // could cause a potential deadlock, if and when watchdog 7497 // is invoked due to unavailability of lock on am and it 7498 // would prevent watchdog from killing system_server. 7499 if (process == null) { 7500 sb.append("Process: ").append(processName).append("\n"); 7501 return; 7502 } 7503 // Note: ProcessRecord 'process' is guarded by the service 7504 // instance. (notably process.pkgList, which could otherwise change 7505 // concurrently during execution of this method) 7506 synchronized (this) { 7507 sb.append("Process: ").append(processName).append("\n"); 7508 int flags = process.info.flags; 7509 IPackageManager pm = AppGlobals.getPackageManager(); 7510 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 7511 for (String pkg : process.pkgList) { 7512 sb.append("Package: ").append(pkg); 7513 try { 7514 PackageInfo pi = pm.getPackageInfo(pkg, 0); 7515 if (pi != null) { 7516 sb.append(" v").append(pi.versionCode); 7517 if (pi.versionName != null) { 7518 sb.append(" (").append(pi.versionName).append(")"); 7519 } 7520 } 7521 } catch (RemoteException e) { 7522 Slog.e(TAG, "Error getting package info: " + pkg, e); 7523 } 7524 sb.append("\n"); 7525 } 7526 } 7527 } 7528 7529 private static String processClass(ProcessRecord process) { 7530 if (process == null || process.pid == MY_PID) { 7531 return "system_server"; 7532 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7533 return "system_app"; 7534 } else { 7535 return "data_app"; 7536 } 7537 } 7538 7539 /** 7540 * Write a description of an error (crash, WTF, ANR) to the drop box. 7541 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 7542 * @param process which caused the error, null means the system server 7543 * @param activity which triggered the error, null if unknown 7544 * @param parent activity related to the error, null if unknown 7545 * @param subject line related to the error, null if absent 7546 * @param report in long form describing the error, null if absent 7547 * @param logFile to include in the report, null if none 7548 * @param crashInfo giving an application stack trace, null if absent 7549 */ 7550 public void addErrorToDropBox(String eventType, 7551 ProcessRecord process, String processName, ActivityRecord activity, 7552 ActivityRecord parent, String subject, 7553 final String report, final File logFile, 7554 final ApplicationErrorReport.CrashInfo crashInfo) { 7555 // NOTE -- this must never acquire the ActivityManagerService lock, 7556 // otherwise the watchdog may be prevented from resetting the system. 7557 7558 final String dropboxTag = processClass(process) + "_" + eventType; 7559 final DropBoxManager dbox = (DropBoxManager) 7560 mContext.getSystemService(Context.DROPBOX_SERVICE); 7561 7562 // Exit early if the dropbox isn't configured to accept this report type. 7563 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7564 7565 final StringBuilder sb = new StringBuilder(1024); 7566 appendDropBoxProcessHeaders(process, processName, sb); 7567 if (activity != null) { 7568 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 7569 } 7570 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 7571 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 7572 } 7573 if (parent != null && parent != activity) { 7574 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 7575 } 7576 if (subject != null) { 7577 sb.append("Subject: ").append(subject).append("\n"); 7578 } 7579 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7580 if (Debug.isDebuggerConnected()) { 7581 sb.append("Debugger: Connected\n"); 7582 } 7583 sb.append("\n"); 7584 7585 // Do the rest in a worker thread to avoid blocking the caller on I/O 7586 // (After this point, we shouldn't access AMS internal data structures.) 7587 Thread worker = new Thread("Error dump: " + dropboxTag) { 7588 @Override 7589 public void run() { 7590 if (report != null) { 7591 sb.append(report); 7592 } 7593 if (logFile != null) { 7594 try { 7595 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 7596 } catch (IOException e) { 7597 Slog.e(TAG, "Error reading " + logFile, e); 7598 } 7599 } 7600 if (crashInfo != null && crashInfo.stackTrace != null) { 7601 sb.append(crashInfo.stackTrace); 7602 } 7603 7604 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 7605 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 7606 if (lines > 0) { 7607 sb.append("\n"); 7608 7609 // Merge several logcat streams, and take the last N lines 7610 InputStreamReader input = null; 7611 try { 7612 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 7613 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 7614 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 7615 7616 try { logcat.getOutputStream().close(); } catch (IOException e) {} 7617 try { logcat.getErrorStream().close(); } catch (IOException e) {} 7618 input = new InputStreamReader(logcat.getInputStream()); 7619 7620 int num; 7621 char[] buf = new char[8192]; 7622 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 7623 } catch (IOException e) { 7624 Slog.e(TAG, "Error running logcat", e); 7625 } finally { 7626 if (input != null) try { input.close(); } catch (IOException e) {} 7627 } 7628 } 7629 7630 dbox.addText(dropboxTag, sb.toString()); 7631 } 7632 }; 7633 7634 if (process == null || process.pid == MY_PID) { 7635 worker.run(); // We may be about to die -- need to run this synchronously 7636 } else { 7637 worker.start(); 7638 } 7639 } 7640 7641 /** 7642 * Bring up the "unexpected error" dialog box for a crashing app. 7643 * Deal with edge cases (intercepts from instrumented applications, 7644 * ActivityController, error intent receivers, that sort of thing). 7645 * @param r the application crashing 7646 * @param crashInfo describing the failure 7647 */ 7648 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 7649 long timeMillis = System.currentTimeMillis(); 7650 String shortMsg = crashInfo.exceptionClassName; 7651 String longMsg = crashInfo.exceptionMessage; 7652 String stackTrace = crashInfo.stackTrace; 7653 if (shortMsg != null && longMsg != null) { 7654 longMsg = shortMsg + ": " + longMsg; 7655 } else if (shortMsg != null) { 7656 longMsg = shortMsg; 7657 } 7658 7659 AppErrorResult result = new AppErrorResult(); 7660 synchronized (this) { 7661 if (mController != null) { 7662 try { 7663 String name = r != null ? r.processName : null; 7664 int pid = r != null ? r.pid : Binder.getCallingPid(); 7665 if (!mController.appCrashed(name, pid, 7666 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 7667 Slog.w(TAG, "Force-killing crashed app " + name 7668 + " at watcher's request"); 7669 Process.killProcess(pid); 7670 return; 7671 } 7672 } catch (RemoteException e) { 7673 mController = null; 7674 } 7675 } 7676 7677 final long origId = Binder.clearCallingIdentity(); 7678 7679 // If this process is running instrumentation, finish it. 7680 if (r != null && r.instrumentationClass != null) { 7681 Slog.w(TAG, "Error in app " + r.processName 7682 + " running instrumentation " + r.instrumentationClass + ":"); 7683 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 7684 if (longMsg != null) Slog.w(TAG, " " + longMsg); 7685 Bundle info = new Bundle(); 7686 info.putString("shortMsg", shortMsg); 7687 info.putString("longMsg", longMsg); 7688 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 7689 Binder.restoreCallingIdentity(origId); 7690 return; 7691 } 7692 7693 // If we can't identify the process or it's already exceeded its crash quota, 7694 // quit right away without showing a crash dialog. 7695 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 7696 Binder.restoreCallingIdentity(origId); 7697 return; 7698 } 7699 7700 Message msg = Message.obtain(); 7701 msg.what = SHOW_ERROR_MSG; 7702 HashMap data = new HashMap(); 7703 data.put("result", result); 7704 data.put("app", r); 7705 msg.obj = data; 7706 mHandler.sendMessage(msg); 7707 7708 Binder.restoreCallingIdentity(origId); 7709 } 7710 7711 int res = result.get(); 7712 7713 Intent appErrorIntent = null; 7714 synchronized (this) { 7715 if (r != null) { 7716 mProcessCrashTimes.put(r.info.processName, r.info.uid, 7717 SystemClock.uptimeMillis()); 7718 } 7719 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 7720 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 7721 } 7722 } 7723 7724 if (appErrorIntent != null) { 7725 try { 7726 mContext.startActivity(appErrorIntent); 7727 } catch (ActivityNotFoundException e) { 7728 Slog.w(TAG, "bug report receiver dissappeared", e); 7729 } 7730 } 7731 } 7732 7733 Intent createAppErrorIntentLocked(ProcessRecord r, 7734 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 7735 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 7736 if (report == null) { 7737 return null; 7738 } 7739 Intent result = new Intent(Intent.ACTION_APP_ERROR); 7740 result.setComponent(r.errorReportReceiver); 7741 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 7742 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7743 return result; 7744 } 7745 7746 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 7747 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 7748 if (r.errorReportReceiver == null) { 7749 return null; 7750 } 7751 7752 if (!r.crashing && !r.notResponding) { 7753 return null; 7754 } 7755 7756 ApplicationErrorReport report = new ApplicationErrorReport(); 7757 report.packageName = r.info.packageName; 7758 report.installerPackageName = r.errorReportReceiver.getPackageName(); 7759 report.processName = r.processName; 7760 report.time = timeMillis; 7761 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 7762 7763 if (r.crashing) { 7764 report.type = ApplicationErrorReport.TYPE_CRASH; 7765 report.crashInfo = crashInfo; 7766 } else if (r.notResponding) { 7767 report.type = ApplicationErrorReport.TYPE_ANR; 7768 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 7769 7770 report.anrInfo.activity = r.notRespondingReport.tag; 7771 report.anrInfo.cause = r.notRespondingReport.shortMsg; 7772 report.anrInfo.info = r.notRespondingReport.longMsg; 7773 } 7774 7775 return report; 7776 } 7777 7778 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 7779 // assume our apps are happy - lazy create the list 7780 List<ActivityManager.ProcessErrorStateInfo> errList = null; 7781 7782 synchronized (this) { 7783 7784 // iterate across all processes 7785 for (int i=mLruProcesses.size()-1; i>=0; i--) { 7786 ProcessRecord app = mLruProcesses.get(i); 7787 if ((app.thread != null) && (app.crashing || app.notResponding)) { 7788 // This one's in trouble, so we'll generate a report for it 7789 // crashes are higher priority (in case there's a crash *and* an anr) 7790 ActivityManager.ProcessErrorStateInfo report = null; 7791 if (app.crashing) { 7792 report = app.crashingReport; 7793 } else if (app.notResponding) { 7794 report = app.notRespondingReport; 7795 } 7796 7797 if (report != null) { 7798 if (errList == null) { 7799 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 7800 } 7801 errList.add(report); 7802 } else { 7803 Slog.w(TAG, "Missing app error report, app = " + app.processName + 7804 " crashing = " + app.crashing + 7805 " notResponding = " + app.notResponding); 7806 } 7807 } 7808 } 7809 } 7810 7811 return errList; 7812 } 7813 7814 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 7815 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 7816 if (currApp != null) { 7817 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 7818 } 7819 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 7820 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 7821 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 7822 } else if (adj >= ProcessList.HOME_APP_ADJ) { 7823 if (currApp != null) { 7824 currApp.lru = 0; 7825 } 7826 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 7827 } else if (adj >= ProcessList.SERVICE_ADJ) { 7828 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 7829 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 7830 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 7831 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 7832 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 7833 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 7834 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 7835 } else { 7836 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 7837 } 7838 } 7839 7840 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 7841 // Lazy instantiation of list 7842 List<ActivityManager.RunningAppProcessInfo> runList = null; 7843 synchronized (this) { 7844 // Iterate across all processes 7845 for (int i=mLruProcesses.size()-1; i>=0; i--) { 7846 ProcessRecord app = mLruProcesses.get(i); 7847 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 7848 // Generate process state info for running application 7849 ActivityManager.RunningAppProcessInfo currApp = 7850 new ActivityManager.RunningAppProcessInfo(app.processName, 7851 app.pid, app.getPackageList()); 7852 currApp.uid = app.info.uid; 7853 if (mHeavyWeightProcess == app) { 7854 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 7855 } 7856 if (app.persistent) { 7857 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 7858 } 7859 int adj = app.curAdj; 7860 currApp.importance = oomAdjToImportance(adj, currApp); 7861 currApp.importanceReasonCode = app.adjTypeCode; 7862 if (app.adjSource instanceof ProcessRecord) { 7863 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 7864 currApp.importanceReasonImportance = oomAdjToImportance( 7865 app.adjSourceOom, null); 7866 } else if (app.adjSource instanceof ActivityRecord) { 7867 ActivityRecord r = (ActivityRecord)app.adjSource; 7868 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 7869 } 7870 if (app.adjTarget instanceof ComponentName) { 7871 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 7872 } 7873 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 7874 // + " lru=" + currApp.lru); 7875 if (runList == null) { 7876 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 7877 } 7878 runList.add(currApp); 7879 } 7880 } 7881 } 7882 return runList; 7883 } 7884 7885 public List<ApplicationInfo> getRunningExternalApplications() { 7886 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 7887 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 7888 if (runningApps != null && runningApps.size() > 0) { 7889 Set<String> extList = new HashSet<String>(); 7890 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 7891 if (app.pkgList != null) { 7892 for (String pkg : app.pkgList) { 7893 extList.add(pkg); 7894 } 7895 } 7896 } 7897 IPackageManager pm = AppGlobals.getPackageManager(); 7898 for (String pkg : extList) { 7899 try { 7900 ApplicationInfo info = pm.getApplicationInfo(pkg, 0); 7901 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 7902 retList.add(info); 7903 } 7904 } catch (RemoteException e) { 7905 } 7906 } 7907 } 7908 return retList; 7909 } 7910 7911 @Override 7912 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 7913 if (checkCallingPermission(android.Manifest.permission.DUMP) 7914 != PackageManager.PERMISSION_GRANTED) { 7915 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 7916 + Binder.getCallingPid() 7917 + ", uid=" + Binder.getCallingUid() 7918 + " without permission " 7919 + android.Manifest.permission.DUMP); 7920 return; 7921 } 7922 7923 boolean dumpAll = false; 7924 boolean dumpClient = false; 7925 String dumpPackage = null; 7926 7927 int opti = 0; 7928 while (opti < args.length) { 7929 String opt = args[opti]; 7930 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 7931 break; 7932 } 7933 opti++; 7934 if ("-a".equals(opt)) { 7935 dumpAll = true; 7936 } else if ("-c".equals(opt)) { 7937 dumpClient = true; 7938 } else if ("-h".equals(opt)) { 7939 pw.println("Activity manager dump options:"); 7940 pw.println(" [-a] [-c] [-h] [cmd] ..."); 7941 pw.println(" cmd may be one of:"); 7942 pw.println(" a[ctivities]: activity stack state"); 7943 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 7944 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 7945 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 7946 pw.println(" o[om]: out of memory management"); 7947 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 7948 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 7949 pw.println(" service [COMP_SPEC]: service client-side state"); 7950 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 7951 pw.println(" all: dump all activities"); 7952 pw.println(" top: dump the top activity"); 7953 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 7954 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 7955 pw.println(" a partial substring in a component name, a"); 7956 pw.println(" hex object identifier."); 7957 pw.println(" -a: include all available server state."); 7958 pw.println(" -c: include client state."); 7959 return; 7960 } else { 7961 pw.println("Unknown argument: " + opt + "; use -h for help"); 7962 } 7963 } 7964 7965 // Is the caller requesting to dump a particular piece of data? 7966 if (opti < args.length) { 7967 String cmd = args[opti]; 7968 opti++; 7969 if ("activities".equals(cmd) || "a".equals(cmd)) { 7970 synchronized (this) { 7971 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 7972 } 7973 return; 7974 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 7975 String[] newArgs; 7976 String name; 7977 if (opti >= args.length) { 7978 name = null; 7979 newArgs = EMPTY_STRING_ARRAY; 7980 } else { 7981 name = args[opti]; 7982 opti++; 7983 newArgs = new String[args.length - opti]; 7984 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 7985 args.length - opti); 7986 } 7987 synchronized (this) { 7988 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 7989 } 7990 return; 7991 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 7992 String[] newArgs; 7993 String name; 7994 if (opti >= args.length) { 7995 name = null; 7996 newArgs = EMPTY_STRING_ARRAY; 7997 } else { 7998 name = args[opti]; 7999 opti++; 8000 newArgs = new String[args.length - opti]; 8001 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8002 args.length - opti); 8003 } 8004 synchronized (this) { 8005 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8006 } 8007 return; 8008 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8009 String[] newArgs; 8010 String name; 8011 if (opti >= args.length) { 8012 name = null; 8013 newArgs = EMPTY_STRING_ARRAY; 8014 } else { 8015 name = args[opti]; 8016 opti++; 8017 newArgs = new String[args.length - opti]; 8018 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8019 args.length - opti); 8020 } 8021 synchronized (this) { 8022 dumpProcessesLocked(fd, pw, args, opti, true, name); 8023 } 8024 return; 8025 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8026 synchronized (this) { 8027 dumpOomLocked(fd, pw, args, opti, true); 8028 } 8029 return; 8030 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8031 synchronized (this) { 8032 dumpProvidersLocked(fd, pw, args, opti, true, null); 8033 } 8034 return; 8035 } else if ("service".equals(cmd)) { 8036 String[] newArgs; 8037 String name; 8038 if (opti >= args.length) { 8039 name = null; 8040 newArgs = EMPTY_STRING_ARRAY; 8041 } else { 8042 name = args[opti]; 8043 opti++; 8044 newArgs = new String[args.length - opti]; 8045 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8046 args.length - opti); 8047 } 8048 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8049 pw.println("No services match: " + name); 8050 pw.println("Use -h for help."); 8051 } 8052 return; 8053 } else if ("package".equals(cmd)) { 8054 String[] newArgs; 8055 if (opti >= args.length) { 8056 pw.println("package: no package name specified"); 8057 pw.println("Use -h for help."); 8058 return; 8059 } else { 8060 dumpPackage = args[opti]; 8061 opti++; 8062 newArgs = new String[args.length - opti]; 8063 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8064 args.length - opti); 8065 args = newArgs; 8066 opti = 0; 8067 } 8068 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8069 synchronized (this) { 8070 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8071 } 8072 return; 8073 } else { 8074 // Dumping a single activity? 8075 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8076 pw.println("Bad activity command, or no activities match: " + cmd); 8077 pw.println("Use -h for help."); 8078 } 8079 return; 8080 } 8081 } 8082 8083 // No piece of data specified, dump everything. 8084 synchronized (this) { 8085 boolean needSep; 8086 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8087 if (needSep) { 8088 pw.println(" "); 8089 } 8090 if (dumpAll) { 8091 pw.println("-------------------------------------------------------------------------------"); 8092 } 8093 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8094 if (needSep) { 8095 pw.println(" "); 8096 } 8097 if (dumpAll) { 8098 pw.println("-------------------------------------------------------------------------------"); 8099 } 8100 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8101 if (needSep) { 8102 pw.println(" "); 8103 } 8104 if (dumpAll) { 8105 pw.println("-------------------------------------------------------------------------------"); 8106 } 8107 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8108 if (needSep) { 8109 pw.println(" "); 8110 } 8111 if (dumpAll) { 8112 pw.println("-------------------------------------------------------------------------------"); 8113 } 8114 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8115 if (needSep) { 8116 pw.println(" "); 8117 } 8118 if (dumpAll) { 8119 pw.println("-------------------------------------------------------------------------------"); 8120 } 8121 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8122 } 8123 } 8124 8125 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8126 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8127 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8128 pw.println(" Main stack:"); 8129 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8130 dumpPackage); 8131 pw.println(" "); 8132 pw.println(" Running activities (most recent first):"); 8133 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8134 dumpPackage); 8135 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8136 pw.println(" "); 8137 pw.println(" Activities waiting for another to become visible:"); 8138 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8139 !dumpAll, false, dumpPackage); 8140 } 8141 if (mMainStack.mStoppingActivities.size() > 0) { 8142 pw.println(" "); 8143 pw.println(" Activities waiting to stop:"); 8144 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8145 !dumpAll, false, dumpPackage); 8146 } 8147 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8148 pw.println(" "); 8149 pw.println(" Activities waiting to sleep:"); 8150 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8151 !dumpAll, false, dumpPackage); 8152 } 8153 if (mMainStack.mFinishingActivities.size() > 0) { 8154 pw.println(" "); 8155 pw.println(" Activities waiting to finish:"); 8156 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8157 !dumpAll, false, dumpPackage); 8158 } 8159 8160 pw.println(" "); 8161 if (mMainStack.mPausingActivity != null) { 8162 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8163 } 8164 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8165 pw.println(" mFocusedActivity: " + mFocusedActivity); 8166 if (dumpAll) { 8167 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8168 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8169 pw.println(" mDismissKeyguardOnNextActivity: " 8170 + mMainStack.mDismissKeyguardOnNextActivity); 8171 } 8172 8173 if (mRecentTasks.size() > 0) { 8174 pw.println(); 8175 pw.println(" Recent tasks:"); 8176 8177 final int N = mRecentTasks.size(); 8178 for (int i=0; i<N; i++) { 8179 TaskRecord tr = mRecentTasks.get(i); 8180 if (dumpPackage != null) { 8181 if (tr.realActivity == null || 8182 !dumpPackage.equals(tr.realActivity)) { 8183 continue; 8184 } 8185 } 8186 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8187 pw.println(tr); 8188 if (dumpAll) { 8189 mRecentTasks.get(i).dump(pw, " "); 8190 } 8191 } 8192 } 8193 8194 if (dumpAll) { 8195 pw.println(" "); 8196 pw.println(" mCurTask: " + mCurTask); 8197 } 8198 8199 return true; 8200 } 8201 8202 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8203 int opti, boolean dumpAll, String dumpPackage) { 8204 boolean needSep = false; 8205 int numPers = 0; 8206 8207 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8208 8209 if (dumpAll) { 8210 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8211 final int NA = procs.size(); 8212 for (int ia=0; ia<NA; ia++) { 8213 ProcessRecord r = procs.valueAt(ia); 8214 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8215 continue; 8216 } 8217 if (!needSep) { 8218 pw.println(" All known processes:"); 8219 needSep = true; 8220 } 8221 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8222 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8223 pw.print(" "); pw.println(r); 8224 r.dump(pw, " "); 8225 if (r.persistent) { 8226 numPers++; 8227 } 8228 } 8229 } 8230 } 8231 8232 if (mLruProcesses.size() > 0) { 8233 if (needSep) pw.println(" "); 8234 needSep = true; 8235 pw.println(" Process LRU list (sorted by oom_adj):"); 8236 dumpProcessOomList(pw, this, mLruProcesses, " ", 8237 "Proc", "PERS", false, dumpPackage); 8238 needSep = true; 8239 } 8240 8241 if (dumpAll) { 8242 synchronized (mPidsSelfLocked) { 8243 boolean printed = false; 8244 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8245 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8246 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8247 continue; 8248 } 8249 if (!printed) { 8250 if (needSep) pw.println(" "); 8251 needSep = true; 8252 pw.println(" PID mappings:"); 8253 printed = true; 8254 } 8255 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8256 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8257 } 8258 } 8259 } 8260 8261 if (mForegroundProcesses.size() > 0) { 8262 synchronized (mPidsSelfLocked) { 8263 boolean printed = false; 8264 for (int i=0; i<mForegroundProcesses.size(); i++) { 8265 ProcessRecord r = mPidsSelfLocked.get( 8266 mForegroundProcesses.valueAt(i).pid); 8267 if (dumpPackage != null && (r == null 8268 || !dumpPackage.equals(r.info.packageName))) { 8269 continue; 8270 } 8271 if (!printed) { 8272 if (needSep) pw.println(" "); 8273 needSep = true; 8274 pw.println(" Foreground Processes:"); 8275 printed = true; 8276 } 8277 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8278 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8279 } 8280 } 8281 } 8282 8283 if (mPersistentStartingProcesses.size() > 0) { 8284 if (needSep) pw.println(" "); 8285 needSep = true; 8286 pw.println(" Persisent processes that are starting:"); 8287 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8288 "Starting Norm", "Restarting PERS", dumpPackage); 8289 } 8290 8291 if (mRemovedProcesses.size() > 0) { 8292 if (needSep) pw.println(" "); 8293 needSep = true; 8294 pw.println(" Processes that are being removed:"); 8295 dumpProcessList(pw, this, mRemovedProcesses, " ", 8296 "Removed Norm", "Removed PERS", dumpPackage); 8297 } 8298 8299 if (mProcessesOnHold.size() > 0) { 8300 if (needSep) pw.println(" "); 8301 needSep = true; 8302 pw.println(" Processes that are on old until the system is ready:"); 8303 dumpProcessList(pw, this, mProcessesOnHold, " ", 8304 "OnHold Norm", "OnHold PERS", dumpPackage); 8305 } 8306 8307 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8308 8309 if (mProcessCrashTimes.getMap().size() > 0) { 8310 boolean printed = false; 8311 long now = SystemClock.uptimeMillis(); 8312 for (Map.Entry<String, SparseArray<Long>> procs 8313 : mProcessCrashTimes.getMap().entrySet()) { 8314 String pname = procs.getKey(); 8315 SparseArray<Long> uids = procs.getValue(); 8316 final int N = uids.size(); 8317 for (int i=0; i<N; i++) { 8318 int puid = uids.keyAt(i); 8319 ProcessRecord r = mProcessNames.get(pname, puid); 8320 if (dumpPackage != null && (r == null 8321 || !dumpPackage.equals(r.info.packageName))) { 8322 continue; 8323 } 8324 if (!printed) { 8325 if (needSep) pw.println(" "); 8326 needSep = true; 8327 pw.println(" Time since processes crashed:"); 8328 printed = true; 8329 } 8330 pw.print(" Process "); pw.print(pname); 8331 pw.print(" uid "); pw.print(puid); 8332 pw.print(": last crashed "); 8333 pw.print((now-uids.valueAt(i))); 8334 pw.println(" ms ago"); 8335 } 8336 } 8337 } 8338 8339 if (mBadProcesses.getMap().size() > 0) { 8340 boolean printed = false; 8341 for (Map.Entry<String, SparseArray<Long>> procs 8342 : mBadProcesses.getMap().entrySet()) { 8343 String pname = procs.getKey(); 8344 SparseArray<Long> uids = procs.getValue(); 8345 final int N = uids.size(); 8346 for (int i=0; i<N; i++) { 8347 int puid = uids.keyAt(i); 8348 ProcessRecord r = mProcessNames.get(pname, puid); 8349 if (dumpPackage != null && (r == null 8350 || !dumpPackage.equals(r.info.packageName))) { 8351 continue; 8352 } 8353 if (!printed) { 8354 if (needSep) pw.println(" "); 8355 needSep = true; 8356 pw.println(" Bad processes:"); 8357 } 8358 pw.print(" Bad process "); pw.print(pname); 8359 pw.print(" uid "); pw.print(puid); 8360 pw.print(": crashed at time "); 8361 pw.println(uids.valueAt(i)); 8362 } 8363 } 8364 } 8365 8366 pw.println(); 8367 pw.println(" mHomeProcess: " + mHomeProcess); 8368 pw.println(" mPreviousProcess: " + mPreviousProcess); 8369 if (dumpAll) { 8370 StringBuilder sb = new StringBuilder(128); 8371 sb.append(" mPreviousProcessVisibleTime: "); 8372 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 8373 pw.println(sb); 8374 } 8375 if (mHeavyWeightProcess != null) { 8376 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8377 } 8378 pw.println(" mConfiguration: " + mConfiguration); 8379 if (dumpAll) { 8380 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 8381 if (mCompatModePackages.getPackages().size() > 0) { 8382 boolean printed = false; 8383 for (Map.Entry<String, Integer> entry 8384 : mCompatModePackages.getPackages().entrySet()) { 8385 String pkg = entry.getKey(); 8386 int mode = entry.getValue(); 8387 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 8388 continue; 8389 } 8390 if (!printed) { 8391 pw.println(" mScreenCompatPackages:"); 8392 printed = true; 8393 } 8394 pw.print(" "); pw.print(pkg); pw.print(": "); 8395 pw.print(mode); pw.println(); 8396 } 8397 } 8398 } 8399 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 8400 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 8401 || mOrigWaitForDebugger) { 8402 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 8403 + " mDebugTransient=" + mDebugTransient 8404 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 8405 } 8406 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 8407 || mProfileFd != null) { 8408 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 8409 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 8410 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 8411 + mAutoStopProfiler); 8412 } 8413 if (mAlwaysFinishActivities || mController != null) { 8414 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 8415 + " mController=" + mController); 8416 } 8417 if (dumpAll) { 8418 pw.println(" Total persistent processes: " + numPers); 8419 pw.println(" mStartRunning=" + mStartRunning 8420 + " mProcessesReady=" + mProcessesReady 8421 + " mSystemReady=" + mSystemReady); 8422 pw.println(" mBooting=" + mBooting 8423 + " mBooted=" + mBooted 8424 + " mFactoryTest=" + mFactoryTest); 8425 pw.print(" mLastPowerCheckRealtime="); 8426 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 8427 pw.println(""); 8428 pw.print(" mLastPowerCheckUptime="); 8429 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 8430 pw.println(""); 8431 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 8432 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 8433 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 8434 pw.println(" mNumServiceProcs=" + mNumServiceProcs 8435 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 8436 } 8437 8438 return true; 8439 } 8440 8441 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 8442 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 8443 if (mProcessesToGc.size() > 0) { 8444 boolean printed = false; 8445 long now = SystemClock.uptimeMillis(); 8446 for (int i=0; i<mProcessesToGc.size(); i++) { 8447 ProcessRecord proc = mProcessesToGc.get(i); 8448 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 8449 continue; 8450 } 8451 if (!printed) { 8452 if (needSep) pw.println(" "); 8453 needSep = true; 8454 pw.println(" Processes that are waiting to GC:"); 8455 printed = true; 8456 } 8457 pw.print(" Process "); pw.println(proc); 8458 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 8459 pw.print(", last gced="); 8460 pw.print(now-proc.lastRequestedGc); 8461 pw.print(" ms ago, last lowMem="); 8462 pw.print(now-proc.lastLowMemory); 8463 pw.println(" ms ago"); 8464 8465 } 8466 } 8467 return needSep; 8468 } 8469 8470 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8471 int opti, boolean dumpAll) { 8472 boolean needSep = false; 8473 8474 if (mLruProcesses.size() > 0) { 8475 if (needSep) pw.println(" "); 8476 needSep = true; 8477 pw.println(" OOM levels:"); 8478 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 8479 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 8480 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 8481 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 8482 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 8483 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 8484 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 8485 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 8486 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 8487 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 8488 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 8489 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 8490 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 8491 8492 if (needSep) pw.println(" "); 8493 needSep = true; 8494 pw.println(" Process OOM control:"); 8495 dumpProcessOomList(pw, this, mLruProcesses, " ", 8496 "Proc", "PERS", true, null); 8497 needSep = true; 8498 } 8499 8500 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 8501 8502 pw.println(); 8503 pw.println(" mHomeProcess: " + mHomeProcess); 8504 pw.println(" mPreviousProcess: " + mPreviousProcess); 8505 if (mHeavyWeightProcess != null) { 8506 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8507 } 8508 8509 return true; 8510 } 8511 8512 /** 8513 * There are three ways to call this: 8514 * - no service specified: dump all the services 8515 * - a flattened component name that matched an existing service was specified as the 8516 * first arg: dump that one service 8517 * - the first arg isn't the flattened component name of an existing service: 8518 * dump all services whose component contains the first arg as a substring 8519 */ 8520 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 8521 int opti, boolean dumpAll) { 8522 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 8523 8524 if ("all".equals(name)) { 8525 synchronized (this) { 8526 for (ServiceRecord r1 : mServices.values()) { 8527 services.add(r1); 8528 } 8529 } 8530 } else { 8531 ComponentName componentName = name != null 8532 ? ComponentName.unflattenFromString(name) : null; 8533 int objectId = 0; 8534 if (componentName == null) { 8535 // Not a '/' separated full component name; maybe an object ID? 8536 try { 8537 objectId = Integer.parseInt(name, 16); 8538 name = null; 8539 componentName = null; 8540 } catch (RuntimeException e) { 8541 } 8542 } 8543 8544 synchronized (this) { 8545 for (ServiceRecord r1 : mServices.values()) { 8546 if (componentName != null) { 8547 if (r1.name.equals(componentName)) { 8548 services.add(r1); 8549 } 8550 } else if (name != null) { 8551 if (r1.name.flattenToString().contains(name)) { 8552 services.add(r1); 8553 } 8554 } else if (System.identityHashCode(r1) == objectId) { 8555 services.add(r1); 8556 } 8557 } 8558 } 8559 } 8560 8561 if (services.size() <= 0) { 8562 return false; 8563 } 8564 8565 boolean needSep = false; 8566 for (int i=0; i<services.size(); i++) { 8567 if (needSep) { 8568 pw.println(); 8569 } 8570 needSep = true; 8571 dumpService("", fd, pw, services.get(i), args, dumpAll); 8572 } 8573 return true; 8574 } 8575 8576 /** 8577 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 8578 * there is a thread associated with the service. 8579 */ 8580 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 8581 final ServiceRecord r, String[] args, boolean dumpAll) { 8582 String innerPrefix = prefix + " "; 8583 synchronized (this) { 8584 pw.print(prefix); pw.print("SERVICE "); 8585 pw.print(r.shortName); pw.print(" "); 8586 pw.print(Integer.toHexString(System.identityHashCode(r))); 8587 pw.print(" pid="); 8588 if (r.app != null) pw.println(r.app.pid); 8589 else pw.println("(not running)"); 8590 if (dumpAll) { 8591 r.dump(pw, innerPrefix); 8592 } 8593 } 8594 if (r.app != null && r.app.thread != null) { 8595 pw.print(prefix); pw.println(" Client:"); 8596 pw.flush(); 8597 try { 8598 TransferPipe tp = new TransferPipe(); 8599 try { 8600 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 8601 tp.setBufferPrefix(prefix + " "); 8602 tp.go(fd); 8603 } finally { 8604 tp.kill(); 8605 } 8606 } catch (IOException e) { 8607 pw.println(prefix + " Failure while dumping the service: " + e); 8608 } catch (RemoteException e) { 8609 pw.println(prefix + " Got a RemoteException while dumping the service"); 8610 } 8611 } 8612 } 8613 8614 static class ItemMatcher { 8615 ArrayList<ComponentName> components; 8616 ArrayList<String> strings; 8617 ArrayList<Integer> objects; 8618 boolean all; 8619 8620 ItemMatcher() { 8621 all = true; 8622 } 8623 8624 void build(String name) { 8625 ComponentName componentName = ComponentName.unflattenFromString(name); 8626 if (componentName != null) { 8627 if (components == null) { 8628 components = new ArrayList<ComponentName>(); 8629 } 8630 components.add(componentName); 8631 all = false; 8632 } else { 8633 int objectId = 0; 8634 // Not a '/' separated full component name; maybe an object ID? 8635 try { 8636 objectId = Integer.parseInt(name, 16); 8637 if (objects == null) { 8638 objects = new ArrayList<Integer>(); 8639 } 8640 objects.add(objectId); 8641 all = false; 8642 } catch (RuntimeException e) { 8643 // Not an integer; just do string match. 8644 if (strings == null) { 8645 strings = new ArrayList<String>(); 8646 } 8647 strings.add(name); 8648 all = false; 8649 } 8650 } 8651 } 8652 8653 int build(String[] args, int opti) { 8654 for (; opti<args.length; opti++) { 8655 String name = args[opti]; 8656 if ("--".equals(name)) { 8657 return opti+1; 8658 } 8659 build(name); 8660 } 8661 return opti; 8662 } 8663 8664 boolean match(Object object, ComponentName comp) { 8665 if (all) { 8666 return true; 8667 } 8668 if (components != null) { 8669 for (int i=0; i<components.size(); i++) { 8670 if (components.get(i).equals(comp)) { 8671 return true; 8672 } 8673 } 8674 } 8675 if (objects != null) { 8676 for (int i=0; i<objects.size(); i++) { 8677 if (System.identityHashCode(object) == objects.get(i)) { 8678 return true; 8679 } 8680 } 8681 } 8682 if (strings != null) { 8683 String flat = comp.flattenToString(); 8684 for (int i=0; i<strings.size(); i++) { 8685 if (flat.contains(strings.get(i))) { 8686 return true; 8687 } 8688 } 8689 } 8690 return false; 8691 } 8692 } 8693 8694 /** 8695 * There are three things that cmd can be: 8696 * - a flattened component name that matches an existing activity 8697 * - the cmd arg isn't the flattened component name of an existing activity: 8698 * dump all activity whose component contains the cmd as a substring 8699 * - A hex number of the ActivityRecord object instance. 8700 */ 8701 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 8702 int opti, boolean dumpAll) { 8703 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 8704 8705 if ("all".equals(name)) { 8706 synchronized (this) { 8707 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 8708 activities.add(r1); 8709 } 8710 } 8711 } else if ("top".equals(name)) { 8712 synchronized (this) { 8713 final int N = mMainStack.mHistory.size(); 8714 if (N > 0) { 8715 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 8716 } 8717 } 8718 } else { 8719 ItemMatcher matcher = new ItemMatcher(); 8720 matcher.build(name); 8721 8722 synchronized (this) { 8723 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 8724 if (matcher.match(r1, r1.intent.getComponent())) { 8725 activities.add(r1); 8726 } 8727 } 8728 } 8729 } 8730 8731 if (activities.size() <= 0) { 8732 return false; 8733 } 8734 8735 String[] newArgs = new String[args.length - opti]; 8736 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8737 8738 TaskRecord lastTask = null; 8739 boolean needSep = false; 8740 for (int i=activities.size()-1; i>=0; i--) { 8741 ActivityRecord r = (ActivityRecord)activities.get(i); 8742 if (needSep) { 8743 pw.println(); 8744 } 8745 needSep = true; 8746 synchronized (this) { 8747 if (lastTask != r.task) { 8748 lastTask = r.task; 8749 pw.print("TASK "); pw.print(lastTask.affinity); 8750 pw.print(" id="); pw.println(lastTask.taskId); 8751 if (dumpAll) { 8752 lastTask.dump(pw, " "); 8753 } 8754 } 8755 } 8756 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 8757 } 8758 return true; 8759 } 8760 8761 /** 8762 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 8763 * there is a thread associated with the activity. 8764 */ 8765 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 8766 final ActivityRecord r, String[] args, boolean dumpAll) { 8767 String innerPrefix = prefix + " "; 8768 synchronized (this) { 8769 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 8770 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 8771 pw.print(" pid="); 8772 if (r.app != null) pw.println(r.app.pid); 8773 else pw.println("(not running)"); 8774 if (dumpAll) { 8775 r.dump(pw, innerPrefix); 8776 } 8777 } 8778 if (r.app != null && r.app.thread != null) { 8779 // flush anything that is already in the PrintWriter since the thread is going 8780 // to write to the file descriptor directly 8781 pw.flush(); 8782 try { 8783 TransferPipe tp = new TransferPipe(); 8784 try { 8785 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 8786 r.appToken, innerPrefix, args); 8787 tp.go(fd); 8788 } finally { 8789 tp.kill(); 8790 } 8791 } catch (IOException e) { 8792 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 8793 } catch (RemoteException e) { 8794 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 8795 } 8796 } 8797 } 8798 8799 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8800 int opti, boolean dumpAll, String dumpPackage) { 8801 boolean needSep = false; 8802 8803 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 8804 if (dumpAll) { 8805 if (mRegisteredReceivers.size() > 0) { 8806 boolean printed = false; 8807 Iterator it = mRegisteredReceivers.values().iterator(); 8808 while (it.hasNext()) { 8809 ReceiverList r = (ReceiverList)it.next(); 8810 if (dumpPackage != null && (r.app == null || 8811 !dumpPackage.equals(r.app.info.packageName))) { 8812 continue; 8813 } 8814 if (!printed) { 8815 pw.println(" Registered Receivers:"); 8816 needSep = true; 8817 printed = true; 8818 } 8819 pw.print(" * "); pw.println(r); 8820 r.dump(pw, " "); 8821 } 8822 } 8823 8824 if (mReceiverResolver.dump(pw, needSep ? 8825 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 8826 " ", dumpPackage, false)) { 8827 needSep = true; 8828 } 8829 } 8830 8831 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 8832 || mPendingBroadcast != null) { 8833 boolean printed = false; 8834 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 8835 BroadcastRecord br = mParallelBroadcasts.get(i); 8836 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) { 8837 continue; 8838 } 8839 if (!printed) { 8840 if (needSep) { 8841 pw.println(); 8842 } 8843 needSep = true; 8844 pw.println(" Active broadcasts:"); 8845 } 8846 pw.println(" Broadcast #" + i + ":"); 8847 br.dump(pw, " "); 8848 } 8849 printed = false; 8850 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 8851 BroadcastRecord br = mOrderedBroadcasts.get(i); 8852 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) { 8853 continue; 8854 } 8855 if (!printed) { 8856 if (needSep) { 8857 pw.println(); 8858 } 8859 needSep = true; 8860 pw.println(" Active ordered broadcasts:"); 8861 } 8862 pw.println(" Ordered Broadcast #" + i + ":"); 8863 mOrderedBroadcasts.get(i).dump(pw, " "); 8864 } 8865 if (dumpPackage == null || (mPendingBroadcast != null 8866 && dumpPackage.equals(mPendingBroadcast.callerPackage))) { 8867 if (needSep) { 8868 pw.println(); 8869 } 8870 pw.println(" Pending broadcast:"); 8871 if (mPendingBroadcast != null) { 8872 mPendingBroadcast.dump(pw, " "); 8873 } else { 8874 pw.println(" (null)"); 8875 } 8876 needSep = true; 8877 } 8878 } 8879 8880 boolean printed = false; 8881 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 8882 BroadcastRecord r = mBroadcastHistory[i]; 8883 if (r == null) { 8884 break; 8885 } 8886 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) { 8887 continue; 8888 } 8889 if (!printed) { 8890 if (needSep) { 8891 pw.println(); 8892 } 8893 needSep = true; 8894 pw.println(" Historical broadcasts:"); 8895 printed = true; 8896 } 8897 if (dumpAll) { 8898 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":"); 8899 r.dump(pw, " "); 8900 } else { 8901 if (i >= 50) { 8902 pw.println(" ..."); 8903 break; 8904 } 8905 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r); 8906 } 8907 } 8908 needSep = true; 8909 8910 if (mStickyBroadcasts != null && dumpPackage == null) { 8911 if (needSep) { 8912 pw.println(); 8913 } 8914 needSep = true; 8915 pw.println(" Sticky broadcasts:"); 8916 StringBuilder sb = new StringBuilder(128); 8917 for (Map.Entry<String, ArrayList<Intent>> ent 8918 : mStickyBroadcasts.entrySet()) { 8919 pw.print(" * Sticky action "); pw.print(ent.getKey()); 8920 if (dumpAll) { 8921 pw.println(":"); 8922 ArrayList<Intent> intents = ent.getValue(); 8923 final int N = intents.size(); 8924 for (int i=0; i<N; i++) { 8925 sb.setLength(0); 8926 sb.append(" Intent: "); 8927 intents.get(i).toShortString(sb, false, true, false); 8928 pw.println(sb.toString()); 8929 Bundle bundle = intents.get(i).getExtras(); 8930 if (bundle != null) { 8931 pw.print(" "); 8932 pw.println(bundle.toString()); 8933 } 8934 } 8935 } else { 8936 pw.println(""); 8937 } 8938 } 8939 needSep = true; 8940 } 8941 8942 if (dumpAll) { 8943 pw.println(); 8944 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 8945 pw.println(" mHandler:"); 8946 mHandler.dump(new PrintWriterPrinter(pw), " "); 8947 needSep = true; 8948 } 8949 8950 return needSep; 8951 } 8952 8953 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8954 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8955 boolean needSep = false; 8956 8957 ItemMatcher matcher = new ItemMatcher(); 8958 matcher.build(args, opti); 8959 8960 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 8961 if (mServices.size() > 0) { 8962 boolean printed = false; 8963 long nowReal = SystemClock.elapsedRealtime(); 8964 Iterator<ServiceRecord> it = mServices.values().iterator(); 8965 needSep = false; 8966 while (it.hasNext()) { 8967 ServiceRecord r = it.next(); 8968 if (!matcher.match(r, r.name)) { 8969 continue; 8970 } 8971 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 8972 continue; 8973 } 8974 if (!printed) { 8975 pw.println(" Active services:"); 8976 printed = true; 8977 } 8978 if (needSep) { 8979 pw.println(); 8980 } 8981 pw.print(" * "); pw.println(r); 8982 if (dumpAll) { 8983 r.dump(pw, " "); 8984 needSep = true; 8985 } else { 8986 pw.print(" app="); pw.println(r.app); 8987 pw.print(" created="); 8988 TimeUtils.formatDuration(r.createTime, nowReal, pw); 8989 pw.print(" started="); pw.print(r.startRequested); 8990 pw.print(" connections="); pw.println(r.connections.size()); 8991 if (r.connections.size() > 0) { 8992 pw.println(" Connections:"); 8993 for (ArrayList<ConnectionRecord> clist : r.connections.values()) { 8994 for (int i=0; i<clist.size(); i++) { 8995 ConnectionRecord conn = clist.get(i); 8996 pw.print(" "); 8997 pw.print(conn.binding.intent.intent.getIntent().toShortString( 8998 false, false, false)); 8999 pw.print(" -> "); 9000 ProcessRecord proc = conn.binding.client; 9001 pw.println(proc != null ? proc.toShortString() : "null"); 9002 } 9003 } 9004 } 9005 } 9006 if (dumpClient && r.app != null && r.app.thread != null) { 9007 pw.println(" Client:"); 9008 pw.flush(); 9009 try { 9010 TransferPipe tp = new TransferPipe(); 9011 try { 9012 r.app.thread.dumpService( 9013 tp.getWriteFd().getFileDescriptor(), r, args); 9014 tp.setBufferPrefix(" "); 9015 // Short timeout, since blocking here can 9016 // deadlock with the application. 9017 tp.go(fd, 2000); 9018 } finally { 9019 tp.kill(); 9020 } 9021 } catch (IOException e) { 9022 pw.println(" Failure while dumping the service: " + e); 9023 } catch (RemoteException e) { 9024 pw.println(" Got a RemoteException while dumping the service"); 9025 } 9026 needSep = true; 9027 } 9028 } 9029 needSep = printed; 9030 } 9031 9032 if (mPendingServices.size() > 0) { 9033 boolean printed = false; 9034 for (int i=0; i<mPendingServices.size(); i++) { 9035 ServiceRecord r = mPendingServices.get(i); 9036 if (!matcher.match(r, r.name)) { 9037 continue; 9038 } 9039 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9040 continue; 9041 } 9042 if (!printed) { 9043 if (needSep) pw.println(" "); 9044 needSep = true; 9045 pw.println(" Pending services:"); 9046 printed = true; 9047 } 9048 pw.print(" * Pending "); pw.println(r); 9049 r.dump(pw, " "); 9050 } 9051 needSep = true; 9052 } 9053 9054 if (mRestartingServices.size() > 0) { 9055 boolean printed = false; 9056 for (int i=0; i<mRestartingServices.size(); i++) { 9057 ServiceRecord r = mRestartingServices.get(i); 9058 if (!matcher.match(r, r.name)) { 9059 continue; 9060 } 9061 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9062 continue; 9063 } 9064 if (!printed) { 9065 if (needSep) pw.println(" "); 9066 needSep = true; 9067 pw.println(" Restarting services:"); 9068 printed = true; 9069 } 9070 pw.print(" * Restarting "); pw.println(r); 9071 r.dump(pw, " "); 9072 } 9073 needSep = true; 9074 } 9075 9076 if (mStoppingServices.size() > 0) { 9077 boolean printed = false; 9078 for (int i=0; i<mStoppingServices.size(); i++) { 9079 ServiceRecord r = mStoppingServices.get(i); 9080 if (!matcher.match(r, r.name)) { 9081 continue; 9082 } 9083 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9084 continue; 9085 } 9086 if (!printed) { 9087 if (needSep) pw.println(" "); 9088 needSep = true; 9089 pw.println(" Stopping services:"); 9090 printed = true; 9091 } 9092 pw.print(" * Stopping "); pw.println(r); 9093 r.dump(pw, " "); 9094 } 9095 needSep = true; 9096 } 9097 9098 if (dumpAll) { 9099 if (mServiceConnections.size() > 0) { 9100 boolean printed = false; 9101 Iterator<ArrayList<ConnectionRecord>> it 9102 = mServiceConnections.values().iterator(); 9103 while (it.hasNext()) { 9104 ArrayList<ConnectionRecord> r = it.next(); 9105 for (int i=0; i<r.size(); i++) { 9106 ConnectionRecord cr = r.get(i); 9107 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 9108 continue; 9109 } 9110 if (dumpPackage != null && (cr.binding.client == null 9111 || !dumpPackage.equals(cr.binding.client.info.packageName))) { 9112 continue; 9113 } 9114 if (!printed) { 9115 if (needSep) pw.println(" "); 9116 needSep = true; 9117 pw.println(" Connection bindings to services:"); 9118 printed = true; 9119 } 9120 pw.print(" * "); pw.println(cr); 9121 cr.dump(pw, " "); 9122 } 9123 } 9124 needSep = true; 9125 } 9126 } 9127 9128 return needSep; 9129 } 9130 9131 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9132 int opti, boolean dumpAll, String dumpPackage) { 9133 boolean needSep = false; 9134 9135 ItemMatcher matcher = new ItemMatcher(); 9136 matcher.build(args, opti); 9137 9138 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9139 if (mProvidersByClass.size() > 0) { 9140 boolean printed = false; 9141 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it 9142 = mProvidersByClass.entrySet().iterator(); 9143 while (it.hasNext()) { 9144 Map.Entry<ComponentName, ContentProviderRecord> e = it.next(); 9145 ContentProviderRecord r = e.getValue(); 9146 ComponentName comp = e.getKey(); 9147 String cls = comp.getClassName(); 9148 int end = cls.lastIndexOf('.'); 9149 if (end > 0 && end < (cls.length()-2)) { 9150 cls = cls.substring(end+1); 9151 } 9152 if (!matcher.match(r, comp)) { 9153 continue; 9154 } 9155 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) { 9156 continue; 9157 } 9158 if (!printed) { 9159 if (needSep) pw.println(" "); 9160 needSep = true; 9161 pw.println(" Published content providers (by class):"); 9162 printed = true; 9163 } 9164 pw.print(" * "); pw.print(cls); pw.print(" ("); 9165 pw.print(comp.flattenToShortString()); pw.println(")"); 9166 if (dumpAll) { 9167 r.dump(pw, " "); 9168 } else { 9169 if (r.proc != null) { 9170 pw.print(" "); pw.println(r.proc); 9171 } else { 9172 pw.println(); 9173 } 9174 if (r.clients.size() > 0) { 9175 pw.println(" Clients:"); 9176 for (ProcessRecord cproc : r.clients) { 9177 pw.print(" - "); pw.println(cproc); 9178 } 9179 } 9180 } 9181 } 9182 } 9183 9184 if (dumpAll) { 9185 if (mProvidersByName.size() > 0) { 9186 boolean printed = false; 9187 Iterator<Map.Entry<String, ContentProviderRecord>> it 9188 = mProvidersByName.entrySet().iterator(); 9189 while (it.hasNext()) { 9190 Map.Entry<String, ContentProviderRecord> e = it.next(); 9191 ContentProviderRecord r = e.getValue(); 9192 if (!matcher.match(r, r.name)) { 9193 continue; 9194 } 9195 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9196 continue; 9197 } 9198 if (!printed) { 9199 if (needSep) pw.println(" "); 9200 needSep = true; 9201 pw.println(" Authority to provider mappings:"); 9202 printed = true; 9203 } 9204 pw.print(" "); pw.print(e.getKey()); pw.println(":"); 9205 pw.print(" "); pw.println(r); 9206 } 9207 } 9208 } 9209 9210 if (mLaunchingProviders.size() > 0) { 9211 boolean printed = false; 9212 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9213 ContentProviderRecord r = mLaunchingProviders.get(i); 9214 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9215 continue; 9216 } 9217 if (!printed) { 9218 if (needSep) pw.println(" "); 9219 needSep = true; 9220 pw.println(" Launching content providers:"); 9221 printed = true; 9222 } 9223 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9224 pw.println(r); 9225 } 9226 } 9227 9228 if (mGrantedUriPermissions.size() > 0) { 9229 if (needSep) pw.println(); 9230 needSep = true; 9231 pw.println("Granted Uri Permissions:"); 9232 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9233 int uid = mGrantedUriPermissions.keyAt(i); 9234 HashMap<Uri, UriPermission> perms 9235 = mGrantedUriPermissions.valueAt(i); 9236 pw.print(" * UID "); pw.print(uid); 9237 pw.println(" holds:"); 9238 for (UriPermission perm : perms.values()) { 9239 pw.print(" "); pw.println(perm); 9240 if (dumpAll) { 9241 perm.dump(pw, " "); 9242 } 9243 } 9244 } 9245 needSep = true; 9246 } 9247 9248 return needSep; 9249 } 9250 9251 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9252 int opti, boolean dumpAll, String dumpPackage) { 9253 boolean needSep = false; 9254 9255 if (mIntentSenderRecords.size() > 0) { 9256 boolean printed = false; 9257 Iterator<WeakReference<PendingIntentRecord>> it 9258 = mIntentSenderRecords.values().iterator(); 9259 while (it.hasNext()) { 9260 WeakReference<PendingIntentRecord> ref = it.next(); 9261 PendingIntentRecord rec = ref != null ? ref.get(): null; 9262 if (dumpPackage != null && (rec == null 9263 || !dumpPackage.equals(rec.key.packageName))) { 9264 continue; 9265 } 9266 if (!printed) { 9267 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9268 printed = true; 9269 } 9270 needSep = true; 9271 if (rec != null) { 9272 pw.print(" * "); pw.println(rec); 9273 if (dumpAll) { 9274 rec.dump(pw, " "); 9275 } 9276 } else { 9277 pw.print(" * "); pw.println(ref); 9278 } 9279 } 9280 } 9281 9282 return needSep; 9283 } 9284 9285 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9286 String prefix, String label, boolean complete, boolean brief, boolean client, 9287 String dumpPackage) { 9288 TaskRecord lastTask = null; 9289 boolean needNL = false; 9290 final String innerPrefix = prefix + " "; 9291 final String[] args = new String[0]; 9292 for (int i=list.size()-1; i>=0; i--) { 9293 final ActivityRecord r = (ActivityRecord)list.get(i); 9294 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9295 continue; 9296 } 9297 final boolean full = !brief && (complete || !r.isInHistory()); 9298 if (needNL) { 9299 pw.println(" "); 9300 needNL = false; 9301 } 9302 if (lastTask != r.task) { 9303 lastTask = r.task; 9304 pw.print(prefix); 9305 pw.print(full ? "* " : " "); 9306 pw.println(lastTask); 9307 if (full) { 9308 lastTask.dump(pw, prefix + " "); 9309 } else if (complete) { 9310 // Complete + brief == give a summary. Isn't that obvious?!? 9311 if (lastTask.intent != null) { 9312 pw.print(prefix); pw.print(" "); 9313 pw.println(lastTask.intent.toInsecureString()); 9314 } 9315 } 9316 } 9317 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9318 pw.print(" #"); pw.print(i); pw.print(": "); 9319 pw.println(r); 9320 if (full) { 9321 r.dump(pw, innerPrefix); 9322 } else if (complete) { 9323 // Complete + brief == give a summary. Isn't that obvious?!? 9324 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9325 if (r.app != null) { 9326 pw.print(innerPrefix); pw.println(r.app); 9327 } 9328 } 9329 if (client && r.app != null && r.app.thread != null) { 9330 // flush anything that is already in the PrintWriter since the thread is going 9331 // to write to the file descriptor directly 9332 pw.flush(); 9333 try { 9334 TransferPipe tp = new TransferPipe(); 9335 try { 9336 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9337 r.appToken, innerPrefix, args); 9338 // Short timeout, since blocking here can 9339 // deadlock with the application. 9340 tp.go(fd, 2000); 9341 } finally { 9342 tp.kill(); 9343 } 9344 } catch (IOException e) { 9345 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9346 } catch (RemoteException e) { 9347 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9348 } 9349 needNL = true; 9350 } 9351 } 9352 } 9353 9354 private static String buildOomTag(String prefix, String space, int val, int base) { 9355 if (val == base) { 9356 if (space == null) return prefix; 9357 return prefix + " "; 9358 } 9359 return prefix + "+" + Integer.toString(val-base); 9360 } 9361 9362 private static final int dumpProcessList(PrintWriter pw, 9363 ActivityManagerService service, List list, 9364 String prefix, String normalLabel, String persistentLabel, 9365 String dumpPackage) { 9366 int numPers = 0; 9367 final int N = list.size()-1; 9368 for (int i=N; i>=0; i--) { 9369 ProcessRecord r = (ProcessRecord)list.get(i); 9370 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9371 continue; 9372 } 9373 pw.println(String.format("%s%s #%2d: %s", 9374 prefix, (r.persistent ? persistentLabel : normalLabel), 9375 i, r.toString())); 9376 if (r.persistent) { 9377 numPers++; 9378 } 9379 } 9380 return numPers; 9381 } 9382 9383 private static final boolean dumpProcessOomList(PrintWriter pw, 9384 ActivityManagerService service, List<ProcessRecord> origList, 9385 String prefix, String normalLabel, String persistentLabel, 9386 boolean inclDetails, String dumpPackage) { 9387 9388 ArrayList<Pair<ProcessRecord, Integer>> list 9389 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9390 for (int i=0; i<origList.size(); i++) { 9391 ProcessRecord r = origList.get(i); 9392 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9393 continue; 9394 } 9395 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9396 } 9397 9398 if (list.size() <= 0) { 9399 return false; 9400 } 9401 9402 Comparator<Pair<ProcessRecord, Integer>> comparator 9403 = new Comparator<Pair<ProcessRecord, Integer>>() { 9404 @Override 9405 public int compare(Pair<ProcessRecord, Integer> object1, 9406 Pair<ProcessRecord, Integer> object2) { 9407 if (object1.first.setAdj != object2.first.setAdj) { 9408 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9409 } 9410 if (object1.second.intValue() != object2.second.intValue()) { 9411 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9412 } 9413 return 0; 9414 } 9415 }; 9416 9417 Collections.sort(list, comparator); 9418 9419 final long curRealtime = SystemClock.elapsedRealtime(); 9420 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9421 final long curUptime = SystemClock.uptimeMillis(); 9422 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9423 9424 for (int i=list.size()-1; i>=0; i--) { 9425 ProcessRecord r = list.get(i).first; 9426 String oomAdj; 9427 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9428 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9429 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9430 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9431 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9432 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9433 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9434 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9435 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9436 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9437 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9438 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9439 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9440 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9441 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9442 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9443 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9444 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9445 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9446 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9447 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9448 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9449 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9450 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9451 } else { 9452 oomAdj = Integer.toString(r.setAdj); 9453 } 9454 String schedGroup; 9455 switch (r.setSchedGroup) { 9456 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9457 schedGroup = "B"; 9458 break; 9459 case Process.THREAD_GROUP_DEFAULT: 9460 schedGroup = "F"; 9461 break; 9462 default: 9463 schedGroup = Integer.toString(r.setSchedGroup); 9464 break; 9465 } 9466 String foreground; 9467 if (r.foregroundActivities) { 9468 foreground = "A"; 9469 } else if (r.foregroundServices) { 9470 foreground = "S"; 9471 } else { 9472 foreground = " "; 9473 } 9474 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9475 prefix, (r.persistent ? persistentLabel : normalLabel), 9476 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9477 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9478 if (r.adjSource != null || r.adjTarget != null) { 9479 pw.print(prefix); 9480 pw.print(" "); 9481 if (r.adjTarget instanceof ComponentName) { 9482 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9483 } else if (r.adjTarget != null) { 9484 pw.print(r.adjTarget.toString()); 9485 } else { 9486 pw.print("{null}"); 9487 } 9488 pw.print("<="); 9489 if (r.adjSource instanceof ProcessRecord) { 9490 pw.print("Proc{"); 9491 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9492 pw.println("}"); 9493 } else if (r.adjSource != null) { 9494 pw.println(r.adjSource.toString()); 9495 } else { 9496 pw.println("{null}"); 9497 } 9498 } 9499 if (inclDetails) { 9500 pw.print(prefix); 9501 pw.print(" "); 9502 pw.print("oom: max="); pw.print(r.maxAdj); 9503 pw.print(" hidden="); pw.print(r.hiddenAdj); 9504 pw.print(" curRaw="); pw.print(r.curRawAdj); 9505 pw.print(" setRaw="); pw.print(r.setRawAdj); 9506 pw.print(" cur="); pw.print(r.curAdj); 9507 pw.print(" set="); pw.println(r.setAdj); 9508 pw.print(prefix); 9509 pw.print(" "); 9510 pw.print("keeping="); pw.print(r.keeping); 9511 pw.print(" hidden="); pw.print(r.hidden); 9512 pw.print(" empty="); pw.print(r.empty); 9513 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9514 9515 if (!r.keeping) { 9516 if (r.lastWakeTime != 0) { 9517 long wtime; 9518 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9519 synchronized (stats) { 9520 wtime = stats.getProcessWakeTime(r.info.uid, 9521 r.pid, curRealtime); 9522 } 9523 long timeUsed = wtime - r.lastWakeTime; 9524 pw.print(prefix); 9525 pw.print(" "); 9526 pw.print("keep awake over "); 9527 TimeUtils.formatDuration(realtimeSince, pw); 9528 pw.print(" used "); 9529 TimeUtils.formatDuration(timeUsed, pw); 9530 pw.print(" ("); 9531 pw.print((timeUsed*100)/realtimeSince); 9532 pw.println("%)"); 9533 } 9534 if (r.lastCpuTime != 0) { 9535 long timeUsed = r.curCpuTime - r.lastCpuTime; 9536 pw.print(prefix); 9537 pw.print(" "); 9538 pw.print("run cpu over "); 9539 TimeUtils.formatDuration(uptimeSince, pw); 9540 pw.print(" used "); 9541 TimeUtils.formatDuration(timeUsed, pw); 9542 pw.print(" ("); 9543 pw.print((timeUsed*100)/uptimeSince); 9544 pw.println("%)"); 9545 } 9546 } 9547 } 9548 } 9549 return true; 9550 } 9551 9552 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9553 ArrayList<ProcessRecord> procs; 9554 synchronized (this) { 9555 if (args != null && args.length > start 9556 && args[start].charAt(0) != '-') { 9557 procs = new ArrayList<ProcessRecord>(); 9558 int pid = -1; 9559 try { 9560 pid = Integer.parseInt(args[start]); 9561 } catch (NumberFormatException e) { 9562 9563 } 9564 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9565 ProcessRecord proc = mLruProcesses.get(i); 9566 if (proc.pid == pid) { 9567 procs.add(proc); 9568 } else if (proc.processName.equals(args[start])) { 9569 procs.add(proc); 9570 } 9571 } 9572 if (procs.size() <= 0) { 9573 pw.println("No process found for: " + args[start]); 9574 return null; 9575 } 9576 } else { 9577 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9578 } 9579 } 9580 return procs; 9581 } 9582 9583 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9584 PrintWriter pw, String[] args) { 9585 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9586 if (procs == null) { 9587 return; 9588 } 9589 9590 long uptime = SystemClock.uptimeMillis(); 9591 long realtime = SystemClock.elapsedRealtime(); 9592 pw.println("Applications Graphics Acceleration Info:"); 9593 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9594 9595 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9596 ProcessRecord r = procs.get(i); 9597 if (r.thread != null) { 9598 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9599 pw.flush(); 9600 try { 9601 TransferPipe tp = new TransferPipe(); 9602 try { 9603 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9604 tp.go(fd); 9605 } finally { 9606 tp.kill(); 9607 } 9608 } catch (IOException e) { 9609 pw.println("Failure while dumping the app: " + r); 9610 pw.flush(); 9611 } catch (RemoteException e) { 9612 pw.println("Got a RemoteException while dumping the app " + r); 9613 pw.flush(); 9614 } 9615 } 9616 } 9617 } 9618 9619 final static class MemItem { 9620 final String label; 9621 final String shortLabel; 9622 final long pss; 9623 final int id; 9624 ArrayList<MemItem> subitems; 9625 9626 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9627 label = _label; 9628 shortLabel = _shortLabel; 9629 pss = _pss; 9630 id = _id; 9631 } 9632 } 9633 9634 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9635 boolean sort) { 9636 if (sort) { 9637 Collections.sort(items, new Comparator<MemItem>() { 9638 @Override 9639 public int compare(MemItem lhs, MemItem rhs) { 9640 if (lhs.pss < rhs.pss) { 9641 return 1; 9642 } else if (lhs.pss > rhs.pss) { 9643 return -1; 9644 } 9645 return 0; 9646 } 9647 }); 9648 } 9649 9650 for (int i=0; i<items.size(); i++) { 9651 MemItem mi = items.get(i); 9652 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9653 if (mi.subitems != null) { 9654 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9655 } 9656 } 9657 } 9658 9659 // These are in KB. 9660 static final long[] DUMP_MEM_BUCKETS = new long[] { 9661 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9662 120*1024, 160*1024, 200*1024, 9663 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9664 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9665 }; 9666 9667 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9668 boolean stackLike) { 9669 int start = label.lastIndexOf('.'); 9670 if (start >= 0) start++; 9671 else start = 0; 9672 int end = label.length(); 9673 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9674 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9675 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9676 out.append(bucket); 9677 out.append(stackLike ? "MB." : "MB "); 9678 out.append(label, start, end); 9679 return; 9680 } 9681 } 9682 out.append(memKB/1024); 9683 out.append(stackLike ? "MB." : "MB "); 9684 out.append(label, start, end); 9685 } 9686 9687 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9688 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9689 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9690 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9691 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9692 }; 9693 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9694 "System", "Persistent", "Foreground", 9695 "Visible", "Perceptible", "Heavy Weight", 9696 "Backup", "A Services", "Home", "Previous", 9697 "B Services", "Background" 9698 }; 9699 9700 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9701 PrintWriter pw, String prefix, String[] args, boolean brief, 9702 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9703 boolean dumpAll = false; 9704 boolean oomOnly = false; 9705 9706 int opti = 0; 9707 while (opti < args.length) { 9708 String opt = args[opti]; 9709 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9710 break; 9711 } 9712 opti++; 9713 if ("-a".equals(opt)) { 9714 dumpAll = true; 9715 } else if ("--oom".equals(opt)) { 9716 oomOnly = true; 9717 } else if ("-h".equals(opt)) { 9718 pw.println("meminfo dump options: [-a] [--oom] [process]"); 9719 pw.println(" -a: include all available information for each process."); 9720 pw.println(" --oom: only show processes organized by oom adj."); 9721 pw.println("If [process] is specified it can be the name or "); 9722 pw.println("pid of a specific process to dump."); 9723 return; 9724 } else { 9725 pw.println("Unknown argument: " + opt + "; use -h for help"); 9726 } 9727 } 9728 9729 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 9730 if (procs == null) { 9731 return; 9732 } 9733 9734 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9735 long uptime = SystemClock.uptimeMillis(); 9736 long realtime = SystemClock.elapsedRealtime(); 9737 9738 if (procs.size() == 1 || isCheckinRequest) { 9739 dumpAll = true; 9740 } 9741 9742 if (isCheckinRequest) { 9743 // short checkin version 9744 pw.println(uptime + "," + realtime); 9745 pw.flush(); 9746 } else { 9747 pw.println("Applications Memory Usage (kB):"); 9748 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9749 } 9750 9751 String[] innerArgs = new String[args.length-opti]; 9752 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 9753 9754 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 9755 long nativePss=0, dalvikPss=0, otherPss=0; 9756 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 9757 9758 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 9759 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 9760 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 9761 9762 long totalPss = 0; 9763 9764 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9765 ProcessRecord r = procs.get(i); 9766 if (r.thread != null) { 9767 if (!isCheckinRequest && dumpAll) { 9768 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9769 pw.flush(); 9770 } 9771 Debug.MemoryInfo mi = null; 9772 if (dumpAll) { 9773 try { 9774 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 9775 } catch (RemoteException e) { 9776 if (!isCheckinRequest) { 9777 pw.println("Got RemoteException!"); 9778 pw.flush(); 9779 } 9780 } 9781 } else { 9782 mi = new Debug.MemoryInfo(); 9783 Debug.getMemoryInfo(r.pid, mi); 9784 } 9785 9786 if (!isCheckinRequest && mi != null) { 9787 long myTotalPss = mi.getTotalPss(); 9788 totalPss += myTotalPss; 9789 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 9790 r.processName, myTotalPss, 0); 9791 procMems.add(pssItem); 9792 9793 nativePss += mi.nativePss; 9794 dalvikPss += mi.dalvikPss; 9795 otherPss += mi.otherPss; 9796 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 9797 long mem = mi.getOtherPss(j); 9798 miscPss[j] += mem; 9799 otherPss -= mem; 9800 } 9801 9802 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 9803 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 9804 || oomIndex == (oomPss.length-1)) { 9805 oomPss[oomIndex] += myTotalPss; 9806 if (oomProcs[oomIndex] == null) { 9807 oomProcs[oomIndex] = new ArrayList<MemItem>(); 9808 } 9809 oomProcs[oomIndex].add(pssItem); 9810 break; 9811 } 9812 } 9813 } 9814 } 9815 } 9816 9817 if (!isCheckinRequest && procs.size() > 1) { 9818 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 9819 9820 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 9821 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 9822 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 9823 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 9824 String label = Debug.MemoryInfo.getOtherLabel(j); 9825 catMems.add(new MemItem(label, label, miscPss[j], j)); 9826 } 9827 9828 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 9829 for (int j=0; j<oomPss.length; j++) { 9830 if (oomPss[j] != 0) { 9831 String label = DUMP_MEM_OOM_LABEL[j]; 9832 MemItem item = new MemItem(label, label, oomPss[j], 9833 DUMP_MEM_OOM_ADJ[j]); 9834 item.subitems = oomProcs[j]; 9835 oomMems.add(item); 9836 } 9837 } 9838 9839 if (outTag != null || outStack != null) { 9840 if (outTag != null) { 9841 appendMemBucket(outTag, totalPss, "total", false); 9842 } 9843 if (outStack != null) { 9844 appendMemBucket(outStack, totalPss, "total", true); 9845 } 9846 boolean firstLine = true; 9847 for (int i=0; i<oomMems.size(); i++) { 9848 MemItem miCat = oomMems.get(i); 9849 if (miCat.subitems == null || miCat.subitems.size() < 1) { 9850 continue; 9851 } 9852 if (miCat.id < ProcessList.SERVICE_ADJ 9853 || miCat.id == ProcessList.HOME_APP_ADJ 9854 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 9855 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 9856 outTag.append(" / "); 9857 } 9858 if (outStack != null) { 9859 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 9860 if (firstLine) { 9861 outStack.append(":"); 9862 firstLine = false; 9863 } 9864 outStack.append("\n\t at "); 9865 } else { 9866 outStack.append("$"); 9867 } 9868 } 9869 for (int j=0; j<miCat.subitems.size(); j++) { 9870 MemItem mi = miCat.subitems.get(j); 9871 if (j > 0) { 9872 if (outTag != null) { 9873 outTag.append(" "); 9874 } 9875 if (outStack != null) { 9876 outStack.append("$"); 9877 } 9878 } 9879 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 9880 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 9881 } 9882 if (outStack != null) { 9883 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 9884 } 9885 } 9886 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 9887 outStack.append("("); 9888 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 9889 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 9890 outStack.append(DUMP_MEM_OOM_LABEL[k]); 9891 outStack.append(":"); 9892 outStack.append(DUMP_MEM_OOM_ADJ[k]); 9893 } 9894 } 9895 outStack.append(")"); 9896 } 9897 } 9898 } 9899 } 9900 9901 if (!brief && !oomOnly) { 9902 pw.println(); 9903 pw.println("Total PSS by process:"); 9904 dumpMemItems(pw, " ", procMems, true); 9905 pw.println(); 9906 } 9907 pw.println("Total PSS by OOM adjustment:"); 9908 dumpMemItems(pw, " ", oomMems, false); 9909 if (!oomOnly) { 9910 PrintWriter out = categoryPw != null ? categoryPw : pw; 9911 out.println(); 9912 out.println("Total PSS by category:"); 9913 dumpMemItems(out, " ", catMems, true); 9914 } 9915 pw.println(); 9916 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 9917 } 9918 } 9919 9920 /** 9921 * Searches array of arguments for the specified string 9922 * @param args array of argument strings 9923 * @param value value to search for 9924 * @return true if the value is contained in the array 9925 */ 9926 private static boolean scanArgs(String[] args, String value) { 9927 if (args != null) { 9928 for (String arg : args) { 9929 if (value.equals(arg)) { 9930 return true; 9931 } 9932 } 9933 } 9934 return false; 9935 } 9936 9937 private final void killServicesLocked(ProcessRecord app, 9938 boolean allowRestart) { 9939 // Report disconnected services. 9940 if (false) { 9941 // XXX we are letting the client link to the service for 9942 // death notifications. 9943 if (app.services.size() > 0) { 9944 Iterator<ServiceRecord> it = app.services.iterator(); 9945 while (it.hasNext()) { 9946 ServiceRecord r = it.next(); 9947 if (r.connections.size() > 0) { 9948 Iterator<ArrayList<ConnectionRecord>> jt 9949 = r.connections.values().iterator(); 9950 while (jt.hasNext()) { 9951 ArrayList<ConnectionRecord> cl = jt.next(); 9952 for (int i=0; i<cl.size(); i++) { 9953 ConnectionRecord c = cl.get(i); 9954 if (c.binding.client != app) { 9955 try { 9956 //c.conn.connected(r.className, null); 9957 } catch (Exception e) { 9958 // todo: this should be asynchronous! 9959 Slog.w(TAG, "Exception thrown disconnected servce " 9960 + r.shortName 9961 + " from app " + app.processName, e); 9962 } 9963 } 9964 } 9965 } 9966 } 9967 } 9968 } 9969 } 9970 9971 // Clean up any connections this application has to other services. 9972 if (app.connections.size() > 0) { 9973 Iterator<ConnectionRecord> it = app.connections.iterator(); 9974 while (it.hasNext()) { 9975 ConnectionRecord r = it.next(); 9976 removeConnectionLocked(r, app, null); 9977 } 9978 } 9979 app.connections.clear(); 9980 9981 if (app.services.size() != 0) { 9982 // Any services running in the application need to be placed 9983 // back in the pending list. 9984 Iterator<ServiceRecord> it = app.services.iterator(); 9985 while (it.hasNext()) { 9986 ServiceRecord sr = it.next(); 9987 synchronized (sr.stats.getBatteryStats()) { 9988 sr.stats.stopLaunchedLocked(); 9989 } 9990 sr.app = null; 9991 sr.executeNesting = 0; 9992 if (mStoppingServices.remove(sr)) { 9993 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 9994 } 9995 9996 boolean hasClients = sr.bindings.size() > 0; 9997 if (hasClients) { 9998 Iterator<IntentBindRecord> bindings 9999 = sr.bindings.values().iterator(); 10000 while (bindings.hasNext()) { 10001 IntentBindRecord b = bindings.next(); 10002 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10003 + ": shouldUnbind=" + b.hasBound); 10004 b.binder = null; 10005 b.requested = b.received = b.hasBound = false; 10006 } 10007 } 10008 10009 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 10010 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 10011 Slog.w(TAG, "Service crashed " + sr.crashCount 10012 + " times, stopping: " + sr); 10013 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10014 sr.crashCount, sr.shortName, app.pid); 10015 bringDownServiceLocked(sr, true); 10016 } else if (!allowRestart) { 10017 bringDownServiceLocked(sr, true); 10018 } else { 10019 boolean canceled = scheduleServiceRestartLocked(sr, true); 10020 10021 // Should the service remain running? Note that in the 10022 // extreme case of so many attempts to deliver a command 10023 // that it failed we also will stop it here. 10024 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10025 if (sr.pendingStarts.size() == 0) { 10026 sr.startRequested = false; 10027 if (!hasClients) { 10028 // Whoops, no reason to restart! 10029 bringDownServiceLocked(sr, true); 10030 } 10031 } 10032 } 10033 } 10034 } 10035 10036 if (!allowRestart) { 10037 app.services.clear(); 10038 } 10039 } 10040 10041 // Make sure we have no more records on the stopping list. 10042 int i = mStoppingServices.size(); 10043 while (i > 0) { 10044 i--; 10045 ServiceRecord sr = mStoppingServices.get(i); 10046 if (sr.app == app) { 10047 mStoppingServices.remove(i); 10048 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10049 } 10050 } 10051 10052 app.executingServices.clear(); 10053 } 10054 10055 private final void removeDyingProviderLocked(ProcessRecord proc, 10056 ContentProviderRecord cpr) { 10057 synchronized (cpr) { 10058 cpr.launchingApp = null; 10059 cpr.notifyAll(); 10060 } 10061 10062 mProvidersByClass.remove(cpr.name); 10063 String names[] = cpr.info.authority.split(";"); 10064 for (int j = 0; j < names.length; j++) { 10065 mProvidersByName.remove(names[j]); 10066 } 10067 10068 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 10069 while (cit.hasNext()) { 10070 ProcessRecord capp = cit.next(); 10071 if (!capp.persistent && capp.thread != null 10072 && capp.pid != 0 10073 && capp.pid != MY_PID) { 10074 Slog.i(TAG, "Kill " + capp.processName 10075 + " (pid " + capp.pid + "): provider " + cpr.info.name 10076 + " in dying process " + (proc != null ? proc.processName : "??")); 10077 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10078 capp.processName, capp.setAdj, "dying provider " 10079 + cpr.name.toShortString()); 10080 Process.killProcessQuiet(capp.pid); 10081 } 10082 } 10083 10084 mLaunchingProviders.remove(cpr); 10085 } 10086 10087 /** 10088 * Main code for cleaning up a process when it has gone away. This is 10089 * called both as a result of the process dying, or directly when stopping 10090 * a process when running in single process mode. 10091 */ 10092 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10093 boolean restarting, boolean allowRestart, int index) { 10094 if (index >= 0) { 10095 mLruProcesses.remove(index); 10096 } 10097 10098 mProcessesToGc.remove(app); 10099 10100 // Dismiss any open dialogs. 10101 if (app.crashDialog != null) { 10102 app.crashDialog.dismiss(); 10103 app.crashDialog = null; 10104 } 10105 if (app.anrDialog != null) { 10106 app.anrDialog.dismiss(); 10107 app.anrDialog = null; 10108 } 10109 if (app.waitDialog != null) { 10110 app.waitDialog.dismiss(); 10111 app.waitDialog = null; 10112 } 10113 10114 app.crashing = false; 10115 app.notResponding = false; 10116 10117 app.resetPackageList(); 10118 app.unlinkDeathRecipient(); 10119 app.thread = null; 10120 app.forcingToForeground = null; 10121 app.foregroundServices = false; 10122 app.foregroundActivities = false; 10123 app.hasShownUi = false; 10124 app.hasAboveClient = false; 10125 10126 killServicesLocked(app, allowRestart); 10127 10128 boolean restart = false; 10129 10130 int NL = mLaunchingProviders.size(); 10131 10132 // Remove published content providers. 10133 if (!app.pubProviders.isEmpty()) { 10134 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10135 while (it.hasNext()) { 10136 ContentProviderRecord cpr = it.next(); 10137 cpr.provider = null; 10138 cpr.proc = null; 10139 10140 // See if someone is waiting for this provider... in which 10141 // case we don't remove it, but just let it restart. 10142 int i = 0; 10143 if (!app.bad && allowRestart) { 10144 for (; i<NL; i++) { 10145 if (mLaunchingProviders.get(i) == cpr) { 10146 restart = true; 10147 break; 10148 } 10149 } 10150 } else { 10151 i = NL; 10152 } 10153 10154 if (i >= NL) { 10155 removeDyingProviderLocked(app, cpr); 10156 NL = mLaunchingProviders.size(); 10157 } 10158 } 10159 app.pubProviders.clear(); 10160 } 10161 10162 // Take care of any launching providers waiting for this process. 10163 if (checkAppInLaunchingProvidersLocked(app, false)) { 10164 restart = true; 10165 } 10166 10167 // Unregister from connected content providers. 10168 if (!app.conProviders.isEmpty()) { 10169 Iterator it = app.conProviders.keySet().iterator(); 10170 while (it.hasNext()) { 10171 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10172 cpr.clients.remove(app); 10173 } 10174 app.conProviders.clear(); 10175 } 10176 10177 // At this point there may be remaining entries in mLaunchingProviders 10178 // where we were the only one waiting, so they are no longer of use. 10179 // Look for these and clean up if found. 10180 // XXX Commented out for now. Trying to figure out a way to reproduce 10181 // the actual situation to identify what is actually going on. 10182 if (false) { 10183 for (int i=0; i<NL; i++) { 10184 ContentProviderRecord cpr = (ContentProviderRecord) 10185 mLaunchingProviders.get(i); 10186 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 10187 synchronized (cpr) { 10188 cpr.launchingApp = null; 10189 cpr.notifyAll(); 10190 } 10191 } 10192 } 10193 } 10194 10195 skipCurrentReceiverLocked(app); 10196 10197 // Unregister any receivers. 10198 if (app.receivers.size() > 0) { 10199 Iterator<ReceiverList> it = app.receivers.iterator(); 10200 while (it.hasNext()) { 10201 removeReceiverLocked(it.next()); 10202 } 10203 app.receivers.clear(); 10204 } 10205 10206 // If the app is undergoing backup, tell the backup manager about it 10207 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10208 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10209 try { 10210 IBackupManager bm = IBackupManager.Stub.asInterface( 10211 ServiceManager.getService(Context.BACKUP_SERVICE)); 10212 bm.agentDisconnected(app.info.packageName); 10213 } catch (RemoteException e) { 10214 // can't happen; backup manager is local 10215 } 10216 } 10217 10218 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10219 10220 // If the caller is restarting this app, then leave it in its 10221 // current lists and let the caller take care of it. 10222 if (restarting) { 10223 return; 10224 } 10225 10226 if (!app.persistent) { 10227 if (DEBUG_PROCESSES) Slog.v(TAG, 10228 "Removing non-persistent process during cleanup: " + app); 10229 mProcessNames.remove(app.processName, app.info.uid); 10230 if (mHeavyWeightProcess == app) { 10231 mHeavyWeightProcess = null; 10232 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10233 } 10234 } else if (!app.removed) { 10235 // This app is persistent, so we need to keep its record around. 10236 // If it is not already on the pending app list, add it there 10237 // and start a new process for it. 10238 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10239 mPersistentStartingProcesses.add(app); 10240 restart = true; 10241 } 10242 } 10243 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10244 "Clean-up removing on hold: " + app); 10245 mProcessesOnHold.remove(app); 10246 10247 if (app == mHomeProcess) { 10248 mHomeProcess = null; 10249 } 10250 if (app == mPreviousProcess) { 10251 mPreviousProcess = null; 10252 } 10253 10254 if (restart) { 10255 // We have components that still need to be running in the 10256 // process, so re-launch it. 10257 mProcessNames.put(app.processName, app.info.uid, app); 10258 startProcessLocked(app, "restart", app.processName); 10259 } else if (app.pid > 0 && app.pid != MY_PID) { 10260 // Goodbye! 10261 synchronized (mPidsSelfLocked) { 10262 mPidsSelfLocked.remove(app.pid); 10263 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10264 } 10265 app.setPid(0); 10266 } 10267 } 10268 10269 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10270 // Look through the content providers we are waiting to have launched, 10271 // and if any run in this process then either schedule a restart of 10272 // the process or kill the client waiting for it if this process has 10273 // gone bad. 10274 int NL = mLaunchingProviders.size(); 10275 boolean restart = false; 10276 for (int i=0; i<NL; i++) { 10277 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10278 if (cpr.launchingApp == app) { 10279 if (!alwaysBad && !app.bad) { 10280 restart = true; 10281 } else { 10282 removeDyingProviderLocked(app, cpr); 10283 NL = mLaunchingProviders.size(); 10284 } 10285 } 10286 } 10287 return restart; 10288 } 10289 10290 // ========================================================= 10291 // SERVICES 10292 // ========================================================= 10293 10294 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10295 ActivityManager.RunningServiceInfo info = 10296 new ActivityManager.RunningServiceInfo(); 10297 info.service = r.name; 10298 if (r.app != null) { 10299 info.pid = r.app.pid; 10300 } 10301 info.uid = r.appInfo.uid; 10302 info.process = r.processName; 10303 info.foreground = r.isForeground; 10304 info.activeSince = r.createTime; 10305 info.started = r.startRequested; 10306 info.clientCount = r.connections.size(); 10307 info.crashCount = r.crashCount; 10308 info.lastActivityTime = r.lastActivity; 10309 if (r.isForeground) { 10310 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10311 } 10312 if (r.startRequested) { 10313 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10314 } 10315 if (r.app != null && r.app.pid == MY_PID) { 10316 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10317 } 10318 if (r.app != null && r.app.persistent) { 10319 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10320 } 10321 10322 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 10323 for (int i=0; i<connl.size(); i++) { 10324 ConnectionRecord conn = connl.get(i); 10325 if (conn.clientLabel != 0) { 10326 info.clientPackage = conn.binding.client.info.packageName; 10327 info.clientLabel = conn.clientLabel; 10328 return info; 10329 } 10330 } 10331 } 10332 return info; 10333 } 10334 10335 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10336 int flags) { 10337 synchronized (this) { 10338 ArrayList<ActivityManager.RunningServiceInfo> res 10339 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10340 10341 if (mServices.size() > 0) { 10342 Iterator<ServiceRecord> it = mServices.values().iterator(); 10343 while (it.hasNext() && res.size() < maxNum) { 10344 res.add(makeRunningServiceInfoLocked(it.next())); 10345 } 10346 } 10347 10348 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10349 ServiceRecord r = mRestartingServices.get(i); 10350 ActivityManager.RunningServiceInfo info = 10351 makeRunningServiceInfoLocked(r); 10352 info.restarting = r.nextRestartTime; 10353 res.add(info); 10354 } 10355 10356 return res; 10357 } 10358 } 10359 10360 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10361 synchronized (this) { 10362 ServiceRecord r = mServices.get(name); 10363 if (r != null) { 10364 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 10365 for (int i=0; i<conn.size(); i++) { 10366 if (conn.get(i).clientIntent != null) { 10367 return conn.get(i).clientIntent; 10368 } 10369 } 10370 } 10371 } 10372 } 10373 return null; 10374 } 10375 10376 private final ServiceRecord findServiceLocked(ComponentName name, 10377 IBinder token) { 10378 ServiceRecord r = mServices.get(name); 10379 return r == token ? r : null; 10380 } 10381 10382 private final class ServiceLookupResult { 10383 final ServiceRecord record; 10384 final String permission; 10385 10386 ServiceLookupResult(ServiceRecord _record, String _permission) { 10387 record = _record; 10388 permission = _permission; 10389 } 10390 }; 10391 10392 private ServiceLookupResult findServiceLocked(Intent service, 10393 String resolvedType) { 10394 ServiceRecord r = null; 10395 if (service.getComponent() != null) { 10396 r = mServices.get(service.getComponent()); 10397 } 10398 if (r == null) { 10399 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10400 r = mServicesByIntent.get(filter); 10401 } 10402 10403 if (r == null) { 10404 try { 10405 ResolveInfo rInfo = 10406 AppGlobals.getPackageManager().resolveService( 10407 service, resolvedType, 0); 10408 ServiceInfo sInfo = 10409 rInfo != null ? rInfo.serviceInfo : null; 10410 if (sInfo == null) { 10411 return null; 10412 } 10413 10414 ComponentName name = new ComponentName( 10415 sInfo.applicationInfo.packageName, sInfo.name); 10416 r = mServices.get(name); 10417 } catch (RemoteException ex) { 10418 // pm is in same process, this will never happen. 10419 } 10420 } 10421 if (r != null) { 10422 int callingPid = Binder.getCallingPid(); 10423 int callingUid = Binder.getCallingUid(); 10424 if (checkComponentPermission(r.permission, 10425 callingPid, callingUid, r.appInfo.uid, r.exported) 10426 != PackageManager.PERMISSION_GRANTED) { 10427 if (!r.exported) { 10428 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10429 + " from pid=" + callingPid 10430 + ", uid=" + callingUid 10431 + " that is not exported from uid " + r.appInfo.uid); 10432 return new ServiceLookupResult(null, "not exported from uid " 10433 + r.appInfo.uid); 10434 } 10435 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10436 + " from pid=" + callingPid 10437 + ", uid=" + callingUid 10438 + " requires " + r.permission); 10439 return new ServiceLookupResult(null, r.permission); 10440 } 10441 return new ServiceLookupResult(r, null); 10442 } 10443 return null; 10444 } 10445 10446 private class ServiceRestarter implements Runnable { 10447 private ServiceRecord mService; 10448 10449 void setService(ServiceRecord service) { 10450 mService = service; 10451 } 10452 10453 public void run() { 10454 synchronized(ActivityManagerService.this) { 10455 performServiceRestartLocked(mService); 10456 } 10457 } 10458 } 10459 10460 private ServiceLookupResult retrieveServiceLocked(Intent service, 10461 String resolvedType, int callingPid, int callingUid) { 10462 ServiceRecord r = null; 10463 if (service.getComponent() != null) { 10464 r = mServices.get(service.getComponent()); 10465 } 10466 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10467 r = mServicesByIntent.get(filter); 10468 if (r == null) { 10469 try { 10470 ResolveInfo rInfo = 10471 AppGlobals.getPackageManager().resolveService( 10472 service, resolvedType, STOCK_PM_FLAGS); 10473 ServiceInfo sInfo = 10474 rInfo != null ? rInfo.serviceInfo : null; 10475 if (sInfo == null) { 10476 Slog.w(TAG, "Unable to start service " + service + 10477 ": not found"); 10478 return null; 10479 } 10480 10481 ComponentName name = new ComponentName( 10482 sInfo.applicationInfo.packageName, sInfo.name); 10483 r = mServices.get(name); 10484 if (r == null) { 10485 filter = new Intent.FilterComparison(service.cloneFilter()); 10486 ServiceRestarter res = new ServiceRestarter(); 10487 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10488 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10489 synchronized (stats) { 10490 ss = stats.getServiceStatsLocked( 10491 sInfo.applicationInfo.uid, sInfo.packageName, 10492 sInfo.name); 10493 } 10494 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 10495 res.setService(r); 10496 mServices.put(name, r); 10497 mServicesByIntent.put(filter, r); 10498 10499 // Make sure this component isn't in the pending list. 10500 int N = mPendingServices.size(); 10501 for (int i=0; i<N; i++) { 10502 ServiceRecord pr = mPendingServices.get(i); 10503 if (pr.name.equals(name)) { 10504 mPendingServices.remove(i); 10505 i--; 10506 N--; 10507 } 10508 } 10509 } 10510 } catch (RemoteException ex) { 10511 // pm is in same process, this will never happen. 10512 } 10513 } 10514 if (r != null) { 10515 if (checkComponentPermission(r.permission, 10516 callingPid, callingUid, r.appInfo.uid, r.exported) 10517 != PackageManager.PERMISSION_GRANTED) { 10518 if (!r.exported) { 10519 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10520 + " from pid=" + callingPid 10521 + ", uid=" + callingUid 10522 + " that is not exported from uid " + r.appInfo.uid); 10523 return new ServiceLookupResult(null, "not exported from uid " 10524 + r.appInfo.uid); 10525 } 10526 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10527 + " from pid=" + callingPid 10528 + ", uid=" + callingUid 10529 + " requires " + r.permission); 10530 return new ServiceLookupResult(null, r.permission); 10531 } 10532 return new ServiceLookupResult(r, null); 10533 } 10534 return null; 10535 } 10536 10537 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 10538 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 10539 + why + " of " + r + " in app " + r.app); 10540 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 10541 + why + " of " + r.shortName); 10542 long now = SystemClock.uptimeMillis(); 10543 if (r.executeNesting == 0 && r.app != null) { 10544 if (r.app.executingServices.size() == 0) { 10545 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10546 msg.obj = r.app; 10547 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10548 } 10549 r.app.executingServices.add(r); 10550 } 10551 r.executeNesting++; 10552 r.executingStart = now; 10553 } 10554 10555 private final void sendServiceArgsLocked(ServiceRecord r, 10556 boolean oomAdjusted) { 10557 final int N = r.pendingStarts.size(); 10558 if (N == 0) { 10559 return; 10560 } 10561 10562 while (r.pendingStarts.size() > 0) { 10563 try { 10564 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 10565 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 10566 + r + " " + r.intent + " args=" + si.intent); 10567 if (si.intent == null && N > 1) { 10568 // If somehow we got a dummy null intent in the middle, 10569 // then skip it. DO NOT skip a null intent when it is 10570 // the only one in the list -- this is to support the 10571 // onStartCommand(null) case. 10572 continue; 10573 } 10574 si.deliveredTime = SystemClock.uptimeMillis(); 10575 r.deliveredStarts.add(si); 10576 si.deliveryCount++; 10577 if (si.targetPermissionUid >= 0 && si.intent != null) { 10578 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid, 10579 r.packageName, si.intent, si.getUriPermissionsLocked()); 10580 } 10581 bumpServiceExecutingLocked(r, "start"); 10582 if (!oomAdjusted) { 10583 oomAdjusted = true; 10584 updateOomAdjLocked(r.app); 10585 } 10586 int flags = 0; 10587 if (si.deliveryCount > 0) { 10588 flags |= Service.START_FLAG_RETRY; 10589 } 10590 if (si.doneExecutingCount > 0) { 10591 flags |= Service.START_FLAG_REDELIVERY; 10592 } 10593 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 10594 } catch (RemoteException e) { 10595 // Remote process gone... we'll let the normal cleanup take 10596 // care of this. 10597 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 10598 break; 10599 } catch (Exception e) { 10600 Slog.w(TAG, "Unexpected exception", e); 10601 break; 10602 } 10603 } 10604 } 10605 10606 private final boolean requestServiceBindingLocked(ServiceRecord r, 10607 IntentBindRecord i, boolean rebind) { 10608 if (r.app == null || r.app.thread == null) { 10609 // If service is not currently running, can't yet bind. 10610 return false; 10611 } 10612 if ((!i.requested || rebind) && i.apps.size() > 0) { 10613 try { 10614 bumpServiceExecutingLocked(r, "bind"); 10615 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10616 if (!rebind) { 10617 i.requested = true; 10618 } 10619 i.hasBound = true; 10620 i.doRebind = false; 10621 } catch (RemoteException e) { 10622 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 10623 return false; 10624 } 10625 } 10626 return true; 10627 } 10628 10629 private final void requestServiceBindingsLocked(ServiceRecord r) { 10630 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10631 while (bindings.hasNext()) { 10632 IntentBindRecord i = bindings.next(); 10633 if (!requestServiceBindingLocked(r, i, false)) { 10634 break; 10635 } 10636 } 10637 } 10638 10639 private final void realStartServiceLocked(ServiceRecord r, 10640 ProcessRecord app) throws RemoteException { 10641 if (app.thread == null) { 10642 throw new RemoteException(); 10643 } 10644 10645 r.app = app; 10646 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10647 10648 app.services.add(r); 10649 bumpServiceExecutingLocked(r, "create"); 10650 updateLruProcessLocked(app, true, true); 10651 10652 boolean created = false; 10653 try { 10654 mStringBuilder.setLength(0); 10655 r.intent.getIntent().toShortString(mStringBuilder, true, false, true); 10656 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 10657 System.identityHashCode(r), r.shortName, 10658 mStringBuilder.toString(), r.app.pid); 10659 synchronized (r.stats.getBatteryStats()) { 10660 r.stats.startLaunchedLocked(); 10661 } 10662 ensurePackageDexOpt(r.serviceInfo.packageName); 10663 app.thread.scheduleCreateService(r, r.serviceInfo, 10664 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 10665 r.postNotification(); 10666 created = true; 10667 } finally { 10668 if (!created) { 10669 app.services.remove(r); 10670 scheduleServiceRestartLocked(r, false); 10671 } 10672 } 10673 10674 requestServiceBindingsLocked(r); 10675 10676 // If the service is in the started state, and there are no 10677 // pending arguments, then fake up one so its onStartCommand() will 10678 // be called. 10679 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10680 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 10681 null, -1)); 10682 } 10683 10684 sendServiceArgsLocked(r, true); 10685 } 10686 10687 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10688 boolean allowCancel) { 10689 boolean canceled = false; 10690 10691 final long now = SystemClock.uptimeMillis(); 10692 long minDuration = SERVICE_RESTART_DURATION; 10693 long resetTime = SERVICE_RESET_RUN_DURATION; 10694 10695 if ((r.serviceInfo.applicationInfo.flags 10696 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 10697 minDuration /= 4; 10698 } 10699 10700 // Any delivered but not yet finished starts should be put back 10701 // on the pending list. 10702 final int N = r.deliveredStarts.size(); 10703 if (N > 0) { 10704 for (int i=N-1; i>=0; i--) { 10705 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10706 si.removeUriPermissionsLocked(); 10707 if (si.intent == null) { 10708 // We'll generate this again if needed. 10709 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10710 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10711 r.pendingStarts.add(0, si); 10712 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10713 dur *= 2; 10714 if (minDuration < dur) minDuration = dur; 10715 if (resetTime < dur) resetTime = dur; 10716 } else { 10717 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 10718 + r.name); 10719 canceled = true; 10720 } 10721 } 10722 r.deliveredStarts.clear(); 10723 } 10724 10725 r.totalRestartCount++; 10726 if (r.restartDelay == 0) { 10727 r.restartCount++; 10728 r.restartDelay = minDuration; 10729 } else { 10730 // If it has been a "reasonably long time" since the service 10731 // was started, then reset our restart duration back to 10732 // the beginning, so we don't infinitely increase the duration 10733 // on a service that just occasionally gets killed (which is 10734 // a normal case, due to process being killed to reclaim memory). 10735 if (now > (r.restartTime+resetTime)) { 10736 r.restartCount = 1; 10737 r.restartDelay = minDuration; 10738 } else { 10739 if ((r.serviceInfo.applicationInfo.flags 10740 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 10741 // Services in peristent processes will restart much more 10742 // quickly, since they are pretty important. (Think SystemUI). 10743 r.restartDelay += minDuration/2; 10744 } else { 10745 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10746 if (r.restartDelay < minDuration) { 10747 r.restartDelay = minDuration; 10748 } 10749 } 10750 } 10751 } 10752 10753 r.nextRestartTime = now + r.restartDelay; 10754 10755 // Make sure that we don't end up restarting a bunch of services 10756 // all at the same time. 10757 boolean repeat; 10758 do { 10759 repeat = false; 10760 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10761 ServiceRecord r2 = mRestartingServices.get(i); 10762 if (r2 != r && r.nextRestartTime 10763 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10764 && r.nextRestartTime 10765 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10766 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10767 r.restartDelay = r.nextRestartTime - now; 10768 repeat = true; 10769 break; 10770 } 10771 } 10772 } while (repeat); 10773 10774 if (!mRestartingServices.contains(r)) { 10775 mRestartingServices.add(r); 10776 } 10777 10778 r.cancelNotification(); 10779 10780 mHandler.removeCallbacks(r.restarter); 10781 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10782 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10783 Slog.w(TAG, "Scheduling restart of crashed service " 10784 + r.shortName + " in " + r.restartDelay + "ms"); 10785 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 10786 r.shortName, r.restartDelay); 10787 10788 return canceled; 10789 } 10790 10791 final void performServiceRestartLocked(ServiceRecord r) { 10792 if (!mRestartingServices.contains(r)) { 10793 return; 10794 } 10795 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10796 } 10797 10798 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10799 if (r.restartDelay == 0) { 10800 return false; 10801 } 10802 r.resetRestartCounter(); 10803 mRestartingServices.remove(r); 10804 mHandler.removeCallbacks(r.restarter); 10805 return true; 10806 } 10807 10808 private final boolean bringUpServiceLocked(ServiceRecord r, 10809 int intentFlags, boolean whileRestarting) { 10810 //Slog.i(TAG, "Bring up service:"); 10811 //r.dump(" "); 10812 10813 if (r.app != null && r.app.thread != null) { 10814 sendServiceArgsLocked(r, false); 10815 return true; 10816 } 10817 10818 if (!whileRestarting && r.restartDelay > 0) { 10819 // If waiting for a restart, then do nothing. 10820 return true; 10821 } 10822 10823 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 10824 10825 // We are now bringing the service up, so no longer in the 10826 // restarting state. 10827 mRestartingServices.remove(r); 10828 10829 // Service is now being launched, its package can't be stopped. 10830 try { 10831 AppGlobals.getPackageManager().setPackageStoppedState( 10832 r.packageName, false); 10833 } catch (RemoteException e) { 10834 } catch (IllegalArgumentException e) { 10835 Slog.w(TAG, "Failed trying to unstop package " 10836 + r.packageName + ": " + e); 10837 } 10838 10839 final String appName = r.processName; 10840 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10841 if (app != null && app.thread != null) { 10842 try { 10843 app.addPackage(r.appInfo.packageName); 10844 realStartServiceLocked(r, app); 10845 return true; 10846 } catch (RemoteException e) { 10847 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 10848 } 10849 10850 // If a dead object exception was thrown -- fall through to 10851 // restart the application. 10852 } 10853 10854 // Not running -- get it started, and enqueue this service record 10855 // to be executed when the app comes up. 10856 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10857 "service", r.name, false) == null) { 10858 Slog.w(TAG, "Unable to launch app " 10859 + r.appInfo.packageName + "/" 10860 + r.appInfo.uid + " for service " 10861 + r.intent.getIntent() + ": process is bad"); 10862 bringDownServiceLocked(r, true); 10863 return false; 10864 } 10865 10866 if (!mPendingServices.contains(r)) { 10867 mPendingServices.add(r); 10868 } 10869 10870 return true; 10871 } 10872 10873 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10874 //Slog.i(TAG, "Bring down service:"); 10875 //r.dump(" "); 10876 10877 // Does it still need to run? 10878 if (!force && r.startRequested) { 10879 return; 10880 } 10881 if (r.connections.size() > 0) { 10882 if (!force) { 10883 // XXX should probably keep a count of the number of auto-create 10884 // connections directly in the service. 10885 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 10886 while (it.hasNext()) { 10887 ArrayList<ConnectionRecord> cr = it.next(); 10888 for (int i=0; i<cr.size(); i++) { 10889 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 10890 return; 10891 } 10892 } 10893 } 10894 } 10895 10896 // Report to all of the connections that the service is no longer 10897 // available. 10898 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 10899 while (it.hasNext()) { 10900 ArrayList<ConnectionRecord> c = it.next(); 10901 for (int i=0; i<c.size(); i++) { 10902 ConnectionRecord cr = c.get(i); 10903 // There is still a connection to the service that is 10904 // being brought down. Mark it as dead. 10905 cr.serviceDead = true; 10906 try { 10907 cr.conn.connected(r.name, null); 10908 } catch (Exception e) { 10909 Slog.w(TAG, "Failure disconnecting service " + r.name + 10910 " to connection " + c.get(i).conn.asBinder() + 10911 " (in " + c.get(i).binding.client.processName + ")", e); 10912 } 10913 } 10914 } 10915 } 10916 10917 // Tell the service that it has been unbound. 10918 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10919 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10920 while (it.hasNext()) { 10921 IntentBindRecord ibr = it.next(); 10922 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 10923 + ": hasBound=" + ibr.hasBound); 10924 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10925 try { 10926 bumpServiceExecutingLocked(r, "bring down unbind"); 10927 updateOomAdjLocked(r.app); 10928 ibr.hasBound = false; 10929 r.app.thread.scheduleUnbindService(r, 10930 ibr.intent.getIntent()); 10931 } catch (Exception e) { 10932 Slog.w(TAG, "Exception when unbinding service " 10933 + r.shortName, e); 10934 serviceDoneExecutingLocked(r, true); 10935 } 10936 } 10937 } 10938 } 10939 10940 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 10941 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 10942 System.identityHashCode(r), r.shortName, 10943 (r.app != null) ? r.app.pid : -1); 10944 10945 mServices.remove(r.name); 10946 mServicesByIntent.remove(r.intent); 10947 r.totalRestartCount = 0; 10948 unscheduleServiceRestartLocked(r); 10949 10950 // Also make sure it is not on the pending list. 10951 int N = mPendingServices.size(); 10952 for (int i=0; i<N; i++) { 10953 if (mPendingServices.get(i) == r) { 10954 mPendingServices.remove(i); 10955 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 10956 i--; 10957 N--; 10958 } 10959 } 10960 10961 r.cancelNotification(); 10962 r.isForeground = false; 10963 r.foregroundId = 0; 10964 r.foregroundNoti = null; 10965 10966 // Clear start entries. 10967 r.clearDeliveredStartsLocked(); 10968 r.pendingStarts.clear(); 10969 10970 if (r.app != null) { 10971 synchronized (r.stats.getBatteryStats()) { 10972 r.stats.stopLaunchedLocked(); 10973 } 10974 r.app.services.remove(r); 10975 if (r.app.thread != null) { 10976 try { 10977 bumpServiceExecutingLocked(r, "stop"); 10978 mStoppingServices.add(r); 10979 updateOomAdjLocked(r.app); 10980 r.app.thread.scheduleStopService(r); 10981 } catch (Exception e) { 10982 Slog.w(TAG, "Exception when stopping service " 10983 + r.shortName, e); 10984 serviceDoneExecutingLocked(r, true); 10985 } 10986 updateServiceForegroundLocked(r.app, false); 10987 } else { 10988 if (DEBUG_SERVICE) Slog.v( 10989 TAG, "Removed service that has no process: " + r); 10990 } 10991 } else { 10992 if (DEBUG_SERVICE) Slog.v( 10993 TAG, "Removed service that is not running: " + r); 10994 } 10995 10996 if (r.bindings.size() > 0) { 10997 r.bindings.clear(); 10998 } 10999 11000 if (r.restarter instanceof ServiceRestarter) { 11001 ((ServiceRestarter)r.restarter).setService(null); 11002 } 11003 } 11004 11005 ComponentName startServiceLocked(IApplicationThread caller, 11006 Intent service, String resolvedType, 11007 int callingPid, int callingUid) { 11008 synchronized(this) { 11009 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11010 + " type=" + resolvedType + " args=" + service.getExtras()); 11011 11012 if (caller != null) { 11013 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11014 if (callerApp == null) { 11015 throw new SecurityException( 11016 "Unable to find app for caller " + caller 11017 + " (pid=" + Binder.getCallingPid() 11018 + ") when starting service " + service); 11019 } 11020 } 11021 11022 ServiceLookupResult res = 11023 retrieveServiceLocked(service, resolvedType, 11024 callingPid, callingUid); 11025 if (res == null) { 11026 return null; 11027 } 11028 if (res.record == null) { 11029 return new ComponentName("!", res.permission != null 11030 ? res.permission : "private to package"); 11031 } 11032 ServiceRecord r = res.record; 11033 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked( 11034 callingUid, r.packageName, service); 11035 if (unscheduleServiceRestartLocked(r)) { 11036 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 11037 } 11038 r.startRequested = true; 11039 r.callStart = false; 11040 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11041 service, targetPermissionUid)); 11042 r.lastActivity = SystemClock.uptimeMillis(); 11043 synchronized (r.stats.getBatteryStats()) { 11044 r.stats.startRunningLocked(); 11045 } 11046 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11047 return new ComponentName("!", "Service process is bad"); 11048 } 11049 return r.name; 11050 } 11051 } 11052 11053 public ComponentName startService(IApplicationThread caller, Intent service, 11054 String resolvedType) { 11055 // Refuse possible leaked file descriptors 11056 if (service != null && service.hasFileDescriptors() == true) { 11057 throw new IllegalArgumentException("File descriptors passed in Intent"); 11058 } 11059 11060 synchronized(this) { 11061 final int callingPid = Binder.getCallingPid(); 11062 final int callingUid = Binder.getCallingUid(); 11063 final long origId = Binder.clearCallingIdentity(); 11064 ComponentName res = startServiceLocked(caller, service, 11065 resolvedType, callingPid, callingUid); 11066 Binder.restoreCallingIdentity(origId); 11067 return res; 11068 } 11069 } 11070 11071 ComponentName startServiceInPackage(int uid, 11072 Intent service, String resolvedType) { 11073 synchronized(this) { 11074 final long origId = Binder.clearCallingIdentity(); 11075 ComponentName res = startServiceLocked(null, service, 11076 resolvedType, -1, uid); 11077 Binder.restoreCallingIdentity(origId); 11078 return res; 11079 } 11080 } 11081 11082 private void stopServiceLocked(ServiceRecord service) { 11083 synchronized (service.stats.getBatteryStats()) { 11084 service.stats.stopRunningLocked(); 11085 } 11086 service.startRequested = false; 11087 service.callStart = false; 11088 bringDownServiceLocked(service, false); 11089 } 11090 11091 public int stopService(IApplicationThread caller, Intent service, 11092 String resolvedType) { 11093 // Refuse possible leaked file descriptors 11094 if (service != null && service.hasFileDescriptors() == true) { 11095 throw new IllegalArgumentException("File descriptors passed in Intent"); 11096 } 11097 11098 synchronized(this) { 11099 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11100 + " type=" + resolvedType); 11101 11102 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11103 if (caller != null && callerApp == null) { 11104 throw new SecurityException( 11105 "Unable to find app for caller " + caller 11106 + " (pid=" + Binder.getCallingPid() 11107 + ") when stopping service " + service); 11108 } 11109 11110 // If this service is active, make sure it is stopped. 11111 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11112 if (r != null) { 11113 if (r.record != null) { 11114 final long origId = Binder.clearCallingIdentity(); 11115 try { 11116 stopServiceLocked(r.record); 11117 } finally { 11118 Binder.restoreCallingIdentity(origId); 11119 } 11120 return 1; 11121 } 11122 return -1; 11123 } 11124 } 11125 11126 return 0; 11127 } 11128 11129 public IBinder peekService(Intent service, String resolvedType) { 11130 // Refuse possible leaked file descriptors 11131 if (service != null && service.hasFileDescriptors() == true) { 11132 throw new IllegalArgumentException("File descriptors passed in Intent"); 11133 } 11134 11135 IBinder ret = null; 11136 11137 synchronized(this) { 11138 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11139 11140 if (r != null) { 11141 // r.record is null if findServiceLocked() failed the caller permission check 11142 if (r.record == null) { 11143 throw new SecurityException( 11144 "Permission Denial: Accessing service " + r.record.name 11145 + " from pid=" + Binder.getCallingPid() 11146 + ", uid=" + Binder.getCallingUid() 11147 + " requires " + r.permission); 11148 } 11149 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11150 if (ib != null) { 11151 ret = ib.binder; 11152 } 11153 } 11154 } 11155 11156 return ret; 11157 } 11158 11159 public boolean stopServiceToken(ComponentName className, IBinder token, 11160 int startId) { 11161 synchronized(this) { 11162 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11163 + " " + token + " startId=" + startId); 11164 ServiceRecord r = findServiceLocked(className, token); 11165 if (r != null) { 11166 if (startId >= 0) { 11167 // Asked to only stop if done with all work. Note that 11168 // to avoid leaks, we will take this as dropping all 11169 // start items up to and including this one. 11170 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11171 if (si != null) { 11172 while (r.deliveredStarts.size() > 0) { 11173 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 11174 cur.removeUriPermissionsLocked(); 11175 if (cur == si) { 11176 break; 11177 } 11178 } 11179 } 11180 11181 if (r.getLastStartId() != startId) { 11182 return false; 11183 } 11184 11185 if (r.deliveredStarts.size() > 0) { 11186 Slog.w(TAG, "stopServiceToken startId " + startId 11187 + " is last, but have " + r.deliveredStarts.size() 11188 + " remaining args"); 11189 } 11190 } 11191 11192 synchronized (r.stats.getBatteryStats()) { 11193 r.stats.stopRunningLocked(); 11194 r.startRequested = false; 11195 r.callStart = false; 11196 } 11197 final long origId = Binder.clearCallingIdentity(); 11198 bringDownServiceLocked(r, false); 11199 Binder.restoreCallingIdentity(origId); 11200 return true; 11201 } 11202 } 11203 return false; 11204 } 11205 11206 public void setServiceForeground(ComponentName className, IBinder token, 11207 int id, Notification notification, boolean removeNotification) { 11208 final long origId = Binder.clearCallingIdentity(); 11209 try { 11210 synchronized(this) { 11211 ServiceRecord r = findServiceLocked(className, token); 11212 if (r != null) { 11213 if (id != 0) { 11214 if (notification == null) { 11215 throw new IllegalArgumentException("null notification"); 11216 } 11217 if (r.foregroundId != id) { 11218 r.cancelNotification(); 11219 r.foregroundId = id; 11220 } 11221 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11222 r.foregroundNoti = notification; 11223 r.isForeground = true; 11224 r.postNotification(); 11225 if (r.app != null) { 11226 updateServiceForegroundLocked(r.app, true); 11227 } 11228 } else { 11229 if (r.isForeground) { 11230 r.isForeground = false; 11231 if (r.app != null) { 11232 updateLruProcessLocked(r.app, false, true); 11233 updateServiceForegroundLocked(r.app, true); 11234 } 11235 } 11236 if (removeNotification) { 11237 r.cancelNotification(); 11238 r.foregroundId = 0; 11239 r.foregroundNoti = null; 11240 } 11241 } 11242 } 11243 } 11244 } finally { 11245 Binder.restoreCallingIdentity(origId); 11246 } 11247 } 11248 11249 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11250 boolean anyForeground = false; 11251 for (ServiceRecord sr : proc.services) { 11252 if (sr.isForeground) { 11253 anyForeground = true; 11254 break; 11255 } 11256 } 11257 if (anyForeground != proc.foregroundServices) { 11258 proc.foregroundServices = anyForeground; 11259 if (oomAdj) { 11260 updateOomAdjLocked(); 11261 } 11262 } 11263 } 11264 11265 public int bindService(IApplicationThread caller, IBinder token, 11266 Intent service, String resolvedType, 11267 IServiceConnection connection, int flags) { 11268 // Refuse possible leaked file descriptors 11269 if (service != null && service.hasFileDescriptors() == true) { 11270 throw new IllegalArgumentException("File descriptors passed in Intent"); 11271 } 11272 11273 synchronized(this) { 11274 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 11275 + " type=" + resolvedType + " conn=" + connection.asBinder() 11276 + " flags=0x" + Integer.toHexString(flags)); 11277 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11278 if (callerApp == null) { 11279 throw new SecurityException( 11280 "Unable to find app for caller " + caller 11281 + " (pid=" + Binder.getCallingPid() 11282 + ") when binding service " + service); 11283 } 11284 11285 ActivityRecord activity = null; 11286 if (token != null) { 11287 activity = mMainStack.isInStackLocked(token); 11288 if (activity == null) { 11289 Slog.w(TAG, "Binding with unknown activity: " + token); 11290 return 0; 11291 } 11292 } 11293 11294 int clientLabel = 0; 11295 PendingIntent clientIntent = null; 11296 11297 if (callerApp.info.uid == Process.SYSTEM_UID) { 11298 // Hacky kind of thing -- allow system stuff to tell us 11299 // what they are, so we can report this elsewhere for 11300 // others to know why certain services are running. 11301 try { 11302 clientIntent = (PendingIntent)service.getParcelableExtra( 11303 Intent.EXTRA_CLIENT_INTENT); 11304 } catch (RuntimeException e) { 11305 } 11306 if (clientIntent != null) { 11307 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11308 if (clientLabel != 0) { 11309 // There are no useful extras in the intent, trash them. 11310 // System code calling with this stuff just needs to know 11311 // this will happen. 11312 service = service.cloneFilter(); 11313 } 11314 } 11315 } 11316 11317 ServiceLookupResult res = 11318 retrieveServiceLocked(service, resolvedType, 11319 Binder.getCallingPid(), Binder.getCallingUid()); 11320 if (res == null) { 11321 return 0; 11322 } 11323 if (res.record == null) { 11324 return -1; 11325 } 11326 ServiceRecord s = res.record; 11327 11328 final long origId = Binder.clearCallingIdentity(); 11329 11330 if (unscheduleServiceRestartLocked(s)) { 11331 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11332 + s); 11333 } 11334 11335 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11336 ConnectionRecord c = new ConnectionRecord(b, activity, 11337 connection, flags, clientLabel, clientIntent); 11338 11339 IBinder binder = connection.asBinder(); 11340 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 11341 if (clist == null) { 11342 clist = new ArrayList<ConnectionRecord>(); 11343 s.connections.put(binder, clist); 11344 } 11345 clist.add(c); 11346 b.connections.add(c); 11347 if (activity != null) { 11348 if (activity.connections == null) { 11349 activity.connections = new HashSet<ConnectionRecord>(); 11350 } 11351 activity.connections.add(c); 11352 } 11353 b.client.connections.add(c); 11354 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 11355 b.client.hasAboveClient = true; 11356 } 11357 clist = mServiceConnections.get(binder); 11358 if (clist == null) { 11359 clist = new ArrayList<ConnectionRecord>(); 11360 mServiceConnections.put(binder, clist); 11361 } 11362 clist.add(c); 11363 11364 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11365 s.lastActivity = SystemClock.uptimeMillis(); 11366 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11367 return 0; 11368 } 11369 } 11370 11371 if (s.app != null) { 11372 // This could have made the service more important. 11373 updateOomAdjLocked(s.app); 11374 } 11375 11376 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 11377 + ": received=" + b.intent.received 11378 + " apps=" + b.intent.apps.size() 11379 + " doRebind=" + b.intent.doRebind); 11380 11381 if (s.app != null && b.intent.received) { 11382 // Service is already running, so we can immediately 11383 // publish the connection. 11384 try { 11385 c.conn.connected(s.name, b.intent.binder); 11386 } catch (Exception e) { 11387 Slog.w(TAG, "Failure sending service " + s.shortName 11388 + " to connection " + c.conn.asBinder() 11389 + " (in " + c.binding.client.processName + ")", e); 11390 } 11391 11392 // If this is the first app connected back to this binding, 11393 // and the service had previously asked to be told when 11394 // rebound, then do so. 11395 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11396 requestServiceBindingLocked(s, b.intent, true); 11397 } 11398 } else if (!b.intent.requested) { 11399 requestServiceBindingLocked(s, b.intent, false); 11400 } 11401 11402 Binder.restoreCallingIdentity(origId); 11403 } 11404 11405 return 1; 11406 } 11407 11408 void removeConnectionLocked( 11409 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 11410 IBinder binder = c.conn.asBinder(); 11411 AppBindRecord b = c.binding; 11412 ServiceRecord s = b.service; 11413 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 11414 if (clist != null) { 11415 clist.remove(c); 11416 if (clist.size() == 0) { 11417 s.connections.remove(binder); 11418 } 11419 } 11420 b.connections.remove(c); 11421 if (c.activity != null && c.activity != skipAct) { 11422 if (c.activity.connections != null) { 11423 c.activity.connections.remove(c); 11424 } 11425 } 11426 if (b.client != skipApp) { 11427 b.client.connections.remove(c); 11428 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 11429 b.client.updateHasAboveClientLocked(); 11430 } 11431 } 11432 clist = mServiceConnections.get(binder); 11433 if (clist != null) { 11434 clist.remove(c); 11435 if (clist.size() == 0) { 11436 mServiceConnections.remove(binder); 11437 } 11438 } 11439 11440 if (b.connections.size() == 0) { 11441 b.intent.apps.remove(b.client); 11442 } 11443 11444 if (!c.serviceDead) { 11445 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 11446 + ": shouldUnbind=" + b.intent.hasBound); 11447 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11448 && b.intent.hasBound) { 11449 try { 11450 bumpServiceExecutingLocked(s, "unbind"); 11451 updateOomAdjLocked(s.app); 11452 b.intent.hasBound = false; 11453 // Assume the client doesn't want to know about a rebind; 11454 // we will deal with that later if it asks for one. 11455 b.intent.doRebind = false; 11456 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11457 } catch (Exception e) { 11458 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 11459 serviceDoneExecutingLocked(s, true); 11460 } 11461 } 11462 11463 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11464 bringDownServiceLocked(s, false); 11465 } 11466 } 11467 } 11468 11469 public boolean unbindService(IServiceConnection connection) { 11470 synchronized (this) { 11471 IBinder binder = connection.asBinder(); 11472 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 11473 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 11474 if (clist == null) { 11475 Slog.w(TAG, "Unbind failed: could not find connection for " 11476 + connection.asBinder()); 11477 return false; 11478 } 11479 11480 final long origId = Binder.clearCallingIdentity(); 11481 11482 while (clist.size() > 0) { 11483 ConnectionRecord r = clist.get(0); 11484 removeConnectionLocked(r, null, null); 11485 11486 if (r.binding.service.app != null) { 11487 // This could have made the service less important. 11488 updateOomAdjLocked(r.binding.service.app); 11489 } 11490 } 11491 11492 Binder.restoreCallingIdentity(origId); 11493 } 11494 11495 return true; 11496 } 11497 11498 public void publishService(IBinder token, Intent intent, IBinder service) { 11499 // Refuse possible leaked file descriptors 11500 if (intent != null && intent.hasFileDescriptors() == true) { 11501 throw new IllegalArgumentException("File descriptors passed in Intent"); 11502 } 11503 11504 synchronized(this) { 11505 if (!(token instanceof ServiceRecord)) { 11506 throw new IllegalArgumentException("Invalid service token"); 11507 } 11508 ServiceRecord r = (ServiceRecord)token; 11509 11510 final long origId = Binder.clearCallingIdentity(); 11511 11512 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 11513 + " " + intent + ": " + service); 11514 if (r != null) { 11515 Intent.FilterComparison filter 11516 = new Intent.FilterComparison(intent); 11517 IntentBindRecord b = r.bindings.get(filter); 11518 if (b != null && !b.received) { 11519 b.binder = service; 11520 b.requested = true; 11521 b.received = true; 11522 if (r.connections.size() > 0) { 11523 Iterator<ArrayList<ConnectionRecord>> it 11524 = r.connections.values().iterator(); 11525 while (it.hasNext()) { 11526 ArrayList<ConnectionRecord> clist = it.next(); 11527 for (int i=0; i<clist.size(); i++) { 11528 ConnectionRecord c = clist.get(i); 11529 if (!filter.equals(c.binding.intent.intent)) { 11530 if (DEBUG_SERVICE) Slog.v( 11531 TAG, "Not publishing to: " + c); 11532 if (DEBUG_SERVICE) Slog.v( 11533 TAG, "Bound intent: " + c.binding.intent.intent); 11534 if (DEBUG_SERVICE) Slog.v( 11535 TAG, "Published intent: " + intent); 11536 continue; 11537 } 11538 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 11539 try { 11540 c.conn.connected(r.name, service); 11541 } catch (Exception e) { 11542 Slog.w(TAG, "Failure sending service " + r.name + 11543 " to connection " + c.conn.asBinder() + 11544 " (in " + c.binding.client.processName + ")", e); 11545 } 11546 } 11547 } 11548 } 11549 } 11550 11551 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11552 11553 Binder.restoreCallingIdentity(origId); 11554 } 11555 } 11556 } 11557 11558 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11559 // Refuse possible leaked file descriptors 11560 if (intent != null && intent.hasFileDescriptors() == true) { 11561 throw new IllegalArgumentException("File descriptors passed in Intent"); 11562 } 11563 11564 synchronized(this) { 11565 if (!(token instanceof ServiceRecord)) { 11566 throw new IllegalArgumentException("Invalid service token"); 11567 } 11568 ServiceRecord r = (ServiceRecord)token; 11569 11570 final long origId = Binder.clearCallingIdentity(); 11571 11572 if (r != null) { 11573 Intent.FilterComparison filter 11574 = new Intent.FilterComparison(intent); 11575 IntentBindRecord b = r.bindings.get(filter); 11576 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 11577 + " at " + b + ": apps=" 11578 + (b != null ? b.apps.size() : 0)); 11579 11580 boolean inStopping = mStoppingServices.contains(r); 11581 if (b != null) { 11582 if (b.apps.size() > 0 && !inStopping) { 11583 // Applications have already bound since the last 11584 // unbind, so just rebind right here. 11585 requestServiceBindingLocked(r, b, true); 11586 } else { 11587 // Note to tell the service the next time there is 11588 // a new client. 11589 b.doRebind = true; 11590 } 11591 } 11592 11593 serviceDoneExecutingLocked(r, inStopping); 11594 11595 Binder.restoreCallingIdentity(origId); 11596 } 11597 } 11598 } 11599 11600 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11601 synchronized(this) { 11602 if (!(token instanceof ServiceRecord)) { 11603 throw new IllegalArgumentException("Invalid service token"); 11604 } 11605 ServiceRecord r = (ServiceRecord)token; 11606 boolean inStopping = mStoppingServices.contains(token); 11607 if (r != null) { 11608 if (r != token) { 11609 Slog.w(TAG, "Done executing service " + r.name 11610 + " with incorrect token: given " + token 11611 + ", expected " + r); 11612 return; 11613 } 11614 11615 if (type == 1) { 11616 // This is a call from a service start... take care of 11617 // book-keeping. 11618 r.callStart = true; 11619 switch (res) { 11620 case Service.START_STICKY_COMPATIBILITY: 11621 case Service.START_STICKY: { 11622 // We are done with the associated start arguments. 11623 r.findDeliveredStart(startId, true); 11624 // Don't stop if killed. 11625 r.stopIfKilled = false; 11626 break; 11627 } 11628 case Service.START_NOT_STICKY: { 11629 // We are done with the associated start arguments. 11630 r.findDeliveredStart(startId, true); 11631 if (r.getLastStartId() == startId) { 11632 // There is no more work, and this service 11633 // doesn't want to hang around if killed. 11634 r.stopIfKilled = true; 11635 } 11636 break; 11637 } 11638 case Service.START_REDELIVER_INTENT: { 11639 // We'll keep this item until they explicitly 11640 // call stop for it, but keep track of the fact 11641 // that it was delivered. 11642 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11643 if (si != null) { 11644 si.deliveryCount = 0; 11645 si.doneExecutingCount++; 11646 // Don't stop if killed. 11647 r.stopIfKilled = true; 11648 } 11649 break; 11650 } 11651 case Service.START_TASK_REMOVED_COMPLETE: { 11652 // Special processing for onTaskRemoved(). Don't 11653 // impact normal onStartCommand() processing. 11654 r.findDeliveredStart(startId, true); 11655 break; 11656 } 11657 default: 11658 throw new IllegalArgumentException( 11659 "Unknown service start result: " + res); 11660 } 11661 if (res == Service.START_STICKY_COMPATIBILITY) { 11662 r.callStart = false; 11663 } 11664 } 11665 11666 final long origId = Binder.clearCallingIdentity(); 11667 serviceDoneExecutingLocked(r, inStopping); 11668 Binder.restoreCallingIdentity(origId); 11669 } else { 11670 Slog.w(TAG, "Done executing unknown service from pid " 11671 + Binder.getCallingPid()); 11672 } 11673 } 11674 } 11675 11676 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11677 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 11678 + ": nesting=" + r.executeNesting 11679 + ", inStopping=" + inStopping + ", app=" + r.app); 11680 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 11681 r.executeNesting--; 11682 if (r.executeNesting <= 0 && r.app != null) { 11683 if (DEBUG_SERVICE) Slog.v(TAG, 11684 "Nesting at 0 of " + r.shortName); 11685 r.app.executingServices.remove(r); 11686 if (r.app.executingServices.size() == 0) { 11687 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 11688 "No more executingServices of " + r.shortName); 11689 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11690 } 11691 if (inStopping) { 11692 if (DEBUG_SERVICE) Slog.v(TAG, 11693 "doneExecuting remove stopping " + r); 11694 mStoppingServices.remove(r); 11695 r.bindings.clear(); 11696 } 11697 updateOomAdjLocked(r.app); 11698 } 11699 } 11700 11701 void serviceTimeout(ProcessRecord proc) { 11702 String anrMessage = null; 11703 11704 synchronized(this) { 11705 if (proc.executingServices.size() == 0 || proc.thread == null) { 11706 return; 11707 } 11708 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11709 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11710 ServiceRecord timeout = null; 11711 long nextTime = 0; 11712 while (it.hasNext()) { 11713 ServiceRecord sr = it.next(); 11714 if (sr.executingStart < maxTime) { 11715 timeout = sr; 11716 break; 11717 } 11718 if (sr.executingStart > nextTime) { 11719 nextTime = sr.executingStart; 11720 } 11721 } 11722 if (timeout != null && mLruProcesses.contains(proc)) { 11723 Slog.w(TAG, "Timeout executing service: " + timeout); 11724 anrMessage = "Executing service " + timeout.shortName; 11725 } else { 11726 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11727 msg.obj = proc; 11728 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11729 } 11730 } 11731 11732 if (anrMessage != null) { 11733 appNotResponding(proc, null, null, anrMessage); 11734 } 11735 } 11736 11737 // ========================================================= 11738 // BACKUP AND RESTORE 11739 // ========================================================= 11740 11741 // Cause the target app to be launched if necessary and its backup agent 11742 // instantiated. The backup agent will invoke backupAgentCreated() on the 11743 // activity manager to announce its creation. 11744 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11745 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11746 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11747 11748 synchronized(this) { 11749 // !!! TODO: currently no check here that we're already bound 11750 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11751 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11752 synchronized (stats) { 11753 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11754 } 11755 11756 // Backup agent is now in use, its package can't be stopped. 11757 try { 11758 AppGlobals.getPackageManager().setPackageStoppedState( 11759 app.packageName, false); 11760 } catch (RemoteException e) { 11761 } catch (IllegalArgumentException e) { 11762 Slog.w(TAG, "Failed trying to unstop package " 11763 + app.packageName + ": " + e); 11764 } 11765 11766 BackupRecord r = new BackupRecord(ss, app, backupMode); 11767 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11768 ? new ComponentName(app.packageName, app.backupAgentName) 11769 : new ComponentName("android", "FullBackupAgent"); 11770 // startProcessLocked() returns existing proc's record if it's already running 11771 ProcessRecord proc = startProcessLocked(app.processName, app, 11772 false, 0, "backup", hostingName, false); 11773 if (proc == null) { 11774 Slog.e(TAG, "Unable to start backup agent process " + r); 11775 return false; 11776 } 11777 11778 r.app = proc; 11779 mBackupTarget = r; 11780 mBackupAppName = app.packageName; 11781 11782 // Try not to kill the process during backup 11783 updateOomAdjLocked(proc); 11784 11785 // If the process is already attached, schedule the creation of the backup agent now. 11786 // If it is not yet live, this will be done when it attaches to the framework. 11787 if (proc.thread != null) { 11788 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11789 try { 11790 proc.thread.scheduleCreateBackupAgent(app, 11791 compatibilityInfoForPackageLocked(app), backupMode); 11792 } catch (RemoteException e) { 11793 // Will time out on the backup manager side 11794 } 11795 } else { 11796 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11797 } 11798 // Invariants: at this point, the target app process exists and the application 11799 // is either already running or in the process of coming up. mBackupTarget and 11800 // mBackupAppName describe the app, so that when it binds back to the AM we 11801 // know that it's scheduled for a backup-agent operation. 11802 } 11803 11804 return true; 11805 } 11806 11807 // A backup agent has just come up 11808 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11809 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11810 + " = " + agent); 11811 11812 synchronized(this) { 11813 if (!agentPackageName.equals(mBackupAppName)) { 11814 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11815 return; 11816 } 11817 } 11818 11819 long oldIdent = Binder.clearCallingIdentity(); 11820 try { 11821 IBackupManager bm = IBackupManager.Stub.asInterface( 11822 ServiceManager.getService(Context.BACKUP_SERVICE)); 11823 bm.agentConnected(agentPackageName, agent); 11824 } catch (RemoteException e) { 11825 // can't happen; the backup manager service is local 11826 } catch (Exception e) { 11827 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11828 e.printStackTrace(); 11829 } finally { 11830 Binder.restoreCallingIdentity(oldIdent); 11831 } 11832 } 11833 11834 // done with this agent 11835 public void unbindBackupAgent(ApplicationInfo appInfo) { 11836 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11837 if (appInfo == null) { 11838 Slog.w(TAG, "unbind backup agent for null app"); 11839 return; 11840 } 11841 11842 synchronized(this) { 11843 if (mBackupAppName == null) { 11844 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11845 return; 11846 } 11847 11848 if (!mBackupAppName.equals(appInfo.packageName)) { 11849 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11850 return; 11851 } 11852 11853 ProcessRecord proc = mBackupTarget.app; 11854 mBackupTarget = null; 11855 mBackupAppName = null; 11856 11857 // Not backing this app up any more; reset its OOM adjustment 11858 updateOomAdjLocked(proc); 11859 11860 // If the app crashed during backup, 'thread' will be null here 11861 if (proc.thread != null) { 11862 try { 11863 proc.thread.scheduleDestroyBackupAgent(appInfo, 11864 compatibilityInfoForPackageLocked(appInfo)); 11865 } catch (Exception e) { 11866 Slog.e(TAG, "Exception when unbinding backup agent:"); 11867 e.printStackTrace(); 11868 } 11869 } 11870 } 11871 } 11872 // ========================================================= 11873 // BROADCASTS 11874 // ========================================================= 11875 11876 private final List getStickiesLocked(String action, IntentFilter filter, 11877 List cur) { 11878 final ContentResolver resolver = mContext.getContentResolver(); 11879 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11880 if (list == null) { 11881 return cur; 11882 } 11883 int N = list.size(); 11884 for (int i=0; i<N; i++) { 11885 Intent intent = list.get(i); 11886 if (filter.match(resolver, intent, true, TAG) >= 0) { 11887 if (cur == null) { 11888 cur = new ArrayList<Intent>(); 11889 } 11890 cur.add(intent); 11891 } 11892 } 11893 return cur; 11894 } 11895 11896 private final void scheduleBroadcastsLocked() { 11897 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current=" 11898 + mBroadcastsScheduled); 11899 11900 if (mBroadcastsScheduled) { 11901 return; 11902 } 11903 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11904 mBroadcastsScheduled = true; 11905 } 11906 11907 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11908 IIntentReceiver receiver, IntentFilter filter, String permission) { 11909 synchronized(this) { 11910 ProcessRecord callerApp = null; 11911 if (caller != null) { 11912 callerApp = getRecordForAppLocked(caller); 11913 if (callerApp == null) { 11914 throw new SecurityException( 11915 "Unable to find app for caller " + caller 11916 + " (pid=" + Binder.getCallingPid() 11917 + ") when registering receiver " + receiver); 11918 } 11919 if (callerApp.info.uid != Process.SYSTEM_UID && 11920 !callerApp.pkgList.contains(callerPackage)) { 11921 throw new SecurityException("Given caller package " + callerPackage 11922 + " is not running in process " + callerApp); 11923 } 11924 } else { 11925 callerPackage = null; 11926 } 11927 11928 List allSticky = null; 11929 11930 // Look for any matching sticky broadcasts... 11931 Iterator actions = filter.actionsIterator(); 11932 if (actions != null) { 11933 while (actions.hasNext()) { 11934 String action = (String)actions.next(); 11935 allSticky = getStickiesLocked(action, filter, allSticky); 11936 } 11937 } else { 11938 allSticky = getStickiesLocked(null, filter, allSticky); 11939 } 11940 11941 // The first sticky in the list is returned directly back to 11942 // the client. 11943 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11944 11945 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11946 + ": " + sticky); 11947 11948 if (receiver == null) { 11949 return sticky; 11950 } 11951 11952 ReceiverList rl 11953 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11954 if (rl == null) { 11955 rl = new ReceiverList(this, callerApp, 11956 Binder.getCallingPid(), 11957 Binder.getCallingUid(), receiver); 11958 if (rl.app != null) { 11959 rl.app.receivers.add(rl); 11960 } else { 11961 try { 11962 receiver.asBinder().linkToDeath(rl, 0); 11963 } catch (RemoteException e) { 11964 return sticky; 11965 } 11966 rl.linkedToDeath = true; 11967 } 11968 mRegisteredReceivers.put(receiver.asBinder(), rl); 11969 } 11970 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 11971 rl.add(bf); 11972 if (!bf.debugCheck()) { 11973 Slog.w(TAG, "==> For Dynamic broadast"); 11974 } 11975 mReceiverResolver.addFilter(bf); 11976 11977 // Enqueue broadcasts for all existing stickies that match 11978 // this filter. 11979 if (allSticky != null) { 11980 ArrayList receivers = new ArrayList(); 11981 receivers.add(bf); 11982 11983 int N = allSticky.size(); 11984 for (int i=0; i<N; i++) { 11985 Intent intent = (Intent)allSticky.get(i); 11986 BroadcastRecord r = new BroadcastRecord(intent, null, 11987 null, -1, -1, null, receivers, null, 0, null, null, 11988 false, true, true); 11989 if (mParallelBroadcasts.size() == 0) { 11990 scheduleBroadcastsLocked(); 11991 } 11992 mParallelBroadcasts.add(r); 11993 } 11994 } 11995 11996 return sticky; 11997 } 11998 } 11999 12000 public void unregisterReceiver(IIntentReceiver receiver) { 12001 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12002 12003 boolean doNext = false; 12004 12005 synchronized(this) { 12006 ReceiverList rl 12007 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12008 if (rl != null) { 12009 if (rl.curBroadcast != null) { 12010 BroadcastRecord r = rl.curBroadcast; 12011 doNext = finishReceiverLocked( 12012 receiver.asBinder(), r.resultCode, r.resultData, 12013 r.resultExtras, r.resultAbort, true); 12014 } 12015 12016 if (rl.app != null) { 12017 rl.app.receivers.remove(rl); 12018 } 12019 removeReceiverLocked(rl); 12020 if (rl.linkedToDeath) { 12021 rl.linkedToDeath = false; 12022 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12023 } 12024 } 12025 } 12026 12027 if (!doNext) { 12028 return; 12029 } 12030 12031 final long origId = Binder.clearCallingIdentity(); 12032 processNextBroadcast(false); 12033 trimApplications(); 12034 Binder.restoreCallingIdentity(origId); 12035 } 12036 12037 void removeReceiverLocked(ReceiverList rl) { 12038 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12039 int N = rl.size(); 12040 for (int i=0; i<N; i++) { 12041 mReceiverResolver.removeFilter(rl.get(i)); 12042 } 12043 } 12044 12045 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12046 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12047 ProcessRecord r = mLruProcesses.get(i); 12048 if (r.thread != null) { 12049 try { 12050 r.thread.dispatchPackageBroadcast(cmd, packages); 12051 } catch (RemoteException ex) { 12052 } 12053 } 12054 } 12055 } 12056 12057 private final int broadcastIntentLocked(ProcessRecord callerApp, 12058 String callerPackage, Intent intent, String resolvedType, 12059 IIntentReceiver resultTo, int resultCode, String resultData, 12060 Bundle map, String requiredPermission, 12061 boolean ordered, boolean sticky, int callingPid, int callingUid) { 12062 intent = new Intent(intent); 12063 12064 // By default broadcasts do not go to stopped apps. 12065 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 12066 12067 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12068 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12069 + " ordered=" + ordered); 12070 if ((resultTo != null) && !ordered) { 12071 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12072 } 12073 12074 // Handle special intents: if this broadcast is from the package 12075 // manager about a package being removed, we need to remove all of 12076 // its activities from the history stack. 12077 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 12078 intent.getAction()); 12079 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12080 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12081 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12082 || uidRemoved) { 12083 if (checkComponentPermission( 12084 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12085 callingPid, callingUid, -1, true) 12086 == PackageManager.PERMISSION_GRANTED) { 12087 if (uidRemoved) { 12088 final Bundle intentExtras = intent.getExtras(); 12089 final int uid = intentExtras != null 12090 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12091 if (uid >= 0) { 12092 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12093 synchronized (bs) { 12094 bs.removeUidStatsLocked(uid); 12095 } 12096 } 12097 } else { 12098 // If resources are unvailble just force stop all 12099 // those packages and flush the attribute cache as well. 12100 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12101 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12102 if (list != null && (list.length > 0)) { 12103 for (String pkg : list) { 12104 forceStopPackageLocked(pkg, -1, false, true, true, false); 12105 } 12106 sendPackageBroadcastLocked( 12107 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12108 } 12109 } else { 12110 Uri data = intent.getData(); 12111 String ssp; 12112 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12113 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12114 forceStopPackageLocked(ssp, 12115 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false); 12116 } 12117 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12118 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12119 new String[] {ssp}); 12120 } 12121 } 12122 } 12123 } 12124 } else { 12125 String msg = "Permission Denial: " + intent.getAction() 12126 + " broadcast from " + callerPackage + " (pid=" + callingPid 12127 + ", uid=" + callingUid + ")" 12128 + " requires " 12129 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12130 Slog.w(TAG, msg); 12131 throw new SecurityException(msg); 12132 } 12133 12134 // Special case for adding a package: by default turn on compatibility 12135 // mode. 12136 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12137 Uri data = intent.getData(); 12138 String ssp; 12139 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12140 mCompatModePackages.handlePackageAddedLocked(ssp, 12141 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12142 } 12143 } 12144 12145 /* 12146 * If this is the time zone changed action, queue up a message that will reset the timezone 12147 * of all currently running processes. This message will get queued up before the broadcast 12148 * happens. 12149 */ 12150 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12151 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12152 } 12153 12154 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12155 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12156 } 12157 12158 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12159 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12160 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12161 } 12162 12163 /* 12164 * Prevent non-system code (defined here to be non-persistent 12165 * processes) from sending protected broadcasts. 12166 */ 12167 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12168 || callingUid == Process.SHELL_UID || callingUid == 0) { 12169 // Always okay. 12170 } else if (callerApp == null || !callerApp.persistent) { 12171 try { 12172 if (AppGlobals.getPackageManager().isProtectedBroadcast( 12173 intent.getAction())) { 12174 String msg = "Permission Denial: not allowed to send broadcast " 12175 + intent.getAction() + " from pid=" 12176 + callingPid + ", uid=" + callingUid; 12177 Slog.w(TAG, msg); 12178 throw new SecurityException(msg); 12179 } 12180 } catch (RemoteException e) { 12181 Slog.w(TAG, "Remote exception", e); 12182 return BROADCAST_SUCCESS; 12183 } 12184 } 12185 12186 // Add to the sticky list if requested. 12187 if (sticky) { 12188 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12189 callingPid, callingUid) 12190 != PackageManager.PERMISSION_GRANTED) { 12191 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12192 + callingPid + ", uid=" + callingUid 12193 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12194 Slog.w(TAG, msg); 12195 throw new SecurityException(msg); 12196 } 12197 if (requiredPermission != null) { 12198 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12199 + " and enforce permission " + requiredPermission); 12200 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12201 } 12202 if (intent.getComponent() != null) { 12203 throw new SecurityException( 12204 "Sticky broadcasts can't target a specific component"); 12205 } 12206 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12207 if (list == null) { 12208 list = new ArrayList<Intent>(); 12209 mStickyBroadcasts.put(intent.getAction(), list); 12210 } 12211 int N = list.size(); 12212 int i; 12213 for (i=0; i<N; i++) { 12214 if (intent.filterEquals(list.get(i))) { 12215 // This sticky already exists, replace it. 12216 list.set(i, new Intent(intent)); 12217 break; 12218 } 12219 } 12220 if (i >= N) { 12221 list.add(new Intent(intent)); 12222 } 12223 } 12224 12225 // Figure out who all will receive this broadcast. 12226 List receivers = null; 12227 List<BroadcastFilter> registeredReceivers = null; 12228 try { 12229 if (intent.getComponent() != null) { 12230 // Broadcast is going to one specific receiver class... 12231 ActivityInfo ai = AppGlobals.getPackageManager(). 12232 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 12233 if (ai != null) { 12234 receivers = new ArrayList(); 12235 ResolveInfo ri = new ResolveInfo(); 12236 ri.activityInfo = ai; 12237 receivers.add(ri); 12238 } 12239 } else { 12240 // Need to resolve the intent to interested receivers... 12241 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12242 == 0) { 12243 receivers = 12244 AppGlobals.getPackageManager().queryIntentReceivers( 12245 intent, resolvedType, STOCK_PM_FLAGS); 12246 } 12247 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 12248 } 12249 } catch (RemoteException ex) { 12250 // pm is in same process, this will never happen. 12251 } 12252 12253 final boolean replacePending = 12254 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12255 12256 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 12257 + " replacePending=" + replacePending); 12258 12259 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12260 if (!ordered && NR > 0) { 12261 // If we are not serializing this broadcast, then send the 12262 // registered receivers separately so they don't wait for the 12263 // components to be launched. 12264 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12265 callerPackage, callingPid, callingUid, requiredPermission, 12266 registeredReceivers, resultTo, resultCode, resultData, map, 12267 ordered, sticky, false); 12268 if (DEBUG_BROADCAST) Slog.v( 12269 TAG, "Enqueueing parallel broadcast " + r 12270 + ": prev had " + mParallelBroadcasts.size()); 12271 boolean replaced = false; 12272 if (replacePending) { 12273 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 12274 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { 12275 if (DEBUG_BROADCAST) Slog.v(TAG, 12276 "***** DROPPING PARALLEL: " + intent); 12277 mParallelBroadcasts.set(i, r); 12278 replaced = true; 12279 break; 12280 } 12281 } 12282 } 12283 if (!replaced) { 12284 mParallelBroadcasts.add(r); 12285 scheduleBroadcastsLocked(); 12286 } 12287 registeredReceivers = null; 12288 NR = 0; 12289 } 12290 12291 // Merge into one list. 12292 int ir = 0; 12293 if (receivers != null) { 12294 // A special case for PACKAGE_ADDED: do not allow the package 12295 // being added to see this broadcast. This prevents them from 12296 // using this as a back door to get run as soon as they are 12297 // installed. Maybe in the future we want to have a special install 12298 // broadcast or such for apps, but we'd like to deliberately make 12299 // this decision. 12300 String skipPackages[] = null; 12301 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 12302 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 12303 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12304 Uri data = intent.getData(); 12305 if (data != null) { 12306 String pkgName = data.getSchemeSpecificPart(); 12307 if (pkgName != null) { 12308 skipPackages = new String[] { pkgName }; 12309 } 12310 } 12311 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 12312 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12313 } 12314 if (skipPackages != null && (skipPackages.length > 0)) { 12315 for (String skipPackage : skipPackages) { 12316 if (skipPackage != null) { 12317 int NT = receivers.size(); 12318 for (int it=0; it<NT; it++) { 12319 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12320 if (curt.activityInfo.packageName.equals(skipPackage)) { 12321 receivers.remove(it); 12322 it--; 12323 NT--; 12324 } 12325 } 12326 } 12327 } 12328 } 12329 12330 int NT = receivers != null ? receivers.size() : 0; 12331 int it = 0; 12332 ResolveInfo curt = null; 12333 BroadcastFilter curr = null; 12334 while (it < NT && ir < NR) { 12335 if (curt == null) { 12336 curt = (ResolveInfo)receivers.get(it); 12337 } 12338 if (curr == null) { 12339 curr = registeredReceivers.get(ir); 12340 } 12341 if (curr.getPriority() >= curt.priority) { 12342 // Insert this broadcast record into the final list. 12343 receivers.add(it, curr); 12344 ir++; 12345 curr = null; 12346 it++; 12347 NT++; 12348 } else { 12349 // Skip to the next ResolveInfo in the final list. 12350 it++; 12351 curt = null; 12352 } 12353 } 12354 } 12355 while (ir < NR) { 12356 if (receivers == null) { 12357 receivers = new ArrayList(); 12358 } 12359 receivers.add(registeredReceivers.get(ir)); 12360 ir++; 12361 } 12362 12363 if ((receivers != null && receivers.size() > 0) 12364 || resultTo != null) { 12365 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12366 callerPackage, callingPid, callingUid, requiredPermission, 12367 receivers, resultTo, resultCode, resultData, map, ordered, 12368 sticky, false); 12369 if (DEBUG_BROADCAST) Slog.v( 12370 TAG, "Enqueueing ordered broadcast " + r 12371 + ": prev had " + mOrderedBroadcasts.size()); 12372 if (DEBUG_BROADCAST) { 12373 int seq = r.intent.getIntExtra("seq", -1); 12374 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12375 } 12376 boolean replaced = false; 12377 if (replacePending) { 12378 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) { 12379 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { 12380 if (DEBUG_BROADCAST) Slog.v(TAG, 12381 "***** DROPPING ORDERED: " + intent); 12382 mOrderedBroadcasts.set(i, r); 12383 replaced = true; 12384 break; 12385 } 12386 } 12387 } 12388 if (!replaced) { 12389 mOrderedBroadcasts.add(r); 12390 scheduleBroadcastsLocked(); 12391 } 12392 } 12393 12394 return BROADCAST_SUCCESS; 12395 } 12396 12397 final Intent verifyBroadcastLocked(Intent intent) { 12398 // Refuse possible leaked file descriptors 12399 if (intent != null && intent.hasFileDescriptors() == true) { 12400 throw new IllegalArgumentException("File descriptors passed in Intent"); 12401 } 12402 12403 int flags = intent.getFlags(); 12404 12405 if (!mProcessesReady) { 12406 // if the caller really truly claims to know what they're doing, go 12407 // ahead and allow the broadcast without launching any receivers 12408 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12409 intent = new Intent(intent); 12410 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12411 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 12412 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12413 + " before boot completion"); 12414 throw new IllegalStateException("Cannot broadcast before boot completed"); 12415 } 12416 } 12417 12418 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12419 throw new IllegalArgumentException( 12420 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12421 } 12422 12423 return intent; 12424 } 12425 12426 public final int broadcastIntent(IApplicationThread caller, 12427 Intent intent, String resolvedType, IIntentReceiver resultTo, 12428 int resultCode, String resultData, Bundle map, 12429 String requiredPermission, boolean serialized, boolean sticky) { 12430 synchronized(this) { 12431 intent = verifyBroadcastLocked(intent); 12432 12433 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12434 final int callingPid = Binder.getCallingPid(); 12435 final int callingUid = Binder.getCallingUid(); 12436 final long origId = Binder.clearCallingIdentity(); 12437 int res = broadcastIntentLocked(callerApp, 12438 callerApp != null ? callerApp.info.packageName : null, 12439 intent, resolvedType, resultTo, 12440 resultCode, resultData, map, requiredPermission, serialized, 12441 sticky, callingPid, callingUid); 12442 Binder.restoreCallingIdentity(origId); 12443 return res; 12444 } 12445 } 12446 12447 int broadcastIntentInPackage(String packageName, int uid, 12448 Intent intent, String resolvedType, IIntentReceiver resultTo, 12449 int resultCode, String resultData, Bundle map, 12450 String requiredPermission, boolean serialized, boolean sticky) { 12451 synchronized(this) { 12452 intent = verifyBroadcastLocked(intent); 12453 12454 final long origId = Binder.clearCallingIdentity(); 12455 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12456 resultTo, resultCode, resultData, map, requiredPermission, 12457 serialized, sticky, -1, uid); 12458 Binder.restoreCallingIdentity(origId); 12459 return res; 12460 } 12461 } 12462 12463 public final void unbroadcastIntent(IApplicationThread caller, 12464 Intent intent) { 12465 // Refuse possible leaked file descriptors 12466 if (intent != null && intent.hasFileDescriptors() == true) { 12467 throw new IllegalArgumentException("File descriptors passed in Intent"); 12468 } 12469 12470 synchronized(this) { 12471 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12472 != PackageManager.PERMISSION_GRANTED) { 12473 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12474 + Binder.getCallingPid() 12475 + ", uid=" + Binder.getCallingUid() 12476 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12477 Slog.w(TAG, msg); 12478 throw new SecurityException(msg); 12479 } 12480 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12481 if (list != null) { 12482 int N = list.size(); 12483 int i; 12484 for (i=0; i<N; i++) { 12485 if (intent.filterEquals(list.get(i))) { 12486 list.remove(i); 12487 break; 12488 } 12489 } 12490 } 12491 } 12492 } 12493 12494 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12495 String resultData, Bundle resultExtras, boolean resultAbort, 12496 boolean explicit) { 12497 if (mOrderedBroadcasts.size() == 0) { 12498 if (explicit) { 12499 Slog.w(TAG, "finishReceiver called but no pending broadcasts"); 12500 } 12501 return false; 12502 } 12503 BroadcastRecord r = mOrderedBroadcasts.get(0); 12504 if (r.receiver == null) { 12505 if (explicit) { 12506 Slog.w(TAG, "finishReceiver called but none active"); 12507 } 12508 return false; 12509 } 12510 if (r.receiver != receiver) { 12511 Slog.w(TAG, "finishReceiver called but active receiver is different"); 12512 return false; 12513 } 12514 int state = r.state; 12515 r.state = BroadcastRecord.IDLE; 12516 if (state == BroadcastRecord.IDLE) { 12517 if (explicit) { 12518 Slog.w(TAG, "finishReceiver called but state is IDLE"); 12519 } 12520 } 12521 r.receiver = null; 12522 r.intent.setComponent(null); 12523 if (r.curApp != null) { 12524 r.curApp.curReceiver = null; 12525 } 12526 if (r.curFilter != null) { 12527 r.curFilter.receiverList.curBroadcast = null; 12528 } 12529 r.curFilter = null; 12530 r.curApp = null; 12531 r.curComponent = null; 12532 r.curReceiver = null; 12533 mPendingBroadcast = null; 12534 12535 r.resultCode = resultCode; 12536 r.resultData = resultData; 12537 r.resultExtras = resultExtras; 12538 r.resultAbort = resultAbort; 12539 12540 // We will process the next receiver right now if this is finishing 12541 // an app receiver (which is always asynchronous) or after we have 12542 // come back from calling a receiver. 12543 return state == BroadcastRecord.APP_RECEIVE 12544 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12545 } 12546 12547 public void finishReceiver(IBinder who, int resultCode, String resultData, 12548 Bundle resultExtras, boolean resultAbort) { 12549 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12550 12551 // Refuse possible leaked file descriptors 12552 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12553 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12554 } 12555 12556 boolean doNext; 12557 12558 final long origId = Binder.clearCallingIdentity(); 12559 12560 synchronized(this) { 12561 doNext = finishReceiverLocked( 12562 who, resultCode, resultData, resultExtras, resultAbort, true); 12563 } 12564 12565 if (doNext) { 12566 processNextBroadcast(false); 12567 } 12568 trimApplications(); 12569 12570 Binder.restoreCallingIdentity(origId); 12571 } 12572 12573 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) { 12574 if (r.nextReceiver > 0) { 12575 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12576 if (curReceiver instanceof BroadcastFilter) { 12577 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12578 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, 12579 System.identityHashCode(r), 12580 r.intent.getAction(), 12581 r.nextReceiver - 1, 12582 System.identityHashCode(bf)); 12583 } else { 12584 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12585 System.identityHashCode(r), 12586 r.intent.getAction(), 12587 r.nextReceiver - 1, 12588 ((ResolveInfo)curReceiver).toString()); 12589 } 12590 } else { 12591 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: " 12592 + r); 12593 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12594 System.identityHashCode(r), 12595 r.intent.getAction(), 12596 r.nextReceiver, 12597 "NONE"); 12598 } 12599 } 12600 12601 private final void setBroadcastTimeoutLocked(long timeoutTime) { 12602 if (! mPendingBroadcastTimeoutMessage) { 12603 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12604 mHandler.sendMessageAtTime(msg, timeoutTime); 12605 mPendingBroadcastTimeoutMessage = true; 12606 } 12607 } 12608 12609 private final void cancelBroadcastTimeoutLocked() { 12610 if (mPendingBroadcastTimeoutMessage) { 12611 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12612 mPendingBroadcastTimeoutMessage = false; 12613 } 12614 } 12615 12616 private final void broadcastTimeoutLocked(boolean fromMsg) { 12617 if (fromMsg) { 12618 mPendingBroadcastTimeoutMessage = false; 12619 } 12620 12621 if (mOrderedBroadcasts.size() == 0) { 12622 return; 12623 } 12624 12625 long now = SystemClock.uptimeMillis(); 12626 BroadcastRecord r = mOrderedBroadcasts.get(0); 12627 if (fromMsg) { 12628 if (mDidDexOpt) { 12629 // Delay timeouts until dexopt finishes. 12630 mDidDexOpt = false; 12631 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT; 12632 setBroadcastTimeoutLocked(timeoutTime); 12633 return; 12634 } 12635 if (! mProcessesReady) { 12636 // Only process broadcast timeouts if the system is ready. That way 12637 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended 12638 // to do heavy lifting for system up. 12639 return; 12640 } 12641 12642 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT; 12643 if (timeoutTime > now) { 12644 // We can observe premature timeouts because we do not cancel and reset the 12645 // broadcast timeout message after each receiver finishes. Instead, we set up 12646 // an initial timeout then kick it down the road a little further as needed 12647 // when it expires. 12648 if (DEBUG_BROADCAST) Slog.v(TAG, 12649 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12650 + timeoutTime); 12651 setBroadcastTimeoutLocked(timeoutTime); 12652 return; 12653 } 12654 } 12655 12656 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver 12657 + ", started " + (now - r.receiverTime) + "ms ago"); 12658 r.receiverTime = now; 12659 r.anrCount++; 12660 12661 // Current receiver has passed its expiration date. 12662 if (r.nextReceiver <= 0) { 12663 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12664 return; 12665 } 12666 12667 ProcessRecord app = null; 12668 String anrMessage = null; 12669 12670 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12671 Slog.w(TAG, "Receiver during timeout: " + curReceiver); 12672 logBroadcastReceiverDiscardLocked(r); 12673 if (curReceiver instanceof BroadcastFilter) { 12674 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12675 if (bf.receiverList.pid != 0 12676 && bf.receiverList.pid != MY_PID) { 12677 synchronized (this.mPidsSelfLocked) { 12678 app = this.mPidsSelfLocked.get( 12679 bf.receiverList.pid); 12680 } 12681 } 12682 } else { 12683 app = r.curApp; 12684 } 12685 12686 if (app != null) { 12687 anrMessage = "Broadcast of " + r.intent.toString(); 12688 } 12689 12690 if (mPendingBroadcast == r) { 12691 mPendingBroadcast = null; 12692 } 12693 12694 // Move on to the next receiver. 12695 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12696 r.resultExtras, r.resultAbort, true); 12697 scheduleBroadcastsLocked(); 12698 12699 if (anrMessage != null) { 12700 // Post the ANR to the handler since we do not want to process ANRs while 12701 // potentially holding our lock. 12702 mHandler.post(new AppNotResponding(app, anrMessage)); 12703 } 12704 } 12705 12706 private final void processCurBroadcastLocked(BroadcastRecord r, 12707 ProcessRecord app) throws RemoteException { 12708 if (DEBUG_BROADCAST) Slog.v(TAG, 12709 "Process cur broadcast " + r + " for app " + app); 12710 if (app.thread == null) { 12711 throw new RemoteException(); 12712 } 12713 r.receiver = app.thread.asBinder(); 12714 r.curApp = app; 12715 app.curReceiver = r; 12716 updateLruProcessLocked(app, true, true); 12717 12718 // Tell the application to launch this receiver. 12719 r.intent.setComponent(r.curComponent); 12720 12721 boolean started = false; 12722 try { 12723 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, 12724 "Delivering to component " + r.curComponent 12725 + ": " + r); 12726 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12727 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12728 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo), 12729 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12730 if (DEBUG_BROADCAST) Slog.v(TAG, 12731 "Process cur broadcast " + r + " DELIVERED for app " + app); 12732 started = true; 12733 } finally { 12734 if (!started) { 12735 if (DEBUG_BROADCAST) Slog.v(TAG, 12736 "Process cur broadcast " + r + ": NOT STARTED!"); 12737 r.receiver = null; 12738 r.curApp = null; 12739 app.curReceiver = null; 12740 } 12741 } 12742 12743 } 12744 12745 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, 12746 Intent intent, int resultCode, String data, Bundle extras, 12747 boolean ordered, boolean sticky) throws RemoteException { 12748 // Send the intent to the receiver asynchronously using one-way binder calls. 12749 if (app != null && app.thread != null) { 12750 // If we have an app thread, do the call through that so it is 12751 // correctly ordered with other one-way calls. 12752 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12753 data, extras, ordered, sticky); 12754 } else { 12755 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12756 } 12757 } 12758 12759 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r, 12760 BroadcastFilter filter, boolean ordered) { 12761 boolean skip = false; 12762 if (filter.requiredPermission != null) { 12763 int perm = checkComponentPermission(filter.requiredPermission, 12764 r.callingPid, r.callingUid, -1, true); 12765 if (perm != PackageManager.PERMISSION_GRANTED) { 12766 Slog.w(TAG, "Permission Denial: broadcasting " 12767 + r.intent.toString() 12768 + " from " + r.callerPackage + " (pid=" 12769 + r.callingPid + ", uid=" + r.callingUid + ")" 12770 + " requires " + filter.requiredPermission 12771 + " due to registered receiver " + filter); 12772 skip = true; 12773 } 12774 } 12775 if (r.requiredPermission != null) { 12776 int perm = checkComponentPermission(r.requiredPermission, 12777 filter.receiverList.pid, filter.receiverList.uid, -1, true); 12778 if (perm != PackageManager.PERMISSION_GRANTED) { 12779 Slog.w(TAG, "Permission Denial: receiving " 12780 + r.intent.toString() 12781 + " to " + filter.receiverList.app 12782 + " (pid=" + filter.receiverList.pid 12783 + ", uid=" + filter.receiverList.uid + ")" 12784 + " requires " + r.requiredPermission 12785 + " due to sender " + r.callerPackage 12786 + " (uid " + r.callingUid + ")"); 12787 skip = true; 12788 } 12789 } 12790 12791 if (!skip) { 12792 // If this is not being sent as an ordered broadcast, then we 12793 // don't want to touch the fields that keep track of the current 12794 // state of ordered broadcasts. 12795 if (ordered) { 12796 r.receiver = filter.receiverList.receiver.asBinder(); 12797 r.curFilter = filter; 12798 filter.receiverList.curBroadcast = r; 12799 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12800 if (filter.receiverList.app != null) { 12801 // Bump hosting application to no longer be in background 12802 // scheduling class. Note that we can't do that if there 12803 // isn't an app... but we can only be in that case for 12804 // things that directly call the IActivityManager API, which 12805 // are already core system stuff so don't matter for this. 12806 r.curApp = filter.receiverList.app; 12807 filter.receiverList.app.curReceiver = r; 12808 updateOomAdjLocked(); 12809 } 12810 } 12811 try { 12812 if (DEBUG_BROADCAST_LIGHT) { 12813 int seq = r.intent.getIntExtra("seq", -1); 12814 Slog.i(TAG, "Delivering to " + filter 12815 + " (seq=" + seq + "): " + r); 12816 } 12817 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, 12818 new Intent(r.intent), r.resultCode, 12819 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 12820 if (ordered) { 12821 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12822 } 12823 } catch (RemoteException e) { 12824 Slog.w(TAG, "Failure sending broadcast " + r.intent, e); 12825 if (ordered) { 12826 r.receiver = null; 12827 r.curFilter = null; 12828 filter.receiverList.curBroadcast = null; 12829 if (filter.receiverList.app != null) { 12830 filter.receiverList.app.curReceiver = null; 12831 } 12832 } 12833 } 12834 } 12835 } 12836 12837 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 12838 if (r.callingUid < 0) { 12839 // This was from a registerReceiver() call; ignore it. 12840 return; 12841 } 12842 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 12843 MAX_BROADCAST_HISTORY-1); 12844 r.finishTime = SystemClock.uptimeMillis(); 12845 mBroadcastHistory[0] = r; 12846 } 12847 12848 private final void processNextBroadcast(boolean fromMsg) { 12849 synchronized(this) { 12850 BroadcastRecord r; 12851 12852 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: " 12853 + mParallelBroadcasts.size() + " broadcasts, " 12854 + mOrderedBroadcasts.size() + " ordered broadcasts"); 12855 12856 updateCpuStats(); 12857 12858 if (fromMsg) { 12859 mBroadcastsScheduled = false; 12860 } 12861 12862 // First, deliver any non-serialized broadcasts right away. 12863 while (mParallelBroadcasts.size() > 0) { 12864 r = mParallelBroadcasts.remove(0); 12865 r.dispatchTime = SystemClock.uptimeMillis(); 12866 r.dispatchClockTime = System.currentTimeMillis(); 12867 final int N = r.receivers.size(); 12868 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast " 12869 + r); 12870 for (int i=0; i<N; i++) { 12871 Object target = r.receivers.get(i); 12872 if (DEBUG_BROADCAST) Slog.v(TAG, 12873 "Delivering non-ordered to registered " 12874 + target + ": " + r); 12875 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false); 12876 } 12877 addBroadcastToHistoryLocked(r); 12878 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast " 12879 + r); 12880 } 12881 12882 // Now take care of the next serialized one... 12883 12884 // If we are waiting for a process to come up to handle the next 12885 // broadcast, then do nothing at this point. Just in case, we 12886 // check that the process we're waiting for still exists. 12887 if (mPendingBroadcast != null) { 12888 if (DEBUG_BROADCAST_LIGHT) { 12889 Slog.v(TAG, "processNextBroadcast: waiting for " 12890 + mPendingBroadcast.curApp); 12891 } 12892 12893 boolean isDead; 12894 synchronized (mPidsSelfLocked) { 12895 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12896 } 12897 if (!isDead) { 12898 // It's still alive, so keep waiting 12899 return; 12900 } else { 12901 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp 12902 + " died before responding to broadcast"); 12903 mPendingBroadcast.state = BroadcastRecord.IDLE; 12904 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 12905 mPendingBroadcast = null; 12906 } 12907 } 12908 12909 boolean looped = false; 12910 12911 do { 12912 if (mOrderedBroadcasts.size() == 0) { 12913 // No more broadcasts pending, so all done! 12914 scheduleAppGcsLocked(); 12915 if (looped) { 12916 // If we had finished the last ordered broadcast, then 12917 // make sure all processes have correct oom and sched 12918 // adjustments. 12919 updateOomAdjLocked(); 12920 } 12921 return; 12922 } 12923 r = mOrderedBroadcasts.get(0); 12924 boolean forceReceive = false; 12925 12926 // Ensure that even if something goes awry with the timeout 12927 // detection, we catch "hung" broadcasts here, discard them, 12928 // and continue to make progress. 12929 // 12930 // This is only done if the system is ready so that PRE_BOOT_COMPLETED 12931 // receivers don't get executed with timeouts. They're intended for 12932 // one time heavy lifting after system upgrades and can take 12933 // significant amounts of time. 12934 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12935 if (mProcessesReady && r.dispatchTime > 0) { 12936 long now = SystemClock.uptimeMillis(); 12937 if ((numReceivers > 0) && 12938 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12939 Slog.w(TAG, "Hung broadcast discarded after timeout failure:" 12940 + " now=" + now 12941 + " dispatchTime=" + r.dispatchTime 12942 + " startTime=" + r.receiverTime 12943 + " intent=" + r.intent 12944 + " numReceivers=" + numReceivers 12945 + " nextReceiver=" + r.nextReceiver 12946 + " state=" + r.state); 12947 broadcastTimeoutLocked(false); // forcibly finish this broadcast 12948 forceReceive = true; 12949 r.state = BroadcastRecord.IDLE; 12950 } 12951 } 12952 12953 if (r.state != BroadcastRecord.IDLE) { 12954 if (DEBUG_BROADCAST) Slog.d(TAG, 12955 "processNextBroadcast() called when not idle (state=" 12956 + r.state + ")"); 12957 return; 12958 } 12959 12960 if (r.receivers == null || r.nextReceiver >= numReceivers 12961 || r.resultAbort || forceReceive) { 12962 // No more receivers for this broadcast! Send the final 12963 // result if requested... 12964 if (r.resultTo != null) { 12965 try { 12966 if (DEBUG_BROADCAST) { 12967 int seq = r.intent.getIntExtra("seq", -1); 12968 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction() 12969 + " seq=" + seq + " app=" + r.callerApp); 12970 } 12971 performReceiveLocked(r.callerApp, r.resultTo, 12972 new Intent(r.intent), r.resultCode, 12973 r.resultData, r.resultExtras, false, false); 12974 // Set this to null so that the reference 12975 // (local and remote) isnt kept in the mBroadcastHistory. 12976 r.resultTo = null; 12977 } catch (RemoteException e) { 12978 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12979 } 12980 } 12981 12982 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12983 cancelBroadcastTimeoutLocked(); 12984 12985 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast " 12986 + r); 12987 12988 // ... and on to the next... 12989 addBroadcastToHistoryLocked(r); 12990 mOrderedBroadcasts.remove(0); 12991 r = null; 12992 looped = true; 12993 continue; 12994 } 12995 } while (r == null); 12996 12997 // Get the next receiver... 12998 int recIdx = r.nextReceiver++; 12999 13000 // Keep track of when this receiver started, and make sure there 13001 // is a timeout message pending to kill it if need be. 13002 r.receiverTime = SystemClock.uptimeMillis(); 13003 if (recIdx == 0) { 13004 r.dispatchTime = r.receiverTime; 13005 r.dispatchClockTime = System.currentTimeMillis(); 13006 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast " 13007 + r); 13008 } 13009 if (! mPendingBroadcastTimeoutMessage) { 13010 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT; 13011 if (DEBUG_BROADCAST) Slog.v(TAG, 13012 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime); 13013 setBroadcastTimeoutLocked(timeoutTime); 13014 } 13015 13016 Object nextReceiver = r.receivers.get(recIdx); 13017 if (nextReceiver instanceof BroadcastFilter) { 13018 // Simple case: this is a registered receiver who gets 13019 // a direct call. 13020 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 13021 if (DEBUG_BROADCAST) Slog.v(TAG, 13022 "Delivering ordered to registered " 13023 + filter + ": " + r); 13024 deliverToRegisteredReceiverLocked(r, filter, r.ordered); 13025 if (r.receiver == null || !r.ordered) { 13026 // The receiver has already finished, so schedule to 13027 // process the next one. 13028 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered=" 13029 + r.ordered + " receiver=" + r.receiver); 13030 r.state = BroadcastRecord.IDLE; 13031 scheduleBroadcastsLocked(); 13032 } 13033 return; 13034 } 13035 13036 // Hard case: need to instantiate the receiver, possibly 13037 // starting its application process to host it. 13038 13039 ResolveInfo info = 13040 (ResolveInfo)nextReceiver; 13041 13042 boolean skip = false; 13043 int perm = checkComponentPermission(info.activityInfo.permission, 13044 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid, 13045 info.activityInfo.exported); 13046 if (perm != PackageManager.PERMISSION_GRANTED) { 13047 if (!info.activityInfo.exported) { 13048 Slog.w(TAG, "Permission Denial: broadcasting " 13049 + r.intent.toString() 13050 + " from " + r.callerPackage + " (pid=" + r.callingPid 13051 + ", uid=" + r.callingUid + ")" 13052 + " is not exported from uid " + info.activityInfo.applicationInfo.uid 13053 + " due to receiver " + info.activityInfo.packageName 13054 + "/" + info.activityInfo.name); 13055 } else { 13056 Slog.w(TAG, "Permission Denial: broadcasting " 13057 + r.intent.toString() 13058 + " from " + r.callerPackage + " (pid=" + r.callingPid 13059 + ", uid=" + r.callingUid + ")" 13060 + " requires " + info.activityInfo.permission 13061 + " due to receiver " + info.activityInfo.packageName 13062 + "/" + info.activityInfo.name); 13063 } 13064 skip = true; 13065 } 13066 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && 13067 r.requiredPermission != null) { 13068 try { 13069 perm = AppGlobals.getPackageManager(). 13070 checkPermission(r.requiredPermission, 13071 info.activityInfo.applicationInfo.packageName); 13072 } catch (RemoteException e) { 13073 perm = PackageManager.PERMISSION_DENIED; 13074 } 13075 if (perm != PackageManager.PERMISSION_GRANTED) { 13076 Slog.w(TAG, "Permission Denial: receiving " 13077 + r.intent + " to " 13078 + info.activityInfo.applicationInfo.packageName 13079 + " requires " + r.requiredPermission 13080 + " due to sender " + r.callerPackage 13081 + " (uid " + r.callingUid + ")"); 13082 skip = true; 13083 } 13084 } 13085 if (r.curApp != null && r.curApp.crashing) { 13086 // If the target process is crashing, just skip it. 13087 if (DEBUG_BROADCAST) Slog.v(TAG, 13088 "Skipping deliver ordered " + r + " to " + r.curApp 13089 + ": process crashing"); 13090 skip = true; 13091 } 13092 13093 if (skip) { 13094 if (DEBUG_BROADCAST) Slog.v(TAG, 13095 "Skipping delivery of ordered " + r + " for whatever reason"); 13096 r.receiver = null; 13097 r.curFilter = null; 13098 r.state = BroadcastRecord.IDLE; 13099 scheduleBroadcastsLocked(); 13100 return; 13101 } 13102 13103 r.state = BroadcastRecord.APP_RECEIVE; 13104 String targetProcess = info.activityInfo.processName; 13105 r.curComponent = new ComponentName( 13106 info.activityInfo.applicationInfo.packageName, 13107 info.activityInfo.name); 13108 r.curReceiver = info.activityInfo; 13109 13110 // Broadcast is being executed, its package can't be stopped. 13111 try { 13112 AppGlobals.getPackageManager().setPackageStoppedState( 13113 r.curComponent.getPackageName(), false); 13114 } catch (RemoteException e) { 13115 } catch (IllegalArgumentException e) { 13116 Slog.w(TAG, "Failed trying to unstop package " 13117 + r.curComponent.getPackageName() + ": " + e); 13118 } 13119 13120 // Is this receiver's application already running? 13121 ProcessRecord app = getProcessRecordLocked(targetProcess, 13122 info.activityInfo.applicationInfo.uid); 13123 if (app != null && app.thread != null) { 13124 try { 13125 app.addPackage(info.activityInfo.packageName); 13126 processCurBroadcastLocked(r, app); 13127 return; 13128 } catch (RemoteException e) { 13129 Slog.w(TAG, "Exception when sending broadcast to " 13130 + r.curComponent, e); 13131 } 13132 13133 // If a dead object exception was thrown -- fall through to 13134 // restart the application. 13135 } 13136 13137 // Not running -- get it started, to be executed when the app comes up. 13138 if (DEBUG_BROADCAST) Slog.v(TAG, 13139 "Need to start app " + targetProcess + " for broadcast " + r); 13140 if ((r.curApp=startProcessLocked(targetProcess, 13141 info.activityInfo.applicationInfo, true, 13142 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 13143 "broadcast", r.curComponent, 13144 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 13145 == null) { 13146 // Ah, this recipient is unavailable. Finish it if necessary, 13147 // and mark the broadcast record as ready for the next. 13148 Slog.w(TAG, "Unable to launch app " 13149 + info.activityInfo.applicationInfo.packageName + "/" 13150 + info.activityInfo.applicationInfo.uid + " for broadcast " 13151 + r.intent + ": process is bad"); 13152 logBroadcastReceiverDiscardLocked(r); 13153 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 13154 r.resultExtras, r.resultAbort, true); 13155 scheduleBroadcastsLocked(); 13156 r.state = BroadcastRecord.IDLE; 13157 return; 13158 } 13159 13160 mPendingBroadcast = r; 13161 mPendingBroadcastRecvIndex = recIdx; 13162 } 13163 } 13164 13165 // ========================================================= 13166 // INSTRUMENTATION 13167 // ========================================================= 13168 13169 public boolean startInstrumentation(ComponentName className, 13170 String profileFile, int flags, Bundle arguments, 13171 IInstrumentationWatcher watcher) { 13172 // Refuse possible leaked file descriptors 13173 if (arguments != null && arguments.hasFileDescriptors()) { 13174 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13175 } 13176 13177 synchronized(this) { 13178 InstrumentationInfo ii = null; 13179 ApplicationInfo ai = null; 13180 try { 13181 ii = mContext.getPackageManager().getInstrumentationInfo( 13182 className, STOCK_PM_FLAGS); 13183 ai = mContext.getPackageManager().getApplicationInfo( 13184 ii.targetPackage, STOCK_PM_FLAGS); 13185 } catch (PackageManager.NameNotFoundException e) { 13186 } 13187 if (ii == null) { 13188 reportStartInstrumentationFailure(watcher, className, 13189 "Unable to find instrumentation info for: " + className); 13190 return false; 13191 } 13192 if (ai == null) { 13193 reportStartInstrumentationFailure(watcher, className, 13194 "Unable to find instrumentation target package: " + ii.targetPackage); 13195 return false; 13196 } 13197 13198 int match = mContext.getPackageManager().checkSignatures( 13199 ii.targetPackage, ii.packageName); 13200 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13201 String msg = "Permission Denial: starting instrumentation " 13202 + className + " from pid=" 13203 + Binder.getCallingPid() 13204 + ", uid=" + Binder.getCallingPid() 13205 + " not allowed because package " + ii.packageName 13206 + " does not have a signature matching the target " 13207 + ii.targetPackage; 13208 reportStartInstrumentationFailure(watcher, className, msg); 13209 throw new SecurityException(msg); 13210 } 13211 13212 final long origId = Binder.clearCallingIdentity(); 13213 // Instrumentation can kill and relaunch even persistent processes 13214 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true); 13215 ProcessRecord app = addAppLocked(ai); 13216 app.instrumentationClass = className; 13217 app.instrumentationInfo = ai; 13218 app.instrumentationProfileFile = profileFile; 13219 app.instrumentationArguments = arguments; 13220 app.instrumentationWatcher = watcher; 13221 app.instrumentationResultClass = className; 13222 Binder.restoreCallingIdentity(origId); 13223 } 13224 13225 return true; 13226 } 13227 13228 /** 13229 * Report errors that occur while attempting to start Instrumentation. Always writes the 13230 * error to the logs, but if somebody is watching, send the report there too. This enables 13231 * the "am" command to report errors with more information. 13232 * 13233 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13234 * @param cn The component name of the instrumentation. 13235 * @param report The error report. 13236 */ 13237 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13238 ComponentName cn, String report) { 13239 Slog.w(TAG, report); 13240 try { 13241 if (watcher != null) { 13242 Bundle results = new Bundle(); 13243 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13244 results.putString("Error", report); 13245 watcher.instrumentationStatus(cn, -1, results); 13246 } 13247 } catch (RemoteException e) { 13248 Slog.w(TAG, e); 13249 } 13250 } 13251 13252 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13253 if (app.instrumentationWatcher != null) { 13254 try { 13255 // NOTE: IInstrumentationWatcher *must* be oneway here 13256 app.instrumentationWatcher.instrumentationFinished( 13257 app.instrumentationClass, 13258 resultCode, 13259 results); 13260 } catch (RemoteException e) { 13261 } 13262 } 13263 app.instrumentationWatcher = null; 13264 app.instrumentationClass = null; 13265 app.instrumentationInfo = null; 13266 app.instrumentationProfileFile = null; 13267 app.instrumentationArguments = null; 13268 13269 forceStopPackageLocked(app.processName, -1, false, false, true, true); 13270 } 13271 13272 public void finishInstrumentation(IApplicationThread target, 13273 int resultCode, Bundle results) { 13274 // Refuse possible leaked file descriptors 13275 if (results != null && results.hasFileDescriptors()) { 13276 throw new IllegalArgumentException("File descriptors passed in Intent"); 13277 } 13278 13279 synchronized(this) { 13280 ProcessRecord app = getRecordForAppLocked(target); 13281 if (app == null) { 13282 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13283 return; 13284 } 13285 final long origId = Binder.clearCallingIdentity(); 13286 finishInstrumentationLocked(app, resultCode, results); 13287 Binder.restoreCallingIdentity(origId); 13288 } 13289 } 13290 13291 // ========================================================= 13292 // CONFIGURATION 13293 // ========================================================= 13294 13295 public ConfigurationInfo getDeviceConfigurationInfo() { 13296 ConfigurationInfo config = new ConfigurationInfo(); 13297 synchronized (this) { 13298 config.reqTouchScreen = mConfiguration.touchscreen; 13299 config.reqKeyboardType = mConfiguration.keyboard; 13300 config.reqNavigation = mConfiguration.navigation; 13301 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13302 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13303 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13304 } 13305 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13306 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13307 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13308 } 13309 config.reqGlEsVersion = GL_ES_VERSION; 13310 } 13311 return config; 13312 } 13313 13314 public Configuration getConfiguration() { 13315 Configuration ci; 13316 synchronized(this) { 13317 ci = new Configuration(mConfiguration); 13318 } 13319 return ci; 13320 } 13321 13322 public void updatePersistentConfiguration(Configuration values) { 13323 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13324 "updateConfiguration()"); 13325 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13326 "updateConfiguration()"); 13327 if (values == null) { 13328 throw new NullPointerException("Configuration must not be null"); 13329 } 13330 13331 synchronized(this) { 13332 final long origId = Binder.clearCallingIdentity(); 13333 updateConfigurationLocked(values, null, true, false); 13334 Binder.restoreCallingIdentity(origId); 13335 } 13336 } 13337 13338 public void updateConfiguration(Configuration values) { 13339 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13340 "updateConfiguration()"); 13341 13342 synchronized(this) { 13343 if (values == null && mWindowManager != null) { 13344 // sentinel: fetch the current configuration from the window manager 13345 values = mWindowManager.computeNewConfiguration(); 13346 } 13347 13348 if (mWindowManager != null) { 13349 mProcessList.applyDisplaySize(mWindowManager); 13350 } 13351 13352 final long origId = Binder.clearCallingIdentity(); 13353 if (values != null) { 13354 Settings.System.clearConfiguration(values); 13355 } 13356 updateConfigurationLocked(values, null, false, false); 13357 Binder.restoreCallingIdentity(origId); 13358 } 13359 } 13360 13361 /** 13362 * Do either or both things: (1) change the current configuration, and (2) 13363 * make sure the given activity is running with the (now) current 13364 * configuration. Returns true if the activity has been left running, or 13365 * false if <var>starting</var> is being destroyed to match the new 13366 * configuration. 13367 * @param persistent TODO 13368 */ 13369 public boolean updateConfigurationLocked(Configuration values, 13370 ActivityRecord starting, boolean persistent, boolean initLocale) { 13371 int changes = 0; 13372 13373 boolean kept = true; 13374 13375 if (values != null) { 13376 Configuration newConfig = new Configuration(mConfiguration); 13377 changes = newConfig.updateFrom(values); 13378 if (changes != 0) { 13379 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13380 Slog.i(TAG, "Updating configuration to: " + values); 13381 } 13382 13383 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13384 13385 if (values.locale != null && !initLocale) { 13386 saveLocaleLocked(values.locale, 13387 !values.locale.equals(mConfiguration.locale), 13388 values.userSetLocale); 13389 } 13390 13391 mConfigurationSeq++; 13392 if (mConfigurationSeq <= 0) { 13393 mConfigurationSeq = 1; 13394 } 13395 newConfig.seq = mConfigurationSeq; 13396 mConfiguration = newConfig; 13397 Slog.i(TAG, "Config changed: " + newConfig); 13398 13399 final Configuration configCopy = new Configuration(mConfiguration); 13400 13401 AttributeCache ac = AttributeCache.instance(); 13402 if (ac != null) { 13403 ac.updateConfiguration(configCopy); 13404 } 13405 13406 // Make sure all resources in our process are updated 13407 // right now, so that anyone who is going to retrieve 13408 // resource values after we return will be sure to get 13409 // the new ones. This is especially important during 13410 // boot, where the first config change needs to guarantee 13411 // all resources have that config before following boot 13412 // code is executed. 13413 mSystemThread.applyConfigurationToResources(configCopy); 13414 13415 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13416 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13417 msg.obj = new Configuration(configCopy); 13418 mHandler.sendMessage(msg); 13419 } 13420 13421 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13422 ProcessRecord app = mLruProcesses.get(i); 13423 try { 13424 if (app.thread != null) { 13425 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13426 + app.processName + " new config " + mConfiguration); 13427 app.thread.scheduleConfigurationChanged(configCopy); 13428 } 13429 } catch (Exception e) { 13430 } 13431 } 13432 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13433 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13434 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13435 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13436 null, false, false, MY_PID, Process.SYSTEM_UID); 13437 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13438 broadcastIntentLocked(null, null, 13439 new Intent(Intent.ACTION_LOCALE_CHANGED), 13440 null, null, 0, null, null, 13441 null, false, false, MY_PID, Process.SYSTEM_UID); 13442 } 13443 } 13444 } 13445 13446 if (changes != 0 && starting == null) { 13447 // If the configuration changed, and the caller is not already 13448 // in the process of starting an activity, then find the top 13449 // activity to check if its configuration needs to change. 13450 starting = mMainStack.topRunningActivityLocked(null); 13451 } 13452 13453 if (starting != null) { 13454 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 13455 // And we need to make sure at this point that all other activities 13456 // are made visible with the correct configuration. 13457 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 13458 } 13459 13460 if (values != null && mWindowManager != null) { 13461 mWindowManager.setNewConfiguration(mConfiguration); 13462 } 13463 13464 return kept; 13465 } 13466 13467 /** 13468 * Save the locale. You must be inside a synchronized (this) block. 13469 */ 13470 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13471 if(isDiff) { 13472 SystemProperties.set("user.language", l.getLanguage()); 13473 SystemProperties.set("user.region", l.getCountry()); 13474 } 13475 13476 if(isPersist) { 13477 SystemProperties.set("persist.sys.language", l.getLanguage()); 13478 SystemProperties.set("persist.sys.country", l.getCountry()); 13479 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13480 } 13481 } 13482 13483 // ========================================================= 13484 // LIFETIME MANAGEMENT 13485 // ========================================================= 13486 13487 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13488 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 13489 if (mAdjSeq == app.adjSeq) { 13490 // This adjustment has already been computed. If we are calling 13491 // from the top, we may have already computed our adjustment with 13492 // an earlier hidden adjustment that isn't really for us... if 13493 // so, use the new hidden adjustment. 13494 if (!recursed && app.hidden) { 13495 app.curAdj = app.curRawAdj = hiddenAdj; 13496 } 13497 return app.curRawAdj; 13498 } 13499 13500 if (app.thread == null) { 13501 app.adjSeq = mAdjSeq; 13502 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13503 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 13504 } 13505 13506 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13507 app.adjSource = null; 13508 app.adjTarget = null; 13509 app.empty = false; 13510 app.hidden = false; 13511 13512 final int activitiesSize = app.activities.size(); 13513 13514 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13515 // The max adjustment doesn't allow this app to be anything 13516 // below foreground, so it is not worth doing work for it. 13517 app.adjType = "fixed"; 13518 app.adjSeq = mAdjSeq; 13519 app.curRawAdj = app.maxAdj; 13520 app.foregroundActivities = false; 13521 app.keeping = true; 13522 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13523 // System process can do UI, and when they do we want to have 13524 // them trim their memory after the user leaves the UI. To 13525 // facilitate this, here we need to determine whether or not it 13526 // is currently showing UI. 13527 app.systemNoUi = true; 13528 if (app == TOP_APP) { 13529 app.systemNoUi = false; 13530 } else if (activitiesSize > 0) { 13531 for (int j = 0; j < activitiesSize; j++) { 13532 final ActivityRecord r = app.activities.get(j); 13533 if (r.visible) { 13534 app.systemNoUi = false; 13535 break; 13536 } 13537 } 13538 } 13539 return (app.curAdj=app.maxAdj); 13540 } 13541 13542 final boolean hadForegroundActivities = app.foregroundActivities; 13543 13544 app.foregroundActivities = false; 13545 app.keeping = false; 13546 app.systemNoUi = false; 13547 13548 // Determine the importance of the process, starting with most 13549 // important to least, and assign an appropriate OOM adjustment. 13550 int adj; 13551 int schedGroup; 13552 if (app == TOP_APP) { 13553 // The last app on the list is the foreground app. 13554 adj = ProcessList.FOREGROUND_APP_ADJ; 13555 schedGroup = Process.THREAD_GROUP_DEFAULT; 13556 app.adjType = "top-activity"; 13557 app.foregroundActivities = true; 13558 } else if (app.instrumentationClass != null) { 13559 // Don't want to kill running instrumentation. 13560 adj = ProcessList.FOREGROUND_APP_ADJ; 13561 schedGroup = Process.THREAD_GROUP_DEFAULT; 13562 app.adjType = "instrumentation"; 13563 } else if (app.curReceiver != null || 13564 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13565 // An app that is currently receiving a broadcast also 13566 // counts as being in the foreground. 13567 adj = ProcessList.FOREGROUND_APP_ADJ; 13568 schedGroup = Process.THREAD_GROUP_DEFAULT; 13569 app.adjType = "broadcast"; 13570 } else if (app.executingServices.size() > 0) { 13571 // An app that is currently executing a service callback also 13572 // counts as being in the foreground. 13573 adj = ProcessList.FOREGROUND_APP_ADJ; 13574 schedGroup = Process.THREAD_GROUP_DEFAULT; 13575 app.adjType = "exec-service"; 13576 } else if (activitiesSize > 0) { 13577 // This app is in the background with paused activities. 13578 // We inspect activities to potentially upgrade adjustment further below. 13579 adj = hiddenAdj; 13580 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13581 app.hidden = true; 13582 app.adjType = "bg-activities"; 13583 } else { 13584 // A very not-needed process. If this is lower in the lru list, 13585 // we will push it in to the empty bucket. 13586 adj = hiddenAdj; 13587 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13588 app.hidden = true; 13589 app.empty = true; 13590 app.adjType = "bg-empty"; 13591 } 13592 13593 // Examine all activities if not already foreground. 13594 if (!app.foregroundActivities && activitiesSize > 0) { 13595 for (int j = 0; j < activitiesSize; j++) { 13596 final ActivityRecord r = app.activities.get(j); 13597 if (r.visible) { 13598 // App has a visible activity; only upgrade adjustment. 13599 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13600 adj = ProcessList.VISIBLE_APP_ADJ; 13601 app.adjType = "visible"; 13602 } 13603 schedGroup = Process.THREAD_GROUP_DEFAULT; 13604 app.hidden = false; 13605 app.foregroundActivities = true; 13606 break; 13607 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED 13608 || r.state == ActivityState.STOPPING) { 13609 // Only upgrade adjustment. 13610 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13611 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13612 app.adjType = "stopping"; 13613 } 13614 app.hidden = false; 13615 app.foregroundActivities = true; 13616 } 13617 } 13618 } 13619 13620 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13621 if (app.foregroundServices) { 13622 // The user is aware of this app, so make it visible. 13623 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13624 app.hidden = false; 13625 app.adjType = "foreground-service"; 13626 schedGroup = Process.THREAD_GROUP_DEFAULT; 13627 } else if (app.forcingToForeground != null) { 13628 // The user is aware of this app, so make it visible. 13629 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13630 app.hidden = false; 13631 app.adjType = "force-foreground"; 13632 app.adjSource = app.forcingToForeground; 13633 schedGroup = Process.THREAD_GROUP_DEFAULT; 13634 } 13635 } 13636 13637 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13638 // We don't want to kill the current heavy-weight process. 13639 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13640 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13641 app.hidden = false; 13642 app.adjType = "heavy"; 13643 } 13644 13645 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13646 // This process is hosting what we currently consider to be the 13647 // home app, so we don't want to let it go into the background. 13648 adj = ProcessList.HOME_APP_ADJ; 13649 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13650 app.hidden = false; 13651 app.adjType = "home"; 13652 } 13653 13654 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13655 && app.activities.size() > 0) { 13656 // This was the previous process that showed UI to the user. 13657 // We want to try to keep it around more aggressively, to give 13658 // a good experience around switching between two apps. 13659 adj = ProcessList.PREVIOUS_APP_ADJ; 13660 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13661 app.hidden = false; 13662 app.adjType = "previous"; 13663 } 13664 13665 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13666 + " reason=" + app.adjType); 13667 13668 // By default, we use the computed adjustment. It may be changed if 13669 // there are applications dependent on our services or providers, but 13670 // this gives us a baseline and makes sure we don't get into an 13671 // infinite recursion. 13672 app.adjSeq = mAdjSeq; 13673 app.curRawAdj = adj; 13674 13675 if (mBackupTarget != null && app == mBackupTarget.app) { 13676 // If possible we want to avoid killing apps while they're being backed up 13677 if (adj > ProcessList.BACKUP_APP_ADJ) { 13678 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13679 adj = ProcessList.BACKUP_APP_ADJ; 13680 app.adjType = "backup"; 13681 app.hidden = false; 13682 } 13683 } 13684 13685 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13686 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13687 final long now = SystemClock.uptimeMillis(); 13688 // This process is more important if the top activity is 13689 // bound to the service. 13690 Iterator<ServiceRecord> jt = app.services.iterator(); 13691 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13692 ServiceRecord s = jt.next(); 13693 if (s.startRequested) { 13694 if (app.hasShownUi && app != mHomeProcess) { 13695 // If this process has shown some UI, let it immediately 13696 // go to the LRU list because it may be pretty heavy with 13697 // UI stuff. We'll tag it with a label just to help 13698 // debug and understand what is going on. 13699 if (adj > ProcessList.SERVICE_ADJ) { 13700 app.adjType = "started-bg-ui-services"; 13701 } 13702 } else { 13703 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13704 // This service has seen some activity within 13705 // recent memory, so we will keep its process ahead 13706 // of the background processes. 13707 if (adj > ProcessList.SERVICE_ADJ) { 13708 adj = ProcessList.SERVICE_ADJ; 13709 app.adjType = "started-services"; 13710 app.hidden = false; 13711 } 13712 } 13713 // If we have let the service slide into the background 13714 // state, still have some text describing what it is doing 13715 // even though the service no longer has an impact. 13716 if (adj > ProcessList.SERVICE_ADJ) { 13717 app.adjType = "started-bg-services"; 13718 } 13719 } 13720 // Don't kill this process because it is doing work; it 13721 // has said it is doing work. 13722 app.keeping = true; 13723 } 13724 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13725 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13726 Iterator<ArrayList<ConnectionRecord>> kt 13727 = s.connections.values().iterator(); 13728 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13729 ArrayList<ConnectionRecord> clist = kt.next(); 13730 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 13731 // XXX should compute this based on the max of 13732 // all connected clients. 13733 ConnectionRecord cr = clist.get(i); 13734 if (cr.binding.client == app) { 13735 // Binding to ourself is not interesting. 13736 continue; 13737 } 13738 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 13739 ProcessRecord client = cr.binding.client; 13740 int clientAdj = adj; 13741 int myHiddenAdj = hiddenAdj; 13742 if (myHiddenAdj > client.hiddenAdj) { 13743 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 13744 myHiddenAdj = client.hiddenAdj; 13745 } else { 13746 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 13747 } 13748 } 13749 clientAdj = computeOomAdjLocked( 13750 client, myHiddenAdj, TOP_APP, true, doingAll); 13751 String adjType = null; 13752 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 13753 // Not doing bind OOM management, so treat 13754 // this guy more like a started service. 13755 if (app.hasShownUi && app != mHomeProcess) { 13756 // If this process has shown some UI, let it immediately 13757 // go to the LRU list because it may be pretty heavy with 13758 // UI stuff. We'll tag it with a label just to help 13759 // debug and understand what is going on. 13760 if (adj > clientAdj) { 13761 adjType = "bound-bg-ui-services"; 13762 } 13763 app.hidden = false; 13764 clientAdj = adj; 13765 } else { 13766 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13767 // This service has not seen activity within 13768 // recent memory, so allow it to drop to the 13769 // LRU list if there is no other reason to keep 13770 // it around. We'll also tag it with a label just 13771 // to help debug and undertand what is going on. 13772 if (adj > clientAdj) { 13773 adjType = "bound-bg-services"; 13774 } 13775 clientAdj = adj; 13776 } 13777 } 13778 } 13779 if (adj > clientAdj) { 13780 // If this process has recently shown UI, and 13781 // the process that is binding to it is less 13782 // important than being visible, then we don't 13783 // care about the binding as much as we care 13784 // about letting this process get into the LRU 13785 // list to be killed and restarted if needed for 13786 // memory. 13787 if (app.hasShownUi && app != mHomeProcess 13788 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13789 adjType = "bound-bg-ui-services"; 13790 } else { 13791 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 13792 |Context.BIND_IMPORTANT)) != 0) { 13793 adj = clientAdj; 13794 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 13795 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 13796 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13797 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13798 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 13799 adj = clientAdj; 13800 } else { 13801 app.pendingUiClean = true; 13802 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13803 adj = ProcessList.VISIBLE_APP_ADJ; 13804 } 13805 } 13806 if (!client.hidden) { 13807 app.hidden = false; 13808 } 13809 if (client.keeping) { 13810 app.keeping = true; 13811 } 13812 adjType = "service"; 13813 } 13814 } 13815 if (adjType != null) { 13816 app.adjType = adjType; 13817 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13818 .REASON_SERVICE_IN_USE; 13819 app.adjSource = cr.binding.client; 13820 app.adjSourceOom = clientAdj; 13821 app.adjTarget = s.name; 13822 } 13823 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13824 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13825 schedGroup = Process.THREAD_GROUP_DEFAULT; 13826 } 13827 } 13828 } 13829 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 13830 ActivityRecord a = cr.activity; 13831 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 13832 (a.visible || a.state == ActivityState.RESUMED 13833 || a.state == ActivityState.PAUSING)) { 13834 adj = ProcessList.FOREGROUND_APP_ADJ; 13835 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13836 schedGroup = Process.THREAD_GROUP_DEFAULT; 13837 } 13838 app.hidden = false; 13839 app.adjType = "service"; 13840 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13841 .REASON_SERVICE_IN_USE; 13842 app.adjSource = a; 13843 app.adjSourceOom = adj; 13844 app.adjTarget = s.name; 13845 } 13846 } 13847 } 13848 } 13849 } 13850 } 13851 13852 // Finally, if this process has active services running in it, we 13853 // would like to avoid killing it unless it would prevent the current 13854 // application from running. By default we put the process in 13855 // with the rest of the background processes; as we scan through 13856 // its services we may bump it up from there. 13857 if (adj > hiddenAdj) { 13858 adj = hiddenAdj; 13859 app.hidden = false; 13860 app.adjType = "bg-services"; 13861 } 13862 } 13863 13864 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13865 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13866 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13867 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13868 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13869 ContentProviderRecord cpr = jt.next(); 13870 if (cpr.clients.size() != 0) { 13871 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13872 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13873 ProcessRecord client = kt.next(); 13874 if (client == app) { 13875 // Being our own client is not interesting. 13876 continue; 13877 } 13878 int myHiddenAdj = hiddenAdj; 13879 if (myHiddenAdj > client.hiddenAdj) { 13880 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13881 myHiddenAdj = client.hiddenAdj; 13882 } else { 13883 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13884 } 13885 } 13886 int clientAdj = computeOomAdjLocked( 13887 client, myHiddenAdj, TOP_APP, true, doingAll); 13888 if (adj > clientAdj) { 13889 if (app.hasShownUi && app != mHomeProcess 13890 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13891 app.adjType = "bg-ui-provider"; 13892 } else { 13893 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13894 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13895 app.adjType = "provider"; 13896 } 13897 if (!client.hidden) { 13898 app.hidden = false; 13899 } 13900 if (client.keeping) { 13901 app.keeping = true; 13902 } 13903 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13904 .REASON_PROVIDER_IN_USE; 13905 app.adjSource = client; 13906 app.adjSourceOom = clientAdj; 13907 app.adjTarget = cpr.name; 13908 } 13909 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13910 schedGroup = Process.THREAD_GROUP_DEFAULT; 13911 } 13912 } 13913 } 13914 // If the provider has external (non-framework) process 13915 // dependencies, ensure that its adjustment is at least 13916 // FOREGROUND_APP_ADJ. 13917 if (cpr.externals != 0) { 13918 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13919 adj = ProcessList.FOREGROUND_APP_ADJ; 13920 schedGroup = Process.THREAD_GROUP_DEFAULT; 13921 app.hidden = false; 13922 app.keeping = true; 13923 app.adjType = "provider"; 13924 app.adjTarget = cpr.name; 13925 } 13926 } 13927 } 13928 } 13929 13930 app.curRawAdj = adj; 13931 13932 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13933 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13934 if (adj > app.maxAdj) { 13935 adj = app.maxAdj; 13936 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13937 schedGroup = Process.THREAD_GROUP_DEFAULT; 13938 } 13939 } 13940 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13941 app.keeping = true; 13942 } 13943 13944 if (app.hasAboveClient) { 13945 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13946 // then we need to drop its adjustment to be lower than the service's 13947 // in order to honor the request. We want to drop it by one adjustment 13948 // level... but there is special meaning applied to various levels so 13949 // we will skip some of them. 13950 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13951 // System process will not get dropped, ever 13952 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13953 adj = ProcessList.VISIBLE_APP_ADJ; 13954 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13955 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13956 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13957 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13958 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13959 adj++; 13960 } 13961 } 13962 13963 if (adj == ProcessList.SERVICE_ADJ) { 13964 if (doingAll) { 13965 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13966 mNewNumServiceProcs++; 13967 } 13968 if (app.serviceb) { 13969 adj = ProcessList.SERVICE_B_ADJ; 13970 } 13971 } else { 13972 app.serviceb = false; 13973 } 13974 13975 app.curAdj = adj; 13976 app.curSchedGroup = schedGroup; 13977 13978 if (hadForegroundActivities != app.foregroundActivities) { 13979 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid, 13980 app.foregroundActivities).sendToTarget(); 13981 } 13982 13983 return app.curRawAdj; 13984 } 13985 13986 /** 13987 * Ask a given process to GC right now. 13988 */ 13989 final void performAppGcLocked(ProcessRecord app) { 13990 try { 13991 app.lastRequestedGc = SystemClock.uptimeMillis(); 13992 if (app.thread != null) { 13993 if (app.reportLowMemory) { 13994 app.reportLowMemory = false; 13995 app.thread.scheduleLowMemory(); 13996 } else { 13997 app.thread.processInBackground(); 13998 } 13999 } 14000 } catch (Exception e) { 14001 // whatever. 14002 } 14003 } 14004 14005 /** 14006 * Returns true if things are idle enough to perform GCs. 14007 */ 14008 private final boolean canGcNowLocked() { 14009 return mParallelBroadcasts.size() == 0 14010 && mOrderedBroadcasts.size() == 0 14011 && (mSleeping || (mMainStack.mResumedActivity != null && 14012 mMainStack.mResumedActivity.idle)); 14013 } 14014 14015 /** 14016 * Perform GCs on all processes that are waiting for it, but only 14017 * if things are idle. 14018 */ 14019 final void performAppGcsLocked() { 14020 final int N = mProcessesToGc.size(); 14021 if (N <= 0) { 14022 return; 14023 } 14024 if (canGcNowLocked()) { 14025 while (mProcessesToGc.size() > 0) { 14026 ProcessRecord proc = mProcessesToGc.remove(0); 14027 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14028 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14029 <= SystemClock.uptimeMillis()) { 14030 // To avoid spamming the system, we will GC processes one 14031 // at a time, waiting a few seconds between each. 14032 performAppGcLocked(proc); 14033 scheduleAppGcsLocked(); 14034 return; 14035 } else { 14036 // It hasn't been long enough since we last GCed this 14037 // process... put it in the list to wait for its time. 14038 addProcessToGcListLocked(proc); 14039 break; 14040 } 14041 } 14042 } 14043 14044 scheduleAppGcsLocked(); 14045 } 14046 } 14047 14048 /** 14049 * If all looks good, perform GCs on all processes waiting for them. 14050 */ 14051 final void performAppGcsIfAppropriateLocked() { 14052 if (canGcNowLocked()) { 14053 performAppGcsLocked(); 14054 return; 14055 } 14056 // Still not idle, wait some more. 14057 scheduleAppGcsLocked(); 14058 } 14059 14060 /** 14061 * Schedule the execution of all pending app GCs. 14062 */ 14063 final void scheduleAppGcsLocked() { 14064 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14065 14066 if (mProcessesToGc.size() > 0) { 14067 // Schedule a GC for the time to the next process. 14068 ProcessRecord proc = mProcessesToGc.get(0); 14069 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14070 14071 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14072 long now = SystemClock.uptimeMillis(); 14073 if (when < (now+GC_TIMEOUT)) { 14074 when = now + GC_TIMEOUT; 14075 } 14076 mHandler.sendMessageAtTime(msg, when); 14077 } 14078 } 14079 14080 /** 14081 * Add a process to the array of processes waiting to be GCed. Keeps the 14082 * list in sorted order by the last GC time. The process can't already be 14083 * on the list. 14084 */ 14085 final void addProcessToGcListLocked(ProcessRecord proc) { 14086 boolean added = false; 14087 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14088 if (mProcessesToGc.get(i).lastRequestedGc < 14089 proc.lastRequestedGc) { 14090 added = true; 14091 mProcessesToGc.add(i+1, proc); 14092 break; 14093 } 14094 } 14095 if (!added) { 14096 mProcessesToGc.add(0, proc); 14097 } 14098 } 14099 14100 /** 14101 * Set up to ask a process to GC itself. This will either do it 14102 * immediately, or put it on the list of processes to gc the next 14103 * time things are idle. 14104 */ 14105 final void scheduleAppGcLocked(ProcessRecord app) { 14106 long now = SystemClock.uptimeMillis(); 14107 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14108 return; 14109 } 14110 if (!mProcessesToGc.contains(app)) { 14111 addProcessToGcListLocked(app); 14112 scheduleAppGcsLocked(); 14113 } 14114 } 14115 14116 final void checkExcessivePowerUsageLocked(boolean doKills) { 14117 updateCpuStatsNow(); 14118 14119 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14120 boolean doWakeKills = doKills; 14121 boolean doCpuKills = doKills; 14122 if (mLastPowerCheckRealtime == 0) { 14123 doWakeKills = false; 14124 } 14125 if (mLastPowerCheckUptime == 0) { 14126 doCpuKills = false; 14127 } 14128 if (stats.isScreenOn()) { 14129 doWakeKills = false; 14130 } 14131 final long curRealtime = SystemClock.elapsedRealtime(); 14132 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14133 final long curUptime = SystemClock.uptimeMillis(); 14134 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14135 mLastPowerCheckRealtime = curRealtime; 14136 mLastPowerCheckUptime = curUptime; 14137 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14138 doWakeKills = false; 14139 } 14140 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14141 doCpuKills = false; 14142 } 14143 int i = mLruProcesses.size(); 14144 while (i > 0) { 14145 i--; 14146 ProcessRecord app = mLruProcesses.get(i); 14147 if (!app.keeping) { 14148 long wtime; 14149 synchronized (stats) { 14150 wtime = stats.getProcessWakeTime(app.info.uid, 14151 app.pid, curRealtime); 14152 } 14153 long wtimeUsed = wtime - app.lastWakeTime; 14154 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14155 if (DEBUG_POWER) { 14156 StringBuilder sb = new StringBuilder(128); 14157 sb.append("Wake for "); 14158 app.toShortString(sb); 14159 sb.append(": over "); 14160 TimeUtils.formatDuration(realtimeSince, sb); 14161 sb.append(" used "); 14162 TimeUtils.formatDuration(wtimeUsed, sb); 14163 sb.append(" ("); 14164 sb.append((wtimeUsed*100)/realtimeSince); 14165 sb.append("%)"); 14166 Slog.i(TAG, sb.toString()); 14167 sb.setLength(0); 14168 sb.append("CPU for "); 14169 app.toShortString(sb); 14170 sb.append(": over "); 14171 TimeUtils.formatDuration(uptimeSince, sb); 14172 sb.append(" used "); 14173 TimeUtils.formatDuration(cputimeUsed, sb); 14174 sb.append(" ("); 14175 sb.append((cputimeUsed*100)/uptimeSince); 14176 sb.append("%)"); 14177 Slog.i(TAG, sb.toString()); 14178 } 14179 // If a process has held a wake lock for more 14180 // than 50% of the time during this period, 14181 // that sounds pad. Kill! 14182 if (doWakeKills && realtimeSince > 0 14183 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14184 synchronized (stats) { 14185 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14186 realtimeSince, wtimeUsed); 14187 } 14188 Slog.w(TAG, "Excessive wake lock in " + app.processName 14189 + " (pid " + app.pid + "): held " + wtimeUsed 14190 + " during " + realtimeSince); 14191 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14192 app.processName, app.setAdj, "excessive wake lock"); 14193 Process.killProcessQuiet(app.pid); 14194 } else if (doCpuKills && uptimeSince > 0 14195 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14196 synchronized (stats) { 14197 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 14198 uptimeSince, cputimeUsed); 14199 } 14200 Slog.w(TAG, "Excessive CPU in " + app.processName 14201 + " (pid " + app.pid + "): used " + cputimeUsed 14202 + " during " + uptimeSince); 14203 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14204 app.processName, app.setAdj, "excessive cpu"); 14205 Process.killProcessQuiet(app.pid); 14206 } else { 14207 app.lastWakeTime = wtime; 14208 app.lastCpuTime = app.curCpuTime; 14209 } 14210 } 14211 } 14212 } 14213 14214 private final boolean updateOomAdjLocked( 14215 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 14216 app.hiddenAdj = hiddenAdj; 14217 14218 if (app.thread == null) { 14219 return false; 14220 } 14221 14222 final boolean wasKeeping = app.keeping; 14223 14224 boolean success = true; 14225 14226 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 14227 14228 if (app.curRawAdj != app.setRawAdj) { 14229 if (false) { 14230 // Removing for now. Forcing GCs is not so useful anymore 14231 // with Dalvik, and the new memory level hint facility is 14232 // better for what we need to do these days. 14233 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ 14234 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14235 // If this app is transitioning from foreground to 14236 // non-foreground, have it do a gc. 14237 scheduleAppGcLocked(app); 14238 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14239 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14240 // Likewise do a gc when an app is moving in to the 14241 // background (such as a service stopping). 14242 scheduleAppGcLocked(app); 14243 } 14244 } 14245 14246 if (wasKeeping && !app.keeping) { 14247 // This app is no longer something we want to keep. Note 14248 // its current wake lock time to later know to kill it if 14249 // it is not behaving well. 14250 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14251 synchronized (stats) { 14252 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 14253 app.pid, SystemClock.elapsedRealtime()); 14254 } 14255 app.lastCpuTime = app.curCpuTime; 14256 } 14257 14258 app.setRawAdj = app.curRawAdj; 14259 } 14260 14261 if (app.curAdj != app.setAdj) { 14262 if (Process.setOomAdj(app.pid, app.curAdj)) { 14263 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 14264 TAG, "Set " + app.pid + " " + app.processName + 14265 " adj " + app.curAdj + ": " + app.adjType); 14266 app.setAdj = app.curAdj; 14267 } else { 14268 success = false; 14269 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 14270 } 14271 } 14272 if (app.setSchedGroup != app.curSchedGroup) { 14273 app.setSchedGroup = app.curSchedGroup; 14274 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 14275 "Setting process group of " + app.processName 14276 + " to " + app.curSchedGroup); 14277 if (app.waitingToKill != null && 14278 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 14279 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 14280 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14281 app.processName, app.setAdj, app.waitingToKill); 14282 Process.killProcessQuiet(app.pid); 14283 success = false; 14284 } else { 14285 if (true) { 14286 long oldId = Binder.clearCallingIdentity(); 14287 try { 14288 Process.setProcessGroup(app.pid, app.curSchedGroup); 14289 } catch (Exception e) { 14290 Slog.w(TAG, "Failed setting process group of " + app.pid 14291 + " to " + app.curSchedGroup); 14292 e.printStackTrace(); 14293 } finally { 14294 Binder.restoreCallingIdentity(oldId); 14295 } 14296 } else { 14297 if (app.thread != null) { 14298 try { 14299 app.thread.setSchedulingGroup(app.curSchedGroup); 14300 } catch (RemoteException e) { 14301 } 14302 } 14303 } 14304 } 14305 } 14306 return success; 14307 } 14308 14309 private final ActivityRecord resumedAppLocked() { 14310 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 14311 if (resumedActivity == null || resumedActivity.app == null) { 14312 resumedActivity = mMainStack.mPausingActivity; 14313 if (resumedActivity == null || resumedActivity.app == null) { 14314 resumedActivity = mMainStack.topRunningActivityLocked(null); 14315 } 14316 } 14317 return resumedActivity; 14318 } 14319 14320 private final boolean updateOomAdjLocked(ProcessRecord app) { 14321 final ActivityRecord TOP_ACT = resumedAppLocked(); 14322 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14323 int curAdj = app.curAdj; 14324 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14325 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14326 14327 mAdjSeq++; 14328 14329 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 14330 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14331 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14332 if (nowHidden != wasHidden) { 14333 // Changed to/from hidden state, so apps after it in the LRU 14334 // list may also be changed. 14335 updateOomAdjLocked(); 14336 } 14337 return success; 14338 } 14339 14340 final void updateOomAdjLocked() { 14341 final ActivityRecord TOP_ACT = resumedAppLocked(); 14342 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14343 14344 if (false) { 14345 RuntimeException e = new RuntimeException(); 14346 e.fillInStackTrace(); 14347 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 14348 } 14349 14350 mAdjSeq++; 14351 mNewNumServiceProcs = 0; 14352 14353 // Let's determine how many processes we have running vs. 14354 // how many slots we have for background processes; we may want 14355 // to put multiple processes in a slot of there are enough of 14356 // them. 14357 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 14358 int factor = (mLruProcesses.size()-4)/numSlots; 14359 if (factor < 1) factor = 1; 14360 int step = 0; 14361 int numHidden = 0; 14362 14363 // First update the OOM adjustment for each of the 14364 // application processes based on their current state. 14365 int i = mLruProcesses.size(); 14366 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 14367 while (i > 0) { 14368 i--; 14369 ProcessRecord app = mLruProcesses.get(i); 14370 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 14371 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 14372 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 14373 && app.curAdj == curHiddenAdj) { 14374 step++; 14375 if (step >= factor) { 14376 step = 0; 14377 curHiddenAdj++; 14378 } 14379 } 14380 if (!app.killedBackground) { 14381 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14382 numHidden++; 14383 if (numHidden > mProcessLimit) { 14384 Slog.i(TAG, "No longer want " + app.processName 14385 + " (pid " + app.pid + "): hidden #" + numHidden); 14386 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14387 app.processName, app.setAdj, "too many background"); 14388 app.killedBackground = true; 14389 Process.killProcessQuiet(app.pid); 14390 } 14391 } 14392 } 14393 } 14394 14395 mNumServiceProcs = mNewNumServiceProcs; 14396 14397 // Now determine the memory trimming level of background processes. 14398 // Unfortunately we need to start at the back of the list to do this 14399 // properly. We only do this if the number of background apps we 14400 // are managing to keep around is less than half the maximum we desire; 14401 // if we are keeping a good number around, we'll let them use whatever 14402 // memory they want. 14403 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 14404 final int N = mLruProcesses.size(); 14405 factor = numHidden/3; 14406 int minFactor = 2; 14407 if (mHomeProcess != null) minFactor++; 14408 if (mPreviousProcess != null) minFactor++; 14409 if (factor < minFactor) factor = minFactor; 14410 step = 0; 14411 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14412 for (i=0; i<N; i++) { 14413 ProcessRecord app = mLruProcesses.get(i); 14414 if (app.curAdj >= ProcessList.HOME_APP_ADJ 14415 && app.curAdj != ProcessList.SERVICE_B_ADJ 14416 && !app.killedBackground) { 14417 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14418 try { 14419 app.thread.scheduleTrimMemory(curLevel); 14420 } catch (RemoteException e) { 14421 } 14422 if (false) { 14423 // For now we won't do this; our memory trimming seems 14424 // to be good enough at this point that destroying 14425 // activities causes more harm than good. 14426 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14427 && app != mHomeProcess && app != mPreviousProcess) { 14428 // For these apps we will also finish their activities 14429 // to help them free memory. 14430 mMainStack.destroyActivitiesLocked(app, false, "trim"); 14431 } 14432 } 14433 } 14434 app.trimMemoryLevel = curLevel; 14435 step++; 14436 if (step >= factor) { 14437 switch (curLevel) { 14438 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14439 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14440 break; 14441 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14442 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14443 break; 14444 } 14445 } 14446 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14447 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14448 && app.thread != null) { 14449 try { 14450 app.thread.scheduleTrimMemory( 14451 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14452 } catch (RemoteException e) { 14453 } 14454 } 14455 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14456 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14457 && app.pendingUiClean) { 14458 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14459 && app.thread != null) { 14460 try { 14461 app.thread.scheduleTrimMemory( 14462 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14463 } catch (RemoteException e) { 14464 } 14465 } 14466 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14467 app.pendingUiClean = false; 14468 } else { 14469 app.trimMemoryLevel = 0; 14470 } 14471 } 14472 } else { 14473 final int N = mLruProcesses.size(); 14474 for (i=0; i<N; i++) { 14475 ProcessRecord app = mLruProcesses.get(i); 14476 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14477 && app.pendingUiClean) { 14478 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14479 && app.thread != null) { 14480 try { 14481 app.thread.scheduleTrimMemory( 14482 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14483 } catch (RemoteException e) { 14484 } 14485 } 14486 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14487 app.pendingUiClean = false; 14488 } else { 14489 app.trimMemoryLevel = 0; 14490 } 14491 } 14492 } 14493 14494 if (mAlwaysFinishActivities) { 14495 mMainStack.destroyActivitiesLocked(null, false, "always-finish"); 14496 } 14497 } 14498 14499 final void trimApplications() { 14500 synchronized (this) { 14501 int i; 14502 14503 // First remove any unused application processes whose package 14504 // has been removed. 14505 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14506 final ProcessRecord app = mRemovedProcesses.get(i); 14507 if (app.activities.size() == 0 14508 && app.curReceiver == null && app.services.size() == 0) { 14509 Slog.i( 14510 TAG, "Exiting empty application process " 14511 + app.processName + " (" 14512 + (app.thread != null ? app.thread.asBinder() : null) 14513 + ")\n"); 14514 if (app.pid > 0 && app.pid != MY_PID) { 14515 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14516 app.processName, app.setAdj, "empty"); 14517 Process.killProcessQuiet(app.pid); 14518 } else { 14519 try { 14520 app.thread.scheduleExit(); 14521 } catch (Exception e) { 14522 // Ignore exceptions. 14523 } 14524 } 14525 cleanUpApplicationRecordLocked(app, false, true, -1); 14526 mRemovedProcesses.remove(i); 14527 14528 if (app.persistent) { 14529 if (app.persistent) { 14530 addAppLocked(app.info); 14531 } 14532 } 14533 } 14534 } 14535 14536 // Now update the oom adj for all processes. 14537 updateOomAdjLocked(); 14538 } 14539 } 14540 14541 /** This method sends the specified signal to each of the persistent apps */ 14542 public void signalPersistentProcesses(int sig) throws RemoteException { 14543 if (sig != Process.SIGNAL_USR1) { 14544 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14545 } 14546 14547 synchronized (this) { 14548 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14549 != PackageManager.PERMISSION_GRANTED) { 14550 throw new SecurityException("Requires permission " 14551 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14552 } 14553 14554 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14555 ProcessRecord r = mLruProcesses.get(i); 14556 if (r.thread != null && r.persistent) { 14557 Process.sendSignal(r.pid, sig); 14558 } 14559 } 14560 } 14561 } 14562 14563 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14564 if (proc == null || proc == mProfileProc) { 14565 proc = mProfileProc; 14566 path = mProfileFile; 14567 profileType = mProfileType; 14568 clearProfilerLocked(); 14569 } 14570 if (proc == null) { 14571 return; 14572 } 14573 try { 14574 proc.thread.profilerControl(false, path, null, profileType); 14575 } catch (RemoteException e) { 14576 throw new IllegalStateException("Process disappeared"); 14577 } 14578 } 14579 14580 private void clearProfilerLocked() { 14581 if (mProfileFd != null) { 14582 try { 14583 mProfileFd.close(); 14584 } catch (IOException e) { 14585 } 14586 } 14587 mProfileApp = null; 14588 mProfileProc = null; 14589 mProfileFile = null; 14590 mProfileType = 0; 14591 mAutoStopProfiler = false; 14592 } 14593 14594 public boolean profileControl(String process, boolean start, 14595 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14596 14597 try { 14598 synchronized (this) { 14599 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14600 // its own permission. 14601 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14602 != PackageManager.PERMISSION_GRANTED) { 14603 throw new SecurityException("Requires permission " 14604 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14605 } 14606 14607 if (start && fd == null) { 14608 throw new IllegalArgumentException("null fd"); 14609 } 14610 14611 ProcessRecord proc = null; 14612 if (process != null) { 14613 try { 14614 int pid = Integer.parseInt(process); 14615 synchronized (mPidsSelfLocked) { 14616 proc = mPidsSelfLocked.get(pid); 14617 } 14618 } catch (NumberFormatException e) { 14619 } 14620 14621 if (proc == null) { 14622 HashMap<String, SparseArray<ProcessRecord>> all 14623 = mProcessNames.getMap(); 14624 SparseArray<ProcessRecord> procs = all.get(process); 14625 if (procs != null && procs.size() > 0) { 14626 proc = procs.valueAt(0); 14627 } 14628 } 14629 } 14630 14631 if (start && (proc == null || proc.thread == null)) { 14632 throw new IllegalArgumentException("Unknown process: " + process); 14633 } 14634 14635 if (start) { 14636 stopProfilerLocked(null, null, 0); 14637 setProfileApp(proc.info, proc.processName, path, fd, false); 14638 mProfileProc = proc; 14639 mProfileType = profileType; 14640 try { 14641 fd = fd.dup(); 14642 } catch (IOException e) { 14643 fd = null; 14644 } 14645 proc.thread.profilerControl(start, path, fd, profileType); 14646 fd = null; 14647 mProfileFd = null; 14648 } else { 14649 stopProfilerLocked(proc, path, profileType); 14650 if (fd != null) { 14651 try { 14652 fd.close(); 14653 } catch (IOException e) { 14654 } 14655 } 14656 } 14657 14658 return true; 14659 } 14660 } catch (RemoteException e) { 14661 throw new IllegalStateException("Process disappeared"); 14662 } finally { 14663 if (fd != null) { 14664 try { 14665 fd.close(); 14666 } catch (IOException e) { 14667 } 14668 } 14669 } 14670 } 14671 14672 public boolean dumpHeap(String process, boolean managed, 14673 String path, ParcelFileDescriptor fd) throws RemoteException { 14674 14675 try { 14676 synchronized (this) { 14677 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14678 // its own permission (same as profileControl). 14679 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14680 != PackageManager.PERMISSION_GRANTED) { 14681 throw new SecurityException("Requires permission " 14682 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14683 } 14684 14685 if (fd == null) { 14686 throw new IllegalArgumentException("null fd"); 14687 } 14688 14689 ProcessRecord proc = null; 14690 try { 14691 int pid = Integer.parseInt(process); 14692 synchronized (mPidsSelfLocked) { 14693 proc = mPidsSelfLocked.get(pid); 14694 } 14695 } catch (NumberFormatException e) { 14696 } 14697 14698 if (proc == null) { 14699 HashMap<String, SparseArray<ProcessRecord>> all 14700 = mProcessNames.getMap(); 14701 SparseArray<ProcessRecord> procs = all.get(process); 14702 if (procs != null && procs.size() > 0) { 14703 proc = procs.valueAt(0); 14704 } 14705 } 14706 14707 if (proc == null || proc.thread == null) { 14708 throw new IllegalArgumentException("Unknown process: " + process); 14709 } 14710 14711 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14712 if (!isDebuggable) { 14713 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14714 throw new SecurityException("Process not debuggable: " + proc); 14715 } 14716 } 14717 14718 proc.thread.dumpHeap(managed, path, fd); 14719 fd = null; 14720 return true; 14721 } 14722 } catch (RemoteException e) { 14723 throw new IllegalStateException("Process disappeared"); 14724 } finally { 14725 if (fd != null) { 14726 try { 14727 fd.close(); 14728 } catch (IOException e) { 14729 } 14730 } 14731 } 14732 } 14733 14734 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14735 public void monitor() { 14736 synchronized (this) { } 14737 } 14738 14739 public void onCoreSettingsChange(Bundle settings) { 14740 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14741 ProcessRecord processRecord = mLruProcesses.get(i); 14742 try { 14743 if (processRecord.thread != null) { 14744 processRecord.thread.setCoreSettings(settings); 14745 } 14746 } catch (RemoteException re) { 14747 /* ignore */ 14748 } 14749 } 14750 } 14751 14752 // Multi-user methods 14753 14754 public boolean switchUser(int userid) { 14755 // TODO 14756 return true; 14757 } 14758 } 14759