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.DataInputStream; 124 import java.io.DataOutputStream; 125 import java.io.File; 126 import java.io.FileDescriptor; 127 import java.io.FileInputStream; 128 import java.io.FileNotFoundException; 129 import java.io.FileOutputStream; 130 import java.io.IOException; 131 import java.io.InputStreamReader; 132 import java.io.PrintWriter; 133 import java.lang.IllegalStateException; 134 import java.lang.ref.WeakReference; 135 import java.util.ArrayList; 136 import java.util.Collections; 137 import java.util.Comparator; 138 import java.util.HashMap; 139 import java.util.HashSet; 140 import java.util.Iterator; 141 import java.util.List; 142 import java.util.Locale; 143 import java.util.Map; 144 import java.util.Set; 145 import java.util.concurrent.atomic.AtomicBoolean; 146 import java.util.concurrent.atomic.AtomicLong; 147 148 public final class ActivityManagerService extends ActivityManagerNative 149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 150 static final String TAG = "ActivityManager"; 151 static final boolean DEBUG = false; 152 static final boolean localLOGV = DEBUG; 153 static final boolean DEBUG_SWITCH = localLOGV || false; 154 static final boolean DEBUG_TASKS = localLOGV || false; 155 static final boolean DEBUG_PAUSE = localLOGV || false; 156 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 157 static final boolean DEBUG_TRANSITION = localLOGV || false; 158 static final boolean DEBUG_BROADCAST = localLOGV || false; 159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 160 static final boolean DEBUG_SERVICE = localLOGV || false; 161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 162 static final boolean DEBUG_VISBILITY = localLOGV || false; 163 static final boolean DEBUG_PROCESSES = localLOGV || false; 164 static final boolean DEBUG_PROVIDER = localLOGV || false; 165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 166 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 167 static final boolean DEBUG_RESULTS = localLOGV || false; 168 static final boolean DEBUG_BACKUP = localLOGV || false; 169 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 170 static final boolean DEBUG_POWER = localLOGV || false; 171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 172 static final boolean VALIDATE_TOKENS = false; 173 static final boolean SHOW_ACTIVITY_START_TIME = true; 174 175 // Control over CPU and battery monitoring. 176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 177 static final boolean MONITOR_CPU_USAGE = true; 178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 180 static final boolean MONITOR_THREAD_CPU_USAGE = false; 181 182 // The flags that are set for all calls we make to the package manager. 183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 184 185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 186 187 // Maximum number of recent tasks that we can remember. 188 static final int MAX_RECENT_TASKS = 20; 189 190 // Amount of time after a call to stopAppSwitches() during which we will 191 // prevent further untrusted switches from happening. 192 static final long APP_SWITCH_DELAY_TIME = 5*1000; 193 194 // How long we wait for a launched process to attach to the activity manager 195 // before we decide it's never going to come up for real. 196 static final int PROC_START_TIMEOUT = 10*1000; 197 198 // How long we wait for a launched process to attach to the activity manager 199 // before we decide it's never going to come up for real, when the process was 200 // started with a wrapper for instrumentation (such as Valgrind) because it 201 // could take much longer than usual. 202 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 203 204 // How long to wait after going idle before forcing apps to GC. 205 static final int GC_TIMEOUT = 5*1000; 206 207 // The minimum amount of time between successive GC requests for a process. 208 static final int GC_MIN_INTERVAL = 60*1000; 209 210 // The rate at which we check for apps using excessive power -- 15 mins. 211 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 212 213 // The minimum sample duration we will allow before deciding we have 214 // enough data on wake locks to start killing things. 215 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 216 217 // The minimum sample duration we will allow before deciding we have 218 // enough data on CPU usage to start killing things. 219 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 220 221 // How long we allow a receiver to run before giving up on it. 222 static final int BROADCAST_TIMEOUT = 10*1000; 223 224 // How long we wait for a service to finish executing. 225 static final int SERVICE_TIMEOUT = 20*1000; 226 227 // How long a service needs to be running until restarting its process 228 // is no longer considered to be a relaunch of the service. 229 static final int SERVICE_RESTART_DURATION = 5*1000; 230 231 // How long a service needs to be running until it will start back at 232 // SERVICE_RESTART_DURATION after being killed. 233 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 234 235 // Multiplying factor to increase restart duration time by, for each time 236 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 237 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 238 239 // The minimum amount of time between restarting services that we allow. 240 // That is, when multiple services are restarting, we won't allow each 241 // to restart less than this amount of time from the last one. 242 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 243 244 // Maximum amount of time for there to be no activity on a service before 245 // we consider it non-essential and allow its process to go on the 246 // LRU background list. 247 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 248 249 // How long we wait until we timeout on key dispatching. 250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 251 252 // How long we wait until we timeout on key dispatching during instrumentation. 253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 254 255 static final int MY_PID = Process.myPid(); 256 257 static final String[] EMPTY_STRING_ARRAY = new String[0]; 258 259 public ActivityStack mMainStack; 260 261 /** 262 * Description of a request to start a new activity, which has been held 263 * due to app switches being disabled. 264 */ 265 static class PendingActivityLaunch { 266 ActivityRecord r; 267 ActivityRecord sourceRecord; 268 Uri[] grantedUriPermissions; 269 int grantedMode; 270 boolean onlyIfNeeded; 271 } 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 /** 277 * List of all active broadcasts that are to be executed immediately 278 * (without waiting for another broadcast to finish). Currently this only 279 * contains broadcasts to registered receivers, to avoid spinning up 280 * a bunch of processes to execute IntentReceiver components. 281 */ 282 final ArrayList<BroadcastRecord> mParallelBroadcasts 283 = new ArrayList<BroadcastRecord>(); 284 285 /** 286 * List of all active broadcasts that are to be executed one at a time. 287 * The object at the top of the list is the currently activity broadcasts; 288 * those after it are waiting for the top to finish.. 289 */ 290 final ArrayList<BroadcastRecord> mOrderedBroadcasts 291 = new ArrayList<BroadcastRecord>(); 292 293 /** 294 * Historical data of past broadcasts, for debugging. 295 */ 296 static final int MAX_BROADCAST_HISTORY = 100; 297 final BroadcastRecord[] mBroadcastHistory 298 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 299 300 /** 301 * Set when we current have a BROADCAST_INTENT_MSG in flight. 302 */ 303 boolean mBroadcastsScheduled = false; 304 305 /** 306 * Activity we have told the window manager to have key focus. 307 */ 308 ActivityRecord mFocusedActivity = null; 309 /** 310 * List of intents that were used to start the most recent tasks. 311 */ 312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 313 314 /** 315 * Process management. 316 */ 317 final ProcessList mProcessList = new ProcessList(); 318 319 /** 320 * All of the applications we currently have running organized by name. 321 * The keys are strings of the application package name (as 322 * returned by the package manager), and the keys are ApplicationRecord 323 * objects. 324 */ 325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 326 327 /** 328 * The currently running heavy-weight process, if any. 329 */ 330 ProcessRecord mHeavyWeightProcess = null; 331 332 /** 333 * The last time that various processes have crashed. 334 */ 335 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 336 337 /** 338 * Set of applications that we consider to be bad, and will reject 339 * incoming broadcasts from (which the user has no control over). 340 * Processes are added to this set when they have crashed twice within 341 * a minimum amount of time; they are removed from it when they are 342 * later restarted (hopefully due to some user action). The value is the 343 * time it was added to the list. 344 */ 345 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 346 347 /** 348 * All of the processes we currently have running organized by pid. 349 * The keys are the pid running the application. 350 * 351 * <p>NOTE: This object is protected by its own lock, NOT the global 352 * activity manager lock! 353 */ 354 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 355 356 /** 357 * All of the processes that have been forced to be foreground. The key 358 * is the pid of the caller who requested it (we hold a death 359 * link on it). 360 */ 361 abstract class ForegroundToken implements IBinder.DeathRecipient { 362 int pid; 363 IBinder token; 364 } 365 final SparseArray<ForegroundToken> mForegroundProcesses 366 = new SparseArray<ForegroundToken>(); 367 368 /** 369 * List of records for processes that someone had tried to start before the 370 * system was ready. We don't start them at that point, but ensure they 371 * are started by the time booting is complete. 372 */ 373 final ArrayList<ProcessRecord> mProcessesOnHold 374 = new ArrayList<ProcessRecord>(); 375 376 /** 377 * List of persistent applications that are in the process 378 * of being started. 379 */ 380 final ArrayList<ProcessRecord> mPersistentStartingProcesses 381 = new ArrayList<ProcessRecord>(); 382 383 /** 384 * Processes that are being forcibly torn down. 385 */ 386 final ArrayList<ProcessRecord> mRemovedProcesses 387 = new ArrayList<ProcessRecord>(); 388 389 /** 390 * List of running applications, sorted by recent usage. 391 * The first entry in the list is the least recently used. 392 * It contains ApplicationRecord objects. This list does NOT include 393 * any persistent application records (since we never want to exit them). 394 */ 395 final ArrayList<ProcessRecord> mLruProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of processes that should gc as soon as things are idle. 400 */ 401 final ArrayList<ProcessRecord> mProcessesToGc 402 = new ArrayList<ProcessRecord>(); 403 404 /** 405 * This is the process holding what we currently consider to be 406 * the "home" activity. 407 */ 408 ProcessRecord mHomeProcess; 409 410 /** 411 * Packages that the user has asked to have run in screen size 412 * compatibility mode instead of filling the screen. 413 */ 414 final CompatModePackages mCompatModePackages; 415 416 /** 417 * Set of PendingResultRecord objects that are currently active. 418 */ 419 final HashSet mPendingResultRecords = new HashSet(); 420 421 /** 422 * Set of IntentSenderRecord objects that are currently active. 423 */ 424 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 425 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 426 427 /** 428 * Fingerprints (hashCode()) of stack traces that we've 429 * already logged DropBox entries for. Guarded by itself. If 430 * something (rogue user app) forces this over 431 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 432 */ 433 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 434 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 435 436 /** 437 * Strict Mode background batched logging state. 438 * 439 * The string buffer is guarded by itself, and its lock is also 440 * used to determine if another batched write is already 441 * in-flight. 442 */ 443 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 444 445 /** 446 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler. 447 */ 448 private boolean mPendingBroadcastTimeoutMessage; 449 450 /** 451 * Intent broadcast that we have tried to start, but are 452 * waiting for its application's process to be created. We only 453 * need one (instead of a list) because we always process broadcasts 454 * one at a time, so no others can be started while waiting for this 455 * one. 456 */ 457 BroadcastRecord mPendingBroadcast = null; 458 459 /** 460 * The receiver index that is pending, to restart the broadcast if needed. 461 */ 462 int mPendingBroadcastRecvIndex; 463 464 /** 465 * Keeps track of all IIntentReceivers that have been registered for 466 * broadcasts. Hash keys are the receiver IBinder, hash value is 467 * a ReceiverList. 468 */ 469 final HashMap mRegisteredReceivers = new HashMap(); 470 471 /** 472 * Resolver for broadcast intents to registered receivers. 473 * Holds BroadcastFilter (subclass of IntentFilter). 474 */ 475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 477 @Override 478 protected boolean allowFilterResult( 479 BroadcastFilter filter, List<BroadcastFilter> dest) { 480 IBinder target = filter.receiverList.receiver.asBinder(); 481 for (int i=dest.size()-1; i>=0; i--) { 482 if (dest.get(i).receiverList.receiver.asBinder() == target) { 483 return false; 484 } 485 } 486 return true; 487 } 488 489 @Override 490 protected String packageForFilter(BroadcastFilter filter) { 491 return filter.packageName; 492 } 493 }; 494 495 /** 496 * State of all active sticky broadcasts. Keys are the action of the 497 * sticky Intent, values are an ArrayList of all broadcasted intents with 498 * that action (which should usually be one). 499 */ 500 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 501 new HashMap<String, ArrayList<Intent>>(); 502 503 /** 504 * All currently running services. 505 */ 506 final HashMap<ComponentName, ServiceRecord> mServices = 507 new HashMap<ComponentName, ServiceRecord>(); 508 509 /** 510 * All currently running services indexed by the Intent used to start them. 511 */ 512 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 513 new HashMap<Intent.FilterComparison, ServiceRecord>(); 514 515 /** 516 * All currently bound service connections. Keys are the IBinder of 517 * the client's IServiceConnection. 518 */ 519 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections 520 = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); 521 522 /** 523 * List of services that we have been asked to start, 524 * but haven't yet been able to. It is used to hold start requests 525 * while waiting for their corresponding application thread to get 526 * going. 527 */ 528 final ArrayList<ServiceRecord> mPendingServices 529 = new ArrayList<ServiceRecord>(); 530 531 /** 532 * List of services that are scheduled to restart following a crash. 533 */ 534 final ArrayList<ServiceRecord> mRestartingServices 535 = new ArrayList<ServiceRecord>(); 536 537 /** 538 * List of services that are in the process of being stopped. 539 */ 540 final ArrayList<ServiceRecord> mStoppingServices 541 = new ArrayList<ServiceRecord>(); 542 543 /** 544 * Backup/restore process management 545 */ 546 String mBackupAppName = null; 547 BackupRecord mBackupTarget = null; 548 549 /** 550 * List of PendingThumbnailsRecord objects of clients who are still 551 * waiting to receive all of the thumbnails for a task. 552 */ 553 final ArrayList mPendingThumbnails = new ArrayList(); 554 555 /** 556 * List of HistoryRecord objects that have been finished and must 557 * still report back to a pending thumbnail receiver. 558 */ 559 final ArrayList mCancelledThumbnails = new ArrayList(); 560 561 /** 562 * All of the currently running global content providers. Keys are a 563 * string containing the provider name and values are a 564 * ContentProviderRecord object containing the data about it. Note 565 * that a single provider may be published under multiple names, so 566 * there may be multiple entries here for a single one in mProvidersByClass. 567 */ 568 final HashMap<String, ContentProviderRecord> mProvidersByName 569 = new HashMap<String, ContentProviderRecord>(); 570 571 /** 572 * All of the currently running global content providers. Keys are a 573 * string containing the provider's implementation class and values are a 574 * ContentProviderRecord object containing the data about it. 575 */ 576 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass 577 = new HashMap<ComponentName, ContentProviderRecord>(); 578 579 /** 580 * List of content providers who have clients waiting for them. The 581 * application is currently being launched and the provider will be 582 * removed from this list once it is published. 583 */ 584 final ArrayList<ContentProviderRecord> mLaunchingProviders 585 = new ArrayList<ContentProviderRecord>(); 586 587 /** 588 * Global set of specific Uri permissions that have been granted. 589 */ 590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 591 = new SparseArray<HashMap<Uri, UriPermission>>(); 592 593 CoreSettingsObserver mCoreSettingsObserver; 594 595 /** 596 * Thread-local storage used to carry caller permissions over through 597 * indirect content-provider access. 598 * @see #ActivityManagerService.openContentUri() 599 */ 600 private class Identity { 601 public int pid; 602 public int uid; 603 604 Identity(int _pid, int _uid) { 605 pid = _pid; 606 uid = _uid; 607 } 608 } 609 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 610 611 /** 612 * All information we have collected about the runtime performance of 613 * any user id that can impact battery performance. 614 */ 615 final BatteryStatsService mBatteryStatsService; 616 617 /** 618 * information about component usage 619 */ 620 final UsageStatsService mUsageStatsService; 621 622 /** 623 * Current configuration information. HistoryRecord objects are given 624 * a reference to this object to indicate which configuration they are 625 * currently running in, so this object must be kept immutable. 626 */ 627 Configuration mConfiguration = new Configuration(); 628 629 /** 630 * Current sequencing integer of the configuration, for skipping old 631 * configurations. 632 */ 633 int mConfigurationSeq = 0; 634 635 /** 636 * Hardware-reported OpenGLES version. 637 */ 638 final int GL_ES_VERSION; 639 640 /** 641 * List of initialization arguments to pass to all processes when binding applications to them. 642 * For example, references to the commonly used services. 643 */ 644 HashMap<String, IBinder> mAppBindArgs; 645 646 /** 647 * Temporary to avoid allocations. Protected by main lock. 648 */ 649 final StringBuilder mStringBuilder = new StringBuilder(256); 650 651 /** 652 * Used to control how we initialize the service. 653 */ 654 boolean mStartRunning = false; 655 ComponentName mTopComponent; 656 String mTopAction; 657 String mTopData; 658 boolean mProcessesReady = false; 659 boolean mSystemReady = false; 660 boolean mBooting = false; 661 boolean mWaitingUpdate = false; 662 boolean mDidUpdate = false; 663 boolean mOnBattery = false; 664 boolean mLaunchWarningShown = false; 665 666 Context mContext; 667 668 int mFactoryTest; 669 670 boolean mCheckedForSetup; 671 672 /** 673 * The time at which we will allow normal application switches again, 674 * after a call to {@link #stopAppSwitches()}. 675 */ 676 long mAppSwitchesAllowedTime; 677 678 /** 679 * This is set to true after the first switch after mAppSwitchesAllowedTime 680 * is set; any switches after that will clear the time. 681 */ 682 boolean mDidAppSwitch; 683 684 /** 685 * Last time (in realtime) at which we checked for power usage. 686 */ 687 long mLastPowerCheckRealtime; 688 689 /** 690 * Last time (in uptime) at which we checked for power usage. 691 */ 692 long mLastPowerCheckUptime; 693 694 /** 695 * Set while we are wanting to sleep, to prevent any 696 * activities from being started/resumed. 697 */ 698 boolean mSleeping = false; 699 700 /** 701 * Set if we are shutting down the system, similar to sleeping. 702 */ 703 boolean mShuttingDown = false; 704 705 /** 706 * Task identifier that activities are currently being started 707 * in. Incremented each time a new task is created. 708 * todo: Replace this with a TokenSpace class that generates non-repeating 709 * integers that won't wrap. 710 */ 711 int mCurTask = 1; 712 713 /** 714 * Current sequence id for oom_adj computation traversal. 715 */ 716 int mAdjSeq = 0; 717 718 /** 719 * Current sequence id for process LRU updating. 720 */ 721 int mLruSeq = 0; 722 723 /** 724 * System monitoring: number of processes that died since the last 725 * N procs were started. 726 */ 727 int[] mProcDeaths = new int[20]; 728 729 /** 730 * This is set if we had to do a delayed dexopt of an app before launching 731 * it, to increasing the ANR timeouts in that case. 732 */ 733 boolean mDidDexOpt; 734 735 String mDebugApp = null; 736 boolean mWaitForDebugger = false; 737 boolean mDebugTransient = false; 738 String mOrigDebugApp = null; 739 boolean mOrigWaitForDebugger = false; 740 boolean mAlwaysFinishActivities = false; 741 IActivityController mController = null; 742 String mProfileApp = null; 743 ProcessRecord mProfileProc = null; 744 String mProfileFile; 745 ParcelFileDescriptor mProfileFd; 746 int mProfileType = 0; 747 boolean mAutoStopProfiler = false; 748 749 final RemoteCallbackList<IActivityWatcher> mWatchers 750 = new RemoteCallbackList<IActivityWatcher>(); 751 752 final RemoteCallbackList<IProcessObserver> mProcessObservers 753 = new RemoteCallbackList<IProcessObserver>(); 754 755 /** 756 * Callback of last caller to {@link #requestPss}. 757 */ 758 Runnable mRequestPssCallback; 759 760 /** 761 * Remaining processes for which we are waiting results from the last 762 * call to {@link #requestPss}. 763 */ 764 final ArrayList<ProcessRecord> mRequestPssList 765 = new ArrayList<ProcessRecord>(); 766 767 /** 768 * Runtime statistics collection thread. This object's lock is used to 769 * protect all related state. 770 */ 771 final Thread mProcessStatsThread; 772 773 /** 774 * Used to collect process stats when showing not responding dialog. 775 * Protected by mProcessStatsThread. 776 */ 777 final ProcessStats mProcessStats = new ProcessStats( 778 MONITOR_THREAD_CPU_USAGE); 779 final AtomicLong mLastCpuTime = new AtomicLong(0); 780 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 781 782 long mLastWriteTime = 0; 783 784 /** 785 * Set to true after the system has finished booting. 786 */ 787 boolean mBooted = false; 788 789 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 790 int mProcessLimitOverride = -1; 791 792 WindowManagerService mWindowManager; 793 794 static ActivityManagerService mSelf; 795 static ActivityThread mSystemThread; 796 797 private final class AppDeathRecipient implements IBinder.DeathRecipient { 798 final ProcessRecord mApp; 799 final int mPid; 800 final IApplicationThread mAppThread; 801 802 AppDeathRecipient(ProcessRecord app, int pid, 803 IApplicationThread thread) { 804 if (localLOGV) Slog.v( 805 TAG, "New death recipient " + this 806 + " for thread " + thread.asBinder()); 807 mApp = app; 808 mPid = pid; 809 mAppThread = thread; 810 } 811 812 public void binderDied() { 813 if (localLOGV) Slog.v( 814 TAG, "Death received in " + this 815 + " for thread " + mAppThread.asBinder()); 816 synchronized(ActivityManagerService.this) { 817 appDiedLocked(mApp, mPid, mAppThread); 818 } 819 } 820 } 821 822 static final int SHOW_ERROR_MSG = 1; 823 static final int SHOW_NOT_RESPONDING_MSG = 2; 824 static final int SHOW_FACTORY_ERROR_MSG = 3; 825 static final int UPDATE_CONFIGURATION_MSG = 4; 826 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 827 static final int WAIT_FOR_DEBUGGER_MSG = 6; 828 static final int BROADCAST_INTENT_MSG = 7; 829 static final int BROADCAST_TIMEOUT_MSG = 8; 830 static final int SERVICE_TIMEOUT_MSG = 12; 831 static final int UPDATE_TIME_ZONE = 13; 832 static final int SHOW_UID_ERROR_MSG = 14; 833 static final int IM_FEELING_LUCKY_MSG = 15; 834 static final int PROC_START_TIMEOUT_MSG = 20; 835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 836 static final int KILL_APPLICATION_MSG = 22; 837 static final int FINALIZE_PENDING_INTENT_MSG = 23; 838 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 842 static final int CLEAR_DNS_CACHE = 28; 843 static final int UPDATE_HTTP_PROXY = 29; 844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 845 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31; 846 static final int DISPATCH_PROCESS_DIED = 32; 847 848 AlertDialog mUidAlert; 849 CompatModeDialog mCompatModeDialog; 850 851 final Handler mHandler = new Handler() { 852 //public Handler() { 853 // if (localLOGV) Slog.v(TAG, "Handler started!"); 854 //} 855 856 public void handleMessage(Message msg) { 857 switch (msg.what) { 858 case SHOW_ERROR_MSG: { 859 HashMap data = (HashMap) msg.obj; 860 synchronized (ActivityManagerService.this) { 861 ProcessRecord proc = (ProcessRecord)data.get("app"); 862 if (proc != null && proc.crashDialog != null) { 863 Slog.e(TAG, "App already has crash dialog: " + proc); 864 return; 865 } 866 AppErrorResult res = (AppErrorResult) data.get("result"); 867 if (!mSleeping && !mShuttingDown) { 868 Dialog d = new AppErrorDialog(mContext, res, proc); 869 d.show(); 870 proc.crashDialog = d; 871 } else { 872 // The device is asleep, so just pretend that the user 873 // saw a crash dialog and hit "force quit". 874 res.set(0); 875 } 876 } 877 878 ensureBootCompleted(); 879 } break; 880 case SHOW_NOT_RESPONDING_MSG: { 881 synchronized (ActivityManagerService.this) { 882 HashMap data = (HashMap) msg.obj; 883 ProcessRecord proc = (ProcessRecord)data.get("app"); 884 if (proc != null && proc.anrDialog != null) { 885 Slog.e(TAG, "App already has anr dialog: " + proc); 886 return; 887 } 888 889 Intent intent = new Intent("android.intent.action.ANR"); 890 if (!mProcessesReady) { 891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 892 } 893 broadcastIntentLocked(null, null, intent, 894 null, null, 0, null, null, null, 895 false, false, MY_PID, Process.SYSTEM_UID); 896 897 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 898 mContext, proc, (ActivityRecord)data.get("activity")); 899 d.show(); 900 proc.anrDialog = d; 901 } 902 903 ensureBootCompleted(); 904 } break; 905 case SHOW_STRICT_MODE_VIOLATION_MSG: { 906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 907 synchronized (ActivityManagerService.this) { 908 ProcessRecord proc = (ProcessRecord) data.get("app"); 909 if (proc == null) { 910 Slog.e(TAG, "App not found when showing strict mode dialog."); 911 break; 912 } 913 if (proc.crashDialog != null) { 914 Slog.e(TAG, "App already has strict mode dialog: " + proc); 915 return; 916 } 917 AppErrorResult res = (AppErrorResult) data.get("result"); 918 if (!mSleeping && !mShuttingDown) { 919 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 920 d.show(); 921 proc.crashDialog = d; 922 } else { 923 // The device is asleep, so just pretend that the user 924 // saw a crash dialog and hit "force quit". 925 res.set(0); 926 } 927 } 928 ensureBootCompleted(); 929 } break; 930 case SHOW_FACTORY_ERROR_MSG: { 931 Dialog d = new FactoryErrorDialog( 932 mContext, msg.getData().getCharSequence("msg")); 933 d.show(); 934 ensureBootCompleted(); 935 } break; 936 case UPDATE_CONFIGURATION_MSG: { 937 final ContentResolver resolver = mContext.getContentResolver(); 938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 939 } break; 940 case GC_BACKGROUND_PROCESSES_MSG: { 941 synchronized (ActivityManagerService.this) { 942 performAppGcsIfAppropriateLocked(); 943 } 944 } break; 945 case WAIT_FOR_DEBUGGER_MSG: { 946 synchronized (ActivityManagerService.this) { 947 ProcessRecord app = (ProcessRecord)msg.obj; 948 if (msg.arg1 != 0) { 949 if (!app.waitedForDebugger) { 950 Dialog d = new AppWaitingForDebuggerDialog( 951 ActivityManagerService.this, 952 mContext, app); 953 app.waitDialog = d; 954 app.waitedForDebugger = true; 955 d.show(); 956 } 957 } else { 958 if (app.waitDialog != null) { 959 app.waitDialog.dismiss(); 960 app.waitDialog = null; 961 } 962 } 963 } 964 } break; 965 case BROADCAST_INTENT_MSG: { 966 if (DEBUG_BROADCAST) Slog.v( 967 TAG, "Received BROADCAST_INTENT_MSG"); 968 processNextBroadcast(true); 969 } break; 970 case BROADCAST_TIMEOUT_MSG: { 971 synchronized (ActivityManagerService.this) { 972 broadcastTimeoutLocked(true); 973 } 974 } break; 975 case SERVICE_TIMEOUT_MSG: { 976 if (mDidDexOpt) { 977 mDidDexOpt = false; 978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 979 nmsg.obj = msg.obj; 980 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 981 return; 982 } 983 serviceTimeout((ProcessRecord)msg.obj); 984 } break; 985 case UPDATE_TIME_ZONE: { 986 synchronized (ActivityManagerService.this) { 987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 988 ProcessRecord r = mLruProcesses.get(i); 989 if (r.thread != null) { 990 try { 991 r.thread.updateTimeZone(); 992 } catch (RemoteException ex) { 993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 994 } 995 } 996 } 997 } 998 } break; 999 case CLEAR_DNS_CACHE: { 1000 synchronized (ActivityManagerService.this) { 1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1002 ProcessRecord r = mLruProcesses.get(i); 1003 if (r.thread != null) { 1004 try { 1005 r.thread.clearDnsCache(); 1006 } catch (RemoteException ex) { 1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1008 } 1009 } 1010 } 1011 } 1012 } break; 1013 case UPDATE_HTTP_PROXY: { 1014 ProxyProperties proxy = (ProxyProperties)msg.obj; 1015 String host = ""; 1016 String port = ""; 1017 String exclList = ""; 1018 if (proxy != null) { 1019 host = proxy.getHost(); 1020 port = Integer.toString(proxy.getPort()); 1021 exclList = proxy.getExclusionList(); 1022 } 1023 synchronized (ActivityManagerService.this) { 1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1025 ProcessRecord r = mLruProcesses.get(i); 1026 if (r.thread != null) { 1027 try { 1028 r.thread.setHttpProxy(host, port, exclList); 1029 } catch (RemoteException ex) { 1030 Slog.w(TAG, "Failed to update http proxy for: " + 1031 r.info.processName); 1032 } 1033 } 1034 } 1035 } 1036 } break; 1037 case SHOW_UID_ERROR_MSG: { 1038 // XXX This is a temporary dialog, no need to localize. 1039 AlertDialog d = new BaseErrorDialog(mContext); 1040 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1041 d.setCancelable(false); 1042 d.setTitle("System UIDs Inconsistent"); 1043 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1044 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1045 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1046 mUidAlert = d; 1047 d.show(); 1048 } break; 1049 case IM_FEELING_LUCKY_MSG: { 1050 if (mUidAlert != null) { 1051 mUidAlert.dismiss(); 1052 mUidAlert = null; 1053 } 1054 } break; 1055 case PROC_START_TIMEOUT_MSG: { 1056 if (mDidDexOpt) { 1057 mDidDexOpt = false; 1058 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1059 nmsg.obj = msg.obj; 1060 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1061 return; 1062 } 1063 ProcessRecord app = (ProcessRecord)msg.obj; 1064 synchronized (ActivityManagerService.this) { 1065 processStartTimedOutLocked(app); 1066 } 1067 } break; 1068 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1069 synchronized (ActivityManagerService.this) { 1070 doPendingActivityLaunchesLocked(true); 1071 } 1072 } break; 1073 case KILL_APPLICATION_MSG: { 1074 synchronized (ActivityManagerService.this) { 1075 int uid = msg.arg1; 1076 boolean restart = (msg.arg2 == 1); 1077 String pkg = (String) msg.obj; 1078 forceStopPackageLocked(pkg, uid, restart, false, true, false); 1079 } 1080 } break; 1081 case FINALIZE_PENDING_INTENT_MSG: { 1082 ((PendingIntentRecord)msg.obj).completeFinalize(); 1083 } break; 1084 case POST_HEAVY_NOTIFICATION_MSG: { 1085 INotificationManager inm = NotificationManager.getService(); 1086 if (inm == null) { 1087 return; 1088 } 1089 1090 ActivityRecord root = (ActivityRecord)msg.obj; 1091 ProcessRecord process = root.app; 1092 if (process == null) { 1093 return; 1094 } 1095 1096 try { 1097 Context context = mContext.createPackageContext(process.info.packageName, 0); 1098 String text = mContext.getString(R.string.heavy_weight_notification, 1099 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1100 Notification notification = new Notification(); 1101 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1102 notification.when = 0; 1103 notification.flags = Notification.FLAG_ONGOING_EVENT; 1104 notification.tickerText = text; 1105 notification.defaults = 0; // please be quiet 1106 notification.sound = null; 1107 notification.vibrate = null; 1108 notification.setLatestEventInfo(context, text, 1109 mContext.getText(R.string.heavy_weight_notification_detail), 1110 PendingIntent.getActivity(mContext, 0, root.intent, 1111 PendingIntent.FLAG_CANCEL_CURRENT)); 1112 1113 try { 1114 int[] outId = new int[1]; 1115 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1116 notification, outId); 1117 } catch (RuntimeException e) { 1118 Slog.w(ActivityManagerService.TAG, 1119 "Error showing notification for heavy-weight app", e); 1120 } catch (RemoteException e) { 1121 } 1122 } catch (NameNotFoundException e) { 1123 Slog.w(TAG, "Unable to create context for heavy notification", e); 1124 } 1125 } break; 1126 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1127 INotificationManager inm = NotificationManager.getService(); 1128 if (inm == null) { 1129 return; 1130 } 1131 try { 1132 inm.cancelNotification("android", 1133 R.string.heavy_weight_notification); 1134 } catch (RuntimeException e) { 1135 Slog.w(ActivityManagerService.TAG, 1136 "Error canceling notification for service", e); 1137 } catch (RemoteException e) { 1138 } 1139 } break; 1140 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1141 synchronized (ActivityManagerService.this) { 1142 checkExcessivePowerUsageLocked(true); 1143 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1144 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1145 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1146 } 1147 } break; 1148 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1149 synchronized (ActivityManagerService.this) { 1150 ActivityRecord ar = (ActivityRecord)msg.obj; 1151 if (mCompatModeDialog != null) { 1152 if (mCompatModeDialog.mAppInfo.packageName.equals( 1153 ar.info.applicationInfo.packageName)) { 1154 return; 1155 } 1156 mCompatModeDialog.dismiss(); 1157 mCompatModeDialog = null; 1158 } 1159 if (ar != null && false) { 1160 if (mCompatModePackages.getPackageAskCompatModeLocked( 1161 ar.packageName)) { 1162 int mode = mCompatModePackages.computeCompatModeLocked( 1163 ar.info.applicationInfo); 1164 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1165 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1166 mCompatModeDialog = new CompatModeDialog( 1167 ActivityManagerService.this, mContext, 1168 ar.info.applicationInfo); 1169 mCompatModeDialog.show(); 1170 } 1171 } 1172 } 1173 } 1174 break; 1175 } 1176 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: { 1177 final int pid = msg.arg1; 1178 final int uid = msg.arg2; 1179 final boolean foregroundActivities = (Boolean) msg.obj; 1180 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities); 1181 break; 1182 } 1183 case DISPATCH_PROCESS_DIED: { 1184 final int pid = msg.arg1; 1185 final int uid = msg.arg2; 1186 dispatchProcessDied(pid, uid); 1187 break; 1188 } 1189 } 1190 } 1191 }; 1192 1193 public static void setSystemProcess() { 1194 try { 1195 ActivityManagerService m = mSelf; 1196 1197 ServiceManager.addService("activity", m); 1198 ServiceManager.addService("meminfo", new MemBinder(m)); 1199 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1200 if (MONITOR_CPU_USAGE) { 1201 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1202 } 1203 ServiceManager.addService("permission", new PermissionController(m)); 1204 1205 ApplicationInfo info = 1206 mSelf.mContext.getPackageManager().getApplicationInfo( 1207 "android", STOCK_PM_FLAGS); 1208 mSystemThread.installSystemApplicationInfo(info); 1209 1210 synchronized (mSelf) { 1211 ProcessRecord app = mSelf.newProcessRecordLocked( 1212 mSystemThread.getApplicationThread(), info, 1213 info.processName); 1214 app.persistent = true; 1215 app.pid = MY_PID; 1216 app.maxAdj = ProcessList.SYSTEM_ADJ; 1217 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1218 synchronized (mSelf.mPidsSelfLocked) { 1219 mSelf.mPidsSelfLocked.put(app.pid, app); 1220 } 1221 mSelf.updateLruProcessLocked(app, true, true); 1222 } 1223 } catch (PackageManager.NameNotFoundException e) { 1224 throw new RuntimeException( 1225 "Unable to find android system package", e); 1226 } 1227 } 1228 1229 public void setWindowManager(WindowManagerService wm) { 1230 mWindowManager = wm; 1231 } 1232 1233 public static final Context main(int factoryTest) { 1234 AThread thr = new AThread(); 1235 thr.start(); 1236 1237 synchronized (thr) { 1238 while (thr.mService == null) { 1239 try { 1240 thr.wait(); 1241 } catch (InterruptedException e) { 1242 } 1243 } 1244 } 1245 1246 ActivityManagerService m = thr.mService; 1247 mSelf = m; 1248 ActivityThread at = ActivityThread.systemMain(); 1249 mSystemThread = at; 1250 Context context = at.getSystemContext(); 1251 context.setTheme(android.R.style.Theme_Holo); 1252 m.mContext = context; 1253 m.mFactoryTest = factoryTest; 1254 m.mMainStack = new ActivityStack(m, context, true); 1255 1256 m.mBatteryStatsService.publish(context); 1257 m.mUsageStatsService.publish(context); 1258 1259 synchronized (thr) { 1260 thr.mReady = true; 1261 thr.notifyAll(); 1262 } 1263 1264 m.startRunning(null, null, null, null); 1265 1266 return context; 1267 } 1268 1269 public static ActivityManagerService self() { 1270 return mSelf; 1271 } 1272 1273 static class AThread extends Thread { 1274 ActivityManagerService mService; 1275 boolean mReady = false; 1276 1277 public AThread() { 1278 super("ActivityManager"); 1279 } 1280 1281 public void run() { 1282 Looper.prepare(); 1283 1284 android.os.Process.setThreadPriority( 1285 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1286 android.os.Process.setCanSelfBackground(false); 1287 1288 ActivityManagerService m = new ActivityManagerService(); 1289 1290 synchronized (this) { 1291 mService = m; 1292 notifyAll(); 1293 } 1294 1295 synchronized (this) { 1296 while (!mReady) { 1297 try { 1298 wait(); 1299 } catch (InterruptedException e) { 1300 } 1301 } 1302 } 1303 1304 // For debug builds, log event loop stalls to dropbox for analysis. 1305 if (StrictMode.conditionallyEnableDebugLogging()) { 1306 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1307 } 1308 1309 Looper.loop(); 1310 } 1311 } 1312 1313 static class MemBinder extends Binder { 1314 ActivityManagerService mActivityManagerService; 1315 MemBinder(ActivityManagerService activityManagerService) { 1316 mActivityManagerService = activityManagerService; 1317 } 1318 1319 @Override 1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1321 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1322 != PackageManager.PERMISSION_GRANTED) { 1323 pw.println("Permission Denial: can't dump meminfo from from pid=" 1324 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1325 + " without permission " + android.Manifest.permission.DUMP); 1326 return; 1327 } 1328 1329 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args); 1330 } 1331 } 1332 1333 static class GraphicsBinder extends Binder { 1334 ActivityManagerService mActivityManagerService; 1335 GraphicsBinder(ActivityManagerService activityManagerService) { 1336 mActivityManagerService = activityManagerService; 1337 } 1338 1339 @Override 1340 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1341 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1342 != PackageManager.PERMISSION_GRANTED) { 1343 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1344 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1345 + " without permission " + android.Manifest.permission.DUMP); 1346 return; 1347 } 1348 1349 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1350 } 1351 } 1352 1353 static class CpuBinder extends Binder { 1354 ActivityManagerService mActivityManagerService; 1355 CpuBinder(ActivityManagerService activityManagerService) { 1356 mActivityManagerService = activityManagerService; 1357 } 1358 1359 @Override 1360 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1361 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1362 != PackageManager.PERMISSION_GRANTED) { 1363 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1364 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1365 + " without permission " + android.Manifest.permission.DUMP); 1366 return; 1367 } 1368 1369 synchronized (mActivityManagerService.mProcessStatsThread) { 1370 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1371 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1372 SystemClock.uptimeMillis())); 1373 } 1374 } 1375 } 1376 1377 private ActivityManagerService() { 1378 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1379 1380 File dataDir = Environment.getDataDirectory(); 1381 File systemDir = new File(dataDir, "system"); 1382 systemDir.mkdirs(); 1383 mBatteryStatsService = new BatteryStatsService(new File( 1384 systemDir, "batterystats.bin").toString()); 1385 mBatteryStatsService.getActiveStatistics().readLocked(); 1386 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1387 mOnBattery = DEBUG_POWER ? true 1388 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1389 mBatteryStatsService.getActiveStatistics().setCallback(this); 1390 1391 mUsageStatsService = new UsageStatsService(new File( 1392 systemDir, "usagestats").toString()); 1393 1394 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1395 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1396 1397 mConfiguration.setToDefaults(); 1398 mConfiguration.locale = Locale.getDefault(); 1399 mProcessStats.init(); 1400 1401 mCompatModePackages = new CompatModePackages(this, systemDir); 1402 1403 // Add ourself to the Watchdog monitors. 1404 Watchdog.getInstance().addMonitor(this); 1405 1406 mProcessStatsThread = new Thread("ProcessStats") { 1407 public void run() { 1408 while (true) { 1409 try { 1410 try { 1411 synchronized(this) { 1412 final long now = SystemClock.uptimeMillis(); 1413 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1414 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1415 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1416 // + ", write delay=" + nextWriteDelay); 1417 if (nextWriteDelay < nextCpuDelay) { 1418 nextCpuDelay = nextWriteDelay; 1419 } 1420 if (nextCpuDelay > 0) { 1421 mProcessStatsMutexFree.set(true); 1422 this.wait(nextCpuDelay); 1423 } 1424 } 1425 } catch (InterruptedException e) { 1426 } 1427 updateCpuStatsNow(); 1428 } catch (Exception e) { 1429 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1430 } 1431 } 1432 } 1433 }; 1434 mProcessStatsThread.start(); 1435 } 1436 1437 @Override 1438 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1439 throws RemoteException { 1440 try { 1441 return super.onTransact(code, data, reply, flags); 1442 } catch (RuntimeException e) { 1443 // The activity manager only throws security exceptions, so let's 1444 // log all others. 1445 if (!(e instanceof SecurityException)) { 1446 Slog.e(TAG, "Activity Manager Crash", e); 1447 } 1448 throw e; 1449 } 1450 } 1451 1452 void updateCpuStats() { 1453 final long now = SystemClock.uptimeMillis(); 1454 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1455 return; 1456 } 1457 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1458 synchronized (mProcessStatsThread) { 1459 mProcessStatsThread.notify(); 1460 } 1461 } 1462 } 1463 1464 void updateCpuStatsNow() { 1465 synchronized (mProcessStatsThread) { 1466 mProcessStatsMutexFree.set(false); 1467 final long now = SystemClock.uptimeMillis(); 1468 boolean haveNewCpuStats = false; 1469 1470 if (MONITOR_CPU_USAGE && 1471 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1472 mLastCpuTime.set(now); 1473 haveNewCpuStats = true; 1474 mProcessStats.update(); 1475 //Slog.i(TAG, mProcessStats.printCurrentState()); 1476 //Slog.i(TAG, "Total CPU usage: " 1477 // + mProcessStats.getTotalCpuPercent() + "%"); 1478 1479 // Slog the cpu usage if the property is set. 1480 if ("true".equals(SystemProperties.get("events.cpu"))) { 1481 int user = mProcessStats.getLastUserTime(); 1482 int system = mProcessStats.getLastSystemTime(); 1483 int iowait = mProcessStats.getLastIoWaitTime(); 1484 int irq = mProcessStats.getLastIrqTime(); 1485 int softIrq = mProcessStats.getLastSoftIrqTime(); 1486 int idle = mProcessStats.getLastIdleTime(); 1487 1488 int total = user + system + iowait + irq + softIrq + idle; 1489 if (total == 0) total = 1; 1490 1491 EventLog.writeEvent(EventLogTags.CPU, 1492 ((user+system+iowait+irq+softIrq) * 100) / total, 1493 (user * 100) / total, 1494 (system * 100) / total, 1495 (iowait * 100) / total, 1496 (irq * 100) / total, 1497 (softIrq * 100) / total); 1498 } 1499 } 1500 1501 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1502 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1503 synchronized(bstats) { 1504 synchronized(mPidsSelfLocked) { 1505 if (haveNewCpuStats) { 1506 if (mOnBattery) { 1507 int perc = bstats.startAddingCpuLocked(); 1508 int totalUTime = 0; 1509 int totalSTime = 0; 1510 final int N = mProcessStats.countStats(); 1511 for (int i=0; i<N; i++) { 1512 ProcessStats.Stats st = mProcessStats.getStats(i); 1513 if (!st.working) { 1514 continue; 1515 } 1516 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1517 int otherUTime = (st.rel_utime*perc)/100; 1518 int otherSTime = (st.rel_stime*perc)/100; 1519 totalUTime += otherUTime; 1520 totalSTime += otherSTime; 1521 if (pr != null) { 1522 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1523 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1524 st.rel_stime-otherSTime); 1525 ps.addSpeedStepTimes(cpuSpeedTimes); 1526 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1527 } else { 1528 BatteryStatsImpl.Uid.Proc ps = 1529 bstats.getProcessStatsLocked(st.name, st.pid); 1530 if (ps != null) { 1531 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1532 st.rel_stime-otherSTime); 1533 ps.addSpeedStepTimes(cpuSpeedTimes); 1534 } 1535 } 1536 } 1537 bstats.finishAddingCpuLocked(perc, totalUTime, 1538 totalSTime, cpuSpeedTimes); 1539 } 1540 } 1541 } 1542 1543 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1544 mLastWriteTime = now; 1545 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1546 } 1547 } 1548 } 1549 } 1550 1551 @Override 1552 public void batteryNeedsCpuUpdate() { 1553 updateCpuStatsNow(); 1554 } 1555 1556 @Override 1557 public void batteryPowerChanged(boolean onBattery) { 1558 // When plugging in, update the CPU stats first before changing 1559 // the plug state. 1560 updateCpuStatsNow(); 1561 synchronized (this) { 1562 synchronized(mPidsSelfLocked) { 1563 mOnBattery = DEBUG_POWER ? true : onBattery; 1564 } 1565 } 1566 } 1567 1568 /** 1569 * Initialize the application bind args. These are passed to each 1570 * process when the bindApplication() IPC is sent to the process. They're 1571 * lazily setup to make sure the services are running when they're asked for. 1572 */ 1573 private HashMap<String, IBinder> getCommonServicesLocked() { 1574 if (mAppBindArgs == null) { 1575 mAppBindArgs = new HashMap<String, IBinder>(); 1576 1577 // Setup the application init args 1578 mAppBindArgs.put("package", ServiceManager.getService("package")); 1579 mAppBindArgs.put("window", ServiceManager.getService("window")); 1580 mAppBindArgs.put(Context.ALARM_SERVICE, 1581 ServiceManager.getService(Context.ALARM_SERVICE)); 1582 } 1583 return mAppBindArgs; 1584 } 1585 1586 final void setFocusedActivityLocked(ActivityRecord r) { 1587 if (mFocusedActivity != r) { 1588 mFocusedActivity = r; 1589 mWindowManager.setFocusedApp(r, true); 1590 } 1591 } 1592 1593 private final void updateLruProcessInternalLocked(ProcessRecord app, 1594 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1595 // put it on the LRU to keep track of when it should be exited. 1596 int lrui = mLruProcesses.indexOf(app); 1597 if (lrui >= 0) mLruProcesses.remove(lrui); 1598 1599 int i = mLruProcesses.size()-1; 1600 int skipTop = 0; 1601 1602 app.lruSeq = mLruSeq; 1603 1604 // compute the new weight for this process. 1605 if (updateActivityTime) { 1606 app.lastActivityTime = SystemClock.uptimeMillis(); 1607 } 1608 if (app.activities.size() > 0) { 1609 // If this process has activities, we more strongly want to keep 1610 // it around. 1611 app.lruWeight = app.lastActivityTime; 1612 } else if (app.pubProviders.size() > 0) { 1613 // If this process contains content providers, we want to keep 1614 // it a little more strongly. 1615 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1616 // Also don't let it kick out the first few "real" hidden processes. 1617 skipTop = ProcessList.MIN_HIDDEN_APPS; 1618 } else { 1619 // If this process doesn't have activities, we less strongly 1620 // want to keep it around, and generally want to avoid getting 1621 // in front of any very recently used activities. 1622 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1623 // Also don't let it kick out the first few "real" hidden processes. 1624 skipTop = ProcessList.MIN_HIDDEN_APPS; 1625 } 1626 1627 while (i >= 0) { 1628 ProcessRecord p = mLruProcesses.get(i); 1629 // If this app shouldn't be in front of the first N background 1630 // apps, then skip over that many that are currently hidden. 1631 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1632 skipTop--; 1633 } 1634 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1635 mLruProcesses.add(i+1, app); 1636 break; 1637 } 1638 i--; 1639 } 1640 if (i < 0) { 1641 mLruProcesses.add(0, app); 1642 } 1643 1644 // If the app is currently using a content provider or service, 1645 // bump those processes as well. 1646 if (app.connections.size() > 0) { 1647 for (ConnectionRecord cr : app.connections) { 1648 if (cr.binding != null && cr.binding.service != null 1649 && cr.binding.service.app != null 1650 && cr.binding.service.app.lruSeq != mLruSeq) { 1651 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, 1652 updateActivityTime, i+1); 1653 } 1654 } 1655 } 1656 if (app.conProviders.size() > 0) { 1657 for (ContentProviderRecord cpr : app.conProviders.keySet()) { 1658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1659 updateLruProcessInternalLocked(cpr.proc, oomAdj, 1660 updateActivityTime, i+1); 1661 } 1662 } 1663 } 1664 1665 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1666 if (oomAdj) { 1667 updateOomAdjLocked(); 1668 } 1669 } 1670 1671 final void updateLruProcessLocked(ProcessRecord app, 1672 boolean oomAdj, boolean updateActivityTime) { 1673 mLruSeq++; 1674 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1675 } 1676 1677 final ProcessRecord getProcessRecordLocked( 1678 String processName, int uid) { 1679 if (uid == Process.SYSTEM_UID) { 1680 // The system gets to run in any process. If there are multiple 1681 // processes with the same uid, just pick the first (this 1682 // should never happen). 1683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1684 processName); 1685 return procs != null ? procs.valueAt(0) : null; 1686 } 1687 ProcessRecord proc = mProcessNames.get(processName, uid); 1688 return proc; 1689 } 1690 1691 void ensurePackageDexOpt(String packageName) { 1692 IPackageManager pm = AppGlobals.getPackageManager(); 1693 try { 1694 if (pm.performDexOpt(packageName)) { 1695 mDidDexOpt = true; 1696 } 1697 } catch (RemoteException e) { 1698 } 1699 } 1700 1701 boolean isNextTransitionForward() { 1702 int transit = mWindowManager.getPendingAppTransition(); 1703 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1704 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1705 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1706 } 1707 1708 final ProcessRecord startProcessLocked(String processName, 1709 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1710 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1711 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1712 // We don't have to do anything more if: 1713 // (1) There is an existing application record; and 1714 // (2) The caller doesn't think it is dead, OR there is no thread 1715 // object attached to it so we know it couldn't have crashed; and 1716 // (3) There is a pid assigned to it, so it is either starting or 1717 // already running. 1718 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1719 + " app=" + app + " knownToBeDead=" + knownToBeDead 1720 + " thread=" + (app != null ? app.thread : null) 1721 + " pid=" + (app != null ? app.pid : -1)); 1722 if (app != null && app.pid > 0) { 1723 if (!knownToBeDead || app.thread == null) { 1724 // We already have the app running, or are waiting for it to 1725 // come up (we have a pid but not yet its thread), so keep it. 1726 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1727 // If this is a new package in the process, add the package to the list 1728 app.addPackage(info.packageName); 1729 return app; 1730 } else { 1731 // An application record is attached to a previous process, 1732 // clean it up now. 1733 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1734 handleAppDiedLocked(app, true, true); 1735 } 1736 } 1737 1738 String hostingNameStr = hostingName != null 1739 ? hostingName.flattenToShortString() : null; 1740 1741 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1742 // If we are in the background, then check to see if this process 1743 // is bad. If so, we will just silently fail. 1744 if (mBadProcesses.get(info.processName, info.uid) != null) { 1745 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1746 + "/" + info.processName); 1747 return null; 1748 } 1749 } else { 1750 // When the user is explicitly starting a process, then clear its 1751 // crash count so that we won't make it bad until they see at 1752 // least one crash dialog again, and make the process good again 1753 // if it had been bad. 1754 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1755 + "/" + info.processName); 1756 mProcessCrashTimes.remove(info.processName, info.uid); 1757 if (mBadProcesses.get(info.processName, info.uid) != null) { 1758 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1759 info.processName); 1760 mBadProcesses.remove(info.processName, info.uid); 1761 if (app != null) { 1762 app.bad = false; 1763 } 1764 } 1765 } 1766 1767 if (app == null) { 1768 app = newProcessRecordLocked(null, info, processName); 1769 mProcessNames.put(processName, info.uid, app); 1770 } else { 1771 // If this is a new package in the process, add the package to the list 1772 app.addPackage(info.packageName); 1773 } 1774 1775 // If the system is not ready yet, then hold off on starting this 1776 // process until it is. 1777 if (!mProcessesReady 1778 && !isAllowedWhileBooting(info) 1779 && !allowWhileBooting) { 1780 if (!mProcessesOnHold.contains(app)) { 1781 mProcessesOnHold.add(app); 1782 } 1783 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1784 return app; 1785 } 1786 1787 startProcessLocked(app, hostingType, hostingNameStr); 1788 return (app.pid != 0) ? app : null; 1789 } 1790 1791 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1792 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1793 } 1794 1795 private final void startProcessLocked(ProcessRecord app, 1796 String hostingType, String hostingNameStr) { 1797 if (app.pid > 0 && app.pid != MY_PID) { 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.remove(app.pid); 1800 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1801 } 1802 app.pid = 0; 1803 } 1804 1805 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1806 "startProcessLocked removing on hold: " + app); 1807 mProcessesOnHold.remove(app); 1808 1809 updateCpuStats(); 1810 1811 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1812 mProcDeaths[0] = 0; 1813 1814 try { 1815 int uid = app.info.uid; 1816 int[] gids = null; 1817 try { 1818 gids = mContext.getPackageManager().getPackageGids( 1819 app.info.packageName); 1820 } catch (PackageManager.NameNotFoundException e) { 1821 Slog.w(TAG, "Unable to retrieve gids", e); 1822 } 1823 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1824 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1825 && mTopComponent != null 1826 && app.processName.equals(mTopComponent.getPackageName())) { 1827 uid = 0; 1828 } 1829 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1830 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1831 uid = 0; 1832 } 1833 } 1834 int debugFlags = 0; 1835 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1836 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1837 // Also turn on CheckJNI for debuggable apps. It's quite 1838 // awkward to turn on otherwise. 1839 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1840 } 1841 // Run the app in safe mode if its manifest requests so or the 1842 // system is booted in safe mode. 1843 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 1844 Zygote.systemInSafeMode == true) { 1845 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1846 } 1847 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1848 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1849 } 1850 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1851 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1852 } 1853 if ("1".equals(SystemProperties.get("debug.assert"))) { 1854 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1855 } 1856 1857 // Start the process. It will either succeed and return a result containing 1858 // the PID of the new process, or else throw a RuntimeException. 1859 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 1860 app.processName, uid, uid, gids, debugFlags, 1861 app.info.targetSdkVersion, null); 1862 1863 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 1864 synchronized (bs) { 1865 if (bs.isOnBattery()) { 1866 app.batteryStats.incStartsLocked(); 1867 } 1868 } 1869 1870 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 1871 app.processName, hostingType, 1872 hostingNameStr != null ? hostingNameStr : ""); 1873 1874 if (app.persistent) { 1875 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 1876 } 1877 1878 StringBuilder buf = mStringBuilder; 1879 buf.setLength(0); 1880 buf.append("Start proc "); 1881 buf.append(app.processName); 1882 buf.append(" for "); 1883 buf.append(hostingType); 1884 if (hostingNameStr != null) { 1885 buf.append(" "); 1886 buf.append(hostingNameStr); 1887 } 1888 buf.append(": pid="); 1889 buf.append(startResult.pid); 1890 buf.append(" uid="); 1891 buf.append(uid); 1892 buf.append(" gids={"); 1893 if (gids != null) { 1894 for (int gi=0; gi<gids.length; gi++) { 1895 if (gi != 0) buf.append(", "); 1896 buf.append(gids[gi]); 1897 1898 } 1899 } 1900 buf.append("}"); 1901 Slog.i(TAG, buf.toString()); 1902 app.pid = startResult.pid; 1903 app.usingWrapper = startResult.usingWrapper; 1904 app.removed = false; 1905 synchronized (mPidsSelfLocked) { 1906 this.mPidsSelfLocked.put(startResult.pid, app); 1907 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1908 msg.obj = app; 1909 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 1910 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 1911 } 1912 } catch (RuntimeException e) { 1913 // XXX do better error recovery. 1914 app.pid = 0; 1915 Slog.e(TAG, "Failure starting process " + app.processName, e); 1916 } 1917 } 1918 1919 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 1920 if (resumed) { 1921 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 1922 } else { 1923 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 1924 } 1925 } 1926 1927 boolean startHomeActivityLocked() { 1928 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1929 && mTopAction == null) { 1930 // We are running in factory test mode, but unable to find 1931 // the factory test app, so just sit around displaying the 1932 // error message and don't try to start anything. 1933 return false; 1934 } 1935 Intent intent = new Intent( 1936 mTopAction, 1937 mTopData != null ? Uri.parse(mTopData) : null); 1938 intent.setComponent(mTopComponent); 1939 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 1940 intent.addCategory(Intent.CATEGORY_HOME); 1941 } 1942 ActivityInfo aInfo = 1943 intent.resolveActivityInfo(mContext.getPackageManager(), 1944 STOCK_PM_FLAGS); 1945 if (aInfo != null) { 1946 intent.setComponent(new ComponentName( 1947 aInfo.applicationInfo.packageName, aInfo.name)); 1948 // Don't do this if the home app is currently being 1949 // instrumented. 1950 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 1951 aInfo.applicationInfo.uid); 1952 if (app == null || app.instrumentationClass == null) { 1953 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 1954 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo, 1955 null, null, 0, 0, 0, false, false, null); 1956 } 1957 } 1958 1959 1960 return true; 1961 } 1962 1963 /** 1964 * Starts the "new version setup screen" if appropriate. 1965 */ 1966 void startSetupActivityLocked() { 1967 // Only do this once per boot. 1968 if (mCheckedForSetup) { 1969 return; 1970 } 1971 1972 // We will show this screen if the current one is a different 1973 // version than the last one shown, and we are not running in 1974 // low-level factory test mode. 1975 final ContentResolver resolver = mContext.getContentResolver(); 1976 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 1977 Settings.Secure.getInt(resolver, 1978 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 1979 mCheckedForSetup = true; 1980 1981 // See if we should be showing the platform update setup UI. 1982 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 1983 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 1984 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 1985 1986 // We don't allow third party apps to replace this. 1987 ResolveInfo ri = null; 1988 for (int i=0; ris != null && i<ris.size(); i++) { 1989 if ((ris.get(i).activityInfo.applicationInfo.flags 1990 & ApplicationInfo.FLAG_SYSTEM) != 0) { 1991 ri = ris.get(i); 1992 break; 1993 } 1994 } 1995 1996 if (ri != null) { 1997 String vers = ri.activityInfo.metaData != null 1998 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 1999 : null; 2000 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2001 vers = ri.activityInfo.applicationInfo.metaData.getString( 2002 Intent.METADATA_SETUP_VERSION); 2003 } 2004 String lastVers = Settings.Secure.getString( 2005 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2006 if (vers != null && !vers.equals(lastVers)) { 2007 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2008 intent.setComponent(new ComponentName( 2009 ri.activityInfo.packageName, ri.activityInfo.name)); 2010 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2011 null, null, 0, 0, 0, false, false, null); 2012 } 2013 } 2014 } 2015 } 2016 2017 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2018 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2019 } 2020 2021 public int getFrontActivityScreenCompatMode() { 2022 synchronized (this) { 2023 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2024 } 2025 } 2026 2027 public void setFrontActivityScreenCompatMode(int mode) { 2028 synchronized (this) { 2029 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2030 } 2031 } 2032 2033 public int getPackageScreenCompatMode(String packageName) { 2034 synchronized (this) { 2035 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2036 } 2037 } 2038 2039 public void setPackageScreenCompatMode(String packageName, int mode) { 2040 synchronized (this) { 2041 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2042 } 2043 } 2044 2045 public boolean getPackageAskScreenCompat(String packageName) { 2046 synchronized (this) { 2047 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2048 } 2049 } 2050 2051 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2052 synchronized (this) { 2053 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2054 } 2055 } 2056 2057 void reportResumedActivityLocked(ActivityRecord r) { 2058 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2059 2060 final int identHash = System.identityHashCode(r); 2061 updateUsageStats(r, true); 2062 2063 int i = mWatchers.beginBroadcast(); 2064 while (i > 0) { 2065 i--; 2066 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2067 if (w != null) { 2068 try { 2069 w.activityResuming(identHash); 2070 } catch (RemoteException e) { 2071 } 2072 } 2073 } 2074 mWatchers.finishBroadcast(); 2075 } 2076 2077 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 2078 int i = mProcessObservers.beginBroadcast(); 2079 while (i > 0) { 2080 i--; 2081 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2082 if (observer != null) { 2083 try { 2084 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities); 2085 } catch (RemoteException e) { 2086 } 2087 } 2088 } 2089 mProcessObservers.finishBroadcast(); 2090 } 2091 2092 private void dispatchProcessDied(int pid, int uid) { 2093 int i = mProcessObservers.beginBroadcast(); 2094 while (i > 0) { 2095 i--; 2096 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2097 if (observer != null) { 2098 try { 2099 observer.onProcessDied(pid, uid); 2100 } catch (RemoteException e) { 2101 } 2102 } 2103 } 2104 mProcessObservers.finishBroadcast(); 2105 } 2106 2107 final void doPendingActivityLaunchesLocked(boolean doResume) { 2108 final int N = mPendingActivityLaunches.size(); 2109 if (N <= 0) { 2110 return; 2111 } 2112 for (int i=0; i<N; i++) { 2113 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2114 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2115 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 2116 doResume && i == (N-1)); 2117 } 2118 mPendingActivityLaunches.clear(); 2119 } 2120 2121 public final int startActivity(IApplicationThread caller, 2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2123 int grantedMode, IBinder resultTo, 2124 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, 2125 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 2126 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2127 grantedUriPermissions, grantedMode, resultTo, resultWho, 2128 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, 2129 null, null); 2130 } 2131 2132 public final WaitResult startActivityAndWait(IApplicationThread caller, 2133 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2134 int grantedMode, IBinder resultTo, 2135 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, 2136 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 2137 WaitResult res = new WaitResult(); 2138 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2139 grantedUriPermissions, grantedMode, resultTo, resultWho, 2140 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, 2141 res, null); 2142 return res; 2143 } 2144 2145 public final int startActivityWithConfig(IApplicationThread caller, 2146 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 2147 int grantedMode, IBinder resultTo, 2148 String resultWho, int requestCode, boolean onlyIfNeeded, 2149 boolean debug, Configuration config) { 2150 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2151 grantedUriPermissions, grantedMode, resultTo, resultWho, 2152 requestCode, onlyIfNeeded, debug, null, null, false, null, config); 2153 } 2154 2155 public int startActivityIntentSender(IApplicationThread caller, 2156 IntentSender intent, Intent fillInIntent, String resolvedType, 2157 IBinder resultTo, String resultWho, int requestCode, 2158 int flagsMask, int flagsValues) { 2159 // Refuse possible leaked file descriptors 2160 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2161 throw new IllegalArgumentException("File descriptors passed in Intent"); 2162 } 2163 2164 IIntentSender sender = intent.getTarget(); 2165 if (!(sender instanceof PendingIntentRecord)) { 2166 throw new IllegalArgumentException("Bad PendingIntent object"); 2167 } 2168 2169 PendingIntentRecord pir = (PendingIntentRecord)sender; 2170 2171 synchronized (this) { 2172 // If this is coming from the currently resumed activity, it is 2173 // effectively saying that app switches are allowed at this point. 2174 if (mMainStack.mResumedActivity != null 2175 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2176 Binder.getCallingUid()) { 2177 mAppSwitchesAllowedTime = 0; 2178 } 2179 } 2180 2181 return pir.sendInner(0, fillInIntent, resolvedType, null, 2182 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 2183 } 2184 2185 public boolean startNextMatchingActivity(IBinder callingActivity, 2186 Intent intent) { 2187 // Refuse possible leaked file descriptors 2188 if (intent != null && intent.hasFileDescriptors() == true) { 2189 throw new IllegalArgumentException("File descriptors passed in Intent"); 2190 } 2191 2192 synchronized (this) { 2193 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2194 if (r == null) { 2195 return false; 2196 } 2197 if (r.app == null || r.app.thread == null) { 2198 // The caller is not running... d'oh! 2199 return false; 2200 } 2201 intent = new Intent(intent); 2202 // The caller is not allowed to change the data. 2203 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2204 // And we are resetting to find the next component... 2205 intent.setComponent(null); 2206 2207 ActivityInfo aInfo = null; 2208 try { 2209 List<ResolveInfo> resolves = 2210 AppGlobals.getPackageManager().queryIntentActivities( 2211 intent, r.resolvedType, 2212 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 2213 2214 // Look for the original activity in the list... 2215 final int N = resolves != null ? resolves.size() : 0; 2216 for (int i=0; i<N; i++) { 2217 ResolveInfo rInfo = resolves.get(i); 2218 if (rInfo.activityInfo.packageName.equals(r.packageName) 2219 && rInfo.activityInfo.name.equals(r.info.name)) { 2220 // We found the current one... the next matching is 2221 // after it. 2222 i++; 2223 if (i<N) { 2224 aInfo = resolves.get(i).activityInfo; 2225 } 2226 break; 2227 } 2228 } 2229 } catch (RemoteException e) { 2230 } 2231 2232 if (aInfo == null) { 2233 // Nobody who is next! 2234 return false; 2235 } 2236 2237 intent.setComponent(new ComponentName( 2238 aInfo.applicationInfo.packageName, aInfo.name)); 2239 intent.setFlags(intent.getFlags()&~( 2240 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2241 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2242 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2243 Intent.FLAG_ACTIVITY_NEW_TASK)); 2244 2245 // Okay now we need to start the new activity, replacing the 2246 // currently running activity. This is a little tricky because 2247 // we want to start the new one as if the current one is finished, 2248 // but not finish the current one first so that there is no flicker. 2249 // And thus... 2250 final boolean wasFinishing = r.finishing; 2251 r.finishing = true; 2252 2253 // Propagate reply information over to the new activity. 2254 final ActivityRecord resultTo = r.resultTo; 2255 final String resultWho = r.resultWho; 2256 final int requestCode = r.requestCode; 2257 r.resultTo = null; 2258 if (resultTo != null) { 2259 resultTo.removeResultsLocked(r, resultWho, requestCode); 2260 } 2261 2262 final long origId = Binder.clearCallingIdentity(); 2263 // XXX we are not dealing with propagating grantedUriPermissions... 2264 // those are not yet exposed to user code, so there is no need. 2265 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2266 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 2267 requestCode, -1, r.launchedFromUid, false, false, null); 2268 Binder.restoreCallingIdentity(origId); 2269 2270 r.finishing = wasFinishing; 2271 if (res != START_SUCCESS) { 2272 return false; 2273 } 2274 return true; 2275 } 2276 } 2277 2278 public final int startActivityInPackage(int uid, 2279 Intent intent, String resolvedType, IBinder resultTo, 2280 String resultWho, int requestCode, boolean onlyIfNeeded) { 2281 2282 // This is so super not safe, that only the system (or okay root) 2283 // can do it. 2284 final int callingUid = Binder.getCallingUid(); 2285 if (callingUid != 0 && callingUid != Process.myUid()) { 2286 throw new SecurityException( 2287 "startActivityInPackage only available to the system"); 2288 } 2289 2290 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2291 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, 2292 null, null, false, null, null); 2293 } 2294 2295 public final int startActivities(IApplicationThread caller, 2296 Intent[] intents, String[] resolvedTypes, IBinder resultTo) { 2297 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo); 2298 } 2299 2300 public final int startActivitiesInPackage(int uid, 2301 Intent[] intents, String[] resolvedTypes, IBinder resultTo) { 2302 2303 // This is so super not safe, that only the system (or okay root) 2304 // can do it. 2305 final int callingUid = Binder.getCallingUid(); 2306 if (callingUid != 0 && callingUid != Process.myUid()) { 2307 throw new SecurityException( 2308 "startActivityInPackage only available to the system"); 2309 } 2310 2311 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo); 2312 } 2313 2314 final void addRecentTaskLocked(TaskRecord task) { 2315 int N = mRecentTasks.size(); 2316 // Quick case: check if the top-most recent task is the same. 2317 if (N > 0 && mRecentTasks.get(0) == task) { 2318 return; 2319 } 2320 // Remove any existing entries that are the same kind of task. 2321 for (int i=0; i<N; i++) { 2322 TaskRecord tr = mRecentTasks.get(i); 2323 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 2324 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 2325 mRecentTasks.remove(i); 2326 i--; 2327 N--; 2328 if (task.intent == null) { 2329 // If the new recent task we are adding is not fully 2330 // specified, then replace it with the existing recent task. 2331 task = tr; 2332 } 2333 } 2334 } 2335 if (N >= MAX_RECENT_TASKS) { 2336 mRecentTasks.remove(N-1); 2337 } 2338 mRecentTasks.add(0, task); 2339 } 2340 2341 public void setRequestedOrientation(IBinder token, 2342 int requestedOrientation) { 2343 synchronized (this) { 2344 ActivityRecord r = mMainStack.isInStackLocked(token); 2345 if (r == null) { 2346 return; 2347 } 2348 final long origId = Binder.clearCallingIdentity(); 2349 mWindowManager.setAppOrientation(r, requestedOrientation); 2350 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2351 mConfiguration, 2352 r.mayFreezeScreenLocked(r.app) ? r : null); 2353 if (config != null) { 2354 r.frozenBeforeDestroy = true; 2355 if (!updateConfigurationLocked(config, r, false)) { 2356 mMainStack.resumeTopActivityLocked(null); 2357 } 2358 } 2359 Binder.restoreCallingIdentity(origId); 2360 } 2361 } 2362 2363 public int getRequestedOrientation(IBinder token) { 2364 synchronized (this) { 2365 ActivityRecord r = mMainStack.isInStackLocked(token); 2366 if (r == null) { 2367 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2368 } 2369 return mWindowManager.getAppOrientation(r); 2370 } 2371 } 2372 2373 /** 2374 * This is the internal entry point for handling Activity.finish(). 2375 * 2376 * @param token The Binder token referencing the Activity we want to finish. 2377 * @param resultCode Result code, if any, from this Activity. 2378 * @param resultData Result data (Intent), if any, from this Activity. 2379 * 2380 * @return Returns true if the activity successfully finished, or false if it is still running. 2381 */ 2382 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2383 // Refuse possible leaked file descriptors 2384 if (resultData != null && resultData.hasFileDescriptors() == true) { 2385 throw new IllegalArgumentException("File descriptors passed in Intent"); 2386 } 2387 2388 synchronized(this) { 2389 if (mController != null) { 2390 // Find the first activity that is not finishing. 2391 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2392 if (next != null) { 2393 // ask watcher if this is allowed 2394 boolean resumeOK = true; 2395 try { 2396 resumeOK = mController.activityResuming(next.packageName); 2397 } catch (RemoteException e) { 2398 mController = null; 2399 } 2400 2401 if (!resumeOK) { 2402 return false; 2403 } 2404 } 2405 } 2406 final long origId = Binder.clearCallingIdentity(); 2407 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2408 resultData, "app-request"); 2409 Binder.restoreCallingIdentity(origId); 2410 return res; 2411 } 2412 } 2413 2414 public final void finishHeavyWeightApp() { 2415 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2416 != PackageManager.PERMISSION_GRANTED) { 2417 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2418 + Binder.getCallingPid() 2419 + ", uid=" + Binder.getCallingUid() 2420 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2421 Slog.w(TAG, msg); 2422 throw new SecurityException(msg); 2423 } 2424 2425 synchronized(this) { 2426 if (mHeavyWeightProcess == null) { 2427 return; 2428 } 2429 2430 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2431 mHeavyWeightProcess.activities); 2432 for (int i=0; i<activities.size(); i++) { 2433 ActivityRecord r = activities.get(i); 2434 if (!r.finishing) { 2435 int index = mMainStack.indexOfTokenLocked(r); 2436 if (index >= 0) { 2437 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2438 null, "finish-heavy"); 2439 } 2440 } 2441 } 2442 2443 mHeavyWeightProcess = null; 2444 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2445 } 2446 } 2447 2448 public void crashApplication(int uid, int initialPid, String packageName, 2449 String message) { 2450 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2451 != PackageManager.PERMISSION_GRANTED) { 2452 String msg = "Permission Denial: crashApplication() from pid=" 2453 + Binder.getCallingPid() 2454 + ", uid=" + Binder.getCallingUid() 2455 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2456 Slog.w(TAG, msg); 2457 throw new SecurityException(msg); 2458 } 2459 2460 synchronized(this) { 2461 ProcessRecord proc = null; 2462 2463 // Figure out which process to kill. We don't trust that initialPid 2464 // still has any relation to current pids, so must scan through the 2465 // list. 2466 synchronized (mPidsSelfLocked) { 2467 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2468 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2469 if (p.info.uid != uid) { 2470 continue; 2471 } 2472 if (p.pid == initialPid) { 2473 proc = p; 2474 break; 2475 } 2476 for (String str : p.pkgList) { 2477 if (str.equals(packageName)) { 2478 proc = p; 2479 } 2480 } 2481 } 2482 } 2483 2484 if (proc == null) { 2485 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2486 + " initialPid=" + initialPid 2487 + " packageName=" + packageName); 2488 return; 2489 } 2490 2491 if (proc.thread != null) { 2492 if (proc.pid == Process.myPid()) { 2493 Log.w(TAG, "crashApplication: trying to crash self!"); 2494 return; 2495 } 2496 long ident = Binder.clearCallingIdentity(); 2497 try { 2498 proc.thread.scheduleCrash(message); 2499 } catch (RemoteException e) { 2500 } 2501 Binder.restoreCallingIdentity(ident); 2502 } 2503 } 2504 } 2505 2506 public final void finishSubActivity(IBinder token, String resultWho, 2507 int requestCode) { 2508 synchronized(this) { 2509 ActivityRecord self = mMainStack.isInStackLocked(token); 2510 if (self == null) { 2511 return; 2512 } 2513 2514 final long origId = Binder.clearCallingIdentity(); 2515 2516 int i; 2517 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2518 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2519 if (r.resultTo == self && r.requestCode == requestCode) { 2520 if ((r.resultWho == null && resultWho == null) || 2521 (r.resultWho != null && r.resultWho.equals(resultWho))) { 2522 mMainStack.finishActivityLocked(r, i, 2523 Activity.RESULT_CANCELED, null, "request-sub"); 2524 } 2525 } 2526 } 2527 2528 Binder.restoreCallingIdentity(origId); 2529 } 2530 } 2531 2532 public boolean willActivityBeVisible(IBinder token) { 2533 synchronized(this) { 2534 int i; 2535 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2536 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2537 if (r == token) { 2538 return true; 2539 } 2540 if (r.fullscreen && !r.finishing) { 2541 return false; 2542 } 2543 } 2544 return true; 2545 } 2546 } 2547 2548 public void overridePendingTransition(IBinder token, String packageName, 2549 int enterAnim, int exitAnim) { 2550 synchronized(this) { 2551 ActivityRecord self = mMainStack.isInStackLocked(token); 2552 if (self == null) { 2553 return; 2554 } 2555 2556 final long origId = Binder.clearCallingIdentity(); 2557 2558 if (self.state == ActivityState.RESUMED 2559 || self.state == ActivityState.PAUSING) { 2560 mWindowManager.overridePendingAppTransition(packageName, 2561 enterAnim, exitAnim); 2562 } 2563 2564 Binder.restoreCallingIdentity(origId); 2565 } 2566 } 2567 2568 /** 2569 * Main function for removing an existing process from the activity manager 2570 * as a result of that process going away. Clears out all connections 2571 * to the process. 2572 */ 2573 private final void handleAppDiedLocked(ProcessRecord app, 2574 boolean restarting, boolean allowRestart) { 2575 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2576 if (!restarting) { 2577 mLruProcesses.remove(app); 2578 } 2579 2580 if (mProfileProc == app) { 2581 clearProfilerLocked(); 2582 } 2583 2584 // Just in case... 2585 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2586 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2587 mMainStack.mPausingActivity = null; 2588 } 2589 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2590 mMainStack.mLastPausedActivity = null; 2591 } 2592 2593 // Remove this application's activities from active lists. 2594 mMainStack.removeHistoryRecordsForAppLocked(app); 2595 2596 boolean atTop = true; 2597 boolean hasVisibleActivities = false; 2598 2599 // Clean out the history list. 2600 int i = mMainStack.mHistory.size(); 2601 if (localLOGV) Slog.v( 2602 TAG, "Removing app " + app + " from history with " + i + " entries"); 2603 while (i > 0) { 2604 i--; 2605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2606 if (localLOGV) Slog.v( 2607 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2608 if (r.app == app) { 2609 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2610 if (ActivityStack.DEBUG_ADD_REMOVE) { 2611 RuntimeException here = new RuntimeException("here"); 2612 here.fillInStackTrace(); 2613 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2614 + ": haveState=" + r.haveState 2615 + " stateNotNeeded=" + r.stateNotNeeded 2616 + " finishing=" + r.finishing 2617 + " state=" + r.state, here); 2618 } 2619 if (!r.finishing) { 2620 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2621 } 2622 r.makeFinishing(); 2623 mMainStack.mHistory.remove(i); 2624 r.takeFromHistory(); 2625 mWindowManager.removeAppToken(r); 2626 if (VALIDATE_TOKENS) { 2627 mWindowManager.validateAppTokens(mMainStack.mHistory); 2628 } 2629 r.removeUriPermissionsLocked(); 2630 2631 } else { 2632 // We have the current state for this activity, so 2633 // it can be restarted later when needed. 2634 if (localLOGV) Slog.v( 2635 TAG, "Keeping entry, setting app to null"); 2636 if (r.visible) { 2637 hasVisibleActivities = true; 2638 } 2639 r.app = null; 2640 r.nowVisible = false; 2641 if (!r.haveState) { 2642 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2643 "App died, clearing saved state of " + r); 2644 r.icicle = null; 2645 } 2646 } 2647 2648 r.stack.cleanUpActivityLocked(r, true, true); 2649 } 2650 atTop = false; 2651 } 2652 2653 app.activities.clear(); 2654 2655 if (app.instrumentationClass != null) { 2656 Slog.w(TAG, "Crash of app " + app.processName 2657 + " running instrumentation " + app.instrumentationClass); 2658 Bundle info = new Bundle(); 2659 info.putString("shortMsg", "Process crashed."); 2660 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2661 } 2662 2663 if (!restarting) { 2664 if (!mMainStack.resumeTopActivityLocked(null)) { 2665 // If there was nothing to resume, and we are not already 2666 // restarting this process, but there is a visible activity that 2667 // is hosted by the process... then make sure all visible 2668 // activities are running, taking care of restarting this 2669 // process. 2670 if (hasVisibleActivities) { 2671 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2672 } 2673 } 2674 } 2675 } 2676 2677 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2678 IBinder threadBinder = thread.asBinder(); 2679 2680 // Find the application record. 2681 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2682 ProcessRecord rec = mLruProcesses.get(i); 2683 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2684 return i; 2685 } 2686 } 2687 return -1; 2688 } 2689 2690 final ProcessRecord getRecordForAppLocked( 2691 IApplicationThread thread) { 2692 if (thread == null) { 2693 return null; 2694 } 2695 2696 int appIndex = getLRURecordIndexForAppLocked(thread); 2697 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2698 } 2699 2700 final void appDiedLocked(ProcessRecord app, int pid, 2701 IApplicationThread thread) { 2702 2703 mProcDeaths[0]++; 2704 2705 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2706 synchronized (stats) { 2707 stats.noteProcessDiedLocked(app.info.uid, pid); 2708 } 2709 2710 // Clean up already done if the process has been re-started. 2711 if (app.pid == pid && app.thread != null && 2712 app.thread.asBinder() == thread.asBinder()) { 2713 if (!app.killedBackground) { 2714 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2715 + ") has died."); 2716 } 2717 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2718 if (localLOGV) Slog.v( 2719 TAG, "Dying app: " + app + ", pid: " + pid 2720 + ", thread: " + thread.asBinder()); 2721 boolean doLowMem = app.instrumentationClass == null; 2722 handleAppDiedLocked(app, false, true); 2723 2724 if (doLowMem) { 2725 // If there are no longer any background processes running, 2726 // and the app that died was not running instrumentation, 2727 // then tell everyone we are now low on memory. 2728 boolean haveBg = false; 2729 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2730 ProcessRecord rec = mLruProcesses.get(i); 2731 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2732 haveBg = true; 2733 break; 2734 } 2735 } 2736 2737 if (!haveBg) { 2738 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2739 long now = SystemClock.uptimeMillis(); 2740 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2741 ProcessRecord rec = mLruProcesses.get(i); 2742 if (rec != app && rec.thread != null && 2743 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2744 // The low memory report is overriding any current 2745 // state for a GC request. Make sure to do 2746 // heavy/important/visible/foreground processes first. 2747 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2748 rec.lastRequestedGc = 0; 2749 } else { 2750 rec.lastRequestedGc = rec.lastLowMemory; 2751 } 2752 rec.reportLowMemory = true; 2753 rec.lastLowMemory = now; 2754 mProcessesToGc.remove(rec); 2755 addProcessToGcListLocked(rec); 2756 } 2757 } 2758 scheduleAppGcsLocked(); 2759 } 2760 } 2761 } else if (app.pid != pid) { 2762 // A new process has already been started. 2763 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2764 + ") has died and restarted (pid " + app.pid + ")."); 2765 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2766 } else if (DEBUG_PROCESSES) { 2767 Slog.d(TAG, "Received spurious death notification for thread " 2768 + thread.asBinder()); 2769 } 2770 } 2771 2772 /** 2773 * If a stack trace dump file is configured, dump process stack traces. 2774 * @param clearTraces causes the dump file to be erased prior to the new 2775 * traces being written, if true; when false, the new traces will be 2776 * appended to any existing file content. 2777 * @param firstPids of dalvik VM processes to dump stack traces for first 2778 * @param lastPids of dalvik VM processes to dump stack traces for last 2779 * @return file containing stack traces, or null if no dump file is configured 2780 */ 2781 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 2782 ProcessStats processStats, SparseArray<Boolean> lastPids) { 2783 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 2784 if (tracesPath == null || tracesPath.length() == 0) { 2785 return null; 2786 } 2787 2788 File tracesFile = new File(tracesPath); 2789 try { 2790 File tracesDir = tracesFile.getParentFile(); 2791 if (!tracesDir.exists()) tracesFile.mkdirs(); 2792 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 2793 2794 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 2795 tracesFile.createNewFile(); 2796 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 2797 } catch (IOException e) { 2798 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 2799 return null; 2800 } 2801 2802 // Use a FileObserver to detect when traces finish writing. 2803 // The order of traces is considered important to maintain for legibility. 2804 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 2805 public synchronized void onEvent(int event, String path) { notify(); } 2806 }; 2807 2808 try { 2809 observer.startWatching(); 2810 2811 // First collect all of the stacks of the most important pids. 2812 try { 2813 int num = firstPids.size(); 2814 for (int i = 0; i < num; i++) { 2815 synchronized (observer) { 2816 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 2817 observer.wait(200); // Wait for write-close, give up after 200msec 2818 } 2819 } 2820 } catch (InterruptedException e) { 2821 Log.wtf(TAG, e); 2822 } 2823 2824 // Next measure CPU usage. 2825 if (processStats != null) { 2826 processStats.init(); 2827 System.gc(); 2828 processStats.update(); 2829 try { 2830 synchronized (processStats) { 2831 processStats.wait(500); // measure over 1/2 second. 2832 } 2833 } catch (InterruptedException e) { 2834 } 2835 processStats.update(); 2836 2837 // We'll take the stack crawls of just the top apps using CPU. 2838 final int N = processStats.countWorkingStats(); 2839 int numProcs = 0; 2840 for (int i=0; i<N && numProcs<5; i++) { 2841 ProcessStats.Stats stats = processStats.getWorkingStats(i); 2842 if (lastPids.indexOfKey(stats.pid) >= 0) { 2843 numProcs++; 2844 try { 2845 synchronized (observer) { 2846 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 2847 observer.wait(200); // Wait for write-close, give up after 200msec 2848 } 2849 } catch (InterruptedException e) { 2850 Log.wtf(TAG, e); 2851 } 2852 2853 } 2854 } 2855 } 2856 2857 return tracesFile; 2858 2859 } finally { 2860 observer.stopWatching(); 2861 } 2862 } 2863 2864 private final class AppNotResponding implements Runnable { 2865 private final ProcessRecord mApp; 2866 private final String mAnnotation; 2867 2868 public AppNotResponding(ProcessRecord app, String annotation) { 2869 mApp = app; 2870 mAnnotation = annotation; 2871 } 2872 2873 @Override 2874 public void run() { 2875 appNotResponding(mApp, null, null, mAnnotation); 2876 } 2877 } 2878 2879 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 2880 ActivityRecord parent, final String annotation) { 2881 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 2882 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 2883 2884 if (mController != null) { 2885 try { 2886 // 0 == continue, -1 = kill process immediately 2887 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 2888 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 2889 } catch (RemoteException e) { 2890 mController = null; 2891 } 2892 } 2893 2894 long anrTime = SystemClock.uptimeMillis(); 2895 if (MONITOR_CPU_USAGE) { 2896 updateCpuStatsNow(); 2897 } 2898 2899 synchronized (this) { 2900 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 2901 if (mShuttingDown) { 2902 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 2903 return; 2904 } else if (app.notResponding) { 2905 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 2906 return; 2907 } else if (app.crashing) { 2908 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 2909 return; 2910 } 2911 2912 // In case we come through here for the same app before completing 2913 // this one, mark as anring now so we will bail out. 2914 app.notResponding = true; 2915 2916 // Log the ANR to the event log. 2917 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 2918 annotation); 2919 2920 // Dump thread traces as quickly as we can, starting with "interesting" processes. 2921 firstPids.add(app.pid); 2922 2923 int parentPid = app.pid; 2924 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 2925 if (parentPid != app.pid) firstPids.add(parentPid); 2926 2927 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 2928 2929 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2930 ProcessRecord r = mLruProcesses.get(i); 2931 if (r != null && r.thread != null) { 2932 int pid = r.pid; 2933 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 2934 if (r.persistent) { 2935 firstPids.add(pid); 2936 } else { 2937 lastPids.put(pid, Boolean.TRUE); 2938 } 2939 } 2940 } 2941 } 2942 } 2943 2944 // Log the ANR to the main log. 2945 StringBuilder info = mStringBuilder; 2946 info.setLength(0); 2947 info.append("ANR in ").append(app.processName); 2948 if (activity != null && activity.shortComponentName != null) { 2949 info.append(" (").append(activity.shortComponentName).append(")"); 2950 } 2951 info.append("\n"); 2952 if (annotation != null) { 2953 info.append("Reason: ").append(annotation).append("\n"); 2954 } 2955 if (parent != null && parent != activity) { 2956 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 2957 } 2958 2959 final ProcessStats processStats = new ProcessStats(true); 2960 2961 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids); 2962 2963 String cpuInfo = null; 2964 if (MONITOR_CPU_USAGE) { 2965 updateCpuStatsNow(); 2966 synchronized (mProcessStatsThread) { 2967 cpuInfo = mProcessStats.printCurrentState(anrTime); 2968 } 2969 info.append(processStats.printCurrentLoad()); 2970 info.append(cpuInfo); 2971 } 2972 2973 info.append(processStats.printCurrentState(anrTime)); 2974 2975 Slog.e(TAG, info.toString()); 2976 if (tracesFile == null) { 2977 // There is no trace file, so dump (only) the alleged culprit's threads to the log 2978 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 2979 } 2980 2981 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null); 2982 2983 if (mController != null) { 2984 try { 2985 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 2986 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 2987 if (res != 0) { 2988 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 2989 return; 2990 } 2991 } catch (RemoteException e) { 2992 mController = null; 2993 } 2994 } 2995 2996 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 2997 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 2998 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 2999 3000 synchronized (this) { 3001 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3002 Slog.w(TAG, "Killing " + app + ": background ANR"); 3003 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3004 app.processName, app.setAdj, "background ANR"); 3005 Process.killProcessQuiet(app.pid); 3006 return; 3007 } 3008 3009 // Set the app's notResponding state, and look up the errorReportReceiver 3010 makeAppNotRespondingLocked(app, 3011 activity != null ? activity.shortComponentName : null, 3012 annotation != null ? "ANR " + annotation : "ANR", 3013 info.toString()); 3014 3015 // Bring up the infamous App Not Responding dialog 3016 Message msg = Message.obtain(); 3017 HashMap map = new HashMap(); 3018 msg.what = SHOW_NOT_RESPONDING_MSG; 3019 msg.obj = map; 3020 map.put("app", app); 3021 if (activity != null) { 3022 map.put("activity", activity); 3023 } 3024 3025 mHandler.sendMessage(msg); 3026 } 3027 } 3028 3029 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3030 if (!mLaunchWarningShown) { 3031 mLaunchWarningShown = true; 3032 mHandler.post(new Runnable() { 3033 @Override 3034 public void run() { 3035 synchronized (ActivityManagerService.this) { 3036 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3037 d.show(); 3038 mHandler.postDelayed(new Runnable() { 3039 @Override 3040 public void run() { 3041 synchronized (ActivityManagerService.this) { 3042 d.dismiss(); 3043 mLaunchWarningShown = false; 3044 } 3045 } 3046 }, 4000); 3047 } 3048 } 3049 }); 3050 } 3051 } 3052 3053 public boolean clearApplicationUserData(final String packageName, 3054 final IPackageDataObserver observer) { 3055 int uid = Binder.getCallingUid(); 3056 int pid = Binder.getCallingPid(); 3057 long callingId = Binder.clearCallingIdentity(); 3058 try { 3059 IPackageManager pm = AppGlobals.getPackageManager(); 3060 int pkgUid = -1; 3061 synchronized(this) { 3062 try { 3063 pkgUid = pm.getPackageUid(packageName); 3064 } catch (RemoteException e) { 3065 } 3066 if (pkgUid == -1) { 3067 Slog.w(TAG, "Invalid packageName:" + packageName); 3068 return false; 3069 } 3070 if (uid == pkgUid || checkComponentPermission( 3071 android.Manifest.permission.CLEAR_APP_USER_DATA, 3072 pid, uid, -1, true) 3073 == PackageManager.PERMISSION_GRANTED) { 3074 forceStopPackageLocked(packageName, pkgUid); 3075 } else { 3076 throw new SecurityException(pid+" does not have permission:"+ 3077 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3078 "for process:"+packageName); 3079 } 3080 } 3081 3082 try { 3083 //clear application user data 3084 pm.clearApplicationUserData(packageName, observer); 3085 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3086 Uri.fromParts("package", packageName, null)); 3087 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3088 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3089 null, null, 0, null, null, null, false, false); 3090 } catch (RemoteException e) { 3091 } 3092 } finally { 3093 Binder.restoreCallingIdentity(callingId); 3094 } 3095 return true; 3096 } 3097 3098 public void killBackgroundProcesses(final String packageName) { 3099 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3100 != PackageManager.PERMISSION_GRANTED && 3101 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3102 != PackageManager.PERMISSION_GRANTED) { 3103 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3104 + Binder.getCallingPid() 3105 + ", uid=" + Binder.getCallingUid() 3106 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3107 Slog.w(TAG, msg); 3108 throw new SecurityException(msg); 3109 } 3110 3111 long callingId = Binder.clearCallingIdentity(); 3112 try { 3113 IPackageManager pm = AppGlobals.getPackageManager(); 3114 int pkgUid = -1; 3115 synchronized(this) { 3116 try { 3117 pkgUid = pm.getPackageUid(packageName); 3118 } catch (RemoteException e) { 3119 } 3120 if (pkgUid == -1) { 3121 Slog.w(TAG, "Invalid packageName: " + packageName); 3122 return; 3123 } 3124 killPackageProcessesLocked(packageName, pkgUid, 3125 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false); 3126 } 3127 } finally { 3128 Binder.restoreCallingIdentity(callingId); 3129 } 3130 } 3131 3132 public void forceStopPackage(final String packageName) { 3133 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3134 != PackageManager.PERMISSION_GRANTED) { 3135 String msg = "Permission Denial: forceStopPackage() from pid=" 3136 + Binder.getCallingPid() 3137 + ", uid=" + Binder.getCallingUid() 3138 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3139 Slog.w(TAG, msg); 3140 throw new SecurityException(msg); 3141 } 3142 3143 long callingId = Binder.clearCallingIdentity(); 3144 try { 3145 IPackageManager pm = AppGlobals.getPackageManager(); 3146 int pkgUid = -1; 3147 synchronized(this) { 3148 try { 3149 pkgUid = pm.getPackageUid(packageName); 3150 } catch (RemoteException e) { 3151 } 3152 if (pkgUid == -1) { 3153 Slog.w(TAG, "Invalid packageName: " + packageName); 3154 return; 3155 } 3156 forceStopPackageLocked(packageName, pkgUid); 3157 try { 3158 pm.setPackageStoppedState(packageName, true); 3159 } catch (RemoteException e) { 3160 } catch (IllegalArgumentException e) { 3161 Slog.w(TAG, "Failed trying to unstop package " 3162 + packageName + ": " + e); 3163 } 3164 } 3165 } finally { 3166 Binder.restoreCallingIdentity(callingId); 3167 } 3168 } 3169 3170 /* 3171 * The pkg name and uid have to be specified. 3172 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3173 */ 3174 public void killApplicationWithUid(String pkg, int uid) { 3175 if (pkg == null) { 3176 return; 3177 } 3178 // Make sure the uid is valid. 3179 if (uid < 0) { 3180 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3181 return; 3182 } 3183 int callerUid = Binder.getCallingUid(); 3184 // Only the system server can kill an application 3185 if (callerUid == Process.SYSTEM_UID) { 3186 // Post an aysnc message to kill the application 3187 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3188 msg.arg1 = uid; 3189 msg.arg2 = 0; 3190 msg.obj = pkg; 3191 mHandler.sendMessage(msg); 3192 } else { 3193 throw new SecurityException(callerUid + " cannot kill pkg: " + 3194 pkg); 3195 } 3196 } 3197 3198 public void closeSystemDialogs(String reason) { 3199 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3200 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3201 if (reason != null) { 3202 intent.putExtra("reason", reason); 3203 } 3204 3205 final int uid = Binder.getCallingUid(); 3206 final long origId = Binder.clearCallingIdentity(); 3207 synchronized (this) { 3208 int i = mWatchers.beginBroadcast(); 3209 while (i > 0) { 3210 i--; 3211 IActivityWatcher w = mWatchers.getBroadcastItem(i); 3212 if (w != null) { 3213 try { 3214 w.closingSystemDialogs(reason); 3215 } catch (RemoteException e) { 3216 } 3217 } 3218 } 3219 mWatchers.finishBroadcast(); 3220 3221 mWindowManager.closeSystemDialogs(reason); 3222 3223 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 3224 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3225 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3226 r.stack.finishActivityLocked(r, i, 3227 Activity.RESULT_CANCELED, null, "close-sys"); 3228 } 3229 } 3230 3231 broadcastIntentLocked(null, null, intent, null, 3232 null, 0, null, null, null, false, false, -1, uid); 3233 } 3234 Binder.restoreCallingIdentity(origId); 3235 } 3236 3237 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3238 throws RemoteException { 3239 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3240 for (int i=pids.length-1; i>=0; i--) { 3241 infos[i] = new Debug.MemoryInfo(); 3242 Debug.getMemoryInfo(pids[i], infos[i]); 3243 } 3244 return infos; 3245 } 3246 3247 public long[] getProcessPss(int[] pids) throws RemoteException { 3248 long[] pss = new long[pids.length]; 3249 for (int i=pids.length-1; i>=0; i--) { 3250 pss[i] = Debug.getPss(pids[i]); 3251 } 3252 return pss; 3253 } 3254 3255 public void killApplicationProcess(String processName, int uid) { 3256 if (processName == null) { 3257 return; 3258 } 3259 3260 int callerUid = Binder.getCallingUid(); 3261 // Only the system server can kill an application 3262 if (callerUid == Process.SYSTEM_UID) { 3263 synchronized (this) { 3264 ProcessRecord app = getProcessRecordLocked(processName, uid); 3265 if (app != null && app.thread != null) { 3266 try { 3267 app.thread.scheduleSuicide(); 3268 } catch (RemoteException e) { 3269 // If the other end already died, then our work here is done. 3270 } 3271 } else { 3272 Slog.w(TAG, "Process/uid not found attempting kill of " 3273 + processName + " / " + uid); 3274 } 3275 } 3276 } else { 3277 throw new SecurityException(callerUid + " cannot kill app process: " + 3278 processName); 3279 } 3280 } 3281 3282 private void forceStopPackageLocked(final String packageName, int uid) { 3283 forceStopPackageLocked(packageName, uid, false, false, true, false); 3284 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3285 Uri.fromParts("package", packageName, null)); 3286 if (!mProcessesReady) { 3287 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3288 } 3289 intent.putExtra(Intent.EXTRA_UID, uid); 3290 broadcastIntentLocked(null, null, intent, 3291 null, null, 0, null, null, null, 3292 false, false, MY_PID, Process.SYSTEM_UID); 3293 } 3294 3295 private final boolean killPackageProcessesLocked(String packageName, int uid, 3296 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3297 boolean evenPersistent) { 3298 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3299 3300 // Remove all processes this package may have touched: all with the 3301 // same UID (except for the system or root user), and all whose name 3302 // matches the package name. 3303 final String procNamePrefix = packageName + ":"; 3304 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3305 final int NA = apps.size(); 3306 for (int ia=0; ia<NA; ia++) { 3307 ProcessRecord app = apps.valueAt(ia); 3308 if (app.persistent && !evenPersistent) { 3309 // we don't kill persistent processes 3310 continue; 3311 } 3312 if (app.removed) { 3313 if (doit) { 3314 procs.add(app); 3315 } 3316 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3317 || app.processName.equals(packageName) 3318 || app.processName.startsWith(procNamePrefix)) { 3319 if (app.setAdj >= minOomAdj) { 3320 if (!doit) { 3321 return true; 3322 } 3323 app.removed = true; 3324 procs.add(app); 3325 } 3326 } 3327 } 3328 } 3329 3330 int N = procs.size(); 3331 for (int i=0; i<N; i++) { 3332 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart); 3333 } 3334 return N > 0; 3335 } 3336 3337 private final boolean forceStopPackageLocked(String name, int uid, 3338 boolean callerWillRestart, boolean purgeCache, boolean doit, 3339 boolean evenPersistent) { 3340 int i; 3341 int N; 3342 3343 if (uid < 0) { 3344 try { 3345 uid = AppGlobals.getPackageManager().getPackageUid(name); 3346 } catch (RemoteException e) { 3347 } 3348 } 3349 3350 if (doit) { 3351 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3352 3353 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3354 while (badApps.hasNext()) { 3355 SparseArray<Long> ba = badApps.next(); 3356 if (ba.get(uid) != null) { 3357 badApps.remove(); 3358 } 3359 } 3360 } 3361 3362 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3363 callerWillRestart, false, doit, evenPersistent); 3364 3365 TaskRecord lastTask = null; 3366 for (i=0; i<mMainStack.mHistory.size(); i++) { 3367 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3368 final boolean samePackage = r.packageName.equals(name); 3369 if ((samePackage || r.task == lastTask) 3370 && (r.app == null || evenPersistent || !r.app.persistent)) { 3371 if (!doit) { 3372 if (r.finishing) { 3373 // If this activity is just finishing, then it is not 3374 // interesting as far as something to stop. 3375 continue; 3376 } 3377 return true; 3378 } 3379 didSomething = true; 3380 Slog.i(TAG, " Force finishing activity " + r); 3381 if (samePackage) { 3382 if (r.app != null) { 3383 r.app.removed = true; 3384 } 3385 r.app = null; 3386 } 3387 lastTask = r.task; 3388 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3389 null, "force-stop")) { 3390 i--; 3391 } 3392 } 3393 } 3394 3395 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 3396 for (ServiceRecord service : mServices.values()) { 3397 if (service.packageName.equals(name) 3398 && (service.app == null || evenPersistent || !service.app.persistent)) { 3399 if (!doit) { 3400 return true; 3401 } 3402 didSomething = true; 3403 Slog.i(TAG, " Force stopping service " + service); 3404 if (service.app != null) { 3405 service.app.removed = true; 3406 } 3407 service.app = null; 3408 services.add(service); 3409 } 3410 } 3411 3412 N = services.size(); 3413 for (i=0; i<N; i++) { 3414 bringDownServiceLocked(services.get(i), true); 3415 } 3416 3417 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3418 for (ContentProviderRecord provider : mProvidersByClass.values()) { 3419 if (provider.info.packageName.equals(name) 3420 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3421 if (!doit) { 3422 return true; 3423 } 3424 didSomething = true; 3425 providers.add(provider); 3426 } 3427 } 3428 3429 N = providers.size(); 3430 for (i=0; i<N; i++) { 3431 removeDyingProviderLocked(null, providers.get(i)); 3432 } 3433 3434 if (doit) { 3435 if (purgeCache) { 3436 AttributeCache ac = AttributeCache.instance(); 3437 if (ac != null) { 3438 ac.removePackage(name); 3439 } 3440 } 3441 if (mBooted) { 3442 mMainStack.resumeTopActivityLocked(null); 3443 mMainStack.scheduleIdleLocked(); 3444 } 3445 } 3446 3447 return didSomething; 3448 } 3449 3450 private final boolean removeProcessLocked(ProcessRecord app, 3451 boolean callerWillRestart, boolean allowRestart) { 3452 final String name = app.processName; 3453 final int uid = app.info.uid; 3454 if (DEBUG_PROCESSES) Slog.d( 3455 TAG, "Force removing process " + app + " (" + name 3456 + "/" + uid + ")"); 3457 3458 mProcessNames.remove(name, uid); 3459 if (mHeavyWeightProcess == app) { 3460 mHeavyWeightProcess = null; 3461 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3462 } 3463 boolean needRestart = false; 3464 if (app.pid > 0 && app.pid != MY_PID) { 3465 int pid = app.pid; 3466 synchronized (mPidsSelfLocked) { 3467 mPidsSelfLocked.remove(pid); 3468 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3469 } 3470 handleAppDiedLocked(app, true, allowRestart); 3471 mLruProcesses.remove(app); 3472 Process.killProcess(pid); 3473 3474 if (app.persistent) { 3475 if (!callerWillRestart) { 3476 addAppLocked(app.info); 3477 } else { 3478 needRestart = true; 3479 } 3480 } 3481 } else { 3482 mRemovedProcesses.add(app); 3483 } 3484 3485 return needRestart; 3486 } 3487 3488 private final void processStartTimedOutLocked(ProcessRecord app) { 3489 final int pid = app.pid; 3490 boolean gone = false; 3491 synchronized (mPidsSelfLocked) { 3492 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3493 if (knownApp != null && knownApp.thread == null) { 3494 mPidsSelfLocked.remove(pid); 3495 gone = true; 3496 } 3497 } 3498 3499 if (gone) { 3500 Slog.w(TAG, "Process " + app + " failed to attach"); 3501 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 3502 app.processName); 3503 mProcessNames.remove(app.processName, app.info.uid); 3504 if (mHeavyWeightProcess == app) { 3505 mHeavyWeightProcess = null; 3506 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3507 } 3508 // Take care of any launching providers waiting for this process. 3509 checkAppInLaunchingProvidersLocked(app, true); 3510 // Take care of any services that are waiting for the process. 3511 for (int i=0; i<mPendingServices.size(); i++) { 3512 ServiceRecord sr = mPendingServices.get(i); 3513 if (app.info.uid == sr.appInfo.uid 3514 && app.processName.equals(sr.processName)) { 3515 Slog.w(TAG, "Forcing bringing down service: " + sr); 3516 mPendingServices.remove(i); 3517 i--; 3518 bringDownServiceLocked(sr, true); 3519 } 3520 } 3521 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3522 app.processName, app.setAdj, "start timeout"); 3523 Process.killProcessQuiet(pid); 3524 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3525 Slog.w(TAG, "Unattached app died before backup, skipping"); 3526 try { 3527 IBackupManager bm = IBackupManager.Stub.asInterface( 3528 ServiceManager.getService(Context.BACKUP_SERVICE)); 3529 bm.agentDisconnected(app.info.packageName); 3530 } catch (RemoteException e) { 3531 // Can't happen; the backup manager is local 3532 } 3533 } 3534 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 3535 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3536 mPendingBroadcast.state = BroadcastRecord.IDLE; 3537 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 3538 mPendingBroadcast = null; 3539 scheduleBroadcastsLocked(); 3540 } 3541 } else { 3542 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3543 } 3544 } 3545 3546 private final boolean attachApplicationLocked(IApplicationThread thread, 3547 int pid) { 3548 3549 // Find the application record that is being attached... either via 3550 // the pid if we are running in multiple processes, or just pull the 3551 // next app record if we are emulating process with anonymous threads. 3552 ProcessRecord app; 3553 if (pid != MY_PID && pid >= 0) { 3554 synchronized (mPidsSelfLocked) { 3555 app = mPidsSelfLocked.get(pid); 3556 } 3557 } else { 3558 app = null; 3559 } 3560 3561 if (app == null) { 3562 Slog.w(TAG, "No pending application record for pid " + pid 3563 + " (IApplicationThread " + thread + "); dropping process"); 3564 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3565 if (pid > 0 && pid != MY_PID) { 3566 Process.killProcessQuiet(pid); 3567 } else { 3568 try { 3569 thread.scheduleExit(); 3570 } catch (Exception e) { 3571 // Ignore exceptions. 3572 } 3573 } 3574 return false; 3575 } 3576 3577 // If this application record is still attached to a previous 3578 // process, clean it up now. 3579 if (app.thread != null) { 3580 handleAppDiedLocked(app, true, true); 3581 } 3582 3583 // Tell the process all about itself. 3584 3585 if (localLOGV) Slog.v( 3586 TAG, "Binding process pid " + pid + " to record " + app); 3587 3588 String processName = app.processName; 3589 try { 3590 AppDeathRecipient adr = new AppDeathRecipient( 3591 app, pid, thread); 3592 thread.asBinder().linkToDeath(adr, 0); 3593 app.deathRecipient = adr; 3594 } catch (RemoteException e) { 3595 app.resetPackageList(); 3596 startProcessLocked(app, "link fail", processName); 3597 return false; 3598 } 3599 3600 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3601 3602 app.thread = thread; 3603 app.curAdj = app.setAdj = -100; 3604 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3605 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3606 app.forcingToForeground = null; 3607 app.foregroundServices = false; 3608 app.hasShownUi = false; 3609 app.debugging = false; 3610 3611 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3612 3613 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3614 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3615 3616 if (!normalMode) { 3617 Slog.i(TAG, "Launching preboot mode app: " + app); 3618 } 3619 3620 if (localLOGV) Slog.v( 3621 TAG, "New app record " + app 3622 + " thread=" + thread.asBinder() + " pid=" + pid); 3623 try { 3624 int testMode = IApplicationThread.DEBUG_OFF; 3625 if (mDebugApp != null && mDebugApp.equals(processName)) { 3626 testMode = mWaitForDebugger 3627 ? IApplicationThread.DEBUG_WAIT 3628 : IApplicationThread.DEBUG_ON; 3629 app.debugging = true; 3630 if (mDebugTransient) { 3631 mDebugApp = mOrigDebugApp; 3632 mWaitForDebugger = mOrigWaitForDebugger; 3633 } 3634 } 3635 String profileFile = app.instrumentationProfileFile; 3636 ParcelFileDescriptor profileFd = null; 3637 boolean profileAutoStop = false; 3638 if (mProfileApp != null && mProfileApp.equals(processName)) { 3639 mProfileProc = app; 3640 profileFile = mProfileFile; 3641 profileFd = mProfileFd; 3642 profileAutoStop = mAutoStopProfiler; 3643 } 3644 3645 // If the app is being launched for restore or full backup, set it up specially 3646 boolean isRestrictedBackupMode = false; 3647 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3648 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3649 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3650 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3651 } 3652 3653 ensurePackageDexOpt(app.instrumentationInfo != null 3654 ? app.instrumentationInfo.packageName 3655 : app.info.packageName); 3656 if (app.instrumentationClass != null) { 3657 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3658 } 3659 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3660 + processName + " with config " + mConfiguration); 3661 ApplicationInfo appInfo = app.instrumentationInfo != null 3662 ? app.instrumentationInfo : app.info; 3663 app.compat = compatibilityInfoForPackageLocked(appInfo); 3664 if (profileFd != null) { 3665 profileFd = profileFd.dup(); 3666 } 3667 thread.bindApplication(processName, appInfo, providers, 3668 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 3669 app.instrumentationArguments, app.instrumentationWatcher, testMode, 3670 isRestrictedBackupMode || !normalMode, app.persistent, 3671 mConfiguration, app.compat, getCommonServicesLocked(), 3672 mCoreSettingsObserver.getCoreSettingsLocked()); 3673 updateLruProcessLocked(app, false, true); 3674 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 3675 } catch (Exception e) { 3676 // todo: Yikes! What should we do? For now we will try to 3677 // start another process, but that could easily get us in 3678 // an infinite loop of restarting processes... 3679 Slog.w(TAG, "Exception thrown during bind!", e); 3680 3681 app.resetPackageList(); 3682 app.unlinkDeathRecipient(); 3683 startProcessLocked(app, "bind fail", processName); 3684 return false; 3685 } 3686 3687 // Remove this record from the list of starting applications. 3688 mPersistentStartingProcesses.remove(app); 3689 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3690 "Attach application locked removing on hold: " + app); 3691 mProcessesOnHold.remove(app); 3692 3693 boolean badApp = false; 3694 boolean didSomething = false; 3695 3696 // See if the top visible activity is waiting to run in this process... 3697 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 3698 if (hr != null && normalMode) { 3699 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 3700 && processName.equals(hr.processName)) { 3701 try { 3702 if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 3703 didSomething = true; 3704 } 3705 } catch (Exception e) { 3706 Slog.w(TAG, "Exception in new application when starting activity " 3707 + hr.intent.getComponent().flattenToShortString(), e); 3708 badApp = true; 3709 } 3710 } else { 3711 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 3712 } 3713 } 3714 3715 // Find any services that should be running in this process... 3716 if (!badApp && mPendingServices.size() > 0) { 3717 ServiceRecord sr = null; 3718 try { 3719 for (int i=0; i<mPendingServices.size(); i++) { 3720 sr = mPendingServices.get(i); 3721 if (app.info.uid != sr.appInfo.uid 3722 || !processName.equals(sr.processName)) { 3723 continue; 3724 } 3725 3726 mPendingServices.remove(i); 3727 i--; 3728 realStartServiceLocked(sr, app); 3729 didSomething = true; 3730 } 3731 } catch (Exception e) { 3732 Slog.w(TAG, "Exception in new application when starting service " 3733 + sr.shortName, e); 3734 badApp = true; 3735 } 3736 } 3737 3738 // Check if the next broadcast receiver is in this process... 3739 BroadcastRecord br = mPendingBroadcast; 3740 if (!badApp && br != null && br.curApp == app) { 3741 try { 3742 mPendingBroadcast = null; 3743 processCurBroadcastLocked(br, app); 3744 didSomething = true; 3745 } catch (Exception e) { 3746 Slog.w(TAG, "Exception in new application when starting receiver " 3747 + br.curComponent.flattenToShortString(), e); 3748 badApp = true; 3749 logBroadcastReceiverDiscardLocked(br); 3750 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 3751 br.resultExtras, br.resultAbort, true); 3752 scheduleBroadcastsLocked(); 3753 // We need to reset the state if we fails to start the receiver. 3754 br.state = BroadcastRecord.IDLE; 3755 } 3756 } 3757 3758 // Check whether the next backup agent is in this process... 3759 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 3760 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 3761 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 3762 try { 3763 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 3764 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 3765 mBackupTarget.backupMode); 3766 } catch (Exception e) { 3767 Slog.w(TAG, "Exception scheduling backup agent creation: "); 3768 e.printStackTrace(); 3769 } 3770 } 3771 3772 if (badApp) { 3773 // todo: Also need to kill application to deal with all 3774 // kinds of exceptions. 3775 handleAppDiedLocked(app, false, true); 3776 return false; 3777 } 3778 3779 if (!didSomething) { 3780 updateOomAdjLocked(); 3781 } 3782 3783 return true; 3784 } 3785 3786 public final void attachApplication(IApplicationThread thread) { 3787 synchronized (this) { 3788 int callingPid = Binder.getCallingPid(); 3789 final long origId = Binder.clearCallingIdentity(); 3790 attachApplicationLocked(thread, callingPid); 3791 Binder.restoreCallingIdentity(origId); 3792 } 3793 } 3794 3795 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 3796 final long origId = Binder.clearCallingIdentity(); 3797 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 3798 if (stopProfiling) { 3799 synchronized (this) { 3800 if (mProfileProc == r.app) { 3801 if (mProfileFd != null) { 3802 try { 3803 mProfileFd.close(); 3804 } catch (IOException e) { 3805 } 3806 clearProfilerLocked(); 3807 } 3808 } 3809 } 3810 } 3811 Binder.restoreCallingIdentity(origId); 3812 } 3813 3814 void enableScreenAfterBoot() { 3815 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 3816 SystemClock.uptimeMillis()); 3817 mWindowManager.enableScreenAfterBoot(); 3818 } 3819 3820 public void showBootMessage(final CharSequence msg, final boolean always) { 3821 mWindowManager.showBootMessage(msg, always); 3822 } 3823 3824 public void dismissKeyguardOnNextActivity() { 3825 synchronized (this) { 3826 mMainStack.dismissKeyguardOnNextActivityLocked(); 3827 } 3828 } 3829 3830 final void finishBooting() { 3831 IntentFilter pkgFilter = new IntentFilter(); 3832 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 3833 pkgFilter.addDataScheme("package"); 3834 mContext.registerReceiver(new BroadcastReceiver() { 3835 @Override 3836 public void onReceive(Context context, Intent intent) { 3837 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 3838 if (pkgs != null) { 3839 for (String pkg : pkgs) { 3840 synchronized (ActivityManagerService.this) { 3841 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) { 3842 setResultCode(Activity.RESULT_OK); 3843 return; 3844 } 3845 } 3846 } 3847 } 3848 } 3849 }, pkgFilter); 3850 3851 synchronized (this) { 3852 // Ensure that any processes we had put on hold are now started 3853 // up. 3854 final int NP = mProcessesOnHold.size(); 3855 if (NP > 0) { 3856 ArrayList<ProcessRecord> procs = 3857 new ArrayList<ProcessRecord>(mProcessesOnHold); 3858 for (int ip=0; ip<NP; ip++) { 3859 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 3860 + procs.get(ip)); 3861 startProcessLocked(procs.get(ip), "on-hold", null); 3862 } 3863 } 3864 3865 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 3866 // Start looking for apps that are abusing wake locks. 3867 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 3868 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 3869 // Tell anyone interested that we are done booting! 3870 SystemProperties.set("sys.boot_completed", "1"); 3871 broadcastIntentLocked(null, null, 3872 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 3873 null, null, 0, null, null, 3874 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 3875 false, false, MY_PID, Process.SYSTEM_UID); 3876 } 3877 } 3878 } 3879 3880 final void ensureBootCompleted() { 3881 boolean booting; 3882 boolean enableScreen; 3883 synchronized (this) { 3884 booting = mBooting; 3885 mBooting = false; 3886 enableScreen = !mBooted; 3887 mBooted = true; 3888 } 3889 3890 if (booting) { 3891 finishBooting(); 3892 } 3893 3894 if (enableScreen) { 3895 enableScreenAfterBoot(); 3896 } 3897 } 3898 3899 public final void activityPaused(IBinder token) { 3900 final long origId = Binder.clearCallingIdentity(); 3901 mMainStack.activityPaused(token, false); 3902 Binder.restoreCallingIdentity(origId); 3903 } 3904 3905 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 3906 CharSequence description) { 3907 if (localLOGV) Slog.v( 3908 TAG, "Activity stopped: token=" + token); 3909 3910 // Refuse possible leaked file descriptors 3911 if (icicle != null && icicle.hasFileDescriptors()) { 3912 throw new IllegalArgumentException("File descriptors passed in Bundle"); 3913 } 3914 3915 ActivityRecord r = null; 3916 3917 final long origId = Binder.clearCallingIdentity(); 3918 3919 synchronized (this) { 3920 r = mMainStack.isInStackLocked(token); 3921 if (r != null) { 3922 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 3923 } 3924 } 3925 3926 if (r != null) { 3927 sendPendingThumbnail(r, null, null, null, false); 3928 } 3929 3930 trimApplications(); 3931 3932 Binder.restoreCallingIdentity(origId); 3933 } 3934 3935 public final void activityDestroyed(IBinder token) { 3936 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 3937 mMainStack.activityDestroyed(token); 3938 } 3939 3940 public String getCallingPackage(IBinder token) { 3941 synchronized (this) { 3942 ActivityRecord r = getCallingRecordLocked(token); 3943 return r != null && r.app != null ? r.info.packageName : null; 3944 } 3945 } 3946 3947 public ComponentName getCallingActivity(IBinder token) { 3948 synchronized (this) { 3949 ActivityRecord r = getCallingRecordLocked(token); 3950 return r != null ? r.intent.getComponent() : null; 3951 } 3952 } 3953 3954 private ActivityRecord getCallingRecordLocked(IBinder token) { 3955 ActivityRecord r = mMainStack.isInStackLocked(token); 3956 if (r == null) { 3957 return null; 3958 } 3959 return r.resultTo; 3960 } 3961 3962 public ComponentName getActivityClassForToken(IBinder token) { 3963 synchronized(this) { 3964 ActivityRecord r = mMainStack.isInStackLocked(token); 3965 if (r == null) { 3966 return null; 3967 } 3968 return r.intent.getComponent(); 3969 } 3970 } 3971 3972 public String getPackageForToken(IBinder token) { 3973 synchronized(this) { 3974 ActivityRecord r = mMainStack.isInStackLocked(token); 3975 if (r == null) { 3976 return null; 3977 } 3978 return r.packageName; 3979 } 3980 } 3981 3982 public IIntentSender getIntentSender(int type, 3983 String packageName, IBinder token, String resultWho, 3984 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) { 3985 // Refuse possible leaked file descriptors 3986 if (intents != null) { 3987 if (intents.length < 1) { 3988 throw new IllegalArgumentException("Intents array length must be >= 1"); 3989 } 3990 for (int i=0; i<intents.length; i++) { 3991 Intent intent = intents[i]; 3992 if (intent != null) { 3993 if (intent.hasFileDescriptors()) { 3994 throw new IllegalArgumentException("File descriptors passed in Intent"); 3995 } 3996 if (type == INTENT_SENDER_BROADCAST && 3997 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 3998 throw new IllegalArgumentException( 3999 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4000 } 4001 intents[i] = new Intent(intent); 4002 } 4003 } 4004 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4005 throw new IllegalArgumentException( 4006 "Intent array length does not match resolvedTypes length"); 4007 } 4008 } 4009 4010 synchronized(this) { 4011 int callingUid = Binder.getCallingUid(); 4012 try { 4013 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4014 int uid = AppGlobals.getPackageManager() 4015 .getPackageUid(packageName); 4016 if (uid != Binder.getCallingUid()) { 4017 String msg = "Permission Denial: getIntentSender() from pid=" 4018 + Binder.getCallingPid() 4019 + ", uid=" + Binder.getCallingUid() 4020 + ", (need uid=" + uid + ")" 4021 + " is not allowed to send as package " + packageName; 4022 Slog.w(TAG, msg); 4023 throw new SecurityException(msg); 4024 } 4025 } 4026 4027 return getIntentSenderLocked(type, packageName, callingUid, 4028 token, resultWho, requestCode, intents, resolvedTypes, flags); 4029 4030 } catch (RemoteException e) { 4031 throw new SecurityException(e); 4032 } 4033 } 4034 } 4035 4036 IIntentSender getIntentSenderLocked(int type, 4037 String packageName, int callingUid, IBinder token, String resultWho, 4038 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) { 4039 ActivityRecord activity = null; 4040 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 4041 activity = mMainStack.isInStackLocked(token); 4042 if (activity == null) { 4043 return null; 4044 } 4045 if (activity.finishing) { 4046 return null; 4047 } 4048 } 4049 4050 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4051 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4052 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4053 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4054 |PendingIntent.FLAG_UPDATE_CURRENT); 4055 4056 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4057 type, packageName, activity, resultWho, 4058 requestCode, intents, resolvedTypes, flags); 4059 WeakReference<PendingIntentRecord> ref; 4060 ref = mIntentSenderRecords.get(key); 4061 PendingIntentRecord rec = ref != null ? ref.get() : null; 4062 if (rec != null) { 4063 if (!cancelCurrent) { 4064 if (updateCurrent) { 4065 if (rec.key.requestIntent != null) { 4066 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null); 4067 } 4068 if (intents != null) { 4069 intents[intents.length-1] = rec.key.requestIntent; 4070 rec.key.allIntents = intents; 4071 rec.key.allResolvedTypes = resolvedTypes; 4072 } else { 4073 rec.key.allIntents = null; 4074 rec.key.allResolvedTypes = null; 4075 } 4076 } 4077 return rec; 4078 } 4079 rec.canceled = true; 4080 mIntentSenderRecords.remove(key); 4081 } 4082 if (noCreate) { 4083 return rec; 4084 } 4085 rec = new PendingIntentRecord(this, key, callingUid); 4086 mIntentSenderRecords.put(key, rec.ref); 4087 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 4088 if (activity.pendingResults == null) { 4089 activity.pendingResults 4090 = new HashSet<WeakReference<PendingIntentRecord>>(); 4091 } 4092 activity.pendingResults.add(rec.ref); 4093 } 4094 return rec; 4095 } 4096 4097 public void cancelIntentSender(IIntentSender sender) { 4098 if (!(sender instanceof PendingIntentRecord)) { 4099 return; 4100 } 4101 synchronized(this) { 4102 PendingIntentRecord rec = (PendingIntentRecord)sender; 4103 try { 4104 int uid = AppGlobals.getPackageManager() 4105 .getPackageUid(rec.key.packageName); 4106 if (uid != Binder.getCallingUid()) { 4107 String msg = "Permission Denial: cancelIntentSender() from pid=" 4108 + Binder.getCallingPid() 4109 + ", uid=" + Binder.getCallingUid() 4110 + " is not allowed to cancel packges " 4111 + rec.key.packageName; 4112 Slog.w(TAG, msg); 4113 throw new SecurityException(msg); 4114 } 4115 } catch (RemoteException e) { 4116 throw new SecurityException(e); 4117 } 4118 cancelIntentSenderLocked(rec, true); 4119 } 4120 } 4121 4122 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4123 rec.canceled = true; 4124 mIntentSenderRecords.remove(rec.key); 4125 if (cleanActivity && rec.key.activity != null) { 4126 rec.key.activity.pendingResults.remove(rec.ref); 4127 } 4128 } 4129 4130 public String getPackageForIntentSender(IIntentSender pendingResult) { 4131 if (!(pendingResult instanceof PendingIntentRecord)) { 4132 return null; 4133 } 4134 try { 4135 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4136 return res.key.packageName; 4137 } catch (ClassCastException e) { 4138 } 4139 return null; 4140 } 4141 4142 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4143 if (!(pendingResult instanceof PendingIntentRecord)) { 4144 return false; 4145 } 4146 try { 4147 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4148 if (res.key.allIntents == null) { 4149 return false; 4150 } 4151 for (int i=0; i<res.key.allIntents.length; i++) { 4152 Intent intent = res.key.allIntents[i]; 4153 if (intent.getPackage() != null && intent.getComponent() != null) { 4154 return false; 4155 } 4156 } 4157 return true; 4158 } catch (ClassCastException e) { 4159 } 4160 return false; 4161 } 4162 4163 public void setProcessLimit(int max) { 4164 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4165 "setProcessLimit()"); 4166 synchronized (this) { 4167 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4168 mProcessLimitOverride = max; 4169 } 4170 trimApplications(); 4171 } 4172 4173 public int getProcessLimit() { 4174 synchronized (this) { 4175 return mProcessLimitOverride; 4176 } 4177 } 4178 4179 void foregroundTokenDied(ForegroundToken token) { 4180 synchronized (ActivityManagerService.this) { 4181 synchronized (mPidsSelfLocked) { 4182 ForegroundToken cur 4183 = mForegroundProcesses.get(token.pid); 4184 if (cur != token) { 4185 return; 4186 } 4187 mForegroundProcesses.remove(token.pid); 4188 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4189 if (pr == null) { 4190 return; 4191 } 4192 pr.forcingToForeground = null; 4193 pr.foregroundServices = false; 4194 } 4195 updateOomAdjLocked(); 4196 } 4197 } 4198 4199 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4200 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4201 "setProcessForeground()"); 4202 synchronized(this) { 4203 boolean changed = false; 4204 4205 synchronized (mPidsSelfLocked) { 4206 ProcessRecord pr = mPidsSelfLocked.get(pid); 4207 if (pr == null) { 4208 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4209 return; 4210 } 4211 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4212 if (oldToken != null) { 4213 oldToken.token.unlinkToDeath(oldToken, 0); 4214 mForegroundProcesses.remove(pid); 4215 pr.forcingToForeground = null; 4216 changed = true; 4217 } 4218 if (isForeground && token != null) { 4219 ForegroundToken newToken = new ForegroundToken() { 4220 public void binderDied() { 4221 foregroundTokenDied(this); 4222 } 4223 }; 4224 newToken.pid = pid; 4225 newToken.token = token; 4226 try { 4227 token.linkToDeath(newToken, 0); 4228 mForegroundProcesses.put(pid, newToken); 4229 pr.forcingToForeground = token; 4230 changed = true; 4231 } catch (RemoteException e) { 4232 // If the process died while doing this, we will later 4233 // do the cleanup with the process death link. 4234 } 4235 } 4236 } 4237 4238 if (changed) { 4239 updateOomAdjLocked(); 4240 } 4241 } 4242 } 4243 4244 // ========================================================= 4245 // PERMISSIONS 4246 // ========================================================= 4247 4248 static class PermissionController extends IPermissionController.Stub { 4249 ActivityManagerService mActivityManagerService; 4250 PermissionController(ActivityManagerService activityManagerService) { 4251 mActivityManagerService = activityManagerService; 4252 } 4253 4254 public boolean checkPermission(String permission, int pid, int uid) { 4255 return mActivityManagerService.checkPermission(permission, pid, 4256 uid) == PackageManager.PERMISSION_GRANTED; 4257 } 4258 } 4259 4260 /** 4261 * This can be called with or without the global lock held. 4262 */ 4263 int checkComponentPermission(String permission, int pid, int uid, 4264 int owningUid, boolean exported) { 4265 // We might be performing an operation on behalf of an indirect binder 4266 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4267 // client identity accordingly before proceeding. 4268 Identity tlsIdentity = sCallerIdentity.get(); 4269 if (tlsIdentity != null) { 4270 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4271 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4272 uid = tlsIdentity.uid; 4273 pid = tlsIdentity.pid; 4274 } 4275 4276 // Root, system server and our own process get to do everything. 4277 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) { 4278 return PackageManager.PERMISSION_GRANTED; 4279 } 4280 // If there is a uid that owns whatever is being accessed, it has 4281 // blanket access to it regardless of the permissions it requires. 4282 if (owningUid >= 0 && uid == owningUid) { 4283 return PackageManager.PERMISSION_GRANTED; 4284 } 4285 // If the target is not exported, then nobody else can get to it. 4286 if (!exported) { 4287 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid); 4288 return PackageManager.PERMISSION_DENIED; 4289 } 4290 if (permission == null) { 4291 return PackageManager.PERMISSION_GRANTED; 4292 } 4293 try { 4294 return AppGlobals.getPackageManager() 4295 .checkUidPermission(permission, uid); 4296 } catch (RemoteException e) { 4297 // Should never happen, but if it does... deny! 4298 Slog.e(TAG, "PackageManager is dead?!?", e); 4299 } 4300 return PackageManager.PERMISSION_DENIED; 4301 } 4302 4303 /** 4304 * As the only public entry point for permissions checking, this method 4305 * can enforce the semantic that requesting a check on a null global 4306 * permission is automatically denied. (Internally a null permission 4307 * string is used when calling {@link #checkComponentPermission} in cases 4308 * when only uid-based security is needed.) 4309 * 4310 * This can be called with or without the global lock held. 4311 */ 4312 public int checkPermission(String permission, int pid, int uid) { 4313 if (permission == null) { 4314 return PackageManager.PERMISSION_DENIED; 4315 } 4316 return checkComponentPermission(permission, pid, uid, -1, true); 4317 } 4318 4319 /** 4320 * Binder IPC calls go through the public entry point. 4321 * This can be called with or without the global lock held. 4322 */ 4323 int checkCallingPermission(String permission) { 4324 return checkPermission(permission, 4325 Binder.getCallingPid(), 4326 Binder.getCallingUid()); 4327 } 4328 4329 /** 4330 * This can be called with or without the global lock held. 4331 */ 4332 void enforceCallingPermission(String permission, String func) { 4333 if (checkCallingPermission(permission) 4334 == PackageManager.PERMISSION_GRANTED) { 4335 return; 4336 } 4337 4338 String msg = "Permission Denial: " + func + " from pid=" 4339 + Binder.getCallingPid() 4340 + ", uid=" + Binder.getCallingUid() 4341 + " requires " + permission; 4342 Slog.w(TAG, msg); 4343 throw new SecurityException(msg); 4344 } 4345 4346 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 4347 ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4348 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4349 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4350 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4351 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4352 try { 4353 // Is the component private from the target uid? 4354 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid; 4355 4356 // Acceptable if the there is no read permission needed from the 4357 // target or the target is holding the read permission. 4358 if (!readPerm) { 4359 if ((!prv && pi.readPermission == null) || 4360 (pm.checkUidPermission(pi.readPermission, uid) 4361 == PackageManager.PERMISSION_GRANTED)) { 4362 readPerm = true; 4363 } 4364 } 4365 4366 // Acceptable if the there is no write permission needed from the 4367 // target or the target is holding the read permission. 4368 if (!writePerm) { 4369 if (!prv && (pi.writePermission == null) || 4370 (pm.checkUidPermission(pi.writePermission, uid) 4371 == PackageManager.PERMISSION_GRANTED)) { 4372 writePerm = true; 4373 } 4374 } 4375 4376 // Acceptable if there is a path permission matching the URI that 4377 // the target holds the permission on. 4378 PathPermission[] pps = pi.pathPermissions; 4379 if (pps != null && (!readPerm || !writePerm)) { 4380 final String path = uri.getPath(); 4381 int i = pps.length; 4382 while (i > 0 && (!readPerm || !writePerm)) { 4383 i--; 4384 PathPermission pp = pps[i]; 4385 if (!readPerm) { 4386 final String pprperm = pp.getReadPermission(); 4387 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4388 + pprperm + " for " + pp.getPath() 4389 + ": match=" + pp.match(path) 4390 + " check=" + pm.checkUidPermission(pprperm, uid)); 4391 if (pprperm != null && pp.match(path) && 4392 (pm.checkUidPermission(pprperm, uid) 4393 == PackageManager.PERMISSION_GRANTED)) { 4394 readPerm = true; 4395 } 4396 } 4397 if (!writePerm) { 4398 final String ppwperm = pp.getWritePermission(); 4399 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4400 + ppwperm + " for " + pp.getPath() 4401 + ": match=" + pp.match(path) 4402 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4403 if (ppwperm != null && pp.match(path) && 4404 (pm.checkUidPermission(ppwperm, uid) 4405 == PackageManager.PERMISSION_GRANTED)) { 4406 writePerm = true; 4407 } 4408 } 4409 } 4410 } 4411 } catch (RemoteException e) { 4412 return false; 4413 } 4414 4415 return readPerm && writePerm; 4416 } 4417 4418 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4419 int modeFlags) { 4420 // Root gets to do everything. 4421 if (uid == 0) { 4422 return true; 4423 } 4424 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4425 if (perms == null) return false; 4426 UriPermission perm = perms.get(uri); 4427 if (perm == null) return false; 4428 return (modeFlags&perm.modeFlags) == modeFlags; 4429 } 4430 4431 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4432 // Another redirected-binder-call permissions check as in 4433 // {@link checkComponentPermission}. 4434 Identity tlsIdentity = sCallerIdentity.get(); 4435 if (tlsIdentity != null) { 4436 uid = tlsIdentity.uid; 4437 pid = tlsIdentity.pid; 4438 } 4439 4440 // Our own process gets to do everything. 4441 if (pid == MY_PID) { 4442 return PackageManager.PERMISSION_GRANTED; 4443 } 4444 synchronized(this) { 4445 return checkUriPermissionLocked(uri, uid, modeFlags) 4446 ? PackageManager.PERMISSION_GRANTED 4447 : PackageManager.PERMISSION_DENIED; 4448 } 4449 } 4450 4451 /** 4452 * Check if the targetPkg can be granted permission to access uri by 4453 * the callingUid using the given modeFlags. Throws a security exception 4454 * if callingUid is not allowed to do this. Returns the uid of the target 4455 * if the URI permission grant should be performed; returns -1 if it is not 4456 * needed (for example targetPkg already has permission to access the URI). 4457 */ 4458 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4459 Uri uri, int modeFlags) { 4460 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4461 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4462 if (modeFlags == 0) { 4463 return -1; 4464 } 4465 4466 if (targetPkg != null) { 4467 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4468 "Checking grant " + targetPkg + " permission to " + uri); 4469 } 4470 4471 final IPackageManager pm = AppGlobals.getPackageManager(); 4472 4473 // If this is not a content: uri, we can't do anything with it. 4474 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4475 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4476 "Can't grant URI permission for non-content URI: " + uri); 4477 return -1; 4478 } 4479 4480 String name = uri.getAuthority(); 4481 ProviderInfo pi = null; 4482 ContentProviderRecord cpr = mProvidersByName.get(name); 4483 if (cpr != null) { 4484 pi = cpr.info; 4485 } else { 4486 try { 4487 pi = pm.resolveContentProvider(name, 4488 PackageManager.GET_URI_PERMISSION_PATTERNS); 4489 } catch (RemoteException ex) { 4490 } 4491 } 4492 if (pi == null) { 4493 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4494 return -1; 4495 } 4496 4497 int targetUid; 4498 if (targetPkg != null) { 4499 try { 4500 targetUid = pm.getPackageUid(targetPkg); 4501 if (targetUid < 0) { 4502 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4503 "Can't grant URI permission no uid for: " + targetPkg); 4504 return -1; 4505 } 4506 } catch (RemoteException ex) { 4507 return -1; 4508 } 4509 } else { 4510 targetUid = -1; 4511 } 4512 4513 if (targetUid >= 0) { 4514 // First... does the target actually need this permission? 4515 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4516 // No need to grant the target this permission. 4517 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4518 "Target " + targetPkg + " already has full permission to " + uri); 4519 return -1; 4520 } 4521 } else { 4522 // First... there is no target package, so can anyone access it? 4523 boolean allowed = pi.exported; 4524 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4525 if (pi.readPermission != null) { 4526 allowed = false; 4527 } 4528 } 4529 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4530 if (pi.writePermission != null) { 4531 allowed = false; 4532 } 4533 } 4534 if (allowed) { 4535 return -1; 4536 } 4537 } 4538 4539 // Second... is the provider allowing granting of URI permissions? 4540 if (!pi.grantUriPermissions) { 4541 throw new SecurityException("Provider " + pi.packageName 4542 + "/" + pi.name 4543 + " does not allow granting of Uri permissions (uri " 4544 + uri + ")"); 4545 } 4546 if (pi.uriPermissionPatterns != null) { 4547 final int N = pi.uriPermissionPatterns.length; 4548 boolean allowed = false; 4549 for (int i=0; i<N; i++) { 4550 if (pi.uriPermissionPatterns[i] != null 4551 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4552 allowed = true; 4553 break; 4554 } 4555 } 4556 if (!allowed) { 4557 throw new SecurityException("Provider " + pi.packageName 4558 + "/" + pi.name 4559 + " does not allow granting of permission to path of Uri " 4560 + uri); 4561 } 4562 } 4563 4564 // Third... does the caller itself have permission to access 4565 // this uri? 4566 if (callingUid != Process.myUid()) { 4567 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4568 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4569 throw new SecurityException("Uid " + callingUid 4570 + " does not have permission to uri " + uri); 4571 } 4572 } 4573 } 4574 4575 return targetUid; 4576 } 4577 4578 public int checkGrantUriPermission(int callingUid, String targetPkg, 4579 Uri uri, int modeFlags) { 4580 synchronized(this) { 4581 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); 4582 } 4583 } 4584 4585 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4586 Uri uri, int modeFlags, UriPermissionOwner owner) { 4587 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4588 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4589 if (modeFlags == 0) { 4590 return; 4591 } 4592 4593 // So here we are: the caller has the assumed permission 4594 // to the uri, and the target doesn't. Let's now give this to 4595 // the target. 4596 4597 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4598 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4599 4600 HashMap<Uri, UriPermission> targetUris 4601 = mGrantedUriPermissions.get(targetUid); 4602 if (targetUris == null) { 4603 targetUris = new HashMap<Uri, UriPermission>(); 4604 mGrantedUriPermissions.put(targetUid, targetUris); 4605 } 4606 4607 UriPermission perm = targetUris.get(uri); 4608 if (perm == null) { 4609 perm = new UriPermission(targetUid, uri); 4610 targetUris.put(uri, perm); 4611 } 4612 4613 perm.modeFlags |= modeFlags; 4614 if (owner == null) { 4615 perm.globalModeFlags |= modeFlags; 4616 } else { 4617 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4618 perm.readOwners.add(owner); 4619 owner.addReadPermission(perm); 4620 } 4621 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4622 perm.writeOwners.add(owner); 4623 owner.addWritePermission(perm); 4624 } 4625 } 4626 } 4627 4628 void grantUriPermissionLocked(int callingUid, 4629 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 4630 if (targetPkg == null) { 4631 throw new NullPointerException("targetPkg"); 4632 } 4633 4634 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); 4635 if (targetUid < 0) { 4636 return; 4637 } 4638 4639 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 4640 } 4641 4642 /** 4643 * Like checkGrantUriPermissionLocked, but takes an Intent. 4644 */ 4645 int checkGrantUriPermissionFromIntentLocked(int callingUid, 4646 String targetPkg, Intent intent) { 4647 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4648 "Checking URI perm to " + (intent != null ? intent.getData() : null) 4649 + " from " + intent + "; flags=0x" 4650 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 4651 4652 if (targetPkg == null) { 4653 throw new NullPointerException("targetPkg"); 4654 } 4655 4656 if (intent == null) { 4657 return -1; 4658 } 4659 Uri data = intent.getData(); 4660 if (data == null) { 4661 return -1; 4662 } 4663 return checkGrantUriPermissionLocked(callingUid, targetPkg, data, 4664 intent.getFlags()); 4665 } 4666 4667 /** 4668 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 4669 */ 4670 void grantUriPermissionUncheckedFromIntentLocked(int targetUid, 4671 String targetPkg, Intent intent, UriPermissionOwner owner) { 4672 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(), 4673 intent.getFlags(), owner); 4674 } 4675 4676 void grantUriPermissionFromIntentLocked(int callingUid, 4677 String targetPkg, Intent intent, UriPermissionOwner owner) { 4678 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent); 4679 if (targetUid < 0) { 4680 return; 4681 } 4682 4683 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner); 4684 } 4685 4686 public void grantUriPermission(IApplicationThread caller, String targetPkg, 4687 Uri uri, int modeFlags) { 4688 synchronized(this) { 4689 final ProcessRecord r = getRecordForAppLocked(caller); 4690 if (r == null) { 4691 throw new SecurityException("Unable to find app for caller " 4692 + caller 4693 + " when granting permission to uri " + uri); 4694 } 4695 if (targetPkg == null) { 4696 throw new IllegalArgumentException("null target"); 4697 } 4698 if (uri == null) { 4699 throw new IllegalArgumentException("null uri"); 4700 } 4701 4702 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 4703 null); 4704 } 4705 } 4706 4707 void removeUriPermissionIfNeededLocked(UriPermission perm) { 4708 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 4709 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 4710 HashMap<Uri, UriPermission> perms 4711 = mGrantedUriPermissions.get(perm.uid); 4712 if (perms != null) { 4713 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4714 "Removing " + perm.uid + " permission to " + perm.uri); 4715 perms.remove(perm.uri); 4716 if (perms.size() == 0) { 4717 mGrantedUriPermissions.remove(perm.uid); 4718 } 4719 } 4720 } 4721 } 4722 4723 private void revokeUriPermissionLocked(int callingUid, Uri uri, 4724 int modeFlags) { 4725 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4726 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4727 if (modeFlags == 0) { 4728 return; 4729 } 4730 4731 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4732 "Revoking all granted permissions to " + uri); 4733 4734 final IPackageManager pm = AppGlobals.getPackageManager(); 4735 4736 final String authority = uri.getAuthority(); 4737 ProviderInfo pi = null; 4738 ContentProviderRecord cpr = mProvidersByName.get(authority); 4739 if (cpr != null) { 4740 pi = cpr.info; 4741 } else { 4742 try { 4743 pi = pm.resolveContentProvider(authority, 4744 PackageManager.GET_URI_PERMISSION_PATTERNS); 4745 } catch (RemoteException ex) { 4746 } 4747 } 4748 if (pi == null) { 4749 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 4750 return; 4751 } 4752 4753 // Does the caller have this permission on the URI? 4754 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4755 // Right now, if you are not the original owner of the permission, 4756 // you are not allowed to revoke it. 4757 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4758 throw new SecurityException("Uid " + callingUid 4759 + " does not have permission to uri " + uri); 4760 //} 4761 } 4762 4763 // Go through all of the permissions and remove any that match. 4764 final List<String> SEGMENTS = uri.getPathSegments(); 4765 if (SEGMENTS != null) { 4766 final int NS = SEGMENTS.size(); 4767 int N = mGrantedUriPermissions.size(); 4768 for (int i=0; i<N; i++) { 4769 HashMap<Uri, UriPermission> perms 4770 = mGrantedUriPermissions.valueAt(i); 4771 Iterator<UriPermission> it = perms.values().iterator(); 4772 toploop: 4773 while (it.hasNext()) { 4774 UriPermission perm = it.next(); 4775 Uri targetUri = perm.uri; 4776 if (!authority.equals(targetUri.getAuthority())) { 4777 continue; 4778 } 4779 List<String> targetSegments = targetUri.getPathSegments(); 4780 if (targetSegments == null) { 4781 continue; 4782 } 4783 if (targetSegments.size() < NS) { 4784 continue; 4785 } 4786 for (int j=0; j<NS; j++) { 4787 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 4788 continue toploop; 4789 } 4790 } 4791 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4792 "Revoking " + perm.uid + " permission to " + perm.uri); 4793 perm.clearModes(modeFlags); 4794 if (perm.modeFlags == 0) { 4795 it.remove(); 4796 } 4797 } 4798 if (perms.size() == 0) { 4799 mGrantedUriPermissions.remove( 4800 mGrantedUriPermissions.keyAt(i)); 4801 N--; 4802 i--; 4803 } 4804 } 4805 } 4806 } 4807 4808 public void revokeUriPermission(IApplicationThread caller, Uri uri, 4809 int modeFlags) { 4810 synchronized(this) { 4811 final ProcessRecord r = getRecordForAppLocked(caller); 4812 if (r == null) { 4813 throw new SecurityException("Unable to find app for caller " 4814 + caller 4815 + " when revoking permission to uri " + uri); 4816 } 4817 if (uri == null) { 4818 Slog.w(TAG, "revokeUriPermission: null uri"); 4819 return; 4820 } 4821 4822 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4823 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4824 if (modeFlags == 0) { 4825 return; 4826 } 4827 4828 final IPackageManager pm = AppGlobals.getPackageManager(); 4829 4830 final String authority = uri.getAuthority(); 4831 ProviderInfo pi = null; 4832 ContentProviderRecord cpr = mProvidersByName.get(authority); 4833 if (cpr != null) { 4834 pi = cpr.info; 4835 } else { 4836 try { 4837 pi = pm.resolveContentProvider(authority, 4838 PackageManager.GET_URI_PERMISSION_PATTERNS); 4839 } catch (RemoteException ex) { 4840 } 4841 } 4842 if (pi == null) { 4843 Slog.w(TAG, "No content provider found for permission revoke: " 4844 + uri.toSafeString()); 4845 return; 4846 } 4847 4848 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 4849 } 4850 } 4851 4852 @Override 4853 public IBinder newUriPermissionOwner(String name) { 4854 synchronized(this) { 4855 UriPermissionOwner owner = new UriPermissionOwner(this, name); 4856 return owner.getExternalTokenLocked(); 4857 } 4858 } 4859 4860 @Override 4861 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 4862 Uri uri, int modeFlags) { 4863 synchronized(this) { 4864 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 4865 if (owner == null) { 4866 throw new IllegalArgumentException("Unknown owner: " + token); 4867 } 4868 if (fromUid != Binder.getCallingUid()) { 4869 if (Binder.getCallingUid() != Process.myUid()) { 4870 // Only system code can grant URI permissions on behalf 4871 // of other users. 4872 throw new SecurityException("nice try"); 4873 } 4874 } 4875 if (targetPkg == null) { 4876 throw new IllegalArgumentException("null target"); 4877 } 4878 if (uri == null) { 4879 throw new IllegalArgumentException("null uri"); 4880 } 4881 4882 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 4883 } 4884 } 4885 4886 @Override 4887 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 4888 synchronized(this) { 4889 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 4890 if (owner == null) { 4891 throw new IllegalArgumentException("Unknown owner: " + token); 4892 } 4893 4894 if (uri == null) { 4895 owner.removeUriPermissionsLocked(mode); 4896 } else { 4897 owner.removeUriPermissionLocked(uri, mode); 4898 } 4899 } 4900 } 4901 4902 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 4903 synchronized (this) { 4904 ProcessRecord app = 4905 who != null ? getRecordForAppLocked(who) : null; 4906 if (app == null) return; 4907 4908 Message msg = Message.obtain(); 4909 msg.what = WAIT_FOR_DEBUGGER_MSG; 4910 msg.obj = app; 4911 msg.arg1 = waiting ? 1 : 0; 4912 mHandler.sendMessage(msg); 4913 } 4914 } 4915 4916 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 4917 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 4918 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 4919 outInfo.availMem = Process.getFreeMemory(); 4920 outInfo.threshold = homeAppMem; 4921 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 4922 outInfo.hiddenAppThreshold = hiddenAppMem; 4923 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 4924 ProcessList.SECONDARY_SERVER_ADJ); 4925 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 4926 ProcessList.VISIBLE_APP_ADJ); 4927 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 4928 ProcessList.FOREGROUND_APP_ADJ); 4929 } 4930 4931 // ========================================================= 4932 // TASK MANAGEMENT 4933 // ========================================================= 4934 4935 public List getTasks(int maxNum, int flags, 4936 IThumbnailReceiver receiver) { 4937 ArrayList list = new ArrayList(); 4938 4939 PendingThumbnailsRecord pending = null; 4940 IApplicationThread topThumbnail = null; 4941 ActivityRecord topRecord = null; 4942 4943 synchronized(this) { 4944 if (localLOGV) Slog.v( 4945 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 4946 + ", receiver=" + receiver); 4947 4948 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 4949 != PackageManager.PERMISSION_GRANTED) { 4950 if (receiver != null) { 4951 // If the caller wants to wait for pending thumbnails, 4952 // it ain't gonna get them. 4953 try { 4954 receiver.finished(); 4955 } catch (RemoteException ex) { 4956 } 4957 } 4958 String msg = "Permission Denial: getTasks() from pid=" 4959 + Binder.getCallingPid() 4960 + ", uid=" + Binder.getCallingUid() 4961 + " requires " + android.Manifest.permission.GET_TASKS; 4962 Slog.w(TAG, msg); 4963 throw new SecurityException(msg); 4964 } 4965 4966 int pos = mMainStack.mHistory.size()-1; 4967 ActivityRecord next = 4968 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 4969 ActivityRecord top = null; 4970 TaskRecord curTask = null; 4971 int numActivities = 0; 4972 int numRunning = 0; 4973 while (pos >= 0 && maxNum > 0) { 4974 final ActivityRecord r = next; 4975 pos--; 4976 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 4977 4978 // Initialize state for next task if needed. 4979 if (top == null || 4980 (top.state == ActivityState.INITIALIZING 4981 && top.task == r.task)) { 4982 top = r; 4983 curTask = r.task; 4984 numActivities = numRunning = 0; 4985 } 4986 4987 // Add 'r' into the current task. 4988 numActivities++; 4989 if (r.app != null && r.app.thread != null) { 4990 numRunning++; 4991 } 4992 4993 if (localLOGV) Slog.v( 4994 TAG, r.intent.getComponent().flattenToShortString() 4995 + ": task=" + r.task); 4996 4997 // If the next one is a different task, generate a new 4998 // TaskInfo entry for what we have. 4999 if (next == null || next.task != curTask) { 5000 ActivityManager.RunningTaskInfo ci 5001 = new ActivityManager.RunningTaskInfo(); 5002 ci.id = curTask.taskId; 5003 ci.baseActivity = r.intent.getComponent(); 5004 ci.topActivity = top.intent.getComponent(); 5005 if (top.thumbHolder != null) { 5006 ci.description = top.thumbHolder.lastDescription; 5007 } 5008 ci.numActivities = numActivities; 5009 ci.numRunning = numRunning; 5010 //System.out.println( 5011 // "#" + maxNum + ": " + " descr=" + ci.description); 5012 if (ci.thumbnail == null && receiver != null) { 5013 if (localLOGV) Slog.v( 5014 TAG, "State=" + top.state + "Idle=" + top.idle 5015 + " app=" + top.app 5016 + " thr=" + (top.app != null ? top.app.thread : null)); 5017 if (top.state == ActivityState.RESUMED 5018 || top.state == ActivityState.PAUSING) { 5019 if (top.idle && top.app != null 5020 && top.app.thread != null) { 5021 topRecord = top; 5022 topThumbnail = top.app.thread; 5023 } else { 5024 top.thumbnailNeeded = true; 5025 } 5026 } 5027 if (pending == null) { 5028 pending = new PendingThumbnailsRecord(receiver); 5029 } 5030 pending.pendingRecords.add(top); 5031 } 5032 list.add(ci); 5033 maxNum--; 5034 top = null; 5035 } 5036 } 5037 5038 if (pending != null) { 5039 mPendingThumbnails.add(pending); 5040 } 5041 } 5042 5043 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5044 5045 if (topThumbnail != null) { 5046 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5047 try { 5048 topThumbnail.requestThumbnail(topRecord); 5049 } catch (Exception e) { 5050 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5051 sendPendingThumbnail(null, topRecord, null, null, true); 5052 } 5053 } 5054 5055 if (pending == null && receiver != null) { 5056 // In this case all thumbnails were available and the client 5057 // is being asked to be told when the remaining ones come in... 5058 // which is unusually, since the top-most currently running 5059 // activity should never have a canned thumbnail! Oh well. 5060 try { 5061 receiver.finished(); 5062 } catch (RemoteException ex) { 5063 } 5064 } 5065 5066 return list; 5067 } 5068 5069 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5070 int flags) { 5071 synchronized (this) { 5072 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5073 "getRecentTasks()"); 5074 5075 IPackageManager pm = AppGlobals.getPackageManager(); 5076 5077 final int N = mRecentTasks.size(); 5078 ArrayList<ActivityManager.RecentTaskInfo> res 5079 = new ArrayList<ActivityManager.RecentTaskInfo>( 5080 maxNum < N ? maxNum : N); 5081 for (int i=0; i<N && maxNum > 0; i++) { 5082 TaskRecord tr = mRecentTasks.get(i); 5083 // Return the entry if desired by the caller. We always return 5084 // the first entry, because callers always expect this to be the 5085 // forground app. We may filter others if the caller has 5086 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5087 // we should exclude the entry. 5088 if (i == 0 5089 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5090 || (tr.intent == null) 5091 || ((tr.intent.getFlags() 5092 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5093 ActivityManager.RecentTaskInfo rti 5094 = new ActivityManager.RecentTaskInfo(); 5095 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5096 rti.persistentId = tr.taskId; 5097 rti.baseIntent = new Intent( 5098 tr.intent != null ? tr.intent : tr.affinityIntent); 5099 rti.origActivity = tr.origActivity; 5100 rti.description = tr.lastDescription; 5101 5102 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5103 // Check whether this activity is currently available. 5104 try { 5105 if (rti.origActivity != null) { 5106 if (pm.getActivityInfo(rti.origActivity, 0) == null) { 5107 continue; 5108 } 5109 } else if (rti.baseIntent != null) { 5110 if (pm.queryIntentActivities(rti.baseIntent, 5111 null, 0) == null) { 5112 continue; 5113 } 5114 } 5115 } catch (RemoteException e) { 5116 // Will never happen. 5117 } 5118 } 5119 5120 res.add(rti); 5121 maxNum--; 5122 } 5123 } 5124 return res; 5125 } 5126 } 5127 5128 private TaskRecord taskForIdLocked(int id) { 5129 final int N = mRecentTasks.size(); 5130 for (int i=0; i<N; i++) { 5131 TaskRecord tr = mRecentTasks.get(i); 5132 if (tr.taskId == id) { 5133 return tr; 5134 } 5135 } 5136 return null; 5137 } 5138 5139 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5140 synchronized (this) { 5141 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5142 "getTaskThumbnails()"); 5143 TaskRecord tr = taskForIdLocked(id); 5144 if (tr != null) { 5145 return mMainStack.getTaskThumbnailsLocked(tr); 5146 } 5147 } 5148 return null; 5149 } 5150 5151 public boolean removeSubTask(int taskId, int subTaskIndex) { 5152 synchronized (this) { 5153 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5154 "removeSubTask()"); 5155 long ident = Binder.clearCallingIdentity(); 5156 try { 5157 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null; 5158 } finally { 5159 Binder.restoreCallingIdentity(ident); 5160 } 5161 } 5162 } 5163 5164 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) { 5165 TaskRecord tr = root.task; 5166 Intent baseIntent = new Intent( 5167 tr.intent != null ? tr.intent : tr.affinityIntent); 5168 ComponentName component = baseIntent.getComponent(); 5169 if (component == null) { 5170 Slog.w(TAG, "Now component for base intent of task: " + tr); 5171 return; 5172 } 5173 5174 // Find any running services associated with this app. 5175 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5176 for (ServiceRecord sr : mServices.values()) { 5177 if (sr.packageName.equals(component.getPackageName())) { 5178 services.add(sr); 5179 } 5180 } 5181 5182 // Take care of any running services associated with the app. 5183 for (int i=0; i<services.size(); i++) { 5184 ServiceRecord sr = services.get(i); 5185 if (sr.startRequested) { 5186 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { 5187 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); 5188 stopServiceLocked(sr); 5189 } else { 5190 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, 5191 sr.makeNextStartId(), baseIntent, -1)); 5192 if (sr.app != null && sr.app.thread != null) { 5193 sendServiceArgsLocked(sr, false); 5194 } 5195 } 5196 } 5197 } 5198 5199 if (killProcesses) { 5200 // Find any running processes associated with this app. 5201 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5202 SparseArray<ProcessRecord> appProcs 5203 = mProcessNames.getMap().get(component.getPackageName()); 5204 if (appProcs != null) { 5205 for (int i=0; i<appProcs.size(); i++) { 5206 procs.add(appProcs.valueAt(i)); 5207 } 5208 } 5209 5210 // Kill the running processes. 5211 for (int i=0; i<procs.size(); i++) { 5212 ProcessRecord pr = procs.get(i); 5213 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5214 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5215 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5216 pr.processName, pr.setAdj, "remove task"); 5217 Process.killProcessQuiet(pr.pid); 5218 } else { 5219 pr.waitingToKill = "remove task"; 5220 } 5221 } 5222 } 5223 } 5224 5225 public boolean removeTask(int taskId, int flags) { 5226 synchronized (this) { 5227 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5228 "removeTask()"); 5229 long ident = Binder.clearCallingIdentity(); 5230 try { 5231 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1); 5232 if (r != null) { 5233 mRecentTasks.remove(r.task); 5234 cleanUpRemovedTaskLocked(r, 5235 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0); 5236 return true; 5237 } else { 5238 TaskRecord tr = null; 5239 int i=0; 5240 while (i < mRecentTasks.size()) { 5241 TaskRecord t = mRecentTasks.get(i); 5242 if (t.taskId == taskId) { 5243 tr = t; 5244 break; 5245 } 5246 i++; 5247 } 5248 if (tr != null) { 5249 if (tr.numActivities <= 0) { 5250 // Caller is just removing a recent task that is 5251 // not actively running. That is easy! 5252 mRecentTasks.remove(i); 5253 } else { 5254 Slog.w(TAG, "removeTask: task " + taskId 5255 + " does not have activities to remove, " 5256 + " but numActivities=" + tr.numActivities 5257 + ": " + tr); 5258 } 5259 } 5260 } 5261 } finally { 5262 Binder.restoreCallingIdentity(ident); 5263 } 5264 } 5265 return false; 5266 } 5267 5268 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5269 int j; 5270 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5271 TaskRecord jt = startTask; 5272 5273 // First look backwards 5274 for (j=startIndex-1; j>=0; j--) { 5275 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5276 if (r.task != jt) { 5277 jt = r.task; 5278 if (affinity.equals(jt.affinity)) { 5279 return j; 5280 } 5281 } 5282 } 5283 5284 // Now look forwards 5285 final int N = mMainStack.mHistory.size(); 5286 jt = startTask; 5287 for (j=startIndex+1; j<N; j++) { 5288 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5289 if (r.task != jt) { 5290 if (affinity.equals(jt.affinity)) { 5291 return j; 5292 } 5293 jt = r.task; 5294 } 5295 } 5296 5297 // Might it be at the top? 5298 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5299 return N-1; 5300 } 5301 5302 return -1; 5303 } 5304 5305 /** 5306 * TODO: Add mController hook 5307 */ 5308 public void moveTaskToFront(int task, int flags) { 5309 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5310 "moveTaskToFront()"); 5311 5312 synchronized(this) { 5313 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5314 Binder.getCallingUid(), "Task to front")) { 5315 return; 5316 } 5317 final long origId = Binder.clearCallingIdentity(); 5318 try { 5319 TaskRecord tr = taskForIdLocked(task); 5320 if (tr != null) { 5321 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5322 mMainStack.mUserLeaving = true; 5323 } 5324 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5325 // Caller wants the home activity moved with it. To accomplish this, 5326 // we'll just move the home task to the top first. 5327 mMainStack.moveHomeToFrontLocked(); 5328 } 5329 mMainStack.moveTaskToFrontLocked(tr, null); 5330 return; 5331 } 5332 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5333 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5334 if (hr.task.taskId == task) { 5335 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5336 mMainStack.mUserLeaving = true; 5337 } 5338 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5339 // Caller wants the home activity moved with it. To accomplish this, 5340 // we'll just move the home task to the top first. 5341 mMainStack.moveHomeToFrontLocked(); 5342 } 5343 mMainStack.moveTaskToFrontLocked(hr.task, null); 5344 return; 5345 } 5346 } 5347 } finally { 5348 Binder.restoreCallingIdentity(origId); 5349 } 5350 } 5351 } 5352 5353 public void moveTaskToBack(int task) { 5354 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5355 "moveTaskToBack()"); 5356 5357 synchronized(this) { 5358 if (mMainStack.mResumedActivity != null 5359 && mMainStack.mResumedActivity.task.taskId == task) { 5360 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5361 Binder.getCallingUid(), "Task to back")) { 5362 return; 5363 } 5364 } 5365 final long origId = Binder.clearCallingIdentity(); 5366 mMainStack.moveTaskToBackLocked(task, null); 5367 Binder.restoreCallingIdentity(origId); 5368 } 5369 } 5370 5371 /** 5372 * Moves an activity, and all of the other activities within the same task, to the bottom 5373 * of the history stack. The activity's order within the task is unchanged. 5374 * 5375 * @param token A reference to the activity we wish to move 5376 * @param nonRoot If false then this only works if the activity is the root 5377 * of a task; if true it will work for any activity in a task. 5378 * @return Returns true if the move completed, false if not. 5379 */ 5380 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5381 synchronized(this) { 5382 final long origId = Binder.clearCallingIdentity(); 5383 int taskId = getTaskForActivityLocked(token, !nonRoot); 5384 if (taskId >= 0) { 5385 return mMainStack.moveTaskToBackLocked(taskId, null); 5386 } 5387 Binder.restoreCallingIdentity(origId); 5388 } 5389 return false; 5390 } 5391 5392 public void moveTaskBackwards(int task) { 5393 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5394 "moveTaskBackwards()"); 5395 5396 synchronized(this) { 5397 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5398 Binder.getCallingUid(), "Task backwards")) { 5399 return; 5400 } 5401 final long origId = Binder.clearCallingIdentity(); 5402 moveTaskBackwardsLocked(task); 5403 Binder.restoreCallingIdentity(origId); 5404 } 5405 } 5406 5407 private final void moveTaskBackwardsLocked(int task) { 5408 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5409 } 5410 5411 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5412 synchronized(this) { 5413 return getTaskForActivityLocked(token, onlyRoot); 5414 } 5415 } 5416 5417 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5418 final int N = mMainStack.mHistory.size(); 5419 TaskRecord lastTask = null; 5420 for (int i=0; i<N; i++) { 5421 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5422 if (r == token) { 5423 if (!onlyRoot || lastTask != r.task) { 5424 return r.task.taskId; 5425 } 5426 return -1; 5427 } 5428 lastTask = r.task; 5429 } 5430 5431 return -1; 5432 } 5433 5434 public void finishOtherInstances(IBinder token, ComponentName className) { 5435 synchronized(this) { 5436 final long origId = Binder.clearCallingIdentity(); 5437 5438 int N = mMainStack.mHistory.size(); 5439 TaskRecord lastTask = null; 5440 for (int i=0; i<N; i++) { 5441 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5442 if (r.realActivity.equals(className) 5443 && r != token && lastTask != r.task) { 5444 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 5445 null, "others")) { 5446 i--; 5447 N--; 5448 } 5449 } 5450 lastTask = r.task; 5451 } 5452 5453 Binder.restoreCallingIdentity(origId); 5454 } 5455 } 5456 5457 // ========================================================= 5458 // THUMBNAILS 5459 // ========================================================= 5460 5461 public void reportThumbnail(IBinder token, 5462 Bitmap thumbnail, CharSequence description) { 5463 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5464 final long origId = Binder.clearCallingIdentity(); 5465 sendPendingThumbnail(null, token, thumbnail, description, true); 5466 Binder.restoreCallingIdentity(origId); 5467 } 5468 5469 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5470 Bitmap thumbnail, CharSequence description, boolean always) { 5471 TaskRecord task = null; 5472 ArrayList receivers = null; 5473 5474 //System.out.println("Send pending thumbnail: " + r); 5475 5476 synchronized(this) { 5477 if (r == null) { 5478 r = mMainStack.isInStackLocked(token); 5479 if (r == null) { 5480 return; 5481 } 5482 } 5483 if (thumbnail == null && r.thumbHolder != null) { 5484 thumbnail = r.thumbHolder.lastThumbnail; 5485 description = r.thumbHolder.lastDescription; 5486 } 5487 if (thumbnail == null && !always) { 5488 // If there is no thumbnail, and this entry is not actually 5489 // going away, then abort for now and pick up the next 5490 // thumbnail we get. 5491 return; 5492 } 5493 task = r.task; 5494 5495 int N = mPendingThumbnails.size(); 5496 int i=0; 5497 while (i<N) { 5498 PendingThumbnailsRecord pr = 5499 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5500 //System.out.println("Looking in " + pr.pendingRecords); 5501 if (pr.pendingRecords.remove(r)) { 5502 if (receivers == null) { 5503 receivers = new ArrayList(); 5504 } 5505 receivers.add(pr); 5506 if (pr.pendingRecords.size() == 0) { 5507 pr.finished = true; 5508 mPendingThumbnails.remove(i); 5509 N--; 5510 continue; 5511 } 5512 } 5513 i++; 5514 } 5515 } 5516 5517 if (receivers != null) { 5518 final int N = receivers.size(); 5519 for (int i=0; i<N; i++) { 5520 try { 5521 PendingThumbnailsRecord pr = 5522 (PendingThumbnailsRecord)receivers.get(i); 5523 pr.receiver.newThumbnail( 5524 task != null ? task.taskId : -1, thumbnail, description); 5525 if (pr.finished) { 5526 pr.receiver.finished(); 5527 } 5528 } catch (Exception e) { 5529 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5530 } 5531 } 5532 } 5533 } 5534 5535 // ========================================================= 5536 // CONTENT PROVIDERS 5537 // ========================================================= 5538 5539 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5540 List<ProviderInfo> providers = null; 5541 try { 5542 providers = AppGlobals.getPackageManager(). 5543 queryContentProviders(app.processName, app.info.uid, 5544 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5545 } catch (RemoteException ex) { 5546 } 5547 if (providers != null) { 5548 final int N = providers.size(); 5549 for (int i=0; i<N; i++) { 5550 ProviderInfo cpi = 5551 (ProviderInfo)providers.get(i); 5552 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5553 ContentProviderRecord cpr = mProvidersByClass.get(comp); 5554 if (cpr == null) { 5555 cpr = new ContentProviderRecord(cpi, app.info, comp); 5556 mProvidersByClass.put(comp, cpr); 5557 } 5558 app.pubProviders.put(cpi.name, cpr); 5559 app.addPackage(cpi.applicationInfo.packageName); 5560 ensurePackageDexOpt(cpi.applicationInfo.packageName); 5561 } 5562 } 5563 return providers; 5564 } 5565 5566 private final String checkContentProviderPermissionLocked( 5567 ProviderInfo cpi, ProcessRecord r) { 5568 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 5569 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 5570 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 5571 cpi.applicationInfo.uid, cpi.exported) 5572 == PackageManager.PERMISSION_GRANTED) { 5573 return null; 5574 } 5575 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 5576 cpi.applicationInfo.uid, cpi.exported) 5577 == PackageManager.PERMISSION_GRANTED) { 5578 return null; 5579 } 5580 5581 PathPermission[] pps = cpi.pathPermissions; 5582 if (pps != null) { 5583 int i = pps.length; 5584 while (i > 0) { 5585 i--; 5586 PathPermission pp = pps[i]; 5587 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 5588 cpi.applicationInfo.uid, cpi.exported) 5589 == PackageManager.PERMISSION_GRANTED) { 5590 return null; 5591 } 5592 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 5593 cpi.applicationInfo.uid, cpi.exported) 5594 == PackageManager.PERMISSION_GRANTED) { 5595 return null; 5596 } 5597 } 5598 } 5599 5600 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 5601 if (perms != null) { 5602 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 5603 if (uri.getKey().getAuthority().equals(cpi.authority)) { 5604 return null; 5605 } 5606 } 5607 } 5608 5609 String msg; 5610 if (!cpi.exported) { 5611 msg = "Permission Denial: opening provider " + cpi.name 5612 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 5613 + ", uid=" + callingUid + ") that is not exported from uid " 5614 + cpi.applicationInfo.uid; 5615 } else { 5616 msg = "Permission Denial: opening provider " + cpi.name 5617 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 5618 + ", uid=" + callingUid + ") requires " 5619 + cpi.readPermission + " or " + cpi.writePermission; 5620 } 5621 Slog.w(TAG, msg); 5622 return msg; 5623 } 5624 5625 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) { 5626 if (r != null) { 5627 Integer cnt = r.conProviders.get(cpr); 5628 if (DEBUG_PROVIDER) Slog.v(TAG, 5629 "Adding provider requested by " 5630 + r.processName + " from process " 5631 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 5632 + " cnt=" + (cnt == null ? 1 : cnt)); 5633 if (cnt == null) { 5634 cpr.clients.add(r); 5635 r.conProviders.put(cpr, new Integer(1)); 5636 return true; 5637 } else { 5638 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 5639 } 5640 } else { 5641 cpr.externals++; 5642 } 5643 return false; 5644 } 5645 5646 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) { 5647 if (r != null) { 5648 Integer cnt = r.conProviders.get(cpr); 5649 if (DEBUG_PROVIDER) Slog.v(TAG, 5650 "Removing provider requested by " 5651 + r.processName + " from process " 5652 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 5653 + " cnt=" + cnt); 5654 if (cnt == null || cnt.intValue() <= 1) { 5655 cpr.clients.remove(r); 5656 r.conProviders.remove(cpr); 5657 return true; 5658 } else { 5659 r.conProviders.put(cpr, new Integer(cnt.intValue()-1)); 5660 } 5661 } else { 5662 cpr.externals++; 5663 } 5664 return false; 5665 } 5666 5667 private final ContentProviderHolder getContentProviderImpl( 5668 IApplicationThread caller, String name) { 5669 ContentProviderRecord cpr; 5670 ProviderInfo cpi = null; 5671 5672 synchronized(this) { 5673 ProcessRecord r = null; 5674 if (caller != null) { 5675 r = getRecordForAppLocked(caller); 5676 if (r == null) { 5677 throw new SecurityException( 5678 "Unable to find app for caller " + caller 5679 + " (pid=" + Binder.getCallingPid() 5680 + ") when getting content provider " + name); 5681 } 5682 } 5683 5684 // First check if this content provider has been published... 5685 cpr = mProvidersByName.get(name); 5686 boolean providerRunning = cpr != null; 5687 if (providerRunning) { 5688 cpi = cpr.info; 5689 String msg; 5690 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 5691 throw new SecurityException(msg); 5692 } 5693 5694 if (r != null && cpr.canRunHere(r)) { 5695 // This provider has been published or is in the process 5696 // of being published... but it is also allowed to run 5697 // in the caller's process, so don't make a connection 5698 // and just let the caller instantiate its own instance. 5699 if (cpr.provider != null) { 5700 // don't give caller the provider object, it needs 5701 // to make its own. 5702 cpr = new ContentProviderRecord(cpr); 5703 } 5704 return cpr; 5705 } 5706 5707 final long origId = Binder.clearCallingIdentity(); 5708 5709 // In this case the provider instance already exists, so we can 5710 // return it right away. 5711 final boolean countChanged = incProviderCount(r, cpr); 5712 if (countChanged) { 5713 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 5714 // If this is a perceptible app accessing the provider, 5715 // make sure to count it as being accessed and thus 5716 // back up on the LRU list. This is good because 5717 // content providers are often expensive to start. 5718 updateLruProcessLocked(cpr.proc, false, true); 5719 } 5720 } 5721 5722 if (cpr.proc != null) { 5723 if (false) { 5724 if (cpr.name.flattenToShortString().equals( 5725 "com.android.providers.calendar/.CalendarProvider2")) { 5726 Slog.v(TAG, "****************** KILLING " 5727 + cpr.name.flattenToShortString()); 5728 Process.killProcess(cpr.proc.pid); 5729 } 5730 } 5731 boolean success = updateOomAdjLocked(cpr.proc); 5732 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 5733 // NOTE: there is still a race here where a signal could be 5734 // pending on the process even though we managed to update its 5735 // adj level. Not sure what to do about this, but at least 5736 // the race is now smaller. 5737 if (!success) { 5738 // Uh oh... it looks like the provider's process 5739 // has been killed on us. We need to wait for a new 5740 // process to be started, and make sure its death 5741 // doesn't kill our process. 5742 Slog.i(TAG, 5743 "Existing provider " + cpr.name.flattenToShortString() 5744 + " is crashing; detaching " + r); 5745 boolean lastRef = decProviderCount(r, cpr); 5746 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 5747 if (!lastRef) { 5748 // This wasn't the last ref our process had on 5749 // the provider... we have now been killed, bail. 5750 return null; 5751 } 5752 providerRunning = false; 5753 } 5754 } 5755 5756 Binder.restoreCallingIdentity(origId); 5757 } 5758 5759 if (!providerRunning) { 5760 try { 5761 cpi = AppGlobals.getPackageManager(). 5762 resolveContentProvider(name, 5763 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5764 } catch (RemoteException ex) { 5765 } 5766 if (cpi == null) { 5767 return null; 5768 } 5769 5770 String msg; 5771 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 5772 throw new SecurityException(msg); 5773 } 5774 5775 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 5776 && !cpi.processName.equals("system")) { 5777 // If this content provider does not run in the system 5778 // process, and the system is not yet ready to run other 5779 // processes, then fail fast instead of hanging. 5780 throw new IllegalArgumentException( 5781 "Attempt to launch content provider before system ready"); 5782 } 5783 5784 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5785 cpr = mProvidersByClass.get(comp); 5786 final boolean firstClass = cpr == null; 5787 if (firstClass) { 5788 try { 5789 ApplicationInfo ai = 5790 AppGlobals.getPackageManager(). 5791 getApplicationInfo( 5792 cpi.applicationInfo.packageName, 5793 STOCK_PM_FLAGS); 5794 if (ai == null) { 5795 Slog.w(TAG, "No package info for content provider " 5796 + cpi.name); 5797 return null; 5798 } 5799 cpr = new ContentProviderRecord(cpi, ai, comp); 5800 } catch (RemoteException ex) { 5801 // pm is in same process, this will never happen. 5802 } 5803 } 5804 5805 if (r != null && cpr.canRunHere(r)) { 5806 // If this is a multiprocess provider, then just return its 5807 // info and allow the caller to instantiate it. Only do 5808 // this if the provider is the same user as the caller's 5809 // process, or can run as root (so can be in any process). 5810 return cpr; 5811 } 5812 5813 if (DEBUG_PROVIDER) { 5814 RuntimeException e = new RuntimeException("here"); 5815 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 5816 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 5817 } 5818 5819 // This is single process, and our app is now connecting to it. 5820 // See if we are already in the process of launching this 5821 // provider. 5822 final int N = mLaunchingProviders.size(); 5823 int i; 5824 for (i=0; i<N; i++) { 5825 if (mLaunchingProviders.get(i) == cpr) { 5826 break; 5827 } 5828 } 5829 5830 // If the provider is not already being launched, then get it 5831 // started. 5832 if (i >= N) { 5833 final long origId = Binder.clearCallingIdentity(); 5834 5835 try { 5836 // Content provider is now in use, its package can't be stopped. 5837 try { 5838 AppGlobals.getPackageManager().setPackageStoppedState( 5839 cpr.appInfo.packageName, false); 5840 } catch (RemoteException e) { 5841 } catch (IllegalArgumentException e) { 5842 Slog.w(TAG, "Failed trying to unstop package " 5843 + cpr.appInfo.packageName + ": " + e); 5844 } 5845 5846 ProcessRecord proc = startProcessLocked(cpi.processName, 5847 cpr.appInfo, false, 0, "content provider", 5848 new ComponentName(cpi.applicationInfo.packageName, 5849 cpi.name), false); 5850 if (proc == null) { 5851 Slog.w(TAG, "Unable to launch app " 5852 + cpi.applicationInfo.packageName + "/" 5853 + cpi.applicationInfo.uid + " for provider " 5854 + name + ": process is bad"); 5855 return null; 5856 } 5857 cpr.launchingApp = proc; 5858 mLaunchingProviders.add(cpr); 5859 } finally { 5860 Binder.restoreCallingIdentity(origId); 5861 } 5862 } 5863 5864 // Make sure the provider is published (the same provider class 5865 // may be published under multiple names). 5866 if (firstClass) { 5867 mProvidersByClass.put(comp, cpr); 5868 } 5869 mProvidersByName.put(name, cpr); 5870 incProviderCount(r, cpr); 5871 } 5872 } 5873 5874 // Wait for the provider to be published... 5875 synchronized (cpr) { 5876 while (cpr.provider == null) { 5877 if (cpr.launchingApp == null) { 5878 Slog.w(TAG, "Unable to launch app " 5879 + cpi.applicationInfo.packageName + "/" 5880 + cpi.applicationInfo.uid + " for provider " 5881 + name + ": launching app became null"); 5882 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 5883 cpi.applicationInfo.packageName, 5884 cpi.applicationInfo.uid, name); 5885 return null; 5886 } 5887 try { 5888 cpr.wait(); 5889 } catch (InterruptedException ex) { 5890 } 5891 } 5892 } 5893 return cpr; 5894 } 5895 5896 public final ContentProviderHolder getContentProvider( 5897 IApplicationThread caller, String name) { 5898 if (caller == null) { 5899 String msg = "null IApplicationThread when getting content provider " 5900 + name; 5901 Slog.w(TAG, msg); 5902 throw new SecurityException(msg); 5903 } 5904 5905 return getContentProviderImpl(caller, name); 5906 } 5907 5908 private ContentProviderHolder getContentProviderExternal(String name) { 5909 return getContentProviderImpl(null, name); 5910 } 5911 5912 /** 5913 * Drop a content provider from a ProcessRecord's bookkeeping 5914 * @param cpr 5915 */ 5916 public void removeContentProvider(IApplicationThread caller, String name) { 5917 synchronized (this) { 5918 ContentProviderRecord cpr = mProvidersByName.get(name); 5919 if(cpr == null) { 5920 // remove from mProvidersByClass 5921 if (DEBUG_PROVIDER) Slog.v(TAG, name + 5922 " provider not found in providers list"); 5923 return; 5924 } 5925 final ProcessRecord r = getRecordForAppLocked(caller); 5926 if (r == null) { 5927 throw new SecurityException( 5928 "Unable to find app for caller " + caller + 5929 " when removing content provider " + name); 5930 } 5931 //update content provider record entry info 5932 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 5933 ContentProviderRecord localCpr = mProvidersByClass.get(comp); 5934 if (localCpr.proc == r) { 5935 //should not happen. taken care of as a local provider 5936 Slog.w(TAG, "removeContentProvider called on local provider: " 5937 + cpr.info.name + " in process " + r.processName); 5938 return; 5939 } else { 5940 if (decProviderCount(r, localCpr)) { 5941 updateOomAdjLocked(); 5942 } 5943 } 5944 } 5945 } 5946 5947 private void removeContentProviderExternal(String name) { 5948 synchronized (this) { 5949 ContentProviderRecord cpr = mProvidersByName.get(name); 5950 if(cpr == null) { 5951 //remove from mProvidersByClass 5952 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 5953 return; 5954 } 5955 5956 //update content provider record entry info 5957 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 5958 ContentProviderRecord localCpr = mProvidersByClass.get(comp); 5959 localCpr.externals--; 5960 if (localCpr.externals < 0) { 5961 Slog.e(TAG, "Externals < 0 for content provider " + localCpr); 5962 } 5963 updateOomAdjLocked(); 5964 } 5965 } 5966 5967 public final void publishContentProviders(IApplicationThread caller, 5968 List<ContentProviderHolder> providers) { 5969 if (providers == null) { 5970 return; 5971 } 5972 5973 synchronized(this) { 5974 final ProcessRecord r = getRecordForAppLocked(caller); 5975 if (r == null) { 5976 throw new SecurityException( 5977 "Unable to find app for caller " + caller 5978 + " (pid=" + Binder.getCallingPid() 5979 + ") when publishing content providers"); 5980 } 5981 5982 final long origId = Binder.clearCallingIdentity(); 5983 5984 final int N = providers.size(); 5985 for (int i=0; i<N; i++) { 5986 ContentProviderHolder src = providers.get(i); 5987 if (src == null || src.info == null || src.provider == null) { 5988 continue; 5989 } 5990 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 5991 if (dst != null) { 5992 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 5993 mProvidersByClass.put(comp, dst); 5994 String names[] = dst.info.authority.split(";"); 5995 for (int j = 0; j < names.length; j++) { 5996 mProvidersByName.put(names[j], dst); 5997 } 5998 5999 int NL = mLaunchingProviders.size(); 6000 int j; 6001 for (j=0; j<NL; j++) { 6002 if (mLaunchingProviders.get(j) == dst) { 6003 mLaunchingProviders.remove(j); 6004 j--; 6005 NL--; 6006 } 6007 } 6008 synchronized (dst) { 6009 dst.provider = src.provider; 6010 dst.proc = r; 6011 dst.notifyAll(); 6012 } 6013 updateOomAdjLocked(r); 6014 } 6015 } 6016 6017 Binder.restoreCallingIdentity(origId); 6018 } 6019 } 6020 6021 public static final void installSystemProviders() { 6022 List<ProviderInfo> providers; 6023 synchronized (mSelf) { 6024 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6025 providers = mSelf.generateApplicationProvidersLocked(app); 6026 if (providers != null) { 6027 for (int i=providers.size()-1; i>=0; i--) { 6028 ProviderInfo pi = (ProviderInfo)providers.get(i); 6029 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6030 Slog.w(TAG, "Not installing system proc provider " + pi.name 6031 + ": not system .apk"); 6032 providers.remove(i); 6033 } 6034 } 6035 } 6036 } 6037 if (providers != null) { 6038 mSystemThread.installSystemProviders(providers); 6039 } 6040 6041 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6042 6043 mSelf.mUsageStatsService.monitorPackages(); 6044 } 6045 6046 /** 6047 * Allows app to retrieve the MIME type of a URI without having permission 6048 * to access its content provider. 6049 * 6050 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6051 * 6052 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6053 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6054 */ 6055 public String getProviderMimeType(Uri uri) { 6056 final String name = uri.getAuthority(); 6057 final long ident = Binder.clearCallingIdentity(); 6058 ContentProviderHolder holder = null; 6059 6060 try { 6061 holder = getContentProviderExternal(name); 6062 if (holder != null) { 6063 return holder.provider.getType(uri); 6064 } 6065 } catch (RemoteException e) { 6066 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6067 return null; 6068 } finally { 6069 if (holder != null) { 6070 removeContentProviderExternal(name); 6071 } 6072 Binder.restoreCallingIdentity(ident); 6073 } 6074 6075 return null; 6076 } 6077 6078 // ========================================================= 6079 // GLOBAL MANAGEMENT 6080 // ========================================================= 6081 6082 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6083 ApplicationInfo info, String customProcess) { 6084 String proc = customProcess != null ? customProcess : info.processName; 6085 BatteryStatsImpl.Uid.Proc ps = null; 6086 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6087 synchronized (stats) { 6088 ps = stats.getProcessStatsLocked(info.uid, proc); 6089 } 6090 return new ProcessRecord(ps, thread, info, proc); 6091 } 6092 6093 final ProcessRecord addAppLocked(ApplicationInfo info) { 6094 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 6095 6096 if (app == null) { 6097 app = newProcessRecordLocked(null, info, null); 6098 mProcessNames.put(info.processName, info.uid, app); 6099 updateLruProcessLocked(app, true, true); 6100 } 6101 6102 // This package really, really can not be stopped. 6103 try { 6104 AppGlobals.getPackageManager().setPackageStoppedState( 6105 info.packageName, false); 6106 } catch (RemoteException e) { 6107 } catch (IllegalArgumentException e) { 6108 Slog.w(TAG, "Failed trying to unstop package " 6109 + info.packageName + ": " + e); 6110 } 6111 6112 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6113 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6114 app.persistent = true; 6115 app.maxAdj = ProcessList.CORE_SERVER_ADJ; 6116 } 6117 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6118 mPersistentStartingProcesses.add(app); 6119 startProcessLocked(app, "added application", app.processName); 6120 } 6121 6122 return app; 6123 } 6124 6125 public void unhandledBack() { 6126 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6127 "unhandledBack()"); 6128 6129 synchronized(this) { 6130 int count = mMainStack.mHistory.size(); 6131 if (DEBUG_SWITCH) Slog.d( 6132 TAG, "Performing unhandledBack(): stack size = " + count); 6133 if (count > 1) { 6134 final long origId = Binder.clearCallingIdentity(); 6135 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6136 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6137 Binder.restoreCallingIdentity(origId); 6138 } 6139 } 6140 } 6141 6142 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6143 String name = uri.getAuthority(); 6144 ContentProviderHolder cph = getContentProviderExternal(name); 6145 ParcelFileDescriptor pfd = null; 6146 if (cph != null) { 6147 // We record the binder invoker's uid in thread-local storage before 6148 // going to the content provider to open the file. Later, in the code 6149 // that handles all permissions checks, we look for this uid and use 6150 // that rather than the Activity Manager's own uid. The effect is that 6151 // we do the check against the caller's permissions even though it looks 6152 // to the content provider like the Activity Manager itself is making 6153 // the request. 6154 sCallerIdentity.set(new Identity( 6155 Binder.getCallingPid(), Binder.getCallingUid())); 6156 try { 6157 pfd = cph.provider.openFile(uri, "r"); 6158 } catch (FileNotFoundException e) { 6159 // do nothing; pfd will be returned null 6160 } finally { 6161 // Ensure that whatever happens, we clean up the identity state 6162 sCallerIdentity.remove(); 6163 } 6164 6165 // We've got the fd now, so we're done with the provider. 6166 removeContentProviderExternal(name); 6167 } else { 6168 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6169 } 6170 return pfd; 6171 } 6172 6173 // Actually is sleeping or shutting down or whatever else in the future 6174 // is an inactive state. 6175 public boolean isSleeping() { 6176 return mSleeping || mShuttingDown; 6177 } 6178 6179 public void goingToSleep() { 6180 synchronized(this) { 6181 mSleeping = true; 6182 mWindowManager.setEventDispatching(false); 6183 6184 mMainStack.stopIfSleepingLocked(); 6185 6186 // Initialize the wake times of all processes. 6187 checkExcessivePowerUsageLocked(false); 6188 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6189 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6190 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6191 } 6192 } 6193 6194 public boolean shutdown(int timeout) { 6195 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6196 != PackageManager.PERMISSION_GRANTED) { 6197 throw new SecurityException("Requires permission " 6198 + android.Manifest.permission.SHUTDOWN); 6199 } 6200 6201 boolean timedout = false; 6202 6203 synchronized(this) { 6204 mShuttingDown = true; 6205 mWindowManager.setEventDispatching(false); 6206 6207 if (mMainStack.mResumedActivity != null) { 6208 mMainStack.stopIfSleepingLocked(); 6209 final long endTime = System.currentTimeMillis() + timeout; 6210 while (mMainStack.mResumedActivity != null 6211 || mMainStack.mPausingActivity != null) { 6212 long delay = endTime - System.currentTimeMillis(); 6213 if (delay <= 0) { 6214 Slog.w(TAG, "Activity manager shutdown timed out"); 6215 timedout = true; 6216 break; 6217 } 6218 try { 6219 this.wait(); 6220 } catch (InterruptedException e) { 6221 } 6222 } 6223 } 6224 } 6225 6226 mUsageStatsService.shutdown(); 6227 mBatteryStatsService.shutdown(); 6228 6229 return timedout; 6230 } 6231 6232 public final void activitySlept(IBinder token) { 6233 if (localLOGV) Slog.v( 6234 TAG, "Activity slept: token=" + token); 6235 6236 ActivityRecord r = null; 6237 6238 final long origId = Binder.clearCallingIdentity(); 6239 6240 synchronized (this) { 6241 r = mMainStack.isInStackLocked(token); 6242 if (r != null) { 6243 mMainStack.activitySleptLocked(r); 6244 } 6245 } 6246 6247 Binder.restoreCallingIdentity(origId); 6248 } 6249 6250 public void wakingUp() { 6251 synchronized(this) { 6252 mWindowManager.setEventDispatching(true); 6253 mSleeping = false; 6254 mMainStack.awakeFromSleepingLocked(); 6255 mMainStack.resumeTopActivityLocked(null); 6256 } 6257 } 6258 6259 public void stopAppSwitches() { 6260 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6261 != PackageManager.PERMISSION_GRANTED) { 6262 throw new SecurityException("Requires permission " 6263 + android.Manifest.permission.STOP_APP_SWITCHES); 6264 } 6265 6266 synchronized(this) { 6267 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6268 + APP_SWITCH_DELAY_TIME; 6269 mDidAppSwitch = false; 6270 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6271 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6272 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6273 } 6274 } 6275 6276 public void resumeAppSwitches() { 6277 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6278 != PackageManager.PERMISSION_GRANTED) { 6279 throw new SecurityException("Requires permission " 6280 + android.Manifest.permission.STOP_APP_SWITCHES); 6281 } 6282 6283 synchronized(this) { 6284 // Note that we don't execute any pending app switches... we will 6285 // let those wait until either the timeout, or the next start 6286 // activity request. 6287 mAppSwitchesAllowedTime = 0; 6288 } 6289 } 6290 6291 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6292 String name) { 6293 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6294 return true; 6295 } 6296 6297 final int perm = checkComponentPermission( 6298 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6299 callingUid, -1, true); 6300 if (perm == PackageManager.PERMISSION_GRANTED) { 6301 return true; 6302 } 6303 6304 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6305 return false; 6306 } 6307 6308 public void setDebugApp(String packageName, boolean waitForDebugger, 6309 boolean persistent) { 6310 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 6311 "setDebugApp()"); 6312 6313 // Note that this is not really thread safe if there are multiple 6314 // callers into it at the same time, but that's not a situation we 6315 // care about. 6316 if (persistent) { 6317 final ContentResolver resolver = mContext.getContentResolver(); 6318 Settings.System.putString( 6319 resolver, Settings.System.DEBUG_APP, 6320 packageName); 6321 Settings.System.putInt( 6322 resolver, Settings.System.WAIT_FOR_DEBUGGER, 6323 waitForDebugger ? 1 : 0); 6324 } 6325 6326 synchronized (this) { 6327 if (!persistent) { 6328 mOrigDebugApp = mDebugApp; 6329 mOrigWaitForDebugger = mWaitForDebugger; 6330 } 6331 mDebugApp = packageName; 6332 mWaitForDebugger = waitForDebugger; 6333 mDebugTransient = !persistent; 6334 if (packageName != null) { 6335 final long origId = Binder.clearCallingIdentity(); 6336 forceStopPackageLocked(packageName, -1, false, false, true, true); 6337 Binder.restoreCallingIdentity(origId); 6338 } 6339 } 6340 } 6341 6342 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 6343 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 6344 synchronized (this) { 6345 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6346 if (!isDebuggable) { 6347 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 6348 throw new SecurityException("Process not debuggable: " + app.packageName); 6349 } 6350 } 6351 mProfileApp = processName; 6352 mProfileFile = profileFile; 6353 if (mProfileFd != null) { 6354 try { 6355 mProfileFd.close(); 6356 } catch (IOException e) { 6357 } 6358 mProfileFd = null; 6359 } 6360 mProfileFd = profileFd; 6361 mProfileType = 0; 6362 mAutoStopProfiler = autoStopProfiler; 6363 } 6364 } 6365 6366 public void setAlwaysFinish(boolean enabled) { 6367 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 6368 "setAlwaysFinish()"); 6369 6370 Settings.System.putInt( 6371 mContext.getContentResolver(), 6372 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 6373 6374 synchronized (this) { 6375 mAlwaysFinishActivities = enabled; 6376 } 6377 } 6378 6379 public void setActivityController(IActivityController controller) { 6380 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 6381 "setActivityController()"); 6382 synchronized (this) { 6383 mController = controller; 6384 } 6385 } 6386 6387 public boolean isUserAMonkey() { 6388 // For now the fact that there is a controller implies 6389 // we have a monkey. 6390 synchronized (this) { 6391 return mController != null; 6392 } 6393 } 6394 6395 public void registerActivityWatcher(IActivityWatcher watcher) { 6396 synchronized (this) { 6397 mWatchers.register(watcher); 6398 } 6399 } 6400 6401 public void unregisterActivityWatcher(IActivityWatcher watcher) { 6402 synchronized (this) { 6403 mWatchers.unregister(watcher); 6404 } 6405 } 6406 6407 public void registerProcessObserver(IProcessObserver observer) { 6408 mProcessObservers.register(observer); 6409 } 6410 6411 public void unregisterProcessObserver(IProcessObserver observer) { 6412 mProcessObservers.unregister(observer); 6413 } 6414 6415 public void setImmersive(IBinder token, boolean immersive) { 6416 synchronized(this) { 6417 ActivityRecord r = mMainStack.isInStackLocked(token); 6418 if (r == null) { 6419 throw new IllegalArgumentException(); 6420 } 6421 r.immersive = immersive; 6422 } 6423 } 6424 6425 public boolean isImmersive(IBinder token) { 6426 synchronized (this) { 6427 ActivityRecord r = mMainStack.isInStackLocked(token); 6428 if (r == null) { 6429 throw new IllegalArgumentException(); 6430 } 6431 return r.immersive; 6432 } 6433 } 6434 6435 public boolean isTopActivityImmersive() { 6436 synchronized (this) { 6437 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 6438 return (r != null) ? r.immersive : false; 6439 } 6440 } 6441 6442 public final void enterSafeMode() { 6443 synchronized(this) { 6444 // It only makes sense to do this before the system is ready 6445 // and started launching other packages. 6446 if (!mSystemReady) { 6447 try { 6448 AppGlobals.getPackageManager().enterSafeMode(); 6449 } catch (RemoteException e) { 6450 } 6451 } 6452 } 6453 } 6454 6455 public final void showSafeModeOverlay() { 6456 View v = LayoutInflater.from(mContext).inflate( 6457 com.android.internal.R.layout.safe_mode, null); 6458 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 6459 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 6460 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 6461 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 6462 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 6463 lp.format = v.getBackground().getOpacity(); 6464 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 6465 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 6466 ((WindowManager)mContext.getSystemService( 6467 Context.WINDOW_SERVICE)).addView(v, lp); 6468 } 6469 6470 public void noteWakeupAlarm(IIntentSender sender) { 6471 if (!(sender instanceof PendingIntentRecord)) { 6472 return; 6473 } 6474 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6475 synchronized (stats) { 6476 if (mBatteryStatsService.isOnBattery()) { 6477 mBatteryStatsService.enforceCallingPermission(); 6478 PendingIntentRecord rec = (PendingIntentRecord)sender; 6479 int MY_UID = Binder.getCallingUid(); 6480 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 6481 BatteryStatsImpl.Uid.Pkg pkg = 6482 stats.getPackageStatsLocked(uid, rec.key.packageName); 6483 pkg.incWakeupsLocked(); 6484 } 6485 } 6486 } 6487 6488 public boolean killPids(int[] pids, String pReason, boolean secure) { 6489 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6490 throw new SecurityException("killPids only available to the system"); 6491 } 6492 String reason = (pReason == null) ? "Unknown" : pReason; 6493 // XXX Note: don't acquire main activity lock here, because the window 6494 // manager calls in with its locks held. 6495 6496 boolean killed = false; 6497 synchronized (mPidsSelfLocked) { 6498 int[] types = new int[pids.length]; 6499 int worstType = 0; 6500 for (int i=0; i<pids.length; i++) { 6501 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 6502 if (proc != null) { 6503 int type = proc.setAdj; 6504 types[i] = type; 6505 if (type > worstType) { 6506 worstType = type; 6507 } 6508 } 6509 } 6510 6511 // If the worst oom_adj is somewhere in the hidden proc LRU range, 6512 // then constrain it so we will kill all hidden procs. 6513 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 6514 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 6515 } 6516 6517 // If this is not a secure call, don't let it kill processes that 6518 // are important. 6519 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) { 6520 worstType = ProcessList.SECONDARY_SERVER_ADJ; 6521 } 6522 6523 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 6524 for (int i=0; i<pids.length; i++) { 6525 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 6526 if (proc == null) { 6527 continue; 6528 } 6529 int adj = proc.setAdj; 6530 if (adj >= worstType && !proc.killedBackground) { 6531 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 6532 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 6533 proc.processName, adj, reason); 6534 killed = true; 6535 proc.killedBackground = true; 6536 Process.killProcessQuiet(pids[i]); 6537 } 6538 } 6539 } 6540 return killed; 6541 } 6542 6543 public final void startRunning(String pkg, String cls, String action, 6544 String data) { 6545 synchronized(this) { 6546 if (mStartRunning) { 6547 return; 6548 } 6549 mStartRunning = true; 6550 mTopComponent = pkg != null && cls != null 6551 ? new ComponentName(pkg, cls) : null; 6552 mTopAction = action != null ? action : Intent.ACTION_MAIN; 6553 mTopData = data; 6554 if (!mSystemReady) { 6555 return; 6556 } 6557 } 6558 6559 systemReady(null); 6560 } 6561 6562 private void retrieveSettings() { 6563 final ContentResolver resolver = mContext.getContentResolver(); 6564 String debugApp = Settings.System.getString( 6565 resolver, Settings.System.DEBUG_APP); 6566 boolean waitForDebugger = Settings.System.getInt( 6567 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 6568 boolean alwaysFinishActivities = Settings.System.getInt( 6569 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 6570 6571 Configuration configuration = new Configuration(); 6572 Settings.System.getConfiguration(resolver, configuration); 6573 6574 synchronized (this) { 6575 mDebugApp = mOrigDebugApp = debugApp; 6576 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 6577 mAlwaysFinishActivities = alwaysFinishActivities; 6578 // This happens before any activities are started, so we can 6579 // change mConfiguration in-place. 6580 mConfiguration.updateFrom(configuration); 6581 mConfigurationSeq = mConfiguration.seq = 1; 6582 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 6583 } 6584 } 6585 6586 public boolean testIsSystemReady() { 6587 // no need to synchronize(this) just to read & return the value 6588 return mSystemReady; 6589 } 6590 6591 private static File getCalledPreBootReceiversFile() { 6592 File dataDir = Environment.getDataDirectory(); 6593 File systemDir = new File(dataDir, "system"); 6594 File fname = new File(systemDir, "called_pre_boots.dat"); 6595 return fname; 6596 } 6597 6598 static final int LAST_DONE_VERSION = 10000; 6599 6600 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 6601 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 6602 File file = getCalledPreBootReceiversFile(); 6603 FileInputStream fis = null; 6604 try { 6605 fis = new FileInputStream(file); 6606 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 6607 int fvers = dis.readInt(); 6608 if (fvers == LAST_DONE_VERSION) { 6609 String vers = dis.readUTF(); 6610 String codename = dis.readUTF(); 6611 String build = dis.readUTF(); 6612 if (android.os.Build.VERSION.RELEASE.equals(vers) 6613 && android.os.Build.VERSION.CODENAME.equals(codename) 6614 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 6615 int num = dis.readInt(); 6616 while (num > 0) { 6617 num--; 6618 String pkg = dis.readUTF(); 6619 String cls = dis.readUTF(); 6620 lastDoneReceivers.add(new ComponentName(pkg, cls)); 6621 } 6622 } 6623 } 6624 } catch (FileNotFoundException e) { 6625 } catch (IOException e) { 6626 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 6627 } finally { 6628 if (fis != null) { 6629 try { 6630 fis.close(); 6631 } catch (IOException e) { 6632 } 6633 } 6634 } 6635 return lastDoneReceivers; 6636 } 6637 6638 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 6639 File file = getCalledPreBootReceiversFile(); 6640 FileOutputStream fos = null; 6641 DataOutputStream dos = null; 6642 try { 6643 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 6644 fos = new FileOutputStream(file); 6645 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 6646 dos.writeInt(LAST_DONE_VERSION); 6647 dos.writeUTF(android.os.Build.VERSION.RELEASE); 6648 dos.writeUTF(android.os.Build.VERSION.CODENAME); 6649 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 6650 dos.writeInt(list.size()); 6651 for (int i=0; i<list.size(); i++) { 6652 dos.writeUTF(list.get(i).getPackageName()); 6653 dos.writeUTF(list.get(i).getClassName()); 6654 } 6655 } catch (IOException e) { 6656 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 6657 file.delete(); 6658 } finally { 6659 FileUtils.sync(fos); 6660 if (dos != null) { 6661 try { 6662 dos.close(); 6663 } catch (IOException e) { 6664 // TODO Auto-generated catch block 6665 e.printStackTrace(); 6666 } 6667 } 6668 } 6669 } 6670 6671 public void systemReady(final Runnable goingCallback) { 6672 synchronized(this) { 6673 if (mSystemReady) { 6674 if (goingCallback != null) goingCallback.run(); 6675 return; 6676 } 6677 6678 // Check to see if there are any update receivers to run. 6679 if (!mDidUpdate) { 6680 if (mWaitingUpdate) { 6681 return; 6682 } 6683 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 6684 List<ResolveInfo> ris = null; 6685 try { 6686 ris = AppGlobals.getPackageManager().queryIntentReceivers( 6687 intent, null, 0); 6688 } catch (RemoteException e) { 6689 } 6690 if (ris != null) { 6691 for (int i=ris.size()-1; i>=0; i--) { 6692 if ((ris.get(i).activityInfo.applicationInfo.flags 6693 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6694 ris.remove(i); 6695 } 6696 } 6697 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 6698 6699 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 6700 6701 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 6702 for (int i=0; i<ris.size(); i++) { 6703 ActivityInfo ai = ris.get(i).activityInfo; 6704 ComponentName comp = new ComponentName(ai.packageName, ai.name); 6705 if (lastDoneReceivers.contains(comp)) { 6706 ris.remove(i); 6707 i--; 6708 } 6709 } 6710 6711 for (int i=0; i<ris.size(); i++) { 6712 ActivityInfo ai = ris.get(i).activityInfo; 6713 ComponentName comp = new ComponentName(ai.packageName, ai.name); 6714 doneReceivers.add(comp); 6715 intent.setComponent(comp); 6716 IIntentReceiver finisher = null; 6717 if (i == ris.size()-1) { 6718 finisher = new IIntentReceiver.Stub() { 6719 public void performReceive(Intent intent, int resultCode, 6720 String data, Bundle extras, boolean ordered, 6721 boolean sticky) { 6722 // The raw IIntentReceiver interface is called 6723 // with the AM lock held, so redispatch to 6724 // execute our code without the lock. 6725 mHandler.post(new Runnable() { 6726 public void run() { 6727 synchronized (ActivityManagerService.this) { 6728 mDidUpdate = true; 6729 } 6730 writeLastDonePreBootReceivers(doneReceivers); 6731 showBootMessage(mContext.getText( 6732 R.string.android_upgrading_complete), 6733 false); 6734 systemReady(goingCallback); 6735 } 6736 }); 6737 } 6738 }; 6739 } 6740 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 6741 broadcastIntentLocked(null, null, intent, null, finisher, 6742 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 6743 if (finisher != null) { 6744 mWaitingUpdate = true; 6745 } 6746 } 6747 } 6748 if (mWaitingUpdate) { 6749 return; 6750 } 6751 mDidUpdate = true; 6752 } 6753 6754 mSystemReady = true; 6755 if (!mStartRunning) { 6756 return; 6757 } 6758 } 6759 6760 ArrayList<ProcessRecord> procsToKill = null; 6761 synchronized(mPidsSelfLocked) { 6762 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 6763 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 6764 if (!isAllowedWhileBooting(proc.info)){ 6765 if (procsToKill == null) { 6766 procsToKill = new ArrayList<ProcessRecord>(); 6767 } 6768 procsToKill.add(proc); 6769 } 6770 } 6771 } 6772 6773 synchronized(this) { 6774 if (procsToKill != null) { 6775 for (int i=procsToKill.size()-1; i>=0; i--) { 6776 ProcessRecord proc = procsToKill.get(i); 6777 Slog.i(TAG, "Removing system update proc: " + proc); 6778 removeProcessLocked(proc, true, false); 6779 } 6780 } 6781 6782 // Now that we have cleaned up any update processes, we 6783 // are ready to start launching real processes and know that 6784 // we won't trample on them any more. 6785 mProcessesReady = true; 6786 } 6787 6788 Slog.i(TAG, "System now ready"); 6789 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 6790 SystemClock.uptimeMillis()); 6791 6792 synchronized(this) { 6793 // Make sure we have no pre-ready processes sitting around. 6794 6795 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 6796 ResolveInfo ri = mContext.getPackageManager() 6797 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 6798 STOCK_PM_FLAGS); 6799 CharSequence errorMsg = null; 6800 if (ri != null) { 6801 ActivityInfo ai = ri.activityInfo; 6802 ApplicationInfo app = ai.applicationInfo; 6803 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6804 mTopAction = Intent.ACTION_FACTORY_TEST; 6805 mTopData = null; 6806 mTopComponent = new ComponentName(app.packageName, 6807 ai.name); 6808 } else { 6809 errorMsg = mContext.getResources().getText( 6810 com.android.internal.R.string.factorytest_not_system); 6811 } 6812 } else { 6813 errorMsg = mContext.getResources().getText( 6814 com.android.internal.R.string.factorytest_no_action); 6815 } 6816 if (errorMsg != null) { 6817 mTopAction = null; 6818 mTopData = null; 6819 mTopComponent = null; 6820 Message msg = Message.obtain(); 6821 msg.what = SHOW_FACTORY_ERROR_MSG; 6822 msg.getData().putCharSequence("msg", errorMsg); 6823 mHandler.sendMessage(msg); 6824 } 6825 } 6826 } 6827 6828 retrieveSettings(); 6829 6830 if (goingCallback != null) goingCallback.run(); 6831 6832 synchronized (this) { 6833 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 6834 try { 6835 List apps = AppGlobals.getPackageManager(). 6836 getPersistentApplications(STOCK_PM_FLAGS); 6837 if (apps != null) { 6838 int N = apps.size(); 6839 int i; 6840 for (i=0; i<N; i++) { 6841 ApplicationInfo info 6842 = (ApplicationInfo)apps.get(i); 6843 if (info != null && 6844 !info.packageName.equals("android")) { 6845 addAppLocked(info); 6846 } 6847 } 6848 } 6849 } catch (RemoteException ex) { 6850 // pm is in same process, this will never happen. 6851 } 6852 } 6853 6854 // Start up initial activity. 6855 mBooting = true; 6856 6857 try { 6858 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 6859 Message msg = Message.obtain(); 6860 msg.what = SHOW_UID_ERROR_MSG; 6861 mHandler.sendMessage(msg); 6862 } 6863 } catch (RemoteException e) { 6864 } 6865 6866 mMainStack.resumeTopActivityLocked(null); 6867 } 6868 } 6869 6870 private boolean makeAppCrashingLocked(ProcessRecord app, 6871 String shortMsg, String longMsg, String stackTrace) { 6872 app.crashing = true; 6873 app.crashingReport = generateProcessError(app, 6874 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 6875 startAppProblemLocked(app); 6876 app.stopFreezingAllLocked(); 6877 return handleAppCrashLocked(app); 6878 } 6879 6880 private void makeAppNotRespondingLocked(ProcessRecord app, 6881 String activity, String shortMsg, String longMsg) { 6882 app.notResponding = true; 6883 app.notRespondingReport = generateProcessError(app, 6884 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 6885 activity, shortMsg, longMsg, null); 6886 startAppProblemLocked(app); 6887 app.stopFreezingAllLocked(); 6888 } 6889 6890 /** 6891 * Generate a process error record, suitable for attachment to a ProcessRecord. 6892 * 6893 * @param app The ProcessRecord in which the error occurred. 6894 * @param condition Crashing, Application Not Responding, etc. Values are defined in 6895 * ActivityManager.AppErrorStateInfo 6896 * @param activity The activity associated with the crash, if known. 6897 * @param shortMsg Short message describing the crash. 6898 * @param longMsg Long message describing the crash. 6899 * @param stackTrace Full crash stack trace, may be null. 6900 * 6901 * @return Returns a fully-formed AppErrorStateInfo record. 6902 */ 6903 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 6904 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 6905 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 6906 6907 report.condition = condition; 6908 report.processName = app.processName; 6909 report.pid = app.pid; 6910 report.uid = app.info.uid; 6911 report.tag = activity; 6912 report.shortMsg = shortMsg; 6913 report.longMsg = longMsg; 6914 report.stackTrace = stackTrace; 6915 6916 return report; 6917 } 6918 6919 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 6920 synchronized (this) { 6921 app.crashing = false; 6922 app.crashingReport = null; 6923 app.notResponding = false; 6924 app.notRespondingReport = null; 6925 if (app.anrDialog == fromDialog) { 6926 app.anrDialog = null; 6927 } 6928 if (app.waitDialog == fromDialog) { 6929 app.waitDialog = null; 6930 } 6931 if (app.pid > 0 && app.pid != MY_PID) { 6932 handleAppCrashLocked(app); 6933 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 6934 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 6935 app.processName, app.setAdj, "user's request after error"); 6936 Process.killProcessQuiet(app.pid); 6937 } 6938 } 6939 } 6940 6941 private boolean handleAppCrashLocked(ProcessRecord app) { 6942 long now = SystemClock.uptimeMillis(); 6943 6944 Long crashTime = mProcessCrashTimes.get(app.info.processName, 6945 app.info.uid); 6946 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 6947 // This process loses! 6948 Slog.w(TAG, "Process " + app.info.processName 6949 + " has crashed too many times: killing!"); 6950 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 6951 app.info.processName, app.info.uid); 6952 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6953 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6954 if (r.app == app) { 6955 Slog.w(TAG, " Force finishing activity " 6956 + r.intent.getComponent().flattenToShortString()); 6957 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 6958 } 6959 } 6960 if (!app.persistent) { 6961 // We don't want to start this process again until the user 6962 // explicitly does so... but for persistent process, we really 6963 // need to keep it running. If a persistent process is actually 6964 // repeatedly crashing, then badness for everyone. 6965 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid, 6966 app.info.processName); 6967 mBadProcesses.put(app.info.processName, app.info.uid, now); 6968 app.bad = true; 6969 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 6970 app.removed = true; 6971 // Don't let services in this process be restarted and potentially 6972 // annoy the user repeatedly. Unless it is persistent, since those 6973 // processes run critical code. 6974 removeProcessLocked(app, false, false); 6975 mMainStack.resumeTopActivityLocked(null); 6976 return false; 6977 } 6978 mMainStack.resumeTopActivityLocked(null); 6979 } else { 6980 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 6981 if (r.app == app) { 6982 // If the top running activity is from this crashing 6983 // process, then terminate it to avoid getting in a loop. 6984 Slog.w(TAG, " Force finishing activity " 6985 + r.intent.getComponent().flattenToShortString()); 6986 int index = mMainStack.indexOfTokenLocked(r); 6987 r.stack.finishActivityLocked(r, index, 6988 Activity.RESULT_CANCELED, null, "crashed"); 6989 // Also terminate any activities below it that aren't yet 6990 // stopped, to avoid a situation where one will get 6991 // re-start our crashing activity once it gets resumed again. 6992 index--; 6993 if (index >= 0) { 6994 r = (ActivityRecord)mMainStack.mHistory.get(index); 6995 if (r.state == ActivityState.RESUMED 6996 || r.state == ActivityState.PAUSING 6997 || r.state == ActivityState.PAUSED) { 6998 if (!r.isHomeActivity || mHomeProcess != r.app) { 6999 Slog.w(TAG, " Force finishing activity " 7000 + r.intent.getComponent().flattenToShortString()); 7001 r.stack.finishActivityLocked(r, index, 7002 Activity.RESULT_CANCELED, null, "crashed"); 7003 } 7004 } 7005 } 7006 } 7007 } 7008 7009 // Bump up the crash count of any services currently running in the proc. 7010 if (app.services.size() != 0) { 7011 // Any services running in the application need to be placed 7012 // back in the pending list. 7013 Iterator<ServiceRecord> it = app.services.iterator(); 7014 while (it.hasNext()) { 7015 ServiceRecord sr = it.next(); 7016 sr.crashCount++; 7017 } 7018 } 7019 7020 // If the crashing process is what we consider to be the "home process" and it has been 7021 // replaced by a third-party app, clear the package preferred activities from packages 7022 // with a home activity running in the process to prevent a repeatedly crashing app 7023 // from blocking the user to manually clear the list. 7024 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7025 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7026 Iterator it = mHomeProcess.activities.iterator(); 7027 while (it.hasNext()) { 7028 ActivityRecord r = (ActivityRecord)it.next(); 7029 if (r.isHomeActivity) { 7030 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7031 try { 7032 ActivityThread.getPackageManager() 7033 .clearPackagePreferredActivities(r.packageName); 7034 } catch (RemoteException c) { 7035 // pm is in same process, this will never happen. 7036 } 7037 } 7038 } 7039 } 7040 7041 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 7042 return true; 7043 } 7044 7045 void startAppProblemLocked(ProcessRecord app) { 7046 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7047 mContext, app.info.packageName, app.info.flags); 7048 skipCurrentReceiverLocked(app); 7049 } 7050 7051 void skipCurrentReceiverLocked(ProcessRecord app) { 7052 boolean reschedule = false; 7053 BroadcastRecord r = app.curReceiver; 7054 if (r != null) { 7055 // The current broadcast is waiting for this app's receiver 7056 // to be finished. Looks like that's not going to happen, so 7057 // let the broadcast continue. 7058 logBroadcastReceiverDiscardLocked(r); 7059 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 7060 r.resultExtras, r.resultAbort, true); 7061 reschedule = true; 7062 } 7063 r = mPendingBroadcast; 7064 if (r != null && r.curApp == app) { 7065 if (DEBUG_BROADCAST) Slog.v(TAG, 7066 "skip & discard pending app " + r); 7067 logBroadcastReceiverDiscardLocked(r); 7068 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 7069 r.resultExtras, r.resultAbort, true); 7070 reschedule = true; 7071 } 7072 if (reschedule) { 7073 scheduleBroadcastsLocked(); 7074 } 7075 } 7076 7077 /** 7078 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7079 * The application process will exit immediately after this call returns. 7080 * @param app object of the crashing app, null for the system server 7081 * @param crashInfo describing the exception 7082 */ 7083 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7084 ProcessRecord r = findAppProcess(app, "Crash"); 7085 7086 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7087 app == null ? "system" : (r == null ? "unknown" : r.processName), 7088 r == null ? -1 : r.info.flags, 7089 crashInfo.exceptionClassName, 7090 crashInfo.exceptionMessage, 7091 crashInfo.throwFileName, 7092 crashInfo.throwLineNumber); 7093 7094 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo); 7095 7096 crashApplication(r, crashInfo); 7097 } 7098 7099 public void handleApplicationStrictModeViolation( 7100 IBinder app, 7101 int violationMask, 7102 StrictMode.ViolationInfo info) { 7103 ProcessRecord r = findAppProcess(app, "StrictMode"); 7104 if (r == null) { 7105 return; 7106 } 7107 7108 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7109 Integer stackFingerprint = info.hashCode(); 7110 boolean logIt = true; 7111 synchronized (mAlreadyLoggedViolatedStacks) { 7112 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7113 logIt = false; 7114 // TODO: sub-sample into EventLog for these, with 7115 // the info.durationMillis? Then we'd get 7116 // the relative pain numbers, without logging all 7117 // the stack traces repeatedly. We'd want to do 7118 // likewise in the client code, which also does 7119 // dup suppression, before the Binder call. 7120 } else { 7121 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7122 mAlreadyLoggedViolatedStacks.clear(); 7123 } 7124 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7125 } 7126 } 7127 if (logIt) { 7128 logStrictModeViolationToDropBox(r, info); 7129 } 7130 } 7131 7132 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7133 AppErrorResult result = new AppErrorResult(); 7134 synchronized (this) { 7135 final long origId = Binder.clearCallingIdentity(); 7136 7137 Message msg = Message.obtain(); 7138 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7139 HashMap<String, Object> data = new HashMap<String, Object>(); 7140 data.put("result", result); 7141 data.put("app", r); 7142 data.put("violationMask", violationMask); 7143 data.put("info", info); 7144 msg.obj = data; 7145 mHandler.sendMessage(msg); 7146 7147 Binder.restoreCallingIdentity(origId); 7148 } 7149 int res = result.get(); 7150 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7151 } 7152 } 7153 7154 // Depending on the policy in effect, there could be a bunch of 7155 // these in quick succession so we try to batch these together to 7156 // minimize disk writes, number of dropbox entries, and maximize 7157 // compression, by having more fewer, larger records. 7158 private void logStrictModeViolationToDropBox( 7159 ProcessRecord process, 7160 StrictMode.ViolationInfo info) { 7161 if (info == null) { 7162 return; 7163 } 7164 final boolean isSystemApp = process == null || 7165 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7166 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7167 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7168 final DropBoxManager dbox = (DropBoxManager) 7169 mContext.getSystemService(Context.DROPBOX_SERVICE); 7170 7171 // Exit early if the dropbox isn't configured to accept this report type. 7172 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7173 7174 boolean bufferWasEmpty; 7175 boolean needsFlush; 7176 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7177 synchronized (sb) { 7178 bufferWasEmpty = sb.length() == 0; 7179 appendDropBoxProcessHeaders(process, sb); 7180 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7181 sb.append("System-App: ").append(isSystemApp).append("\n"); 7182 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7183 if (info.violationNumThisLoop != 0) { 7184 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7185 } 7186 if (info.numAnimationsRunning != 0) { 7187 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7188 } 7189 if (info.broadcastIntentAction != null) { 7190 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7191 } 7192 if (info.durationMillis != -1) { 7193 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7194 } 7195 if (info.numInstances != -1) { 7196 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7197 } 7198 if (info.tags != null) { 7199 for (String tag : info.tags) { 7200 sb.append("Span-Tag: ").append(tag).append("\n"); 7201 } 7202 } 7203 sb.append("\n"); 7204 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7205 sb.append(info.crashInfo.stackTrace); 7206 } 7207 sb.append("\n"); 7208 7209 // Only buffer up to ~64k. Various logging bits truncate 7210 // things at 128k. 7211 needsFlush = (sb.length() > 64 * 1024); 7212 } 7213 7214 // Flush immediately if the buffer's grown too large, or this 7215 // is a non-system app. Non-system apps are isolated with a 7216 // different tag & policy and not batched. 7217 // 7218 // Batching is useful during internal testing with 7219 // StrictMode settings turned up high. Without batching, 7220 // thousands of separate files could be created on boot. 7221 if (!isSystemApp || needsFlush) { 7222 new Thread("Error dump: " + dropboxTag) { 7223 @Override 7224 public void run() { 7225 String report; 7226 synchronized (sb) { 7227 report = sb.toString(); 7228 sb.delete(0, sb.length()); 7229 sb.trimToSize(); 7230 } 7231 if (report.length() != 0) { 7232 dbox.addText(dropboxTag, report); 7233 } 7234 } 7235 }.start(); 7236 return; 7237 } 7238 7239 // System app batching: 7240 if (!bufferWasEmpty) { 7241 // An existing dropbox-writing thread is outstanding, so 7242 // we don't need to start it up. The existing thread will 7243 // catch the buffer appends we just did. 7244 return; 7245 } 7246 7247 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7248 // (After this point, we shouldn't access AMS internal data structures.) 7249 new Thread("Error dump: " + dropboxTag) { 7250 @Override 7251 public void run() { 7252 // 5 second sleep to let stacks arrive and be batched together 7253 try { 7254 Thread.sleep(5000); // 5 seconds 7255 } catch (InterruptedException e) {} 7256 7257 String errorReport; 7258 synchronized (mStrictModeBuffer) { 7259 errorReport = mStrictModeBuffer.toString(); 7260 if (errorReport.length() == 0) { 7261 return; 7262 } 7263 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 7264 mStrictModeBuffer.trimToSize(); 7265 } 7266 dbox.addText(dropboxTag, errorReport); 7267 } 7268 }.start(); 7269 } 7270 7271 /** 7272 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 7273 * @param app object of the crashing app, null for the system server 7274 * @param tag reported by the caller 7275 * @param crashInfo describing the context of the error 7276 * @return true if the process should exit immediately (WTF is fatal) 7277 */ 7278 public boolean handleApplicationWtf(IBinder app, String tag, 7279 ApplicationErrorReport.CrashInfo crashInfo) { 7280 ProcessRecord r = findAppProcess(app, "WTF"); 7281 7282 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 7283 app == null ? "system" : (r == null ? "unknown" : r.processName), 7284 r == null ? -1 : r.info.flags, 7285 tag, crashInfo.exceptionMessage); 7286 7287 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo); 7288 7289 if (r != null && r.pid != Process.myPid() && 7290 Settings.Secure.getInt(mContext.getContentResolver(), 7291 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 7292 crashApplication(r, crashInfo); 7293 return true; 7294 } else { 7295 return false; 7296 } 7297 } 7298 7299 /** 7300 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 7301 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 7302 */ 7303 private ProcessRecord findAppProcess(IBinder app, String reason) { 7304 if (app == null) { 7305 return null; 7306 } 7307 7308 synchronized (this) { 7309 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 7310 final int NA = apps.size(); 7311 for (int ia=0; ia<NA; ia++) { 7312 ProcessRecord p = apps.valueAt(ia); 7313 if (p.thread != null && p.thread.asBinder() == app) { 7314 return p; 7315 } 7316 } 7317 } 7318 7319 Slog.w(TAG, "Can't find mystery application for " + reason 7320 + " from pid=" + Binder.getCallingPid() 7321 + " uid=" + Binder.getCallingUid() + ": " + app); 7322 return null; 7323 } 7324 } 7325 7326 /** 7327 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 7328 * to append various headers to the dropbox log text. 7329 */ 7330 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) { 7331 // Watchdog thread ends up invoking this function (with 7332 // a null ProcessRecord) to add the stack file to dropbox. 7333 // Do not acquire a lock on this (am) in such cases, as it 7334 // could cause a potential deadlock, if and when watchdog 7335 // is invoked due to unavailability of lock on am and it 7336 // would prevent watchdog from killing system_server. 7337 if (process == null) { 7338 sb.append("Process: system_server\n"); 7339 return; 7340 } 7341 // Note: ProcessRecord 'process' is guarded by the service 7342 // instance. (notably process.pkgList, which could otherwise change 7343 // concurrently during execution of this method) 7344 synchronized (this) { 7345 if (process.pid == MY_PID) { 7346 sb.append("Process: system_server\n"); 7347 } else { 7348 sb.append("Process: ").append(process.processName).append("\n"); 7349 } 7350 int flags = process.info.flags; 7351 IPackageManager pm = AppGlobals.getPackageManager(); 7352 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 7353 for (String pkg : process.pkgList) { 7354 sb.append("Package: ").append(pkg); 7355 try { 7356 PackageInfo pi = pm.getPackageInfo(pkg, 0); 7357 if (pi != null) { 7358 sb.append(" v").append(pi.versionCode); 7359 if (pi.versionName != null) { 7360 sb.append(" (").append(pi.versionName).append(")"); 7361 } 7362 } 7363 } catch (RemoteException e) { 7364 Slog.e(TAG, "Error getting package info: " + pkg, e); 7365 } 7366 sb.append("\n"); 7367 } 7368 } 7369 } 7370 7371 private static String processClass(ProcessRecord process) { 7372 if (process == null || process.pid == MY_PID) { 7373 return "system_server"; 7374 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7375 return "system_app"; 7376 } else { 7377 return "data_app"; 7378 } 7379 } 7380 7381 /** 7382 * Write a description of an error (crash, WTF, ANR) to the drop box. 7383 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 7384 * @param process which caused the error, null means the system server 7385 * @param activity which triggered the error, null if unknown 7386 * @param parent activity related to the error, null if unknown 7387 * @param subject line related to the error, null if absent 7388 * @param report in long form describing the error, null if absent 7389 * @param logFile to include in the report, null if none 7390 * @param crashInfo giving an application stack trace, null if absent 7391 */ 7392 public void addErrorToDropBox(String eventType, 7393 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject, 7394 final String report, final File logFile, 7395 final ApplicationErrorReport.CrashInfo crashInfo) { 7396 // NOTE -- this must never acquire the ActivityManagerService lock, 7397 // otherwise the watchdog may be prevented from resetting the system. 7398 7399 final String dropboxTag = processClass(process) + "_" + eventType; 7400 final DropBoxManager dbox = (DropBoxManager) 7401 mContext.getSystemService(Context.DROPBOX_SERVICE); 7402 7403 // Exit early if the dropbox isn't configured to accept this report type. 7404 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7405 7406 final StringBuilder sb = new StringBuilder(1024); 7407 appendDropBoxProcessHeaders(process, sb); 7408 if (activity != null) { 7409 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 7410 } 7411 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 7412 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 7413 } 7414 if (parent != null && parent != activity) { 7415 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 7416 } 7417 if (subject != null) { 7418 sb.append("Subject: ").append(subject).append("\n"); 7419 } 7420 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7421 if (Debug.isDebuggerConnected()) { 7422 sb.append("Debugger: Connected\n"); 7423 } 7424 sb.append("\n"); 7425 7426 // Do the rest in a worker thread to avoid blocking the caller on I/O 7427 // (After this point, we shouldn't access AMS internal data structures.) 7428 Thread worker = new Thread("Error dump: " + dropboxTag) { 7429 @Override 7430 public void run() { 7431 if (report != null) { 7432 sb.append(report); 7433 } 7434 if (logFile != null) { 7435 try { 7436 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 7437 } catch (IOException e) { 7438 Slog.e(TAG, "Error reading " + logFile, e); 7439 } 7440 } 7441 if (crashInfo != null && crashInfo.stackTrace != null) { 7442 sb.append(crashInfo.stackTrace); 7443 } 7444 7445 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 7446 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 7447 if (lines > 0) { 7448 sb.append("\n"); 7449 7450 // Merge several logcat streams, and take the last N lines 7451 InputStreamReader input = null; 7452 try { 7453 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 7454 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 7455 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 7456 7457 try { logcat.getOutputStream().close(); } catch (IOException e) {} 7458 try { logcat.getErrorStream().close(); } catch (IOException e) {} 7459 input = new InputStreamReader(logcat.getInputStream()); 7460 7461 int num; 7462 char[] buf = new char[8192]; 7463 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 7464 } catch (IOException e) { 7465 Slog.e(TAG, "Error running logcat", e); 7466 } finally { 7467 if (input != null) try { input.close(); } catch (IOException e) {} 7468 } 7469 } 7470 7471 dbox.addText(dropboxTag, sb.toString()); 7472 } 7473 }; 7474 7475 if (process == null || process.pid == MY_PID) { 7476 worker.run(); // We may be about to die -- need to run this synchronously 7477 } else { 7478 worker.start(); 7479 } 7480 } 7481 7482 /** 7483 * Bring up the "unexpected error" dialog box for a crashing app. 7484 * Deal with edge cases (intercepts from instrumented applications, 7485 * ActivityController, error intent receivers, that sort of thing). 7486 * @param r the application crashing 7487 * @param crashInfo describing the failure 7488 */ 7489 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 7490 long timeMillis = System.currentTimeMillis(); 7491 String shortMsg = crashInfo.exceptionClassName; 7492 String longMsg = crashInfo.exceptionMessage; 7493 String stackTrace = crashInfo.stackTrace; 7494 if (shortMsg != null && longMsg != null) { 7495 longMsg = shortMsg + ": " + longMsg; 7496 } else if (shortMsg != null) { 7497 longMsg = shortMsg; 7498 } 7499 7500 AppErrorResult result = new AppErrorResult(); 7501 synchronized (this) { 7502 if (mController != null) { 7503 try { 7504 String name = r != null ? r.processName : null; 7505 int pid = r != null ? r.pid : Binder.getCallingPid(); 7506 if (!mController.appCrashed(name, pid, 7507 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 7508 Slog.w(TAG, "Force-killing crashed app " + name 7509 + " at watcher's request"); 7510 Process.killProcess(pid); 7511 return; 7512 } 7513 } catch (RemoteException e) { 7514 mController = null; 7515 } 7516 } 7517 7518 final long origId = Binder.clearCallingIdentity(); 7519 7520 // If this process is running instrumentation, finish it. 7521 if (r != null && r.instrumentationClass != null) { 7522 Slog.w(TAG, "Error in app " + r.processName 7523 + " running instrumentation " + r.instrumentationClass + ":"); 7524 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 7525 if (longMsg != null) Slog.w(TAG, " " + longMsg); 7526 Bundle info = new Bundle(); 7527 info.putString("shortMsg", shortMsg); 7528 info.putString("longMsg", longMsg); 7529 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 7530 Binder.restoreCallingIdentity(origId); 7531 return; 7532 } 7533 7534 // If we can't identify the process or it's already exceeded its crash quota, 7535 // quit right away without showing a crash dialog. 7536 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 7537 Binder.restoreCallingIdentity(origId); 7538 return; 7539 } 7540 7541 Message msg = Message.obtain(); 7542 msg.what = SHOW_ERROR_MSG; 7543 HashMap data = new HashMap(); 7544 data.put("result", result); 7545 data.put("app", r); 7546 msg.obj = data; 7547 mHandler.sendMessage(msg); 7548 7549 Binder.restoreCallingIdentity(origId); 7550 } 7551 7552 int res = result.get(); 7553 7554 Intent appErrorIntent = null; 7555 synchronized (this) { 7556 if (r != null) { 7557 mProcessCrashTimes.put(r.info.processName, r.info.uid, 7558 SystemClock.uptimeMillis()); 7559 } 7560 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 7561 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 7562 } 7563 } 7564 7565 if (appErrorIntent != null) { 7566 try { 7567 mContext.startActivity(appErrorIntent); 7568 } catch (ActivityNotFoundException e) { 7569 Slog.w(TAG, "bug report receiver dissappeared", e); 7570 } 7571 } 7572 } 7573 7574 Intent createAppErrorIntentLocked(ProcessRecord r, 7575 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 7576 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 7577 if (report == null) { 7578 return null; 7579 } 7580 Intent result = new Intent(Intent.ACTION_APP_ERROR); 7581 result.setComponent(r.errorReportReceiver); 7582 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 7583 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7584 return result; 7585 } 7586 7587 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 7588 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 7589 if (r.errorReportReceiver == null) { 7590 return null; 7591 } 7592 7593 if (!r.crashing && !r.notResponding) { 7594 return null; 7595 } 7596 7597 ApplicationErrorReport report = new ApplicationErrorReport(); 7598 report.packageName = r.info.packageName; 7599 report.installerPackageName = r.errorReportReceiver.getPackageName(); 7600 report.processName = r.processName; 7601 report.time = timeMillis; 7602 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 7603 7604 if (r.crashing) { 7605 report.type = ApplicationErrorReport.TYPE_CRASH; 7606 report.crashInfo = crashInfo; 7607 } else if (r.notResponding) { 7608 report.type = ApplicationErrorReport.TYPE_ANR; 7609 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 7610 7611 report.anrInfo.activity = r.notRespondingReport.tag; 7612 report.anrInfo.cause = r.notRespondingReport.shortMsg; 7613 report.anrInfo.info = r.notRespondingReport.longMsg; 7614 } 7615 7616 return report; 7617 } 7618 7619 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 7620 // assume our apps are happy - lazy create the list 7621 List<ActivityManager.ProcessErrorStateInfo> errList = null; 7622 7623 synchronized (this) { 7624 7625 // iterate across all processes 7626 for (int i=mLruProcesses.size()-1; i>=0; i--) { 7627 ProcessRecord app = mLruProcesses.get(i); 7628 if ((app.thread != null) && (app.crashing || app.notResponding)) { 7629 // This one's in trouble, so we'll generate a report for it 7630 // crashes are higher priority (in case there's a crash *and* an anr) 7631 ActivityManager.ProcessErrorStateInfo report = null; 7632 if (app.crashing) { 7633 report = app.crashingReport; 7634 } else if (app.notResponding) { 7635 report = app.notRespondingReport; 7636 } 7637 7638 if (report != null) { 7639 if (errList == null) { 7640 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 7641 } 7642 errList.add(report); 7643 } else { 7644 Slog.w(TAG, "Missing app error report, app = " + app.processName + 7645 " crashing = " + app.crashing + 7646 " notResponding = " + app.notResponding); 7647 } 7648 } 7649 } 7650 } 7651 7652 return errList; 7653 } 7654 7655 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 7656 if (adj >= ProcessList.EMPTY_APP_ADJ) { 7657 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 7658 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 7659 if (currApp != null) { 7660 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 7661 } 7662 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 7663 } else if (adj >= ProcessList.HOME_APP_ADJ) { 7664 if (currApp != null) { 7665 currApp.lru = 0; 7666 } 7667 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 7668 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) { 7669 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 7670 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 7671 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 7672 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 7673 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 7674 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 7675 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 7676 } else { 7677 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 7678 } 7679 } 7680 7681 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 7682 // Lazy instantiation of list 7683 List<ActivityManager.RunningAppProcessInfo> runList = null; 7684 synchronized (this) { 7685 // Iterate across all processes 7686 for (int i=mLruProcesses.size()-1; i>=0; i--) { 7687 ProcessRecord app = mLruProcesses.get(i); 7688 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 7689 // Generate process state info for running application 7690 ActivityManager.RunningAppProcessInfo currApp = 7691 new ActivityManager.RunningAppProcessInfo(app.processName, 7692 app.pid, app.getPackageList()); 7693 currApp.uid = app.info.uid; 7694 if (mHeavyWeightProcess == app) { 7695 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 7696 } 7697 if (app.persistent) { 7698 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 7699 } 7700 int adj = app.curAdj; 7701 currApp.importance = oomAdjToImportance(adj, currApp); 7702 currApp.importanceReasonCode = app.adjTypeCode; 7703 if (app.adjSource instanceof ProcessRecord) { 7704 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 7705 currApp.importanceReasonImportance = oomAdjToImportance( 7706 app.adjSourceOom, null); 7707 } else if (app.adjSource instanceof ActivityRecord) { 7708 ActivityRecord r = (ActivityRecord)app.adjSource; 7709 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 7710 } 7711 if (app.adjTarget instanceof ComponentName) { 7712 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 7713 } 7714 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 7715 // + " lru=" + currApp.lru); 7716 if (runList == null) { 7717 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 7718 } 7719 runList.add(currApp); 7720 } 7721 } 7722 } 7723 return runList; 7724 } 7725 7726 public List<ApplicationInfo> getRunningExternalApplications() { 7727 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 7728 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 7729 if (runningApps != null && runningApps.size() > 0) { 7730 Set<String> extList = new HashSet<String>(); 7731 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 7732 if (app.pkgList != null) { 7733 for (String pkg : app.pkgList) { 7734 extList.add(pkg); 7735 } 7736 } 7737 } 7738 IPackageManager pm = AppGlobals.getPackageManager(); 7739 for (String pkg : extList) { 7740 try { 7741 ApplicationInfo info = pm.getApplicationInfo(pkg, 0); 7742 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 7743 retList.add(info); 7744 } 7745 } catch (RemoteException e) { 7746 } 7747 } 7748 } 7749 return retList; 7750 } 7751 7752 @Override 7753 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 7754 if (checkCallingPermission(android.Manifest.permission.DUMP) 7755 != PackageManager.PERMISSION_GRANTED) { 7756 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 7757 + Binder.getCallingPid() 7758 + ", uid=" + Binder.getCallingUid() 7759 + " without permission " 7760 + android.Manifest.permission.DUMP); 7761 return; 7762 } 7763 7764 boolean dumpAll = false; 7765 boolean dumpClient = false; 7766 7767 int opti = 0; 7768 while (opti < args.length) { 7769 String opt = args[opti]; 7770 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 7771 break; 7772 } 7773 opti++; 7774 if ("-a".equals(opt)) { 7775 dumpAll = true; 7776 } else if ("-c".equals(opt)) { 7777 dumpClient = true; 7778 } else if ("-h".equals(opt)) { 7779 pw.println("Activity manager dump options:"); 7780 pw.println(" [-a] [-c] [-h] [cmd] ..."); 7781 pw.println(" cmd may be one of:"); 7782 pw.println(" a[ctivities]: activity stack state"); 7783 pw.println(" b[roadcasts]: broadcast state"); 7784 pw.println(" i[ntents]: pending intent state"); 7785 pw.println(" p[rocesses]: process state"); 7786 pw.println(" o[om]: out of memory management"); 7787 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 7788 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 7789 pw.println(" service [COMP_SPEC]: service client-side state"); 7790 pw.println(" all: dump all activities"); 7791 pw.println(" top: dump the top activity"); 7792 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 7793 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 7794 pw.println(" a partial substring in a component name, a"); 7795 pw.println(" hex object identifier."); 7796 pw.println(" -a: include all available server state."); 7797 pw.println(" -c: include client state."); 7798 return; 7799 } else { 7800 pw.println("Unknown argument: " + opt + "; use -h for help"); 7801 } 7802 } 7803 7804 // Is the caller requesting to dump a particular piece of data? 7805 if (opti < args.length) { 7806 String cmd = args[opti]; 7807 opti++; 7808 if ("activities".equals(cmd) || "a".equals(cmd)) { 7809 synchronized (this) { 7810 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient); 7811 } 7812 return; 7813 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 7814 synchronized (this) { 7815 dumpBroadcastsLocked(fd, pw, args, opti, true); 7816 } 7817 return; 7818 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 7819 synchronized (this) { 7820 dumpPendingIntentsLocked(fd, pw, args, opti, true); 7821 } 7822 return; 7823 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 7824 synchronized (this) { 7825 dumpProcessesLocked(fd, pw, args, opti, true); 7826 } 7827 return; 7828 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 7829 synchronized (this) { 7830 dumpOomLocked(fd, pw, args, opti, true); 7831 } 7832 return; 7833 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 7834 synchronized (this) { 7835 dumpProvidersLocked(fd, pw, args, opti, true); 7836 } 7837 return; 7838 } else if ("service".equals(cmd)) { 7839 String[] newArgs; 7840 String name; 7841 if (opti >= args.length) { 7842 name = null; 7843 newArgs = EMPTY_STRING_ARRAY; 7844 } else { 7845 name = args[opti]; 7846 opti++; 7847 newArgs = new String[args.length - opti]; 7848 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 7849 } 7850 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 7851 pw.println("No services match: " + name); 7852 pw.println("Use -h for help."); 7853 } 7854 return; 7855 } else if ("services".equals(cmd) || "s".equals(cmd)) { 7856 synchronized (this) { 7857 dumpServicesLocked(fd, pw, args, opti, true, dumpClient); 7858 } 7859 return; 7860 } else { 7861 // Dumping a single activity? 7862 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 7863 pw.println("Bad activity command, or no activities match: " + cmd); 7864 pw.println("Use -h for help."); 7865 } 7866 return; 7867 } 7868 } 7869 7870 // No piece of data specified, dump everything. 7871 synchronized (this) { 7872 boolean needSep; 7873 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll); 7874 if (needSep) { 7875 pw.println(" "); 7876 } 7877 if (dumpAll) { 7878 pw.println("-------------------------------------------------------------------------------"); 7879 } 7880 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll); 7881 if (needSep) { 7882 pw.println(" "); 7883 } 7884 if (dumpAll) { 7885 pw.println("-------------------------------------------------------------------------------"); 7886 } 7887 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll); 7888 if (needSep) { 7889 pw.println(" "); 7890 } 7891 if (dumpAll) { 7892 pw.println("-------------------------------------------------------------------------------"); 7893 } 7894 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient); 7895 if (needSep) { 7896 pw.println(" "); 7897 } 7898 if (dumpAll) { 7899 pw.println("-------------------------------------------------------------------------------"); 7900 } 7901 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient); 7902 if (needSep) { 7903 pw.println(" "); 7904 } 7905 if (dumpAll) { 7906 pw.println("-------------------------------------------------------------------------------"); 7907 } 7908 dumpProcessesLocked(fd, pw, args, opti, dumpAll); 7909 } 7910 } 7911 7912 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 7913 int opti, boolean dumpAll, boolean dumpClient) { 7914 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 7915 pw.println(" Main stack:"); 7916 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient); 7917 pw.println(" "); 7918 pw.println(" Running activities (most recent first):"); 7919 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false); 7920 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 7921 pw.println(" "); 7922 pw.println(" Activities waiting for another to become visible:"); 7923 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 7924 !dumpAll, false); 7925 } 7926 if (mMainStack.mStoppingActivities.size() > 0) { 7927 pw.println(" "); 7928 pw.println(" Activities waiting to stop:"); 7929 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 7930 !dumpAll, false); 7931 } 7932 if (mMainStack.mGoingToSleepActivities.size() > 0) { 7933 pw.println(" "); 7934 pw.println(" Activities waiting to sleep:"); 7935 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 7936 !dumpAll, false); 7937 } 7938 if (mMainStack.mFinishingActivities.size() > 0) { 7939 pw.println(" "); 7940 pw.println(" Activities waiting to finish:"); 7941 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 7942 !dumpAll, false); 7943 } 7944 7945 pw.println(" "); 7946 if (mMainStack.mPausingActivity != null) { 7947 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 7948 } 7949 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 7950 pw.println(" mFocusedActivity: " + mFocusedActivity); 7951 if (dumpAll) { 7952 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 7953 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 7954 pw.println(" mDismissKeyguardOnNextActivity: " 7955 + mMainStack.mDismissKeyguardOnNextActivity); 7956 } 7957 7958 if (mRecentTasks.size() > 0) { 7959 pw.println(); 7960 pw.println(" Recent tasks:"); 7961 7962 final int N = mRecentTasks.size(); 7963 for (int i=0; i<N; i++) { 7964 TaskRecord tr = mRecentTasks.get(i); 7965 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 7966 pw.println(tr); 7967 if (dumpAll) { 7968 mRecentTasks.get(i).dump(pw, " "); 7969 } 7970 } 7971 } 7972 7973 if (dumpAll) { 7974 pw.println(" "); 7975 pw.println(" mCurTask: " + mCurTask); 7976 } 7977 7978 return true; 7979 } 7980 7981 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 7982 int opti, boolean dumpAll) { 7983 boolean needSep = false; 7984 int numPers = 0; 7985 7986 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 7987 7988 if (dumpAll) { 7989 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 7990 final int NA = procs.size(); 7991 for (int ia=0; ia<NA; ia++) { 7992 if (!needSep) { 7993 pw.println(" All known processes:"); 7994 needSep = true; 7995 } 7996 ProcessRecord r = procs.valueAt(ia); 7997 pw.print(r.persistent ? " *PERS*" : " *APP*"); 7998 pw.print(" UID "); pw.print(procs.keyAt(ia)); 7999 pw.print(" "); pw.println(r); 8000 r.dump(pw, " "); 8001 if (r.persistent) { 8002 numPers++; 8003 } 8004 } 8005 } 8006 } 8007 8008 if (mLruProcesses.size() > 0) { 8009 if (needSep) pw.println(" "); 8010 needSep = true; 8011 pw.println(" Process LRU list (sorted by oom_adj):"); 8012 dumpProcessOomList(pw, this, mLruProcesses, " ", 8013 "Proc", "PERS", false); 8014 needSep = true; 8015 } 8016 8017 if (dumpAll) { 8018 synchronized (mPidsSelfLocked) { 8019 if (mPidsSelfLocked.size() > 0) { 8020 if (needSep) pw.println(" "); 8021 needSep = true; 8022 pw.println(" PID mappings:"); 8023 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8024 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8025 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8026 } 8027 } 8028 } 8029 } 8030 8031 if (mForegroundProcesses.size() > 0) { 8032 if (needSep) pw.println(" "); 8033 needSep = true; 8034 pw.println(" Foreground Processes:"); 8035 for (int i=0; i<mForegroundProcesses.size(); i++) { 8036 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8037 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8038 } 8039 } 8040 8041 if (mPersistentStartingProcesses.size() > 0) { 8042 if (needSep) pw.println(" "); 8043 needSep = true; 8044 pw.println(" Persisent processes that are starting:"); 8045 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8046 "Starting Norm", "Restarting PERS"); 8047 } 8048 8049 if (mRemovedProcesses.size() > 0) { 8050 if (needSep) pw.println(" "); 8051 needSep = true; 8052 pw.println(" Processes that are being removed:"); 8053 dumpProcessList(pw, this, mRemovedProcesses, " ", 8054 "Removed Norm", "Removed PERS"); 8055 } 8056 8057 if (mProcessesOnHold.size() > 0) { 8058 if (needSep) pw.println(" "); 8059 needSep = true; 8060 pw.println(" Processes that are on old until the system is ready:"); 8061 dumpProcessList(pw, this, mProcessesOnHold, " ", 8062 "OnHold Norm", "OnHold PERS"); 8063 } 8064 8065 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll); 8066 8067 if (mProcessCrashTimes.getMap().size() > 0) { 8068 if (needSep) pw.println(" "); 8069 needSep = true; 8070 pw.println(" Time since processes crashed:"); 8071 long now = SystemClock.uptimeMillis(); 8072 for (Map.Entry<String, SparseArray<Long>> procs 8073 : mProcessCrashTimes.getMap().entrySet()) { 8074 SparseArray<Long> uids = procs.getValue(); 8075 final int N = uids.size(); 8076 for (int i=0; i<N; i++) { 8077 pw.print(" Process "); pw.print(procs.getKey()); 8078 pw.print(" uid "); pw.print(uids.keyAt(i)); 8079 pw.print(": last crashed "); 8080 pw.print((now-uids.valueAt(i))); 8081 pw.println(" ms ago"); 8082 } 8083 } 8084 } 8085 8086 if (mBadProcesses.getMap().size() > 0) { 8087 if (needSep) pw.println(" "); 8088 needSep = true; 8089 pw.println(" Bad processes:"); 8090 for (Map.Entry<String, SparseArray<Long>> procs 8091 : mBadProcesses.getMap().entrySet()) { 8092 SparseArray<Long> uids = procs.getValue(); 8093 final int N = uids.size(); 8094 for (int i=0; i<N; i++) { 8095 pw.print(" Bad process "); pw.print(procs.getKey()); 8096 pw.print(" uid "); pw.print(uids.keyAt(i)); 8097 pw.print(": crashed at time "); 8098 pw.println(uids.valueAt(i)); 8099 } 8100 } 8101 } 8102 8103 pw.println(); 8104 pw.println(" mHomeProcess: " + mHomeProcess); 8105 if (mHeavyWeightProcess != null) { 8106 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8107 } 8108 pw.println(" mConfiguration: " + mConfiguration); 8109 if (dumpAll) { 8110 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 8111 if (mCompatModePackages.getPackages().size() > 0) { 8112 pw.println(" mScreenCompatPackages:"); 8113 for (Map.Entry<String, Integer> entry 8114 : mCompatModePackages.getPackages().entrySet()) { 8115 String pkg = entry.getKey(); 8116 int mode = entry.getValue(); 8117 pw.print(" "); pw.print(pkg); pw.print(": "); 8118 pw.print(mode); pw.println(); 8119 } 8120 } 8121 } 8122 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 8123 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 8124 || mOrigWaitForDebugger) { 8125 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 8126 + " mDebugTransient=" + mDebugTransient 8127 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 8128 } 8129 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 8130 || mProfileFd != null) { 8131 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 8132 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 8133 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 8134 + mAutoStopProfiler); 8135 } 8136 if (mAlwaysFinishActivities || mController != null) { 8137 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 8138 + " mController=" + mController); 8139 } 8140 if (dumpAll) { 8141 pw.println(" Total persistent processes: " + numPers); 8142 pw.println(" mStartRunning=" + mStartRunning 8143 + " mProcessesReady=" + mProcessesReady 8144 + " mSystemReady=" + mSystemReady); 8145 pw.println(" mBooting=" + mBooting 8146 + " mBooted=" + mBooted 8147 + " mFactoryTest=" + mFactoryTest); 8148 pw.print(" mLastPowerCheckRealtime="); 8149 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 8150 pw.println(""); 8151 pw.print(" mLastPowerCheckUptime="); 8152 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 8153 pw.println(""); 8154 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 8155 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 8156 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 8157 } 8158 8159 return true; 8160 } 8161 8162 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 8163 int opti, boolean needSep, boolean dumpAll) { 8164 if (mProcessesToGc.size() > 0) { 8165 if (needSep) pw.println(" "); 8166 needSep = true; 8167 pw.println(" Processes that are waiting to GC:"); 8168 long now = SystemClock.uptimeMillis(); 8169 for (int i=0; i<mProcessesToGc.size(); i++) { 8170 ProcessRecord proc = mProcessesToGc.get(i); 8171 pw.print(" Process "); pw.println(proc); 8172 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 8173 pw.print(", last gced="); 8174 pw.print(now-proc.lastRequestedGc); 8175 pw.print(" ms ago, last lowMem="); 8176 pw.print(now-proc.lastLowMemory); 8177 pw.println(" ms ago"); 8178 8179 } 8180 } 8181 return needSep; 8182 } 8183 8184 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8185 int opti, boolean dumpAll) { 8186 boolean needSep = false; 8187 8188 if (mLruProcesses.size() > 0) { 8189 if (needSep) pw.println(" "); 8190 needSep = true; 8191 pw.println(" OOM levels:"); 8192 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 8193 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ); 8194 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 8195 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 8196 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 8197 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 8198 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 8199 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ); 8200 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 8201 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 8202 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ); 8203 8204 if (needSep) pw.println(" "); 8205 needSep = true; 8206 pw.println(" Process OOM control:"); 8207 dumpProcessOomList(pw, this, mLruProcesses, " ", 8208 "Proc", "PERS", true); 8209 needSep = true; 8210 } 8211 8212 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll); 8213 8214 pw.println(); 8215 pw.println(" mHomeProcess: " + mHomeProcess); 8216 if (mHeavyWeightProcess != null) { 8217 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8218 } 8219 8220 return true; 8221 } 8222 8223 /** 8224 * There are three ways to call this: 8225 * - no service specified: dump all the services 8226 * - a flattened component name that matched an existing service was specified as the 8227 * first arg: dump that one service 8228 * - the first arg isn't the flattened component name of an existing service: 8229 * dump all services whose component contains the first arg as a substring 8230 */ 8231 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 8232 int opti, boolean dumpAll) { 8233 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 8234 8235 if ("all".equals(name)) { 8236 synchronized (this) { 8237 for (ServiceRecord r1 : mServices.values()) { 8238 services.add(r1); 8239 } 8240 } 8241 } else { 8242 ComponentName componentName = name != null 8243 ? ComponentName.unflattenFromString(name) : null; 8244 int objectId = 0; 8245 if (componentName == null) { 8246 // Not a '/' separated full component name; maybe an object ID? 8247 try { 8248 objectId = Integer.parseInt(name, 16); 8249 name = null; 8250 componentName = null; 8251 } catch (RuntimeException e) { 8252 } 8253 } 8254 8255 synchronized (this) { 8256 for (ServiceRecord r1 : mServices.values()) { 8257 if (componentName != null) { 8258 if (r1.name.equals(componentName)) { 8259 services.add(r1); 8260 } 8261 } else if (name != null) { 8262 if (r1.name.flattenToString().contains(name)) { 8263 services.add(r1); 8264 } 8265 } else if (System.identityHashCode(r1) == objectId) { 8266 services.add(r1); 8267 } 8268 } 8269 } 8270 } 8271 8272 if (services.size() <= 0) { 8273 return false; 8274 } 8275 8276 boolean needSep = false; 8277 for (int i=0; i<services.size(); i++) { 8278 if (needSep) { 8279 pw.println(); 8280 } 8281 needSep = true; 8282 dumpService("", fd, pw, services.get(i), args, dumpAll); 8283 } 8284 return true; 8285 } 8286 8287 /** 8288 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 8289 * there is a thread associated with the service. 8290 */ 8291 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 8292 final ServiceRecord r, String[] args, boolean dumpAll) { 8293 String innerPrefix = prefix + " "; 8294 synchronized (this) { 8295 pw.print(prefix); pw.print("SERVICE "); 8296 pw.print(r.shortName); pw.print(" "); 8297 pw.print(Integer.toHexString(System.identityHashCode(r))); 8298 pw.print(" pid="); 8299 if (r.app != null) pw.println(r.app.pid); 8300 else pw.println("(not running)"); 8301 if (dumpAll) { 8302 r.dump(pw, innerPrefix); 8303 } 8304 } 8305 if (r.app != null && r.app.thread != null) { 8306 pw.print(prefix); pw.println(" Client:"); 8307 pw.flush(); 8308 try { 8309 TransferPipe tp = new TransferPipe(); 8310 try { 8311 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 8312 tp.setBufferPrefix(prefix + " "); 8313 tp.go(fd); 8314 } finally { 8315 tp.kill(); 8316 } 8317 } catch (IOException e) { 8318 pw.println(prefix + " Failure while dumping the service: " + e); 8319 } catch (RemoteException e) { 8320 pw.println(prefix + " Got a RemoteException while dumping the service"); 8321 } 8322 } 8323 } 8324 8325 static class ItemMatcher { 8326 ArrayList<ComponentName> components; 8327 ArrayList<String> strings; 8328 ArrayList<Integer> objects; 8329 boolean all; 8330 8331 ItemMatcher() { 8332 all = true; 8333 } 8334 8335 void build(String name) { 8336 ComponentName componentName = ComponentName.unflattenFromString(name); 8337 if (componentName != null) { 8338 if (components == null) { 8339 components = new ArrayList<ComponentName>(); 8340 } 8341 components.add(componentName); 8342 all = false; 8343 } else { 8344 int objectId = 0; 8345 // Not a '/' separated full component name; maybe an object ID? 8346 try { 8347 objectId = Integer.parseInt(name, 16); 8348 if (objects == null) { 8349 objects = new ArrayList<Integer>(); 8350 } 8351 objects.add(objectId); 8352 all = false; 8353 } catch (RuntimeException e) { 8354 // Not an integer; just do string match. 8355 if (strings == null) { 8356 strings = new ArrayList<String>(); 8357 } 8358 strings.add(name); 8359 all = false; 8360 } 8361 } 8362 } 8363 8364 int build(String[] args, int opti) { 8365 for (; opti<args.length; opti++) { 8366 String name = args[opti]; 8367 if ("--".equals(name)) { 8368 return opti+1; 8369 } 8370 build(name); 8371 } 8372 return opti; 8373 } 8374 8375 boolean match(Object object, ComponentName comp) { 8376 if (all) { 8377 return true; 8378 } 8379 if (components != null) { 8380 for (int i=0; i<components.size(); i++) { 8381 if (components.get(i).equals(comp)) { 8382 return true; 8383 } 8384 } 8385 } 8386 if (objects != null) { 8387 for (int i=0; i<objects.size(); i++) { 8388 if (System.identityHashCode(object) == objects.get(i)) { 8389 return true; 8390 } 8391 } 8392 } 8393 if (strings != null) { 8394 String flat = comp.flattenToString(); 8395 for (int i=0; i<strings.size(); i++) { 8396 if (flat.contains(strings.get(i))) { 8397 return true; 8398 } 8399 } 8400 } 8401 return false; 8402 } 8403 } 8404 8405 /** 8406 * There are three things that cmd can be: 8407 * - a flattened component name that matches an existing activity 8408 * - the cmd arg isn't the flattened component name of an existing activity: 8409 * dump all activity whose component contains the cmd as a substring 8410 * - A hex number of the ActivityRecord object instance. 8411 */ 8412 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 8413 int opti, boolean dumpAll) { 8414 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 8415 8416 if ("all".equals(name)) { 8417 synchronized (this) { 8418 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 8419 activities.add(r1); 8420 } 8421 } 8422 } else if ("top".equals(name)) { 8423 synchronized (this) { 8424 final int N = mMainStack.mHistory.size(); 8425 if (N > 0) { 8426 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 8427 } 8428 } 8429 } else { 8430 ItemMatcher matcher = new ItemMatcher(); 8431 matcher.build(name); 8432 8433 synchronized (this) { 8434 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 8435 if (matcher.match(r1, r1.intent.getComponent())) { 8436 activities.add(r1); 8437 } 8438 } 8439 } 8440 } 8441 8442 if (activities.size() <= 0) { 8443 return false; 8444 } 8445 8446 String[] newArgs = new String[args.length - opti]; 8447 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8448 8449 TaskRecord lastTask = null; 8450 boolean needSep = false; 8451 for (int i=activities.size()-1; i>=0; i--) { 8452 ActivityRecord r = (ActivityRecord)activities.get(i); 8453 if (needSep) { 8454 pw.println(); 8455 } 8456 needSep = true; 8457 synchronized (this) { 8458 if (lastTask != r.task) { 8459 lastTask = r.task; 8460 pw.print("TASK "); pw.print(lastTask.affinity); 8461 pw.print(" id="); pw.println(lastTask.taskId); 8462 if (dumpAll) { 8463 lastTask.dump(pw, " "); 8464 } 8465 } 8466 } 8467 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 8468 } 8469 return true; 8470 } 8471 8472 /** 8473 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 8474 * there is a thread associated with the activity. 8475 */ 8476 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 8477 final ActivityRecord r, String[] args, boolean dumpAll) { 8478 String innerPrefix = prefix + " "; 8479 synchronized (this) { 8480 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 8481 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 8482 pw.print(" pid="); 8483 if (r.app != null) pw.println(r.app.pid); 8484 else pw.println("(not running)"); 8485 if (dumpAll) { 8486 r.dump(pw, innerPrefix); 8487 } 8488 } 8489 if (r.app != null && r.app.thread != null) { 8490 // flush anything that is already in the PrintWriter since the thread is going 8491 // to write to the file descriptor directly 8492 pw.flush(); 8493 try { 8494 TransferPipe tp = new TransferPipe(); 8495 try { 8496 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r, 8497 innerPrefix, args); 8498 tp.go(fd); 8499 } finally { 8500 tp.kill(); 8501 } 8502 } catch (IOException e) { 8503 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 8504 } catch (RemoteException e) { 8505 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 8506 } 8507 } 8508 } 8509 8510 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8511 int opti, boolean dumpAll) { 8512 boolean needSep = false; 8513 8514 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 8515 if (dumpAll) { 8516 if (mRegisteredReceivers.size() > 0) { 8517 pw.println(" Registered Receivers:"); 8518 Iterator it = mRegisteredReceivers.values().iterator(); 8519 while (it.hasNext()) { 8520 ReceiverList r = (ReceiverList)it.next(); 8521 pw.print(" * "); pw.println(r); 8522 r.dump(pw, " "); 8523 } 8524 } 8525 8526 pw.println(); 8527 pw.println(" Receiver Resolver Table:"); 8528 mReceiverResolver.dump(pw, null, " ", null, false); 8529 needSep = true; 8530 } 8531 8532 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 8533 || mPendingBroadcast != null) { 8534 if (mParallelBroadcasts.size() > 0) { 8535 pw.println(); 8536 pw.println(" Active broadcasts:"); 8537 } 8538 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 8539 pw.println(" Broadcast #" + i + ":"); 8540 mParallelBroadcasts.get(i).dump(pw, " "); 8541 } 8542 if (mOrderedBroadcasts.size() > 0) { 8543 pw.println(); 8544 pw.println(" Active ordered broadcasts:"); 8545 } 8546 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 8547 pw.println(" Serialized Broadcast #" + i + ":"); 8548 mOrderedBroadcasts.get(i).dump(pw, " "); 8549 } 8550 pw.println(); 8551 pw.println(" Pending broadcast:"); 8552 if (mPendingBroadcast != null) { 8553 mPendingBroadcast.dump(pw, " "); 8554 } else { 8555 pw.println(" (null)"); 8556 } 8557 needSep = true; 8558 } 8559 8560 if (needSep) { 8561 pw.println(); 8562 } 8563 pw.println(" Historical broadcasts:"); 8564 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 8565 BroadcastRecord r = mBroadcastHistory[i]; 8566 if (r == null) { 8567 break; 8568 } 8569 if (dumpAll) { 8570 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":"); 8571 r.dump(pw, " "); 8572 } else { 8573 if (i >= 50) { 8574 pw.println(" ..."); 8575 break; 8576 } 8577 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r); 8578 } 8579 } 8580 needSep = true; 8581 8582 if (mStickyBroadcasts != null) { 8583 pw.println(); 8584 pw.println(" Sticky broadcasts:"); 8585 StringBuilder sb = new StringBuilder(128); 8586 for (Map.Entry<String, ArrayList<Intent>> ent 8587 : mStickyBroadcasts.entrySet()) { 8588 pw.print(" * Sticky action "); pw.print(ent.getKey()); 8589 if (dumpAll) { 8590 pw.println(":"); 8591 ArrayList<Intent> intents = ent.getValue(); 8592 final int N = intents.size(); 8593 for (int i=0; i<N; i++) { 8594 sb.setLength(0); 8595 sb.append(" Intent: "); 8596 intents.get(i).toShortString(sb, false, true, false); 8597 pw.println(sb.toString()); 8598 Bundle bundle = intents.get(i).getExtras(); 8599 if (bundle != null) { 8600 pw.print(" "); 8601 pw.println(bundle.toString()); 8602 } 8603 } 8604 } else { 8605 pw.println(""); 8606 } 8607 } 8608 needSep = true; 8609 } 8610 8611 if (dumpAll) { 8612 pw.println(); 8613 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 8614 pw.println(" mHandler:"); 8615 mHandler.dump(new PrintWriterPrinter(pw), " "); 8616 needSep = true; 8617 } 8618 8619 return needSep; 8620 } 8621 8622 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8623 int opti, boolean dumpAll, boolean dumpClient) { 8624 boolean needSep = false; 8625 8626 ItemMatcher matcher = new ItemMatcher(); 8627 matcher.build(args, opti); 8628 8629 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 8630 if (mServices.size() > 0) { 8631 pw.println(" Active services:"); 8632 long nowReal = SystemClock.elapsedRealtime(); 8633 Iterator<ServiceRecord> it = mServices.values().iterator(); 8634 needSep = false; 8635 while (it.hasNext()) { 8636 ServiceRecord r = it.next(); 8637 if (!matcher.match(r, r.name)) { 8638 continue; 8639 } 8640 if (needSep) { 8641 pw.println(); 8642 } 8643 pw.print(" * "); pw.println(r); 8644 if (dumpAll) { 8645 r.dump(pw, " "); 8646 needSep = true; 8647 } else { 8648 pw.print(" app="); pw.println(r.app); 8649 pw.print(" created="); 8650 TimeUtils.formatDuration(r.createTime, nowReal, pw); 8651 pw.print(" started="); pw.print(r.startRequested); 8652 pw.print(" connections="); pw.println(r.connections.size()); 8653 } 8654 if (dumpClient && r.app != null && r.app.thread != null) { 8655 pw.println(" Client:"); 8656 pw.flush(); 8657 try { 8658 TransferPipe tp = new TransferPipe(); 8659 try { 8660 r.app.thread.dumpService( 8661 tp.getWriteFd().getFileDescriptor(), r, args); 8662 tp.setBufferPrefix(" "); 8663 // Short timeout, since blocking here can 8664 // deadlock with the application. 8665 tp.go(fd, 2000); 8666 } finally { 8667 tp.kill(); 8668 } 8669 } catch (IOException e) { 8670 pw.println(" Failure while dumping the service: " + e); 8671 } catch (RemoteException e) { 8672 pw.println(" Got a RemoteException while dumping the service"); 8673 } 8674 needSep = true; 8675 } 8676 } 8677 needSep = true; 8678 } 8679 8680 if (mPendingServices.size() > 0) { 8681 if (needSep) pw.println(" "); 8682 pw.println(" Pending services:"); 8683 for (int i=0; i<mPendingServices.size(); i++) { 8684 ServiceRecord r = mPendingServices.get(i); 8685 if (!matcher.match(r, r.name)) { 8686 continue; 8687 } 8688 pw.print(" * Pending "); pw.println(r); 8689 r.dump(pw, " "); 8690 } 8691 needSep = true; 8692 } 8693 8694 if (mRestartingServices.size() > 0) { 8695 if (needSep) pw.println(" "); 8696 pw.println(" Restarting services:"); 8697 for (int i=0; i<mRestartingServices.size(); i++) { 8698 ServiceRecord r = mRestartingServices.get(i); 8699 if (!matcher.match(r, r.name)) { 8700 continue; 8701 } 8702 pw.print(" * Restarting "); pw.println(r); 8703 r.dump(pw, " "); 8704 } 8705 needSep = true; 8706 } 8707 8708 if (mStoppingServices.size() > 0) { 8709 if (needSep) pw.println(" "); 8710 pw.println(" Stopping services:"); 8711 for (int i=0; i<mStoppingServices.size(); i++) { 8712 ServiceRecord r = mStoppingServices.get(i); 8713 if (!matcher.match(r, r.name)) { 8714 continue; 8715 } 8716 pw.print(" * Stopping "); pw.println(r); 8717 r.dump(pw, " "); 8718 } 8719 needSep = true; 8720 } 8721 8722 if (dumpAll) { 8723 if (mServiceConnections.size() > 0) { 8724 if (needSep) pw.println(" "); 8725 pw.println(" Connection bindings to services:"); 8726 Iterator<ArrayList<ConnectionRecord>> it 8727 = mServiceConnections.values().iterator(); 8728 while (it.hasNext()) { 8729 ArrayList<ConnectionRecord> r = it.next(); 8730 for (int i=0; i<r.size(); i++) { 8731 ConnectionRecord cr = r.get(i); 8732 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 8733 continue; 8734 } 8735 pw.print(" * "); pw.println(cr); 8736 cr.dump(pw, " "); 8737 } 8738 } 8739 needSep = true; 8740 } 8741 } 8742 8743 return needSep; 8744 } 8745 8746 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8747 int opti, boolean dumpAll) { 8748 boolean needSep = false; 8749 8750 ItemMatcher matcher = new ItemMatcher(); 8751 matcher.build(args, opti); 8752 8753 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 8754 if (mProvidersByClass.size() > 0) { 8755 if (needSep) pw.println(" "); 8756 pw.println(" Published content providers (by class):"); 8757 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it 8758 = mProvidersByClass.entrySet().iterator(); 8759 while (it.hasNext()) { 8760 Map.Entry<ComponentName, ContentProviderRecord> e = it.next(); 8761 ContentProviderRecord r = e.getValue(); 8762 ComponentName comp = e.getKey(); 8763 String cls = comp.getClassName(); 8764 int end = cls.lastIndexOf('.'); 8765 if (end > 0 && end < (cls.length()-2)) { 8766 cls = cls.substring(end+1); 8767 } 8768 if (!matcher.match(r, comp)) { 8769 continue; 8770 } 8771 pw.print(" * "); pw.print(cls); pw.print(" ("); 8772 pw.print(comp.flattenToShortString()); pw.print(")"); 8773 if (dumpAll) { 8774 pw.println(); 8775 r.dump(pw, " "); 8776 } else { 8777 pw.print(" * "); pw.print(e.getKey().flattenToShortString()); 8778 if (r.proc != null) { 8779 pw.println(":"); 8780 pw.print(" "); pw.println(r.proc); 8781 } else { 8782 pw.println(); 8783 } 8784 } 8785 } 8786 needSep = true; 8787 } 8788 8789 if (dumpAll) { 8790 if (mProvidersByName.size() > 0) { 8791 pw.println(" "); 8792 pw.println(" Authority to provider mappings:"); 8793 Iterator<Map.Entry<String, ContentProviderRecord>> it 8794 = mProvidersByName.entrySet().iterator(); 8795 while (it.hasNext()) { 8796 Map.Entry<String, ContentProviderRecord> e = it.next(); 8797 ContentProviderRecord r = e.getValue(); 8798 if (!matcher.match(r, r.name)) { 8799 continue; 8800 } 8801 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 8802 pw.println(r); 8803 } 8804 needSep = true; 8805 } 8806 } 8807 8808 if (mLaunchingProviders.size() > 0) { 8809 if (needSep) pw.println(" "); 8810 pw.println(" Launching content providers:"); 8811 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 8812 pw.print(" Launching #"); pw.print(i); pw.print(": "); 8813 pw.println(mLaunchingProviders.get(i)); 8814 } 8815 needSep = true; 8816 } 8817 8818 if (mGrantedUriPermissions.size() > 0) { 8819 pw.println(); 8820 pw.println("Granted Uri Permissions:"); 8821 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 8822 int uid = mGrantedUriPermissions.keyAt(i); 8823 HashMap<Uri, UriPermission> perms 8824 = mGrantedUriPermissions.valueAt(i); 8825 pw.print(" * UID "); pw.print(uid); 8826 pw.println(" holds:"); 8827 for (UriPermission perm : perms.values()) { 8828 pw.print(" "); pw.println(perm); 8829 if (dumpAll) { 8830 perm.dump(pw, " "); 8831 } 8832 } 8833 } 8834 needSep = true; 8835 } 8836 8837 return needSep; 8838 } 8839 8840 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8841 int opti, boolean dumpAll) { 8842 boolean needSep = false; 8843 8844 if (this.mIntentSenderRecords.size() > 0) { 8845 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 8846 Iterator<WeakReference<PendingIntentRecord>> it 8847 = mIntentSenderRecords.values().iterator(); 8848 while (it.hasNext()) { 8849 WeakReference<PendingIntentRecord> ref = it.next(); 8850 PendingIntentRecord rec = ref != null ? ref.get(): null; 8851 needSep = true; 8852 if (rec != null) { 8853 pw.print(" * "); pw.println(rec); 8854 if (dumpAll) { 8855 rec.dump(pw, " "); 8856 } 8857 } else { 8858 pw.print(" * "); pw.println(ref); 8859 } 8860 } 8861 } 8862 8863 return needSep; 8864 } 8865 8866 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 8867 String prefix, String label, boolean complete, boolean brief, boolean client) { 8868 TaskRecord lastTask = null; 8869 boolean needNL = false; 8870 final String innerPrefix = prefix + " "; 8871 final String[] args = new String[0]; 8872 for (int i=list.size()-1; i>=0; i--) { 8873 final ActivityRecord r = (ActivityRecord)list.get(i); 8874 final boolean full = !brief && (complete || !r.isInHistory()); 8875 if (needNL) { 8876 pw.println(" "); 8877 needNL = false; 8878 } 8879 if (lastTask != r.task) { 8880 lastTask = r.task; 8881 pw.print(prefix); 8882 pw.print(full ? "* " : " "); 8883 pw.println(lastTask); 8884 if (full) { 8885 lastTask.dump(pw, prefix + " "); 8886 } else if (complete) { 8887 // Complete + brief == give a summary. Isn't that obvious?!? 8888 if (lastTask.intent != null) { 8889 pw.print(prefix); pw.print(" "); 8890 pw.println(lastTask.intent.toInsecureString()); 8891 } 8892 } 8893 } 8894 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 8895 pw.print(" #"); pw.print(i); pw.print(": "); 8896 pw.println(r); 8897 if (full) { 8898 r.dump(pw, innerPrefix); 8899 } else if (complete) { 8900 // Complete + brief == give a summary. Isn't that obvious?!? 8901 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 8902 if (r.app != null) { 8903 pw.print(innerPrefix); pw.println(r.app); 8904 } 8905 } 8906 if (client && r.app != null && r.app.thread != null) { 8907 // flush anything that is already in the PrintWriter since the thread is going 8908 // to write to the file descriptor directly 8909 pw.flush(); 8910 try { 8911 TransferPipe tp = new TransferPipe(); 8912 try { 8913 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r, 8914 innerPrefix, args); 8915 // Short timeout, since blocking here can 8916 // deadlock with the application. 8917 tp.go(fd, 2000); 8918 } finally { 8919 tp.kill(); 8920 } 8921 } catch (IOException e) { 8922 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 8923 } catch (RemoteException e) { 8924 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 8925 } 8926 needNL = true; 8927 } 8928 } 8929 } 8930 8931 private static String buildOomTag(String prefix, String space, int val, int base) { 8932 if (val == base) { 8933 if (space == null) return prefix; 8934 return prefix + " "; 8935 } 8936 return prefix + "+" + Integer.toString(val-base); 8937 } 8938 8939 private static final int dumpProcessList(PrintWriter pw, 8940 ActivityManagerService service, List list, 8941 String prefix, String normalLabel, String persistentLabel) { 8942 int numPers = 0; 8943 final int N = list.size()-1; 8944 for (int i=N; i>=0; i--) { 8945 ProcessRecord r = (ProcessRecord)list.get(i); 8946 pw.println(String.format("%s%s #%2d: %s", 8947 prefix, (r.persistent ? persistentLabel : normalLabel), 8948 i, r.toString())); 8949 if (r.persistent) { 8950 numPers++; 8951 } 8952 } 8953 return numPers; 8954 } 8955 8956 private static final void dumpProcessOomList(PrintWriter pw, 8957 ActivityManagerService service, List<ProcessRecord> origList, 8958 String prefix, String normalLabel, String persistentLabel, 8959 boolean inclDetails) { 8960 8961 ArrayList<Pair<ProcessRecord, Integer>> list 8962 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 8963 for (int i=0; i<origList.size(); i++) { 8964 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 8965 } 8966 8967 Comparator<Pair<ProcessRecord, Integer>> comparator 8968 = new Comparator<Pair<ProcessRecord, Integer>>() { 8969 @Override 8970 public int compare(Pair<ProcessRecord, Integer> object1, 8971 Pair<ProcessRecord, Integer> object2) { 8972 if (object1.first.setAdj != object2.first.setAdj) { 8973 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 8974 } 8975 if (object1.second.intValue() != object2.second.intValue()) { 8976 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 8977 } 8978 return 0; 8979 } 8980 }; 8981 8982 Collections.sort(list, comparator); 8983 8984 final long curRealtime = SystemClock.elapsedRealtime(); 8985 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 8986 final long curUptime = SystemClock.uptimeMillis(); 8987 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 8988 8989 final int N = list.size()-1; 8990 for (int i=N; i>=0; i--) { 8991 ProcessRecord r = list.get(i).first; 8992 String oomAdj; 8993 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) { 8994 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ); 8995 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8996 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 8997 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 8998 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 8999 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) { 9000 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ); 9001 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9002 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9003 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9004 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9005 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9006 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9007 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9008 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9009 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9010 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9011 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) { 9012 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ); 9013 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9014 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9015 } else { 9016 oomAdj = Integer.toString(r.setAdj); 9017 } 9018 String schedGroup; 9019 switch (r.setSchedGroup) { 9020 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9021 schedGroup = "B"; 9022 break; 9023 case Process.THREAD_GROUP_DEFAULT: 9024 schedGroup = "F"; 9025 break; 9026 default: 9027 schedGroup = Integer.toString(r.setSchedGroup); 9028 break; 9029 } 9030 String foreground; 9031 if (r.foregroundActivities) { 9032 foreground = "A"; 9033 } else if (r.foregroundServices) { 9034 foreground = "S"; 9035 } else { 9036 foreground = " "; 9037 } 9038 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9039 prefix, (r.persistent ? persistentLabel : normalLabel), 9040 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel, 9041 r.toShortString(), r.adjType)); 9042 if (r.adjSource != null || r.adjTarget != null) { 9043 pw.print(prefix); 9044 pw.print(" "); 9045 if (r.adjTarget instanceof ComponentName) { 9046 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9047 } else if (r.adjTarget != null) { 9048 pw.print(r.adjTarget.toString()); 9049 } else { 9050 pw.print("{null}"); 9051 } 9052 pw.print("<="); 9053 if (r.adjSource instanceof ProcessRecord) { 9054 pw.print("Proc{"); 9055 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9056 pw.println("}"); 9057 } else if (r.adjSource != null) { 9058 pw.println(r.adjSource.toString()); 9059 } else { 9060 pw.println("{null}"); 9061 } 9062 } 9063 if (inclDetails) { 9064 pw.print(prefix); 9065 pw.print(" "); 9066 pw.print("oom: max="); pw.print(r.maxAdj); 9067 pw.print(" hidden="); pw.print(r.hiddenAdj); 9068 pw.print(" curRaw="); pw.print(r.curRawAdj); 9069 pw.print(" setRaw="); pw.print(r.setRawAdj); 9070 pw.print(" cur="); pw.print(r.curAdj); 9071 pw.print(" set="); pw.println(r.setAdj); 9072 pw.print(prefix); 9073 pw.print(" "); 9074 pw.print("keeping="); pw.print(r.keeping); 9075 pw.print(" hidden="); pw.print(r.hidden); 9076 pw.print(" empty="); pw.print(r.empty); 9077 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9078 9079 if (!r.keeping) { 9080 if (r.lastWakeTime != 0) { 9081 long wtime; 9082 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9083 synchronized (stats) { 9084 wtime = stats.getProcessWakeTime(r.info.uid, 9085 r.pid, curRealtime); 9086 } 9087 long timeUsed = wtime - r.lastWakeTime; 9088 pw.print(prefix); 9089 pw.print(" "); 9090 pw.print("keep awake over "); 9091 TimeUtils.formatDuration(realtimeSince, pw); 9092 pw.print(" used "); 9093 TimeUtils.formatDuration(timeUsed, pw); 9094 pw.print(" ("); 9095 pw.print((timeUsed*100)/realtimeSince); 9096 pw.println("%)"); 9097 } 9098 if (r.lastCpuTime != 0) { 9099 long timeUsed = r.curCpuTime - r.lastCpuTime; 9100 pw.print(prefix); 9101 pw.print(" "); 9102 pw.print("run cpu over "); 9103 TimeUtils.formatDuration(uptimeSince, pw); 9104 pw.print(" used "); 9105 TimeUtils.formatDuration(timeUsed, pw); 9106 pw.print(" ("); 9107 pw.print((timeUsed*100)/uptimeSince); 9108 pw.println("%)"); 9109 } 9110 } 9111 } 9112 } 9113 } 9114 9115 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9116 ArrayList<ProcessRecord> procs; 9117 synchronized (this) { 9118 if (args != null && args.length > start 9119 && args[start].charAt(0) != '-') { 9120 procs = new ArrayList<ProcessRecord>(); 9121 int pid = -1; 9122 try { 9123 pid = Integer.parseInt(args[start]); 9124 } catch (NumberFormatException e) { 9125 9126 } 9127 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9128 ProcessRecord proc = mLruProcesses.get(i); 9129 if (proc.pid == pid) { 9130 procs.add(proc); 9131 } else if (proc.processName.equals(args[start])) { 9132 procs.add(proc); 9133 } 9134 } 9135 if (procs.size() <= 0) { 9136 pw.println("No process found for: " + args[start]); 9137 return null; 9138 } 9139 } else { 9140 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9141 } 9142 } 9143 return procs; 9144 } 9145 9146 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9147 PrintWriter pw, String[] args) { 9148 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9149 if (procs == null) { 9150 return; 9151 } 9152 9153 long uptime = SystemClock.uptimeMillis(); 9154 long realtime = SystemClock.elapsedRealtime(); 9155 pw.println("Applications Graphics Acceleration Info:"); 9156 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9157 9158 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9159 ProcessRecord r = procs.get(i); 9160 if (r.thread != null) { 9161 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9162 pw.flush(); 9163 try { 9164 TransferPipe tp = new TransferPipe(); 9165 try { 9166 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9167 tp.go(fd); 9168 } finally { 9169 tp.kill(); 9170 } 9171 } catch (IOException e) { 9172 pw.println("Failure while dumping the app: " + r); 9173 pw.flush(); 9174 } catch (RemoteException e) { 9175 pw.println("Got a RemoteException while dumping the app " + r); 9176 pw.flush(); 9177 } 9178 } 9179 } 9180 } 9181 9182 final static class MemItem { 9183 final String label; 9184 final long pss; 9185 ArrayList<MemItem> subitems; 9186 9187 public MemItem(String _label, long _pss) { 9188 label = _label; 9189 pss = _pss; 9190 } 9191 } 9192 9193 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9194 boolean sort) { 9195 if (sort) { 9196 Collections.sort(items, new Comparator<MemItem>() { 9197 @Override 9198 public int compare(MemItem lhs, MemItem rhs) { 9199 if (lhs.pss < rhs.pss) { 9200 return 1; 9201 } else if (lhs.pss > rhs.pss) { 9202 return -1; 9203 } 9204 return 0; 9205 } 9206 }); 9207 } 9208 9209 for (int i=0; i<items.size(); i++) { 9210 MemItem mi = items.get(i); 9211 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label); 9212 if (mi.subitems != null) { 9213 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9214 } 9215 } 9216 } 9217 9218 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9219 PrintWriter pw, String prefix, String[] args) { 9220 boolean dumpAll = false; 9221 9222 int opti = 0; 9223 while (opti < args.length) { 9224 String opt = args[opti]; 9225 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9226 break; 9227 } 9228 opti++; 9229 if ("-a".equals(opt)) { 9230 dumpAll = true; 9231 } else if ("-h".equals(opt)) { 9232 pw.println("meminfo dump options: [-a] [process]"); 9233 pw.println(" -a: include all available information for each process."); 9234 pw.println("If [process] is specified it can be the name or "); 9235 pw.println("pid of a specific process to dump."); 9236 return; 9237 } else { 9238 pw.println("Unknown argument: " + opt + "; use -h for help"); 9239 } 9240 } 9241 9242 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 9243 if (procs == null) { 9244 return; 9245 } 9246 9247 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9248 long uptime = SystemClock.uptimeMillis(); 9249 long realtime = SystemClock.elapsedRealtime(); 9250 9251 if (procs.size() == 1 || isCheckinRequest) { 9252 dumpAll = true; 9253 } 9254 9255 if (isCheckinRequest) { 9256 // short checkin version 9257 pw.println(uptime + "," + realtime); 9258 pw.flush(); 9259 } else { 9260 pw.println("Applications Memory Usage (kB):"); 9261 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9262 } 9263 9264 String[] innerArgs = new String[args.length-opti]; 9265 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 9266 9267 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 9268 long nativePss=0, dalvikPss=0, otherPss=0; 9269 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 9270 9271 final int[] oomAdj = new int[] { 9272 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9273 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9274 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ 9275 }; 9276 final String[] oomLabel = new String[] { 9277 "System", "Persistent", "Foreground", 9278 "Visible", "Perceptible", "Heavy Weight", 9279 "Backup", "Services", "Home", "Background" 9280 }; 9281 long oomPss[] = new long[oomLabel.length]; 9282 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length]; 9283 9284 long totalPss = 0; 9285 9286 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9287 ProcessRecord r = procs.get(i); 9288 if (r.thread != null) { 9289 if (!isCheckinRequest && dumpAll) { 9290 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9291 pw.flush(); 9292 } 9293 Debug.MemoryInfo mi = null; 9294 if (dumpAll) { 9295 try { 9296 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 9297 } catch (RemoteException e) { 9298 if (!isCheckinRequest) { 9299 pw.println("Got RemoteException!"); 9300 pw.flush(); 9301 } 9302 } 9303 } else { 9304 mi = new Debug.MemoryInfo(); 9305 Debug.getMemoryInfo(r.pid, mi); 9306 } 9307 9308 if (!isCheckinRequest && mi != null) { 9309 long myTotalPss = mi.getTotalPss(); 9310 totalPss += myTotalPss; 9311 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 9312 myTotalPss); 9313 procMems.add(pssItem); 9314 9315 nativePss += mi.nativePss; 9316 dalvikPss += mi.dalvikPss; 9317 otherPss += mi.otherPss; 9318 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 9319 long mem = mi.getOtherPss(j); 9320 miscPss[j] += mem; 9321 otherPss -= mem; 9322 } 9323 9324 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 9325 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) { 9326 oomPss[oomIndex] += myTotalPss; 9327 if (oomProcs[oomIndex] == null) { 9328 oomProcs[oomIndex] = new ArrayList<MemItem>(); 9329 } 9330 oomProcs[oomIndex].add(pssItem); 9331 break; 9332 } 9333 } 9334 } 9335 } 9336 } 9337 9338 if (!isCheckinRequest && procs.size() > 1) { 9339 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 9340 9341 catMems.add(new MemItem("Native", nativePss)); 9342 catMems.add(new MemItem("Dalvik", dalvikPss)); 9343 catMems.add(new MemItem("Unknown", otherPss)); 9344 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 9345 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j])); 9346 } 9347 9348 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 9349 for (int j=0; j<oomPss.length; j++) { 9350 if (oomPss[j] != 0) { 9351 MemItem item = new MemItem(oomLabel[j], oomPss[j]); 9352 item.subitems = oomProcs[j]; 9353 oomMems.add(item); 9354 } 9355 } 9356 9357 pw.println(); 9358 pw.println("Total PSS by process:"); 9359 dumpMemItems(pw, " ", procMems, true); 9360 pw.println(); 9361 pw.println("Total PSS by OOM adjustment:"); 9362 dumpMemItems(pw, " ", oomMems, false); 9363 pw.println(); 9364 pw.println("Total PSS by category:"); 9365 dumpMemItems(pw, " ", catMems, true); 9366 pw.println(); 9367 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb"); 9368 } 9369 } 9370 9371 /** 9372 * Searches array of arguments for the specified string 9373 * @param args array of argument strings 9374 * @param value value to search for 9375 * @return true if the value is contained in the array 9376 */ 9377 private static boolean scanArgs(String[] args, String value) { 9378 if (args != null) { 9379 for (String arg : args) { 9380 if (value.equals(arg)) { 9381 return true; 9382 } 9383 } 9384 } 9385 return false; 9386 } 9387 9388 private final void killServicesLocked(ProcessRecord app, 9389 boolean allowRestart) { 9390 // Report disconnected services. 9391 if (false) { 9392 // XXX we are letting the client link to the service for 9393 // death notifications. 9394 if (app.services.size() > 0) { 9395 Iterator<ServiceRecord> it = app.services.iterator(); 9396 while (it.hasNext()) { 9397 ServiceRecord r = it.next(); 9398 if (r.connections.size() > 0) { 9399 Iterator<ArrayList<ConnectionRecord>> jt 9400 = r.connections.values().iterator(); 9401 while (jt.hasNext()) { 9402 ArrayList<ConnectionRecord> cl = jt.next(); 9403 for (int i=0; i<cl.size(); i++) { 9404 ConnectionRecord c = cl.get(i); 9405 if (c.binding.client != app) { 9406 try { 9407 //c.conn.connected(r.className, null); 9408 } catch (Exception e) { 9409 // todo: this should be asynchronous! 9410 Slog.w(TAG, "Exception thrown disconnected servce " 9411 + r.shortName 9412 + " from app " + app.processName, e); 9413 } 9414 } 9415 } 9416 } 9417 } 9418 } 9419 } 9420 } 9421 9422 // Clean up any connections this application has to other services. 9423 if (app.connections.size() > 0) { 9424 Iterator<ConnectionRecord> it = app.connections.iterator(); 9425 while (it.hasNext()) { 9426 ConnectionRecord r = it.next(); 9427 removeConnectionLocked(r, app, null); 9428 } 9429 } 9430 app.connections.clear(); 9431 9432 if (app.services.size() != 0) { 9433 // Any services running in the application need to be placed 9434 // back in the pending list. 9435 Iterator<ServiceRecord> it = app.services.iterator(); 9436 while (it.hasNext()) { 9437 ServiceRecord sr = it.next(); 9438 synchronized (sr.stats.getBatteryStats()) { 9439 sr.stats.stopLaunchedLocked(); 9440 } 9441 sr.app = null; 9442 sr.executeNesting = 0; 9443 if (mStoppingServices.remove(sr)) { 9444 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 9445 } 9446 9447 boolean hasClients = sr.bindings.size() > 0; 9448 if (hasClients) { 9449 Iterator<IntentBindRecord> bindings 9450 = sr.bindings.values().iterator(); 9451 while (bindings.hasNext()) { 9452 IntentBindRecord b = bindings.next(); 9453 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 9454 + ": shouldUnbind=" + b.hasBound); 9455 b.binder = null; 9456 b.requested = b.received = b.hasBound = false; 9457 } 9458 } 9459 9460 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 9461 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 9462 Slog.w(TAG, "Service crashed " + sr.crashCount 9463 + " times, stopping: " + sr); 9464 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 9465 sr.crashCount, sr.shortName, app.pid); 9466 bringDownServiceLocked(sr, true); 9467 } else if (!allowRestart) { 9468 bringDownServiceLocked(sr, true); 9469 } else { 9470 boolean canceled = scheduleServiceRestartLocked(sr, true); 9471 9472 // Should the service remain running? Note that in the 9473 // extreme case of so many attempts to deliver a command 9474 // that it failed we also will stop it here. 9475 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 9476 if (sr.pendingStarts.size() == 0) { 9477 sr.startRequested = false; 9478 if (!hasClients) { 9479 // Whoops, no reason to restart! 9480 bringDownServiceLocked(sr, true); 9481 } 9482 } 9483 } 9484 } 9485 } 9486 9487 if (!allowRestart) { 9488 app.services.clear(); 9489 } 9490 } 9491 9492 // Make sure we have no more records on the stopping list. 9493 int i = mStoppingServices.size(); 9494 while (i > 0) { 9495 i--; 9496 ServiceRecord sr = mStoppingServices.get(i); 9497 if (sr.app == app) { 9498 mStoppingServices.remove(i); 9499 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 9500 } 9501 } 9502 9503 app.executingServices.clear(); 9504 } 9505 9506 private final void removeDyingProviderLocked(ProcessRecord proc, 9507 ContentProviderRecord cpr) { 9508 synchronized (cpr) { 9509 cpr.launchingApp = null; 9510 cpr.notifyAll(); 9511 } 9512 9513 mProvidersByClass.remove(cpr.name); 9514 String names[] = cpr.info.authority.split(";"); 9515 for (int j = 0; j < names.length; j++) { 9516 mProvidersByName.remove(names[j]); 9517 } 9518 9519 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 9520 while (cit.hasNext()) { 9521 ProcessRecord capp = cit.next(); 9522 if (!capp.persistent && capp.thread != null 9523 && capp.pid != 0 9524 && capp.pid != MY_PID) { 9525 Slog.i(TAG, "Kill " + capp.processName 9526 + " (pid " + capp.pid + "): provider " + cpr.info.name 9527 + " in dying process " + (proc != null ? proc.processName : "??")); 9528 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 9529 capp.processName, capp.setAdj, "dying provider " 9530 + cpr.name.toShortString()); 9531 Process.killProcessQuiet(capp.pid); 9532 } 9533 } 9534 9535 mLaunchingProviders.remove(cpr); 9536 } 9537 9538 /** 9539 * Main code for cleaning up a process when it has gone away. This is 9540 * called both as a result of the process dying, or directly when stopping 9541 * a process when running in single process mode. 9542 */ 9543 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 9544 boolean restarting, boolean allowRestart, int index) { 9545 if (index >= 0) { 9546 mLruProcesses.remove(index); 9547 } 9548 9549 mProcessesToGc.remove(app); 9550 9551 // Dismiss any open dialogs. 9552 if (app.crashDialog != null) { 9553 app.crashDialog.dismiss(); 9554 app.crashDialog = null; 9555 } 9556 if (app.anrDialog != null) { 9557 app.anrDialog.dismiss(); 9558 app.anrDialog = null; 9559 } 9560 if (app.waitDialog != null) { 9561 app.waitDialog.dismiss(); 9562 app.waitDialog = null; 9563 } 9564 9565 app.crashing = false; 9566 app.notResponding = false; 9567 9568 app.resetPackageList(); 9569 app.unlinkDeathRecipient(); 9570 app.thread = null; 9571 app.forcingToForeground = null; 9572 app.foregroundServices = false; 9573 app.foregroundActivities = false; 9574 app.hasShownUi = false; 9575 app.hasAboveClient = false; 9576 9577 killServicesLocked(app, allowRestart); 9578 9579 boolean restart = false; 9580 9581 int NL = mLaunchingProviders.size(); 9582 9583 // Remove published content providers. 9584 if (!app.pubProviders.isEmpty()) { 9585 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 9586 while (it.hasNext()) { 9587 ContentProviderRecord cpr = it.next(); 9588 cpr.provider = null; 9589 cpr.proc = null; 9590 9591 // See if someone is waiting for this provider... in which 9592 // case we don't remove it, but just let it restart. 9593 int i = 0; 9594 if (!app.bad && allowRestart) { 9595 for (; i<NL; i++) { 9596 if (mLaunchingProviders.get(i) == cpr) { 9597 restart = true; 9598 break; 9599 } 9600 } 9601 } else { 9602 i = NL; 9603 } 9604 9605 if (i >= NL) { 9606 removeDyingProviderLocked(app, cpr); 9607 NL = mLaunchingProviders.size(); 9608 } 9609 } 9610 app.pubProviders.clear(); 9611 } 9612 9613 // Take care of any launching providers waiting for this process. 9614 if (checkAppInLaunchingProvidersLocked(app, false)) { 9615 restart = true; 9616 } 9617 9618 // Unregister from connected content providers. 9619 if (!app.conProviders.isEmpty()) { 9620 Iterator it = app.conProviders.keySet().iterator(); 9621 while (it.hasNext()) { 9622 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9623 cpr.clients.remove(app); 9624 } 9625 app.conProviders.clear(); 9626 } 9627 9628 // At this point there may be remaining entries in mLaunchingProviders 9629 // where we were the only one waiting, so they are no longer of use. 9630 // Look for these and clean up if found. 9631 // XXX Commented out for now. Trying to figure out a way to reproduce 9632 // the actual situation to identify what is actually going on. 9633 if (false) { 9634 for (int i=0; i<NL; i++) { 9635 ContentProviderRecord cpr = (ContentProviderRecord) 9636 mLaunchingProviders.get(i); 9637 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 9638 synchronized (cpr) { 9639 cpr.launchingApp = null; 9640 cpr.notifyAll(); 9641 } 9642 } 9643 } 9644 } 9645 9646 skipCurrentReceiverLocked(app); 9647 9648 // Unregister any receivers. 9649 if (app.receivers.size() > 0) { 9650 Iterator<ReceiverList> it = app.receivers.iterator(); 9651 while (it.hasNext()) { 9652 removeReceiverLocked(it.next()); 9653 } 9654 app.receivers.clear(); 9655 } 9656 9657 // If the app is undergoing backup, tell the backup manager about it 9658 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 9659 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 9660 try { 9661 IBackupManager bm = IBackupManager.Stub.asInterface( 9662 ServiceManager.getService(Context.BACKUP_SERVICE)); 9663 bm.agentDisconnected(app.info.packageName); 9664 } catch (RemoteException e) { 9665 // can't happen; backup manager is local 9666 } 9667 } 9668 9669 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 9670 9671 // If the caller is restarting this app, then leave it in its 9672 // current lists and let the caller take care of it. 9673 if (restarting) { 9674 return; 9675 } 9676 9677 if (!app.persistent) { 9678 if (DEBUG_PROCESSES) Slog.v(TAG, 9679 "Removing non-persistent process during cleanup: " + app); 9680 mProcessNames.remove(app.processName, app.info.uid); 9681 if (mHeavyWeightProcess == app) { 9682 mHeavyWeightProcess = null; 9683 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 9684 } 9685 } else if (!app.removed) { 9686 // This app is persistent, so we need to keep its record around. 9687 // If it is not already on the pending app list, add it there 9688 // and start a new process for it. 9689 if (mPersistentStartingProcesses.indexOf(app) < 0) { 9690 mPersistentStartingProcesses.add(app); 9691 restart = true; 9692 } 9693 } 9694 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 9695 "Clean-up removing on hold: " + app); 9696 mProcessesOnHold.remove(app); 9697 9698 if (app == mHomeProcess) { 9699 mHomeProcess = null; 9700 } 9701 9702 if (restart) { 9703 // We have components that still need to be running in the 9704 // process, so re-launch it. 9705 mProcessNames.put(app.processName, app.info.uid, app); 9706 startProcessLocked(app, "restart", app.processName); 9707 } else if (app.pid > 0 && app.pid != MY_PID) { 9708 // Goodbye! 9709 synchronized (mPidsSelfLocked) { 9710 mPidsSelfLocked.remove(app.pid); 9711 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 9712 } 9713 app.setPid(0); 9714 } 9715 } 9716 9717 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 9718 // Look through the content providers we are waiting to have launched, 9719 // and if any run in this process then either schedule a restart of 9720 // the process or kill the client waiting for it if this process has 9721 // gone bad. 9722 int NL = mLaunchingProviders.size(); 9723 boolean restart = false; 9724 for (int i=0; i<NL; i++) { 9725 ContentProviderRecord cpr = mLaunchingProviders.get(i); 9726 if (cpr.launchingApp == app) { 9727 if (!alwaysBad && !app.bad) { 9728 restart = true; 9729 } else { 9730 removeDyingProviderLocked(app, cpr); 9731 NL = mLaunchingProviders.size(); 9732 } 9733 } 9734 } 9735 return restart; 9736 } 9737 9738 // ========================================================= 9739 // SERVICES 9740 // ========================================================= 9741 9742 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 9743 ActivityManager.RunningServiceInfo info = 9744 new ActivityManager.RunningServiceInfo(); 9745 info.service = r.name; 9746 if (r.app != null) { 9747 info.pid = r.app.pid; 9748 } 9749 info.uid = r.appInfo.uid; 9750 info.process = r.processName; 9751 info.foreground = r.isForeground; 9752 info.activeSince = r.createTime; 9753 info.started = r.startRequested; 9754 info.clientCount = r.connections.size(); 9755 info.crashCount = r.crashCount; 9756 info.lastActivityTime = r.lastActivity; 9757 if (r.isForeground) { 9758 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 9759 } 9760 if (r.startRequested) { 9761 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 9762 } 9763 if (r.app != null && r.app.pid == MY_PID) { 9764 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 9765 } 9766 if (r.app != null && r.app.persistent) { 9767 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 9768 } 9769 9770 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 9771 for (int i=0; i<connl.size(); i++) { 9772 ConnectionRecord conn = connl.get(i); 9773 if (conn.clientLabel != 0) { 9774 info.clientPackage = conn.binding.client.info.packageName; 9775 info.clientLabel = conn.clientLabel; 9776 return info; 9777 } 9778 } 9779 } 9780 return info; 9781 } 9782 9783 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 9784 int flags) { 9785 synchronized (this) { 9786 ArrayList<ActivityManager.RunningServiceInfo> res 9787 = new ArrayList<ActivityManager.RunningServiceInfo>(); 9788 9789 if (mServices.size() > 0) { 9790 Iterator<ServiceRecord> it = mServices.values().iterator(); 9791 while (it.hasNext() && res.size() < maxNum) { 9792 res.add(makeRunningServiceInfoLocked(it.next())); 9793 } 9794 } 9795 9796 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 9797 ServiceRecord r = mRestartingServices.get(i); 9798 ActivityManager.RunningServiceInfo info = 9799 makeRunningServiceInfoLocked(r); 9800 info.restarting = r.nextRestartTime; 9801 res.add(info); 9802 } 9803 9804 return res; 9805 } 9806 } 9807 9808 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 9809 synchronized (this) { 9810 ServiceRecord r = mServices.get(name); 9811 if (r != null) { 9812 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 9813 for (int i=0; i<conn.size(); i++) { 9814 if (conn.get(i).clientIntent != null) { 9815 return conn.get(i).clientIntent; 9816 } 9817 } 9818 } 9819 } 9820 } 9821 return null; 9822 } 9823 9824 private final ServiceRecord findServiceLocked(ComponentName name, 9825 IBinder token) { 9826 ServiceRecord r = mServices.get(name); 9827 return r == token ? r : null; 9828 } 9829 9830 private final class ServiceLookupResult { 9831 final ServiceRecord record; 9832 final String permission; 9833 9834 ServiceLookupResult(ServiceRecord _record, String _permission) { 9835 record = _record; 9836 permission = _permission; 9837 } 9838 }; 9839 9840 private ServiceLookupResult findServiceLocked(Intent service, 9841 String resolvedType) { 9842 ServiceRecord r = null; 9843 if (service.getComponent() != null) { 9844 r = mServices.get(service.getComponent()); 9845 } 9846 if (r == null) { 9847 Intent.FilterComparison filter = new Intent.FilterComparison(service); 9848 r = mServicesByIntent.get(filter); 9849 } 9850 9851 if (r == null) { 9852 try { 9853 ResolveInfo rInfo = 9854 AppGlobals.getPackageManager().resolveService( 9855 service, resolvedType, 0); 9856 ServiceInfo sInfo = 9857 rInfo != null ? rInfo.serviceInfo : null; 9858 if (sInfo == null) { 9859 return null; 9860 } 9861 9862 ComponentName name = new ComponentName( 9863 sInfo.applicationInfo.packageName, sInfo.name); 9864 r = mServices.get(name); 9865 } catch (RemoteException ex) { 9866 // pm is in same process, this will never happen. 9867 } 9868 } 9869 if (r != null) { 9870 int callingPid = Binder.getCallingPid(); 9871 int callingUid = Binder.getCallingUid(); 9872 if (checkComponentPermission(r.permission, 9873 callingPid, callingUid, r.appInfo.uid, r.exported) 9874 != PackageManager.PERMISSION_GRANTED) { 9875 if (!r.exported) { 9876 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 9877 + " from pid=" + callingPid 9878 + ", uid=" + callingUid 9879 + " that is not exported from uid " + r.appInfo.uid); 9880 return new ServiceLookupResult(null, "not exported from uid " 9881 + r.appInfo.uid); 9882 } 9883 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 9884 + " from pid=" + callingPid 9885 + ", uid=" + callingUid 9886 + " requires " + r.permission); 9887 return new ServiceLookupResult(null, r.permission); 9888 } 9889 return new ServiceLookupResult(r, null); 9890 } 9891 return null; 9892 } 9893 9894 private class ServiceRestarter implements Runnable { 9895 private ServiceRecord mService; 9896 9897 void setService(ServiceRecord service) { 9898 mService = service; 9899 } 9900 9901 public void run() { 9902 synchronized(ActivityManagerService.this) { 9903 performServiceRestartLocked(mService); 9904 } 9905 } 9906 } 9907 9908 private ServiceLookupResult retrieveServiceLocked(Intent service, 9909 String resolvedType, int callingPid, int callingUid) { 9910 ServiceRecord r = null; 9911 if (service.getComponent() != null) { 9912 r = mServices.get(service.getComponent()); 9913 } 9914 Intent.FilterComparison filter = new Intent.FilterComparison(service); 9915 r = mServicesByIntent.get(filter); 9916 if (r == null) { 9917 try { 9918 ResolveInfo rInfo = 9919 AppGlobals.getPackageManager().resolveService( 9920 service, resolvedType, STOCK_PM_FLAGS); 9921 ServiceInfo sInfo = 9922 rInfo != null ? rInfo.serviceInfo : null; 9923 if (sInfo == null) { 9924 Slog.w(TAG, "Unable to start service " + service + 9925 ": not found"); 9926 return null; 9927 } 9928 9929 ComponentName name = new ComponentName( 9930 sInfo.applicationInfo.packageName, sInfo.name); 9931 r = mServices.get(name); 9932 if (r == null) { 9933 filter = new Intent.FilterComparison(service.cloneFilter()); 9934 ServiceRestarter res = new ServiceRestarter(); 9935 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 9936 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9937 synchronized (stats) { 9938 ss = stats.getServiceStatsLocked( 9939 sInfo.applicationInfo.uid, sInfo.packageName, 9940 sInfo.name); 9941 } 9942 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 9943 res.setService(r); 9944 mServices.put(name, r); 9945 mServicesByIntent.put(filter, r); 9946 9947 // Make sure this component isn't in the pending list. 9948 int N = mPendingServices.size(); 9949 for (int i=0; i<N; i++) { 9950 ServiceRecord pr = mPendingServices.get(i); 9951 if (pr.name.equals(name)) { 9952 mPendingServices.remove(i); 9953 i--; 9954 N--; 9955 } 9956 } 9957 } 9958 } catch (RemoteException ex) { 9959 // pm is in same process, this will never happen. 9960 } 9961 } 9962 if (r != null) { 9963 if (checkComponentPermission(r.permission, 9964 callingPid, callingUid, r.appInfo.uid, r.exported) 9965 != PackageManager.PERMISSION_GRANTED) { 9966 if (!r.exported) { 9967 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 9968 + " from pid=" + callingPid 9969 + ", uid=" + callingUid 9970 + " that is not exported from uid " + r.appInfo.uid); 9971 return new ServiceLookupResult(null, "not exported from uid " 9972 + r.appInfo.uid); 9973 } 9974 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 9975 + " from pid=" + callingPid 9976 + ", uid=" + callingUid 9977 + " requires " + r.permission); 9978 return new ServiceLookupResult(null, r.permission); 9979 } 9980 return new ServiceLookupResult(r, null); 9981 } 9982 return null; 9983 } 9984 9985 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 9986 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 9987 + why + " of " + r + " in app " + r.app); 9988 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 9989 + why + " of " + r.shortName); 9990 long now = SystemClock.uptimeMillis(); 9991 if (r.executeNesting == 0 && r.app != null) { 9992 if (r.app.executingServices.size() == 0) { 9993 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 9994 msg.obj = r.app; 9995 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 9996 } 9997 r.app.executingServices.add(r); 9998 } 9999 r.executeNesting++; 10000 r.executingStart = now; 10001 } 10002 10003 private final void sendServiceArgsLocked(ServiceRecord r, 10004 boolean oomAdjusted) { 10005 final int N = r.pendingStarts.size(); 10006 if (N == 0) { 10007 return; 10008 } 10009 10010 while (r.pendingStarts.size() > 0) { 10011 try { 10012 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 10013 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 10014 + r + " " + r.intent + " args=" + si.intent); 10015 if (si.intent == null && N > 1) { 10016 // If somehow we got a dummy null intent in the middle, 10017 // then skip it. DO NOT skip a null intent when it is 10018 // the only one in the list -- this is to support the 10019 // onStartCommand(null) case. 10020 continue; 10021 } 10022 si.deliveredTime = SystemClock.uptimeMillis(); 10023 r.deliveredStarts.add(si); 10024 si.deliveryCount++; 10025 if (si.targetPermissionUid >= 0 && si.intent != null) { 10026 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid, 10027 r.packageName, si.intent, si.getUriPermissionsLocked()); 10028 } 10029 bumpServiceExecutingLocked(r, "start"); 10030 if (!oomAdjusted) { 10031 oomAdjusted = true; 10032 updateOomAdjLocked(r.app); 10033 } 10034 int flags = 0; 10035 if (si.deliveryCount > 0) { 10036 flags |= Service.START_FLAG_RETRY; 10037 } 10038 if (si.doneExecutingCount > 0) { 10039 flags |= Service.START_FLAG_REDELIVERY; 10040 } 10041 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 10042 } catch (RemoteException e) { 10043 // Remote process gone... we'll let the normal cleanup take 10044 // care of this. 10045 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 10046 break; 10047 } catch (Exception e) { 10048 Slog.w(TAG, "Unexpected exception", e); 10049 break; 10050 } 10051 } 10052 } 10053 10054 private final boolean requestServiceBindingLocked(ServiceRecord r, 10055 IntentBindRecord i, boolean rebind) { 10056 if (r.app == null || r.app.thread == null) { 10057 // If service is not currently running, can't yet bind. 10058 return false; 10059 } 10060 if ((!i.requested || rebind) && i.apps.size() > 0) { 10061 try { 10062 bumpServiceExecutingLocked(r, "bind"); 10063 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10064 if (!rebind) { 10065 i.requested = true; 10066 } 10067 i.hasBound = true; 10068 i.doRebind = false; 10069 } catch (RemoteException e) { 10070 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 10071 return false; 10072 } 10073 } 10074 return true; 10075 } 10076 10077 private final void requestServiceBindingsLocked(ServiceRecord r) { 10078 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10079 while (bindings.hasNext()) { 10080 IntentBindRecord i = bindings.next(); 10081 if (!requestServiceBindingLocked(r, i, false)) { 10082 break; 10083 } 10084 } 10085 } 10086 10087 private final void realStartServiceLocked(ServiceRecord r, 10088 ProcessRecord app) throws RemoteException { 10089 if (app.thread == null) { 10090 throw new RemoteException(); 10091 } 10092 10093 r.app = app; 10094 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10095 10096 app.services.add(r); 10097 bumpServiceExecutingLocked(r, "create"); 10098 updateLruProcessLocked(app, true, true); 10099 10100 boolean created = false; 10101 try { 10102 mStringBuilder.setLength(0); 10103 r.intent.getIntent().toShortString(mStringBuilder, true, false, true); 10104 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 10105 System.identityHashCode(r), r.shortName, 10106 mStringBuilder.toString(), r.app.pid); 10107 synchronized (r.stats.getBatteryStats()) { 10108 r.stats.startLaunchedLocked(); 10109 } 10110 ensurePackageDexOpt(r.serviceInfo.packageName); 10111 app.thread.scheduleCreateService(r, r.serviceInfo, 10112 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 10113 r.postNotification(); 10114 created = true; 10115 } finally { 10116 if (!created) { 10117 app.services.remove(r); 10118 scheduleServiceRestartLocked(r, false); 10119 } 10120 } 10121 10122 requestServiceBindingsLocked(r); 10123 10124 // If the service is in the started state, and there are no 10125 // pending arguments, then fake up one so its onStartCommand() will 10126 // be called. 10127 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10128 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 10129 null, -1)); 10130 } 10131 10132 sendServiceArgsLocked(r, true); 10133 } 10134 10135 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10136 boolean allowCancel) { 10137 boolean canceled = false; 10138 10139 final long now = SystemClock.uptimeMillis(); 10140 long minDuration = SERVICE_RESTART_DURATION; 10141 long resetTime = SERVICE_RESET_RUN_DURATION; 10142 10143 if ((r.serviceInfo.applicationInfo.flags 10144 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 10145 minDuration /= 4; 10146 } 10147 10148 // Any delivered but not yet finished starts should be put back 10149 // on the pending list. 10150 final int N = r.deliveredStarts.size(); 10151 if (N > 0) { 10152 for (int i=N-1; i>=0; i--) { 10153 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10154 si.removeUriPermissionsLocked(); 10155 if (si.intent == null) { 10156 // We'll generate this again if needed. 10157 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10158 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10159 r.pendingStarts.add(0, si); 10160 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10161 dur *= 2; 10162 if (minDuration < dur) minDuration = dur; 10163 if (resetTime < dur) resetTime = dur; 10164 } else { 10165 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 10166 + r.name); 10167 canceled = true; 10168 } 10169 } 10170 r.deliveredStarts.clear(); 10171 } 10172 10173 r.totalRestartCount++; 10174 if (r.restartDelay == 0) { 10175 r.restartCount++; 10176 r.restartDelay = minDuration; 10177 } else { 10178 // If it has been a "reasonably long time" since the service 10179 // was started, then reset our restart duration back to 10180 // the beginning, so we don't infinitely increase the duration 10181 // on a service that just occasionally gets killed (which is 10182 // a normal case, due to process being killed to reclaim memory). 10183 if (now > (r.restartTime+resetTime)) { 10184 r.restartCount = 1; 10185 r.restartDelay = minDuration; 10186 } else { 10187 if ((r.serviceInfo.applicationInfo.flags 10188 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 10189 // Services in peristent processes will restart much more 10190 // quickly, since they are pretty important. (Think SystemUI). 10191 r.restartDelay += minDuration/2; 10192 } else { 10193 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10194 if (r.restartDelay < minDuration) { 10195 r.restartDelay = minDuration; 10196 } 10197 } 10198 } 10199 } 10200 10201 r.nextRestartTime = now + r.restartDelay; 10202 10203 // Make sure that we don't end up restarting a bunch of services 10204 // all at the same time. 10205 boolean repeat; 10206 do { 10207 repeat = false; 10208 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10209 ServiceRecord r2 = mRestartingServices.get(i); 10210 if (r2 != r && r.nextRestartTime 10211 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10212 && r.nextRestartTime 10213 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10214 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10215 r.restartDelay = r.nextRestartTime - now; 10216 repeat = true; 10217 break; 10218 } 10219 } 10220 } while (repeat); 10221 10222 if (!mRestartingServices.contains(r)) { 10223 mRestartingServices.add(r); 10224 } 10225 10226 r.cancelNotification(); 10227 10228 mHandler.removeCallbacks(r.restarter); 10229 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10230 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10231 Slog.w(TAG, "Scheduling restart of crashed service " 10232 + r.shortName + " in " + r.restartDelay + "ms"); 10233 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 10234 r.shortName, r.restartDelay); 10235 10236 return canceled; 10237 } 10238 10239 final void performServiceRestartLocked(ServiceRecord r) { 10240 if (!mRestartingServices.contains(r)) { 10241 return; 10242 } 10243 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10244 } 10245 10246 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10247 if (r.restartDelay == 0) { 10248 return false; 10249 } 10250 r.resetRestartCounter(); 10251 mRestartingServices.remove(r); 10252 mHandler.removeCallbacks(r.restarter); 10253 return true; 10254 } 10255 10256 private final boolean bringUpServiceLocked(ServiceRecord r, 10257 int intentFlags, boolean whileRestarting) { 10258 //Slog.i(TAG, "Bring up service:"); 10259 //r.dump(" "); 10260 10261 if (r.app != null && r.app.thread != null) { 10262 sendServiceArgsLocked(r, false); 10263 return true; 10264 } 10265 10266 if (!whileRestarting && r.restartDelay > 0) { 10267 // If waiting for a restart, then do nothing. 10268 return true; 10269 } 10270 10271 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 10272 10273 // We are now bringing the service up, so no longer in the 10274 // restarting state. 10275 mRestartingServices.remove(r); 10276 10277 // Service is now being launched, its package can't be stopped. 10278 try { 10279 AppGlobals.getPackageManager().setPackageStoppedState( 10280 r.packageName, false); 10281 } catch (RemoteException e) { 10282 } catch (IllegalArgumentException e) { 10283 Slog.w(TAG, "Failed trying to unstop package " 10284 + r.packageName + ": " + e); 10285 } 10286 10287 final String appName = r.processName; 10288 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10289 if (app != null && app.thread != null) { 10290 try { 10291 app.addPackage(r.appInfo.packageName); 10292 realStartServiceLocked(r, app); 10293 return true; 10294 } catch (RemoteException e) { 10295 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 10296 } 10297 10298 // If a dead object exception was thrown -- fall through to 10299 // restart the application. 10300 } 10301 10302 // Not running -- get it started, and enqueue this service record 10303 // to be executed when the app comes up. 10304 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10305 "service", r.name, false) == null) { 10306 Slog.w(TAG, "Unable to launch app " 10307 + r.appInfo.packageName + "/" 10308 + r.appInfo.uid + " for service " 10309 + r.intent.getIntent() + ": process is bad"); 10310 bringDownServiceLocked(r, true); 10311 return false; 10312 } 10313 10314 if (!mPendingServices.contains(r)) { 10315 mPendingServices.add(r); 10316 } 10317 10318 return true; 10319 } 10320 10321 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10322 //Slog.i(TAG, "Bring down service:"); 10323 //r.dump(" "); 10324 10325 // Does it still need to run? 10326 if (!force && r.startRequested) { 10327 return; 10328 } 10329 if (r.connections.size() > 0) { 10330 if (!force) { 10331 // XXX should probably keep a count of the number of auto-create 10332 // connections directly in the service. 10333 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 10334 while (it.hasNext()) { 10335 ArrayList<ConnectionRecord> cr = it.next(); 10336 for (int i=0; i<cr.size(); i++) { 10337 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 10338 return; 10339 } 10340 } 10341 } 10342 } 10343 10344 // Report to all of the connections that the service is no longer 10345 // available. 10346 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 10347 while (it.hasNext()) { 10348 ArrayList<ConnectionRecord> c = it.next(); 10349 for (int i=0; i<c.size(); i++) { 10350 ConnectionRecord cr = c.get(i); 10351 // There is still a connection to the service that is 10352 // being brought down. Mark it as dead. 10353 cr.serviceDead = true; 10354 try { 10355 cr.conn.connected(r.name, null); 10356 } catch (Exception e) { 10357 Slog.w(TAG, "Failure disconnecting service " + r.name + 10358 " to connection " + c.get(i).conn.asBinder() + 10359 " (in " + c.get(i).binding.client.processName + ")", e); 10360 } 10361 } 10362 } 10363 } 10364 10365 // Tell the service that it has been unbound. 10366 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10367 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10368 while (it.hasNext()) { 10369 IntentBindRecord ibr = it.next(); 10370 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 10371 + ": hasBound=" + ibr.hasBound); 10372 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10373 try { 10374 bumpServiceExecutingLocked(r, "bring down unbind"); 10375 updateOomAdjLocked(r.app); 10376 ibr.hasBound = false; 10377 r.app.thread.scheduleUnbindService(r, 10378 ibr.intent.getIntent()); 10379 } catch (Exception e) { 10380 Slog.w(TAG, "Exception when unbinding service " 10381 + r.shortName, e); 10382 serviceDoneExecutingLocked(r, true); 10383 } 10384 } 10385 } 10386 } 10387 10388 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 10389 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 10390 System.identityHashCode(r), r.shortName, 10391 (r.app != null) ? r.app.pid : -1); 10392 10393 mServices.remove(r.name); 10394 mServicesByIntent.remove(r.intent); 10395 r.totalRestartCount = 0; 10396 unscheduleServiceRestartLocked(r); 10397 10398 // Also make sure it is not on the pending list. 10399 int N = mPendingServices.size(); 10400 for (int i=0; i<N; i++) { 10401 if (mPendingServices.get(i) == r) { 10402 mPendingServices.remove(i); 10403 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 10404 i--; 10405 N--; 10406 } 10407 } 10408 10409 r.cancelNotification(); 10410 r.isForeground = false; 10411 r.foregroundId = 0; 10412 r.foregroundNoti = null; 10413 10414 // Clear start entries. 10415 r.clearDeliveredStartsLocked(); 10416 r.pendingStarts.clear(); 10417 10418 if (r.app != null) { 10419 synchronized (r.stats.getBatteryStats()) { 10420 r.stats.stopLaunchedLocked(); 10421 } 10422 r.app.services.remove(r); 10423 if (r.app.thread != null) { 10424 try { 10425 bumpServiceExecutingLocked(r, "stop"); 10426 mStoppingServices.add(r); 10427 updateOomAdjLocked(r.app); 10428 r.app.thread.scheduleStopService(r); 10429 } catch (Exception e) { 10430 Slog.w(TAG, "Exception when stopping service " 10431 + r.shortName, e); 10432 serviceDoneExecutingLocked(r, true); 10433 } 10434 updateServiceForegroundLocked(r.app, false); 10435 } else { 10436 if (DEBUG_SERVICE) Slog.v( 10437 TAG, "Removed service that has no process: " + r); 10438 } 10439 } else { 10440 if (DEBUG_SERVICE) Slog.v( 10441 TAG, "Removed service that is not running: " + r); 10442 } 10443 10444 if (r.bindings.size() > 0) { 10445 r.bindings.clear(); 10446 } 10447 10448 if (r.restarter instanceof ServiceRestarter) { 10449 ((ServiceRestarter)r.restarter).setService(null); 10450 } 10451 } 10452 10453 ComponentName startServiceLocked(IApplicationThread caller, 10454 Intent service, String resolvedType, 10455 int callingPid, int callingUid) { 10456 synchronized(this) { 10457 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 10458 + " type=" + resolvedType + " args=" + service.getExtras()); 10459 10460 if (caller != null) { 10461 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10462 if (callerApp == null) { 10463 throw new SecurityException( 10464 "Unable to find app for caller " + caller 10465 + " (pid=" + Binder.getCallingPid() 10466 + ") when starting service " + service); 10467 } 10468 } 10469 10470 ServiceLookupResult res = 10471 retrieveServiceLocked(service, resolvedType, 10472 callingPid, callingUid); 10473 if (res == null) { 10474 return null; 10475 } 10476 if (res.record == null) { 10477 return new ComponentName("!", res.permission != null 10478 ? res.permission : "private to package"); 10479 } 10480 ServiceRecord r = res.record; 10481 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked( 10482 callingUid, r.packageName, service); 10483 if (unscheduleServiceRestartLocked(r)) { 10484 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 10485 } 10486 r.startRequested = true; 10487 r.callStart = false; 10488 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 10489 service, targetPermissionUid)); 10490 r.lastActivity = SystemClock.uptimeMillis(); 10491 synchronized (r.stats.getBatteryStats()) { 10492 r.stats.startRunningLocked(); 10493 } 10494 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 10495 return new ComponentName("!", "Service process is bad"); 10496 } 10497 return r.name; 10498 } 10499 } 10500 10501 public ComponentName startService(IApplicationThread caller, Intent service, 10502 String resolvedType) { 10503 // Refuse possible leaked file descriptors 10504 if (service != null && service.hasFileDescriptors() == true) { 10505 throw new IllegalArgumentException("File descriptors passed in Intent"); 10506 } 10507 10508 synchronized(this) { 10509 final int callingPid = Binder.getCallingPid(); 10510 final int callingUid = Binder.getCallingUid(); 10511 final long origId = Binder.clearCallingIdentity(); 10512 ComponentName res = startServiceLocked(caller, service, 10513 resolvedType, callingPid, callingUid); 10514 Binder.restoreCallingIdentity(origId); 10515 return res; 10516 } 10517 } 10518 10519 ComponentName startServiceInPackage(int uid, 10520 Intent service, String resolvedType) { 10521 synchronized(this) { 10522 final long origId = Binder.clearCallingIdentity(); 10523 ComponentName res = startServiceLocked(null, service, 10524 resolvedType, -1, uid); 10525 Binder.restoreCallingIdentity(origId); 10526 return res; 10527 } 10528 } 10529 10530 private void stopServiceLocked(ServiceRecord service) { 10531 synchronized (service.stats.getBatteryStats()) { 10532 service.stats.stopRunningLocked(); 10533 } 10534 service.startRequested = false; 10535 service.callStart = false; 10536 bringDownServiceLocked(service, false); 10537 } 10538 10539 public int stopService(IApplicationThread caller, Intent service, 10540 String resolvedType) { 10541 // Refuse possible leaked file descriptors 10542 if (service != null && service.hasFileDescriptors() == true) { 10543 throw new IllegalArgumentException("File descriptors passed in Intent"); 10544 } 10545 10546 synchronized(this) { 10547 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 10548 + " type=" + resolvedType); 10549 10550 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10551 if (caller != null && callerApp == null) { 10552 throw new SecurityException( 10553 "Unable to find app for caller " + caller 10554 + " (pid=" + Binder.getCallingPid() 10555 + ") when stopping service " + service); 10556 } 10557 10558 // If this service is active, make sure it is stopped. 10559 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10560 if (r != null) { 10561 if (r.record != null) { 10562 final long origId = Binder.clearCallingIdentity(); 10563 try { 10564 stopServiceLocked(r.record); 10565 } finally { 10566 Binder.restoreCallingIdentity(origId); 10567 } 10568 return 1; 10569 } 10570 return -1; 10571 } 10572 } 10573 10574 return 0; 10575 } 10576 10577 public IBinder peekService(Intent service, String resolvedType) { 10578 // Refuse possible leaked file descriptors 10579 if (service != null && service.hasFileDescriptors() == true) { 10580 throw new IllegalArgumentException("File descriptors passed in Intent"); 10581 } 10582 10583 IBinder ret = null; 10584 10585 synchronized(this) { 10586 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10587 10588 if (r != null) { 10589 // r.record is null if findServiceLocked() failed the caller permission check 10590 if (r.record == null) { 10591 throw new SecurityException( 10592 "Permission Denial: Accessing service " + r.record.name 10593 + " from pid=" + Binder.getCallingPid() 10594 + ", uid=" + Binder.getCallingUid() 10595 + " requires " + r.permission); 10596 } 10597 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 10598 if (ib != null) { 10599 ret = ib.binder; 10600 } 10601 } 10602 } 10603 10604 return ret; 10605 } 10606 10607 public boolean stopServiceToken(ComponentName className, IBinder token, 10608 int startId) { 10609 synchronized(this) { 10610 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 10611 + " " + token + " startId=" + startId); 10612 ServiceRecord r = findServiceLocked(className, token); 10613 if (r != null) { 10614 if (startId >= 0) { 10615 // Asked to only stop if done with all work. Note that 10616 // to avoid leaks, we will take this as dropping all 10617 // start items up to and including this one. 10618 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 10619 if (si != null) { 10620 while (r.deliveredStarts.size() > 0) { 10621 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 10622 cur.removeUriPermissionsLocked(); 10623 if (cur == si) { 10624 break; 10625 } 10626 } 10627 } 10628 10629 if (r.getLastStartId() != startId) { 10630 return false; 10631 } 10632 10633 if (r.deliveredStarts.size() > 0) { 10634 Slog.w(TAG, "stopServiceToken startId " + startId 10635 + " is last, but have " + r.deliveredStarts.size() 10636 + " remaining args"); 10637 } 10638 } 10639 10640 synchronized (r.stats.getBatteryStats()) { 10641 r.stats.stopRunningLocked(); 10642 r.startRequested = false; 10643 r.callStart = false; 10644 } 10645 final long origId = Binder.clearCallingIdentity(); 10646 bringDownServiceLocked(r, false); 10647 Binder.restoreCallingIdentity(origId); 10648 return true; 10649 } 10650 } 10651 return false; 10652 } 10653 10654 public void setServiceForeground(ComponentName className, IBinder token, 10655 int id, Notification notification, boolean removeNotification) { 10656 final long origId = Binder.clearCallingIdentity(); 10657 try { 10658 synchronized(this) { 10659 ServiceRecord r = findServiceLocked(className, token); 10660 if (r != null) { 10661 if (id != 0) { 10662 if (notification == null) { 10663 throw new IllegalArgumentException("null notification"); 10664 } 10665 if (r.foregroundId != id) { 10666 r.cancelNotification(); 10667 r.foregroundId = id; 10668 } 10669 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 10670 r.foregroundNoti = notification; 10671 r.isForeground = true; 10672 r.postNotification(); 10673 if (r.app != null) { 10674 updateServiceForegroundLocked(r.app, true); 10675 } 10676 } else { 10677 if (r.isForeground) { 10678 r.isForeground = false; 10679 if (r.app != null) { 10680 updateLruProcessLocked(r.app, false, true); 10681 updateServiceForegroundLocked(r.app, true); 10682 } 10683 } 10684 if (removeNotification) { 10685 r.cancelNotification(); 10686 r.foregroundId = 0; 10687 r.foregroundNoti = null; 10688 } 10689 } 10690 } 10691 } 10692 } finally { 10693 Binder.restoreCallingIdentity(origId); 10694 } 10695 } 10696 10697 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 10698 boolean anyForeground = false; 10699 for (ServiceRecord sr : proc.services) { 10700 if (sr.isForeground) { 10701 anyForeground = true; 10702 break; 10703 } 10704 } 10705 if (anyForeground != proc.foregroundServices) { 10706 proc.foregroundServices = anyForeground; 10707 if (oomAdj) { 10708 updateOomAdjLocked(); 10709 } 10710 } 10711 } 10712 10713 public int bindService(IApplicationThread caller, IBinder token, 10714 Intent service, String resolvedType, 10715 IServiceConnection connection, int flags) { 10716 // Refuse possible leaked file descriptors 10717 if (service != null && service.hasFileDescriptors() == true) { 10718 throw new IllegalArgumentException("File descriptors passed in Intent"); 10719 } 10720 10721 synchronized(this) { 10722 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 10723 + " type=" + resolvedType + " conn=" + connection.asBinder() 10724 + " flags=0x" + Integer.toHexString(flags)); 10725 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10726 if (callerApp == null) { 10727 throw new SecurityException( 10728 "Unable to find app for caller " + caller 10729 + " (pid=" + Binder.getCallingPid() 10730 + ") when binding service " + service); 10731 } 10732 10733 ActivityRecord activity = null; 10734 if (token != null) { 10735 activity = mMainStack.isInStackLocked(token); 10736 if (activity == null) { 10737 Slog.w(TAG, "Binding with unknown activity: " + token); 10738 return 0; 10739 } 10740 } 10741 10742 int clientLabel = 0; 10743 PendingIntent clientIntent = null; 10744 10745 if (callerApp.info.uid == Process.SYSTEM_UID) { 10746 // Hacky kind of thing -- allow system stuff to tell us 10747 // what they are, so we can report this elsewhere for 10748 // others to know why certain services are running. 10749 try { 10750 clientIntent = (PendingIntent)service.getParcelableExtra( 10751 Intent.EXTRA_CLIENT_INTENT); 10752 } catch (RuntimeException e) { 10753 } 10754 if (clientIntent != null) { 10755 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 10756 if (clientLabel != 0) { 10757 // There are no useful extras in the intent, trash them. 10758 // System code calling with this stuff just needs to know 10759 // this will happen. 10760 service = service.cloneFilter(); 10761 } 10762 } 10763 } 10764 10765 ServiceLookupResult res = 10766 retrieveServiceLocked(service, resolvedType, 10767 Binder.getCallingPid(), Binder.getCallingUid()); 10768 if (res == null) { 10769 return 0; 10770 } 10771 if (res.record == null) { 10772 return -1; 10773 } 10774 ServiceRecord s = res.record; 10775 10776 final long origId = Binder.clearCallingIdentity(); 10777 10778 if (unscheduleServiceRestartLocked(s)) { 10779 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 10780 + s); 10781 } 10782 10783 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 10784 ConnectionRecord c = new ConnectionRecord(b, activity, 10785 connection, flags, clientLabel, clientIntent); 10786 10787 IBinder binder = connection.asBinder(); 10788 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 10789 if (clist == null) { 10790 clist = new ArrayList<ConnectionRecord>(); 10791 s.connections.put(binder, clist); 10792 } 10793 clist.add(c); 10794 b.connections.add(c); 10795 if (activity != null) { 10796 if (activity.connections == null) { 10797 activity.connections = new HashSet<ConnectionRecord>(); 10798 } 10799 activity.connections.add(c); 10800 } 10801 b.client.connections.add(c); 10802 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 10803 b.client.hasAboveClient = true; 10804 } 10805 clist = mServiceConnections.get(binder); 10806 if (clist == null) { 10807 clist = new ArrayList<ConnectionRecord>(); 10808 mServiceConnections.put(binder, clist); 10809 } 10810 clist.add(c); 10811 10812 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 10813 s.lastActivity = SystemClock.uptimeMillis(); 10814 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 10815 return 0; 10816 } 10817 } 10818 10819 if (s.app != null) { 10820 // This could have made the service more important. 10821 updateOomAdjLocked(s.app); 10822 } 10823 10824 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 10825 + ": received=" + b.intent.received 10826 + " apps=" + b.intent.apps.size() 10827 + " doRebind=" + b.intent.doRebind); 10828 10829 if (s.app != null && b.intent.received) { 10830 // Service is already running, so we can immediately 10831 // publish the connection. 10832 try { 10833 c.conn.connected(s.name, b.intent.binder); 10834 } catch (Exception e) { 10835 Slog.w(TAG, "Failure sending service " + s.shortName 10836 + " to connection " + c.conn.asBinder() 10837 + " (in " + c.binding.client.processName + ")", e); 10838 } 10839 10840 // If this is the first app connected back to this binding, 10841 // and the service had previously asked to be told when 10842 // rebound, then do so. 10843 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 10844 requestServiceBindingLocked(s, b.intent, true); 10845 } 10846 } else if (!b.intent.requested) { 10847 requestServiceBindingLocked(s, b.intent, false); 10848 } 10849 10850 Binder.restoreCallingIdentity(origId); 10851 } 10852 10853 return 1; 10854 } 10855 10856 void removeConnectionLocked( 10857 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 10858 IBinder binder = c.conn.asBinder(); 10859 AppBindRecord b = c.binding; 10860 ServiceRecord s = b.service; 10861 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 10862 if (clist != null) { 10863 clist.remove(c); 10864 if (clist.size() == 0) { 10865 s.connections.remove(binder); 10866 } 10867 } 10868 b.connections.remove(c); 10869 if (c.activity != null && c.activity != skipAct) { 10870 if (c.activity.connections != null) { 10871 c.activity.connections.remove(c); 10872 } 10873 } 10874 if (b.client != skipApp) { 10875 b.client.connections.remove(c); 10876 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 10877 b.client.updateHasAboveClientLocked(); 10878 } 10879 } 10880 clist = mServiceConnections.get(binder); 10881 if (clist != null) { 10882 clist.remove(c); 10883 if (clist.size() == 0) { 10884 mServiceConnections.remove(binder); 10885 } 10886 } 10887 10888 if (b.connections.size() == 0) { 10889 b.intent.apps.remove(b.client); 10890 } 10891 10892 if (!c.serviceDead) { 10893 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 10894 + ": shouldUnbind=" + b.intent.hasBound); 10895 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 10896 && b.intent.hasBound) { 10897 try { 10898 bumpServiceExecutingLocked(s, "unbind"); 10899 updateOomAdjLocked(s.app); 10900 b.intent.hasBound = false; 10901 // Assume the client doesn't want to know about a rebind; 10902 // we will deal with that later if it asks for one. 10903 b.intent.doRebind = false; 10904 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 10905 } catch (Exception e) { 10906 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 10907 serviceDoneExecutingLocked(s, true); 10908 } 10909 } 10910 10911 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 10912 bringDownServiceLocked(s, false); 10913 } 10914 } 10915 } 10916 10917 public boolean unbindService(IServiceConnection connection) { 10918 synchronized (this) { 10919 IBinder binder = connection.asBinder(); 10920 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 10921 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 10922 if (clist == null) { 10923 Slog.w(TAG, "Unbind failed: could not find connection for " 10924 + connection.asBinder()); 10925 return false; 10926 } 10927 10928 final long origId = Binder.clearCallingIdentity(); 10929 10930 while (clist.size() > 0) { 10931 ConnectionRecord r = clist.get(0); 10932 removeConnectionLocked(r, null, null); 10933 10934 if (r.binding.service.app != null) { 10935 // This could have made the service less important. 10936 updateOomAdjLocked(r.binding.service.app); 10937 } 10938 } 10939 10940 Binder.restoreCallingIdentity(origId); 10941 } 10942 10943 return true; 10944 } 10945 10946 public void publishService(IBinder token, Intent intent, IBinder service) { 10947 // Refuse possible leaked file descriptors 10948 if (intent != null && intent.hasFileDescriptors() == true) { 10949 throw new IllegalArgumentException("File descriptors passed in Intent"); 10950 } 10951 10952 synchronized(this) { 10953 if (!(token instanceof ServiceRecord)) { 10954 throw new IllegalArgumentException("Invalid service token"); 10955 } 10956 ServiceRecord r = (ServiceRecord)token; 10957 10958 final long origId = Binder.clearCallingIdentity(); 10959 10960 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 10961 + " " + intent + ": " + service); 10962 if (r != null) { 10963 Intent.FilterComparison filter 10964 = new Intent.FilterComparison(intent); 10965 IntentBindRecord b = r.bindings.get(filter); 10966 if (b != null && !b.received) { 10967 b.binder = service; 10968 b.requested = true; 10969 b.received = true; 10970 if (r.connections.size() > 0) { 10971 Iterator<ArrayList<ConnectionRecord>> it 10972 = r.connections.values().iterator(); 10973 while (it.hasNext()) { 10974 ArrayList<ConnectionRecord> clist = it.next(); 10975 for (int i=0; i<clist.size(); i++) { 10976 ConnectionRecord c = clist.get(i); 10977 if (!filter.equals(c.binding.intent.intent)) { 10978 if (DEBUG_SERVICE) Slog.v( 10979 TAG, "Not publishing to: " + c); 10980 if (DEBUG_SERVICE) Slog.v( 10981 TAG, "Bound intent: " + c.binding.intent.intent); 10982 if (DEBUG_SERVICE) Slog.v( 10983 TAG, "Published intent: " + intent); 10984 continue; 10985 } 10986 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 10987 try { 10988 c.conn.connected(r.name, service); 10989 } catch (Exception e) { 10990 Slog.w(TAG, "Failure sending service " + r.name + 10991 " to connection " + c.conn.asBinder() + 10992 " (in " + c.binding.client.processName + ")", e); 10993 } 10994 } 10995 } 10996 } 10997 } 10998 10999 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11000 11001 Binder.restoreCallingIdentity(origId); 11002 } 11003 } 11004 } 11005 11006 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11007 // Refuse possible leaked file descriptors 11008 if (intent != null && intent.hasFileDescriptors() == true) { 11009 throw new IllegalArgumentException("File descriptors passed in Intent"); 11010 } 11011 11012 synchronized(this) { 11013 if (!(token instanceof ServiceRecord)) { 11014 throw new IllegalArgumentException("Invalid service token"); 11015 } 11016 ServiceRecord r = (ServiceRecord)token; 11017 11018 final long origId = Binder.clearCallingIdentity(); 11019 11020 if (r != null) { 11021 Intent.FilterComparison filter 11022 = new Intent.FilterComparison(intent); 11023 IntentBindRecord b = r.bindings.get(filter); 11024 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 11025 + " at " + b + ": apps=" 11026 + (b != null ? b.apps.size() : 0)); 11027 11028 boolean inStopping = mStoppingServices.contains(r); 11029 if (b != null) { 11030 if (b.apps.size() > 0 && !inStopping) { 11031 // Applications have already bound since the last 11032 // unbind, so just rebind right here. 11033 requestServiceBindingLocked(r, b, true); 11034 } else { 11035 // Note to tell the service the next time there is 11036 // a new client. 11037 b.doRebind = true; 11038 } 11039 } 11040 11041 serviceDoneExecutingLocked(r, inStopping); 11042 11043 Binder.restoreCallingIdentity(origId); 11044 } 11045 } 11046 } 11047 11048 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11049 synchronized(this) { 11050 if (!(token instanceof ServiceRecord)) { 11051 throw new IllegalArgumentException("Invalid service token"); 11052 } 11053 ServiceRecord r = (ServiceRecord)token; 11054 boolean inStopping = mStoppingServices.contains(token); 11055 if (r != null) { 11056 if (r != token) { 11057 Slog.w(TAG, "Done executing service " + r.name 11058 + " with incorrect token: given " + token 11059 + ", expected " + r); 11060 return; 11061 } 11062 11063 if (type == 1) { 11064 // This is a call from a service start... take care of 11065 // book-keeping. 11066 r.callStart = true; 11067 switch (res) { 11068 case Service.START_STICKY_COMPATIBILITY: 11069 case Service.START_STICKY: { 11070 // We are done with the associated start arguments. 11071 r.findDeliveredStart(startId, true); 11072 // Don't stop if killed. 11073 r.stopIfKilled = false; 11074 break; 11075 } 11076 case Service.START_NOT_STICKY: { 11077 // We are done with the associated start arguments. 11078 r.findDeliveredStart(startId, true); 11079 if (r.getLastStartId() == startId) { 11080 // There is no more work, and this service 11081 // doesn't want to hang around if killed. 11082 r.stopIfKilled = true; 11083 } 11084 break; 11085 } 11086 case Service.START_REDELIVER_INTENT: { 11087 // We'll keep this item until they explicitly 11088 // call stop for it, but keep track of the fact 11089 // that it was delivered. 11090 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11091 if (si != null) { 11092 si.deliveryCount = 0; 11093 si.doneExecutingCount++; 11094 // Don't stop if killed. 11095 r.stopIfKilled = true; 11096 } 11097 break; 11098 } 11099 case Service.START_TASK_REMOVED_COMPLETE: { 11100 // Special processing for onTaskRemoved(). Don't 11101 // impact normal onStartCommand() processing. 11102 r.findDeliveredStart(startId, true); 11103 break; 11104 } 11105 default: 11106 throw new IllegalArgumentException( 11107 "Unknown service start result: " + res); 11108 } 11109 if (res == Service.START_STICKY_COMPATIBILITY) { 11110 r.callStart = false; 11111 } 11112 } 11113 11114 final long origId = Binder.clearCallingIdentity(); 11115 serviceDoneExecutingLocked(r, inStopping); 11116 Binder.restoreCallingIdentity(origId); 11117 } else { 11118 Slog.w(TAG, "Done executing unknown service from pid " 11119 + Binder.getCallingPid()); 11120 } 11121 } 11122 } 11123 11124 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11125 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 11126 + ": nesting=" + r.executeNesting 11127 + ", inStopping=" + inStopping + ", app=" + r.app); 11128 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 11129 r.executeNesting--; 11130 if (r.executeNesting <= 0 && r.app != null) { 11131 if (DEBUG_SERVICE) Slog.v(TAG, 11132 "Nesting at 0 of " + r.shortName); 11133 r.app.executingServices.remove(r); 11134 if (r.app.executingServices.size() == 0) { 11135 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 11136 "No more executingServices of " + r.shortName); 11137 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11138 } 11139 if (inStopping) { 11140 if (DEBUG_SERVICE) Slog.v(TAG, 11141 "doneExecuting remove stopping " + r); 11142 mStoppingServices.remove(r); 11143 r.bindings.clear(); 11144 } 11145 updateOomAdjLocked(r.app); 11146 } 11147 } 11148 11149 void serviceTimeout(ProcessRecord proc) { 11150 String anrMessage = null; 11151 11152 synchronized(this) { 11153 if (proc.executingServices.size() == 0 || proc.thread == null) { 11154 return; 11155 } 11156 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11157 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11158 ServiceRecord timeout = null; 11159 long nextTime = 0; 11160 while (it.hasNext()) { 11161 ServiceRecord sr = it.next(); 11162 if (sr.executingStart < maxTime) { 11163 timeout = sr; 11164 break; 11165 } 11166 if (sr.executingStart > nextTime) { 11167 nextTime = sr.executingStart; 11168 } 11169 } 11170 if (timeout != null && mLruProcesses.contains(proc)) { 11171 Slog.w(TAG, "Timeout executing service: " + timeout); 11172 anrMessage = "Executing service " + timeout.shortName; 11173 } else { 11174 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11175 msg.obj = proc; 11176 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11177 } 11178 } 11179 11180 if (anrMessage != null) { 11181 appNotResponding(proc, null, null, anrMessage); 11182 } 11183 } 11184 11185 // ========================================================= 11186 // BACKUP AND RESTORE 11187 // ========================================================= 11188 11189 // Cause the target app to be launched if necessary and its backup agent 11190 // instantiated. The backup agent will invoke backupAgentCreated() on the 11191 // activity manager to announce its creation. 11192 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11193 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11194 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11195 11196 synchronized(this) { 11197 // !!! TODO: currently no check here that we're already bound 11198 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11199 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11200 synchronized (stats) { 11201 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11202 } 11203 11204 // Backup agent is now in use, its package can't be stopped. 11205 try { 11206 AppGlobals.getPackageManager().setPackageStoppedState( 11207 app.packageName, false); 11208 } catch (RemoteException e) { 11209 } catch (IllegalArgumentException e) { 11210 Slog.w(TAG, "Failed trying to unstop package " 11211 + app.packageName + ": " + e); 11212 } 11213 11214 BackupRecord r = new BackupRecord(ss, app, backupMode); 11215 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11216 ? new ComponentName(app.packageName, app.backupAgentName) 11217 : new ComponentName("android", "FullBackupAgent"); 11218 // startProcessLocked() returns existing proc's record if it's already running 11219 ProcessRecord proc = startProcessLocked(app.processName, app, 11220 false, 0, "backup", hostingName, false); 11221 if (proc == null) { 11222 Slog.e(TAG, "Unable to start backup agent process " + r); 11223 return false; 11224 } 11225 11226 r.app = proc; 11227 mBackupTarget = r; 11228 mBackupAppName = app.packageName; 11229 11230 // Try not to kill the process during backup 11231 updateOomAdjLocked(proc); 11232 11233 // If the process is already attached, schedule the creation of the backup agent now. 11234 // If it is not yet live, this will be done when it attaches to the framework. 11235 if (proc.thread != null) { 11236 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11237 try { 11238 proc.thread.scheduleCreateBackupAgent(app, 11239 compatibilityInfoForPackageLocked(app), backupMode); 11240 } catch (RemoteException e) { 11241 // Will time out on the backup manager side 11242 } 11243 } else { 11244 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11245 } 11246 // Invariants: at this point, the target app process exists and the application 11247 // is either already running or in the process of coming up. mBackupTarget and 11248 // mBackupAppName describe the app, so that when it binds back to the AM we 11249 // know that it's scheduled for a backup-agent operation. 11250 } 11251 11252 return true; 11253 } 11254 11255 // A backup agent has just come up 11256 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11257 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11258 + " = " + agent); 11259 11260 synchronized(this) { 11261 if (!agentPackageName.equals(mBackupAppName)) { 11262 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11263 return; 11264 } 11265 } 11266 11267 long oldIdent = Binder.clearCallingIdentity(); 11268 try { 11269 IBackupManager bm = IBackupManager.Stub.asInterface( 11270 ServiceManager.getService(Context.BACKUP_SERVICE)); 11271 bm.agentConnected(agentPackageName, agent); 11272 } catch (RemoteException e) { 11273 // can't happen; the backup manager service is local 11274 } catch (Exception e) { 11275 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11276 e.printStackTrace(); 11277 } finally { 11278 Binder.restoreCallingIdentity(oldIdent); 11279 } 11280 } 11281 11282 // done with this agent 11283 public void unbindBackupAgent(ApplicationInfo appInfo) { 11284 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11285 if (appInfo == null) { 11286 Slog.w(TAG, "unbind backup agent for null app"); 11287 return; 11288 } 11289 11290 synchronized(this) { 11291 if (mBackupAppName == null) { 11292 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11293 return; 11294 } 11295 11296 if (!mBackupAppName.equals(appInfo.packageName)) { 11297 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11298 return; 11299 } 11300 11301 ProcessRecord proc = mBackupTarget.app; 11302 mBackupTarget = null; 11303 mBackupAppName = null; 11304 11305 // Not backing this app up any more; reset its OOM adjustment 11306 updateOomAdjLocked(proc); 11307 11308 // If the app crashed during backup, 'thread' will be null here 11309 if (proc.thread != null) { 11310 try { 11311 proc.thread.scheduleDestroyBackupAgent(appInfo, 11312 compatibilityInfoForPackageLocked(appInfo)); 11313 } catch (Exception e) { 11314 Slog.e(TAG, "Exception when unbinding backup agent:"); 11315 e.printStackTrace(); 11316 } 11317 } 11318 } 11319 } 11320 // ========================================================= 11321 // BROADCASTS 11322 // ========================================================= 11323 11324 private final List getStickiesLocked(String action, IntentFilter filter, 11325 List cur) { 11326 final ContentResolver resolver = mContext.getContentResolver(); 11327 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11328 if (list == null) { 11329 return cur; 11330 } 11331 int N = list.size(); 11332 for (int i=0; i<N; i++) { 11333 Intent intent = list.get(i); 11334 if (filter.match(resolver, intent, true, TAG) >= 0) { 11335 if (cur == null) { 11336 cur = new ArrayList<Intent>(); 11337 } 11338 cur.add(intent); 11339 } 11340 } 11341 return cur; 11342 } 11343 11344 private final void scheduleBroadcastsLocked() { 11345 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current=" 11346 + mBroadcastsScheduled); 11347 11348 if (mBroadcastsScheduled) { 11349 return; 11350 } 11351 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11352 mBroadcastsScheduled = true; 11353 } 11354 11355 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11356 IIntentReceiver receiver, IntentFilter filter, String permission) { 11357 synchronized(this) { 11358 ProcessRecord callerApp = null; 11359 if (caller != null) { 11360 callerApp = getRecordForAppLocked(caller); 11361 if (callerApp == null) { 11362 throw new SecurityException( 11363 "Unable to find app for caller " + caller 11364 + " (pid=" + Binder.getCallingPid() 11365 + ") when registering receiver " + receiver); 11366 } 11367 if (callerApp.info.uid != Process.SYSTEM_UID && 11368 !callerApp.pkgList.contains(callerPackage)) { 11369 throw new SecurityException("Given caller package " + callerPackage 11370 + " is not running in process " + callerApp); 11371 } 11372 } else { 11373 callerPackage = null; 11374 } 11375 11376 List allSticky = null; 11377 11378 // Look for any matching sticky broadcasts... 11379 Iterator actions = filter.actionsIterator(); 11380 if (actions != null) { 11381 while (actions.hasNext()) { 11382 String action = (String)actions.next(); 11383 allSticky = getStickiesLocked(action, filter, allSticky); 11384 } 11385 } else { 11386 allSticky = getStickiesLocked(null, filter, allSticky); 11387 } 11388 11389 // The first sticky in the list is returned directly back to 11390 // the client. 11391 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11392 11393 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11394 + ": " + sticky); 11395 11396 if (receiver == null) { 11397 return sticky; 11398 } 11399 11400 ReceiverList rl 11401 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11402 if (rl == null) { 11403 rl = new ReceiverList(this, callerApp, 11404 Binder.getCallingPid(), 11405 Binder.getCallingUid(), receiver); 11406 if (rl.app != null) { 11407 rl.app.receivers.add(rl); 11408 } else { 11409 try { 11410 receiver.asBinder().linkToDeath(rl, 0); 11411 } catch (RemoteException e) { 11412 return sticky; 11413 } 11414 rl.linkedToDeath = true; 11415 } 11416 mRegisteredReceivers.put(receiver.asBinder(), rl); 11417 } 11418 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 11419 rl.add(bf); 11420 if (!bf.debugCheck()) { 11421 Slog.w(TAG, "==> For Dynamic broadast"); 11422 } 11423 mReceiverResolver.addFilter(bf); 11424 11425 // Enqueue broadcasts for all existing stickies that match 11426 // this filter. 11427 if (allSticky != null) { 11428 ArrayList receivers = new ArrayList(); 11429 receivers.add(bf); 11430 11431 int N = allSticky.size(); 11432 for (int i=0; i<N; i++) { 11433 Intent intent = (Intent)allSticky.get(i); 11434 BroadcastRecord r = new BroadcastRecord(intent, null, 11435 null, -1, -1, null, receivers, null, 0, null, null, 11436 false, true, true); 11437 if (mParallelBroadcasts.size() == 0) { 11438 scheduleBroadcastsLocked(); 11439 } 11440 mParallelBroadcasts.add(r); 11441 } 11442 } 11443 11444 return sticky; 11445 } 11446 } 11447 11448 public void unregisterReceiver(IIntentReceiver receiver) { 11449 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11450 11451 boolean doNext = false; 11452 11453 synchronized(this) { 11454 ReceiverList rl 11455 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11456 if (rl != null) { 11457 if (rl.curBroadcast != null) { 11458 BroadcastRecord r = rl.curBroadcast; 11459 doNext = finishReceiverLocked( 11460 receiver.asBinder(), r.resultCode, r.resultData, 11461 r.resultExtras, r.resultAbort, true); 11462 } 11463 11464 if (rl.app != null) { 11465 rl.app.receivers.remove(rl); 11466 } 11467 removeReceiverLocked(rl); 11468 if (rl.linkedToDeath) { 11469 rl.linkedToDeath = false; 11470 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11471 } 11472 } 11473 } 11474 11475 if (!doNext) { 11476 return; 11477 } 11478 11479 final long origId = Binder.clearCallingIdentity(); 11480 processNextBroadcast(false); 11481 trimApplications(); 11482 Binder.restoreCallingIdentity(origId); 11483 } 11484 11485 void removeReceiverLocked(ReceiverList rl) { 11486 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11487 int N = rl.size(); 11488 for (int i=0; i<N; i++) { 11489 mReceiverResolver.removeFilter(rl.get(i)); 11490 } 11491 } 11492 11493 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11494 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11495 ProcessRecord r = mLruProcesses.get(i); 11496 if (r.thread != null) { 11497 try { 11498 r.thread.dispatchPackageBroadcast(cmd, packages); 11499 } catch (RemoteException ex) { 11500 } 11501 } 11502 } 11503 } 11504 11505 private final int broadcastIntentLocked(ProcessRecord callerApp, 11506 String callerPackage, Intent intent, String resolvedType, 11507 IIntentReceiver resultTo, int resultCode, String resultData, 11508 Bundle map, String requiredPermission, 11509 boolean ordered, boolean sticky, int callingPid, int callingUid) { 11510 intent = new Intent(intent); 11511 11512 // By default broadcasts do not go to stopped apps. 11513 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11514 11515 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11516 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11517 + " ordered=" + ordered); 11518 if ((resultTo != null) && !ordered) { 11519 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11520 } 11521 11522 // Handle special intents: if this broadcast is from the package 11523 // manager about a package being removed, we need to remove all of 11524 // its activities from the history stack. 11525 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11526 intent.getAction()); 11527 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11528 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11529 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11530 || uidRemoved) { 11531 if (checkComponentPermission( 11532 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11533 callingPid, callingUid, -1, true) 11534 == PackageManager.PERMISSION_GRANTED) { 11535 if (uidRemoved) { 11536 final Bundle intentExtras = intent.getExtras(); 11537 final int uid = intentExtras != null 11538 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11539 if (uid >= 0) { 11540 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11541 synchronized (bs) { 11542 bs.removeUidStatsLocked(uid); 11543 } 11544 } 11545 } else { 11546 // If resources are unvailble just force stop all 11547 // those packages and flush the attribute cache as well. 11548 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11549 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11550 if (list != null && (list.length > 0)) { 11551 for (String pkg : list) { 11552 forceStopPackageLocked(pkg, -1, false, true, true, false); 11553 } 11554 sendPackageBroadcastLocked( 11555 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11556 } 11557 } else { 11558 Uri data = intent.getData(); 11559 String ssp; 11560 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11561 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11562 forceStopPackageLocked(ssp, 11563 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false); 11564 } 11565 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11566 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11567 new String[] {ssp}); 11568 } 11569 } 11570 } 11571 } 11572 } else { 11573 String msg = "Permission Denial: " + intent.getAction() 11574 + " broadcast from " + callerPackage + " (pid=" + callingPid 11575 + ", uid=" + callingUid + ")" 11576 + " requires " 11577 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11578 Slog.w(TAG, msg); 11579 throw new SecurityException(msg); 11580 } 11581 11582 // Special case for adding a package: by default turn on compatibility 11583 // mode. 11584 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11585 Uri data = intent.getData(); 11586 String ssp; 11587 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11588 mCompatModePackages.handlePackageAddedLocked(ssp, 11589 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11590 } 11591 } 11592 11593 /* 11594 * If this is the time zone changed action, queue up a message that will reset the timezone 11595 * of all currently running processes. This message will get queued up before the broadcast 11596 * happens. 11597 */ 11598 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11599 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11600 } 11601 11602 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11603 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11604 } 11605 11606 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11607 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11608 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11609 } 11610 11611 /* 11612 * Prevent non-system code (defined here to be non-persistent 11613 * processes) from sending protected broadcasts. 11614 */ 11615 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11616 || callingUid == Process.SHELL_UID || callingUid == 0) { 11617 // Always okay. 11618 } else if (callerApp == null || !callerApp.persistent) { 11619 try { 11620 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11621 intent.getAction())) { 11622 String msg = "Permission Denial: not allowed to send broadcast " 11623 + intent.getAction() + " from pid=" 11624 + callingPid + ", uid=" + callingUid; 11625 Slog.w(TAG, msg); 11626 throw new SecurityException(msg); 11627 } 11628 } catch (RemoteException e) { 11629 Slog.w(TAG, "Remote exception", e); 11630 return BROADCAST_SUCCESS; 11631 } 11632 } 11633 11634 // Add to the sticky list if requested. 11635 if (sticky) { 11636 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11637 callingPid, callingUid) 11638 != PackageManager.PERMISSION_GRANTED) { 11639 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11640 + callingPid + ", uid=" + callingUid 11641 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11642 Slog.w(TAG, msg); 11643 throw new SecurityException(msg); 11644 } 11645 if (requiredPermission != null) { 11646 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11647 + " and enforce permission " + requiredPermission); 11648 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11649 } 11650 if (intent.getComponent() != null) { 11651 throw new SecurityException( 11652 "Sticky broadcasts can't target a specific component"); 11653 } 11654 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11655 if (list == null) { 11656 list = new ArrayList<Intent>(); 11657 mStickyBroadcasts.put(intent.getAction(), list); 11658 } 11659 int N = list.size(); 11660 int i; 11661 for (i=0; i<N; i++) { 11662 if (intent.filterEquals(list.get(i))) { 11663 // This sticky already exists, replace it. 11664 list.set(i, new Intent(intent)); 11665 break; 11666 } 11667 } 11668 if (i >= N) { 11669 list.add(new Intent(intent)); 11670 } 11671 } 11672 11673 // Figure out who all will receive this broadcast. 11674 List receivers = null; 11675 List<BroadcastFilter> registeredReceivers = null; 11676 try { 11677 if (intent.getComponent() != null) { 11678 // Broadcast is going to one specific receiver class... 11679 ActivityInfo ai = AppGlobals.getPackageManager(). 11680 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 11681 if (ai != null) { 11682 receivers = new ArrayList(); 11683 ResolveInfo ri = new ResolveInfo(); 11684 ri.activityInfo = ai; 11685 receivers.add(ri); 11686 } 11687 } else { 11688 // Need to resolve the intent to interested receivers... 11689 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11690 == 0) { 11691 receivers = 11692 AppGlobals.getPackageManager().queryIntentReceivers( 11693 intent, resolvedType, STOCK_PM_FLAGS); 11694 } 11695 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 11696 } 11697 } catch (RemoteException ex) { 11698 // pm is in same process, this will never happen. 11699 } 11700 11701 final boolean replacePending = 11702 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11703 11704 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11705 + " replacePending=" + replacePending); 11706 11707 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11708 if (!ordered && NR > 0) { 11709 // If we are not serializing this broadcast, then send the 11710 // registered receivers separately so they don't wait for the 11711 // components to be launched. 11712 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11713 callerPackage, callingPid, callingUid, requiredPermission, 11714 registeredReceivers, resultTo, resultCode, resultData, map, 11715 ordered, sticky, false); 11716 if (DEBUG_BROADCAST) Slog.v( 11717 TAG, "Enqueueing parallel broadcast " + r 11718 + ": prev had " + mParallelBroadcasts.size()); 11719 boolean replaced = false; 11720 if (replacePending) { 11721 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 11722 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { 11723 if (DEBUG_BROADCAST) Slog.v(TAG, 11724 "***** DROPPING PARALLEL: " + intent); 11725 mParallelBroadcasts.set(i, r); 11726 replaced = true; 11727 break; 11728 } 11729 } 11730 } 11731 if (!replaced) { 11732 mParallelBroadcasts.add(r); 11733 scheduleBroadcastsLocked(); 11734 } 11735 registeredReceivers = null; 11736 NR = 0; 11737 } 11738 11739 // Merge into one list. 11740 int ir = 0; 11741 if (receivers != null) { 11742 // A special case for PACKAGE_ADDED: do not allow the package 11743 // being added to see this broadcast. This prevents them from 11744 // using this as a back door to get run as soon as they are 11745 // installed. Maybe in the future we want to have a special install 11746 // broadcast or such for apps, but we'd like to deliberately make 11747 // this decision. 11748 String skipPackages[] = null; 11749 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11750 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11751 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11752 Uri data = intent.getData(); 11753 if (data != null) { 11754 String pkgName = data.getSchemeSpecificPart(); 11755 if (pkgName != null) { 11756 skipPackages = new String[] { pkgName }; 11757 } 11758 } 11759 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11760 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11761 } 11762 if (skipPackages != null && (skipPackages.length > 0)) { 11763 for (String skipPackage : skipPackages) { 11764 if (skipPackage != null) { 11765 int NT = receivers.size(); 11766 for (int it=0; it<NT; it++) { 11767 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11768 if (curt.activityInfo.packageName.equals(skipPackage)) { 11769 receivers.remove(it); 11770 it--; 11771 NT--; 11772 } 11773 } 11774 } 11775 } 11776 } 11777 11778 int NT = receivers != null ? receivers.size() : 0; 11779 int it = 0; 11780 ResolveInfo curt = null; 11781 BroadcastFilter curr = null; 11782 while (it < NT && ir < NR) { 11783 if (curt == null) { 11784 curt = (ResolveInfo)receivers.get(it); 11785 } 11786 if (curr == null) { 11787 curr = registeredReceivers.get(ir); 11788 } 11789 if (curr.getPriority() >= curt.priority) { 11790 // Insert this broadcast record into the final list. 11791 receivers.add(it, curr); 11792 ir++; 11793 curr = null; 11794 it++; 11795 NT++; 11796 } else { 11797 // Skip to the next ResolveInfo in the final list. 11798 it++; 11799 curt = null; 11800 } 11801 } 11802 } 11803 while (ir < NR) { 11804 if (receivers == null) { 11805 receivers = new ArrayList(); 11806 } 11807 receivers.add(registeredReceivers.get(ir)); 11808 ir++; 11809 } 11810 11811 if ((receivers != null && receivers.size() > 0) 11812 || resultTo != null) { 11813 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11814 callerPackage, callingPid, callingUid, requiredPermission, 11815 receivers, resultTo, resultCode, resultData, map, ordered, 11816 sticky, false); 11817 if (DEBUG_BROADCAST) Slog.v( 11818 TAG, "Enqueueing ordered broadcast " + r 11819 + ": prev had " + mOrderedBroadcasts.size()); 11820 if (DEBUG_BROADCAST) { 11821 int seq = r.intent.getIntExtra("seq", -1); 11822 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11823 } 11824 boolean replaced = false; 11825 if (replacePending) { 11826 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) { 11827 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { 11828 if (DEBUG_BROADCAST) Slog.v(TAG, 11829 "***** DROPPING ORDERED: " + intent); 11830 mOrderedBroadcasts.set(i, r); 11831 replaced = true; 11832 break; 11833 } 11834 } 11835 } 11836 if (!replaced) { 11837 mOrderedBroadcasts.add(r); 11838 scheduleBroadcastsLocked(); 11839 } 11840 } 11841 11842 return BROADCAST_SUCCESS; 11843 } 11844 11845 final Intent verifyBroadcastLocked(Intent intent) { 11846 // Refuse possible leaked file descriptors 11847 if (intent != null && intent.hasFileDescriptors() == true) { 11848 throw new IllegalArgumentException("File descriptors passed in Intent"); 11849 } 11850 11851 int flags = intent.getFlags(); 11852 11853 if (!mProcessesReady) { 11854 // if the caller really truly claims to know what they're doing, go 11855 // ahead and allow the broadcast without launching any receivers 11856 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11857 intent = new Intent(intent); 11858 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11859 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11860 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11861 + " before boot completion"); 11862 throw new IllegalStateException("Cannot broadcast before boot completed"); 11863 } 11864 } 11865 11866 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11867 throw new IllegalArgumentException( 11868 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11869 } 11870 11871 return intent; 11872 } 11873 11874 public final int broadcastIntent(IApplicationThread caller, 11875 Intent intent, String resolvedType, IIntentReceiver resultTo, 11876 int resultCode, String resultData, Bundle map, 11877 String requiredPermission, boolean serialized, boolean sticky) { 11878 synchronized(this) { 11879 intent = verifyBroadcastLocked(intent); 11880 11881 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11882 final int callingPid = Binder.getCallingPid(); 11883 final int callingUid = Binder.getCallingUid(); 11884 final long origId = Binder.clearCallingIdentity(); 11885 int res = broadcastIntentLocked(callerApp, 11886 callerApp != null ? callerApp.info.packageName : null, 11887 intent, resolvedType, resultTo, 11888 resultCode, resultData, map, requiredPermission, serialized, 11889 sticky, callingPid, callingUid); 11890 Binder.restoreCallingIdentity(origId); 11891 return res; 11892 } 11893 } 11894 11895 int broadcastIntentInPackage(String packageName, int uid, 11896 Intent intent, String resolvedType, IIntentReceiver resultTo, 11897 int resultCode, String resultData, Bundle map, 11898 String requiredPermission, boolean serialized, boolean sticky) { 11899 synchronized(this) { 11900 intent = verifyBroadcastLocked(intent); 11901 11902 final long origId = Binder.clearCallingIdentity(); 11903 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11904 resultTo, resultCode, resultData, map, requiredPermission, 11905 serialized, sticky, -1, uid); 11906 Binder.restoreCallingIdentity(origId); 11907 return res; 11908 } 11909 } 11910 11911 public final void unbroadcastIntent(IApplicationThread caller, 11912 Intent intent) { 11913 // Refuse possible leaked file descriptors 11914 if (intent != null && intent.hasFileDescriptors() == true) { 11915 throw new IllegalArgumentException("File descriptors passed in Intent"); 11916 } 11917 11918 synchronized(this) { 11919 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11920 != PackageManager.PERMISSION_GRANTED) { 11921 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11922 + Binder.getCallingPid() 11923 + ", uid=" + Binder.getCallingUid() 11924 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11925 Slog.w(TAG, msg); 11926 throw new SecurityException(msg); 11927 } 11928 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11929 if (list != null) { 11930 int N = list.size(); 11931 int i; 11932 for (i=0; i<N; i++) { 11933 if (intent.filterEquals(list.get(i))) { 11934 list.remove(i); 11935 break; 11936 } 11937 } 11938 } 11939 } 11940 } 11941 11942 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11943 String resultData, Bundle resultExtras, boolean resultAbort, 11944 boolean explicit) { 11945 if (mOrderedBroadcasts.size() == 0) { 11946 if (explicit) { 11947 Slog.w(TAG, "finishReceiver called but no pending broadcasts"); 11948 } 11949 return false; 11950 } 11951 BroadcastRecord r = mOrderedBroadcasts.get(0); 11952 if (r.receiver == null) { 11953 if (explicit) { 11954 Slog.w(TAG, "finishReceiver called but none active"); 11955 } 11956 return false; 11957 } 11958 if (r.receiver != receiver) { 11959 Slog.w(TAG, "finishReceiver called but active receiver is different"); 11960 return false; 11961 } 11962 int state = r.state; 11963 r.state = BroadcastRecord.IDLE; 11964 if (state == BroadcastRecord.IDLE) { 11965 if (explicit) { 11966 Slog.w(TAG, "finishReceiver called but state is IDLE"); 11967 } 11968 } 11969 r.receiver = null; 11970 r.intent.setComponent(null); 11971 if (r.curApp != null) { 11972 r.curApp.curReceiver = null; 11973 } 11974 if (r.curFilter != null) { 11975 r.curFilter.receiverList.curBroadcast = null; 11976 } 11977 r.curFilter = null; 11978 r.curApp = null; 11979 r.curComponent = null; 11980 r.curReceiver = null; 11981 mPendingBroadcast = null; 11982 11983 r.resultCode = resultCode; 11984 r.resultData = resultData; 11985 r.resultExtras = resultExtras; 11986 r.resultAbort = resultAbort; 11987 11988 // We will process the next receiver right now if this is finishing 11989 // an app receiver (which is always asynchronous) or after we have 11990 // come back from calling a receiver. 11991 return state == BroadcastRecord.APP_RECEIVE 11992 || state == BroadcastRecord.CALL_DONE_RECEIVE; 11993 } 11994 11995 public void finishReceiver(IBinder who, int resultCode, String resultData, 11996 Bundle resultExtras, boolean resultAbort) { 11997 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11998 11999 // Refuse possible leaked file descriptors 12000 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12001 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12002 } 12003 12004 boolean doNext; 12005 12006 final long origId = Binder.clearCallingIdentity(); 12007 12008 synchronized(this) { 12009 doNext = finishReceiverLocked( 12010 who, resultCode, resultData, resultExtras, resultAbort, true); 12011 } 12012 12013 if (doNext) { 12014 processNextBroadcast(false); 12015 } 12016 trimApplications(); 12017 12018 Binder.restoreCallingIdentity(origId); 12019 } 12020 12021 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) { 12022 if (r.nextReceiver > 0) { 12023 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12024 if (curReceiver instanceof BroadcastFilter) { 12025 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12026 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, 12027 System.identityHashCode(r), 12028 r.intent.getAction(), 12029 r.nextReceiver - 1, 12030 System.identityHashCode(bf)); 12031 } else { 12032 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12033 System.identityHashCode(r), 12034 r.intent.getAction(), 12035 r.nextReceiver - 1, 12036 ((ResolveInfo)curReceiver).toString()); 12037 } 12038 } else { 12039 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: " 12040 + r); 12041 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12042 System.identityHashCode(r), 12043 r.intent.getAction(), 12044 r.nextReceiver, 12045 "NONE"); 12046 } 12047 } 12048 12049 private final void setBroadcastTimeoutLocked(long timeoutTime) { 12050 if (! mPendingBroadcastTimeoutMessage) { 12051 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12052 mHandler.sendMessageAtTime(msg, timeoutTime); 12053 mPendingBroadcastTimeoutMessage = true; 12054 } 12055 } 12056 12057 private final void cancelBroadcastTimeoutLocked() { 12058 if (mPendingBroadcastTimeoutMessage) { 12059 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12060 mPendingBroadcastTimeoutMessage = false; 12061 } 12062 } 12063 12064 private final void broadcastTimeoutLocked(boolean fromMsg) { 12065 if (fromMsg) { 12066 mPendingBroadcastTimeoutMessage = false; 12067 } 12068 12069 if (mOrderedBroadcasts.size() == 0) { 12070 return; 12071 } 12072 12073 long now = SystemClock.uptimeMillis(); 12074 BroadcastRecord r = mOrderedBroadcasts.get(0); 12075 if (fromMsg) { 12076 if (mDidDexOpt) { 12077 // Delay timeouts until dexopt finishes. 12078 mDidDexOpt = false; 12079 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT; 12080 setBroadcastTimeoutLocked(timeoutTime); 12081 return; 12082 } 12083 if (! mProcessesReady) { 12084 // Only process broadcast timeouts if the system is ready. That way 12085 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended 12086 // to do heavy lifting for system up. 12087 return; 12088 } 12089 12090 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT; 12091 if (timeoutTime > now) { 12092 // We can observe premature timeouts because we do not cancel and reset the 12093 // broadcast timeout message after each receiver finishes. Instead, we set up 12094 // an initial timeout then kick it down the road a little further as needed 12095 // when it expires. 12096 if (DEBUG_BROADCAST) Slog.v(TAG, 12097 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12098 + timeoutTime); 12099 setBroadcastTimeoutLocked(timeoutTime); 12100 return; 12101 } 12102 } 12103 12104 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver 12105 + ", started " + (now - r.receiverTime) + "ms ago"); 12106 r.receiverTime = now; 12107 r.anrCount++; 12108 12109 // Current receiver has passed its expiration date. 12110 if (r.nextReceiver <= 0) { 12111 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12112 return; 12113 } 12114 12115 ProcessRecord app = null; 12116 String anrMessage = null; 12117 12118 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12119 Slog.w(TAG, "Receiver during timeout: " + curReceiver); 12120 logBroadcastReceiverDiscardLocked(r); 12121 if (curReceiver instanceof BroadcastFilter) { 12122 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12123 if (bf.receiverList.pid != 0 12124 && bf.receiverList.pid != MY_PID) { 12125 synchronized (this.mPidsSelfLocked) { 12126 app = this.mPidsSelfLocked.get( 12127 bf.receiverList.pid); 12128 } 12129 } 12130 } else { 12131 app = r.curApp; 12132 } 12133 12134 if (app != null) { 12135 anrMessage = "Broadcast of " + r.intent.toString(); 12136 } 12137 12138 if (mPendingBroadcast == r) { 12139 mPendingBroadcast = null; 12140 } 12141 12142 // Move on to the next receiver. 12143 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12144 r.resultExtras, r.resultAbort, true); 12145 scheduleBroadcastsLocked(); 12146 12147 if (anrMessage != null) { 12148 // Post the ANR to the handler since we do not want to process ANRs while 12149 // potentially holding our lock. 12150 mHandler.post(new AppNotResponding(app, anrMessage)); 12151 } 12152 } 12153 12154 private final void processCurBroadcastLocked(BroadcastRecord r, 12155 ProcessRecord app) throws RemoteException { 12156 if (DEBUG_BROADCAST) Slog.v(TAG, 12157 "Process cur broadcast " + r + " for app " + app); 12158 if (app.thread == null) { 12159 throw new RemoteException(); 12160 } 12161 r.receiver = app.thread.asBinder(); 12162 r.curApp = app; 12163 app.curReceiver = r; 12164 updateLruProcessLocked(app, true, true); 12165 12166 // Tell the application to launch this receiver. 12167 r.intent.setComponent(r.curComponent); 12168 12169 boolean started = false; 12170 try { 12171 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, 12172 "Delivering to component " + r.curComponent 12173 + ": " + r); 12174 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12175 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12176 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo), 12177 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12178 if (DEBUG_BROADCAST) Slog.v(TAG, 12179 "Process cur broadcast " + r + " DELIVERED for app " + app); 12180 started = true; 12181 } finally { 12182 if (!started) { 12183 if (DEBUG_BROADCAST) Slog.v(TAG, 12184 "Process cur broadcast " + r + ": NOT STARTED!"); 12185 r.receiver = null; 12186 r.curApp = null; 12187 app.curReceiver = null; 12188 } 12189 } 12190 12191 } 12192 12193 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, 12194 Intent intent, int resultCode, String data, Bundle extras, 12195 boolean ordered, boolean sticky) throws RemoteException { 12196 // Send the intent to the receiver asynchronously using one-way binder calls. 12197 if (app != null && app.thread != null) { 12198 // If we have an app thread, do the call through that so it is 12199 // correctly ordered with other one-way calls. 12200 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12201 data, extras, ordered, sticky); 12202 } else { 12203 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12204 } 12205 } 12206 12207 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r, 12208 BroadcastFilter filter, boolean ordered) { 12209 boolean skip = false; 12210 if (filter.requiredPermission != null) { 12211 int perm = checkComponentPermission(filter.requiredPermission, 12212 r.callingPid, r.callingUid, -1, true); 12213 if (perm != PackageManager.PERMISSION_GRANTED) { 12214 Slog.w(TAG, "Permission Denial: broadcasting " 12215 + r.intent.toString() 12216 + " from " + r.callerPackage + " (pid=" 12217 + r.callingPid + ", uid=" + r.callingUid + ")" 12218 + " requires " + filter.requiredPermission 12219 + " due to registered receiver " + filter); 12220 skip = true; 12221 } 12222 } 12223 if (r.requiredPermission != null) { 12224 int perm = checkComponentPermission(r.requiredPermission, 12225 filter.receiverList.pid, filter.receiverList.uid, -1, true); 12226 if (perm != PackageManager.PERMISSION_GRANTED) { 12227 Slog.w(TAG, "Permission Denial: receiving " 12228 + r.intent.toString() 12229 + " to " + filter.receiverList.app 12230 + " (pid=" + filter.receiverList.pid 12231 + ", uid=" + filter.receiverList.uid + ")" 12232 + " requires " + r.requiredPermission 12233 + " due to sender " + r.callerPackage 12234 + " (uid " + r.callingUid + ")"); 12235 skip = true; 12236 } 12237 } 12238 12239 if (!skip) { 12240 // If this is not being sent as an ordered broadcast, then we 12241 // don't want to touch the fields that keep track of the current 12242 // state of ordered broadcasts. 12243 if (ordered) { 12244 r.receiver = filter.receiverList.receiver.asBinder(); 12245 r.curFilter = filter; 12246 filter.receiverList.curBroadcast = r; 12247 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12248 if (filter.receiverList.app != null) { 12249 // Bump hosting application to no longer be in background 12250 // scheduling class. Note that we can't do that if there 12251 // isn't an app... but we can only be in that case for 12252 // things that directly call the IActivityManager API, which 12253 // are already core system stuff so don't matter for this. 12254 r.curApp = filter.receiverList.app; 12255 filter.receiverList.app.curReceiver = r; 12256 updateOomAdjLocked(); 12257 } 12258 } 12259 try { 12260 if (DEBUG_BROADCAST_LIGHT) { 12261 int seq = r.intent.getIntExtra("seq", -1); 12262 Slog.i(TAG, "Delivering to " + filter 12263 + " (seq=" + seq + "): " + r); 12264 } 12265 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, 12266 new Intent(r.intent), r.resultCode, 12267 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 12268 if (ordered) { 12269 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12270 } 12271 } catch (RemoteException e) { 12272 Slog.w(TAG, "Failure sending broadcast " + r.intent, e); 12273 if (ordered) { 12274 r.receiver = null; 12275 r.curFilter = null; 12276 filter.receiverList.curBroadcast = null; 12277 if (filter.receiverList.app != null) { 12278 filter.receiverList.app.curReceiver = null; 12279 } 12280 } 12281 } 12282 } 12283 } 12284 12285 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 12286 if (r.callingUid < 0) { 12287 // This was from a registerReceiver() call; ignore it. 12288 return; 12289 } 12290 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 12291 MAX_BROADCAST_HISTORY-1); 12292 r.finishTime = SystemClock.uptimeMillis(); 12293 mBroadcastHistory[0] = r; 12294 } 12295 12296 private final void processNextBroadcast(boolean fromMsg) { 12297 synchronized(this) { 12298 BroadcastRecord r; 12299 12300 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: " 12301 + mParallelBroadcasts.size() + " broadcasts, " 12302 + mOrderedBroadcasts.size() + " ordered broadcasts"); 12303 12304 updateCpuStats(); 12305 12306 if (fromMsg) { 12307 mBroadcastsScheduled = false; 12308 } 12309 12310 // First, deliver any non-serialized broadcasts right away. 12311 while (mParallelBroadcasts.size() > 0) { 12312 r = mParallelBroadcasts.remove(0); 12313 r.dispatchTime = SystemClock.uptimeMillis(); 12314 r.dispatchClockTime = System.currentTimeMillis(); 12315 final int N = r.receivers.size(); 12316 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast " 12317 + r); 12318 for (int i=0; i<N; i++) { 12319 Object target = r.receivers.get(i); 12320 if (DEBUG_BROADCAST) Slog.v(TAG, 12321 "Delivering non-ordered to registered " 12322 + target + ": " + r); 12323 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false); 12324 } 12325 addBroadcastToHistoryLocked(r); 12326 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast " 12327 + r); 12328 } 12329 12330 // Now take care of the next serialized one... 12331 12332 // If we are waiting for a process to come up to handle the next 12333 // broadcast, then do nothing at this point. Just in case, we 12334 // check that the process we're waiting for still exists. 12335 if (mPendingBroadcast != null) { 12336 if (DEBUG_BROADCAST_LIGHT) { 12337 Slog.v(TAG, "processNextBroadcast: waiting for " 12338 + mPendingBroadcast.curApp); 12339 } 12340 12341 boolean isDead; 12342 synchronized (mPidsSelfLocked) { 12343 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12344 } 12345 if (!isDead) { 12346 // It's still alive, so keep waiting 12347 return; 12348 } else { 12349 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp 12350 + " died before responding to broadcast"); 12351 mPendingBroadcast.state = BroadcastRecord.IDLE; 12352 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 12353 mPendingBroadcast = null; 12354 } 12355 } 12356 12357 boolean looped = false; 12358 12359 do { 12360 if (mOrderedBroadcasts.size() == 0) { 12361 // No more broadcasts pending, so all done! 12362 scheduleAppGcsLocked(); 12363 if (looped) { 12364 // If we had finished the last ordered broadcast, then 12365 // make sure all processes have correct oom and sched 12366 // adjustments. 12367 updateOomAdjLocked(); 12368 } 12369 return; 12370 } 12371 r = mOrderedBroadcasts.get(0); 12372 boolean forceReceive = false; 12373 12374 // Ensure that even if something goes awry with the timeout 12375 // detection, we catch "hung" broadcasts here, discard them, 12376 // and continue to make progress. 12377 // 12378 // This is only done if the system is ready so that PRE_BOOT_COMPLETED 12379 // receivers don't get executed with timeouts. They're intended for 12380 // one time heavy lifting after system upgrades and can take 12381 // significant amounts of time. 12382 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12383 if (mProcessesReady && r.dispatchTime > 0) { 12384 long now = SystemClock.uptimeMillis(); 12385 if ((numReceivers > 0) && 12386 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12387 Slog.w(TAG, "Hung broadcast discarded after timeout failure:" 12388 + " now=" + now 12389 + " dispatchTime=" + r.dispatchTime 12390 + " startTime=" + r.receiverTime 12391 + " intent=" + r.intent 12392 + " numReceivers=" + numReceivers 12393 + " nextReceiver=" + r.nextReceiver 12394 + " state=" + r.state); 12395 broadcastTimeoutLocked(false); // forcibly finish this broadcast 12396 forceReceive = true; 12397 r.state = BroadcastRecord.IDLE; 12398 } 12399 } 12400 12401 if (r.state != BroadcastRecord.IDLE) { 12402 if (DEBUG_BROADCAST) Slog.d(TAG, 12403 "processNextBroadcast() called when not idle (state=" 12404 + r.state + ")"); 12405 return; 12406 } 12407 12408 if (r.receivers == null || r.nextReceiver >= numReceivers 12409 || r.resultAbort || forceReceive) { 12410 // No more receivers for this broadcast! Send the final 12411 // result if requested... 12412 if (r.resultTo != null) { 12413 try { 12414 if (DEBUG_BROADCAST) { 12415 int seq = r.intent.getIntExtra("seq", -1); 12416 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction() 12417 + " seq=" + seq + " app=" + r.callerApp); 12418 } 12419 performReceiveLocked(r.callerApp, r.resultTo, 12420 new Intent(r.intent), r.resultCode, 12421 r.resultData, r.resultExtras, false, false); 12422 // Set this to null so that the reference 12423 // (local and remote) isnt kept in the mBroadcastHistory. 12424 r.resultTo = null; 12425 } catch (RemoteException e) { 12426 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12427 } 12428 } 12429 12430 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12431 cancelBroadcastTimeoutLocked(); 12432 12433 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast " 12434 + r); 12435 12436 // ... and on to the next... 12437 addBroadcastToHistoryLocked(r); 12438 mOrderedBroadcasts.remove(0); 12439 r = null; 12440 looped = true; 12441 continue; 12442 } 12443 } while (r == null); 12444 12445 // Get the next receiver... 12446 int recIdx = r.nextReceiver++; 12447 12448 // Keep track of when this receiver started, and make sure there 12449 // is a timeout message pending to kill it if need be. 12450 r.receiverTime = SystemClock.uptimeMillis(); 12451 if (recIdx == 0) { 12452 r.dispatchTime = r.receiverTime; 12453 r.dispatchClockTime = System.currentTimeMillis(); 12454 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast " 12455 + r); 12456 } 12457 if (! mPendingBroadcastTimeoutMessage) { 12458 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT; 12459 if (DEBUG_BROADCAST) Slog.v(TAG, 12460 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime); 12461 setBroadcastTimeoutLocked(timeoutTime); 12462 } 12463 12464 Object nextReceiver = r.receivers.get(recIdx); 12465 if (nextReceiver instanceof BroadcastFilter) { 12466 // Simple case: this is a registered receiver who gets 12467 // a direct call. 12468 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 12469 if (DEBUG_BROADCAST) Slog.v(TAG, 12470 "Delivering ordered to registered " 12471 + filter + ": " + r); 12472 deliverToRegisteredReceiverLocked(r, filter, r.ordered); 12473 if (r.receiver == null || !r.ordered) { 12474 // The receiver has already finished, so schedule to 12475 // process the next one. 12476 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered=" 12477 + r.ordered + " receiver=" + r.receiver); 12478 r.state = BroadcastRecord.IDLE; 12479 scheduleBroadcastsLocked(); 12480 } 12481 return; 12482 } 12483 12484 // Hard case: need to instantiate the receiver, possibly 12485 // starting its application process to host it. 12486 12487 ResolveInfo info = 12488 (ResolveInfo)nextReceiver; 12489 12490 boolean skip = false; 12491 int perm = checkComponentPermission(info.activityInfo.permission, 12492 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid, 12493 info.activityInfo.exported); 12494 if (perm != PackageManager.PERMISSION_GRANTED) { 12495 if (!info.activityInfo.exported) { 12496 Slog.w(TAG, "Permission Denial: broadcasting " 12497 + r.intent.toString() 12498 + " from " + r.callerPackage + " (pid=" + r.callingPid 12499 + ", uid=" + r.callingUid + ")" 12500 + " is not exported from uid " + info.activityInfo.applicationInfo.uid 12501 + " due to receiver " + info.activityInfo.packageName 12502 + "/" + info.activityInfo.name); 12503 } else { 12504 Slog.w(TAG, "Permission Denial: broadcasting " 12505 + r.intent.toString() 12506 + " from " + r.callerPackage + " (pid=" + r.callingPid 12507 + ", uid=" + r.callingUid + ")" 12508 + " requires " + info.activityInfo.permission 12509 + " due to receiver " + info.activityInfo.packageName 12510 + "/" + info.activityInfo.name); 12511 } 12512 skip = true; 12513 } 12514 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && 12515 r.requiredPermission != null) { 12516 try { 12517 perm = AppGlobals.getPackageManager(). 12518 checkPermission(r.requiredPermission, 12519 info.activityInfo.applicationInfo.packageName); 12520 } catch (RemoteException e) { 12521 perm = PackageManager.PERMISSION_DENIED; 12522 } 12523 if (perm != PackageManager.PERMISSION_GRANTED) { 12524 Slog.w(TAG, "Permission Denial: receiving " 12525 + r.intent + " to " 12526 + info.activityInfo.applicationInfo.packageName 12527 + " requires " + r.requiredPermission 12528 + " due to sender " + r.callerPackage 12529 + " (uid " + r.callingUid + ")"); 12530 skip = true; 12531 } 12532 } 12533 if (r.curApp != null && r.curApp.crashing) { 12534 // If the target process is crashing, just skip it. 12535 if (DEBUG_BROADCAST) Slog.v(TAG, 12536 "Skipping deliver ordered " + r + " to " + r.curApp 12537 + ": process crashing"); 12538 skip = true; 12539 } 12540 12541 if (skip) { 12542 if (DEBUG_BROADCAST) Slog.v(TAG, 12543 "Skipping delivery of ordered " + r + " for whatever reason"); 12544 r.receiver = null; 12545 r.curFilter = null; 12546 r.state = BroadcastRecord.IDLE; 12547 scheduleBroadcastsLocked(); 12548 return; 12549 } 12550 12551 r.state = BroadcastRecord.APP_RECEIVE; 12552 String targetProcess = info.activityInfo.processName; 12553 r.curComponent = new ComponentName( 12554 info.activityInfo.applicationInfo.packageName, 12555 info.activityInfo.name); 12556 r.curReceiver = info.activityInfo; 12557 12558 // Broadcast is being executed, its package can't be stopped. 12559 try { 12560 AppGlobals.getPackageManager().setPackageStoppedState( 12561 r.curComponent.getPackageName(), false); 12562 } catch (RemoteException e) { 12563 } catch (IllegalArgumentException e) { 12564 Slog.w(TAG, "Failed trying to unstop package " 12565 + r.curComponent.getPackageName() + ": " + e); 12566 } 12567 12568 // Is this receiver's application already running? 12569 ProcessRecord app = getProcessRecordLocked(targetProcess, 12570 info.activityInfo.applicationInfo.uid); 12571 if (app != null && app.thread != null) { 12572 try { 12573 app.addPackage(info.activityInfo.packageName); 12574 processCurBroadcastLocked(r, app); 12575 return; 12576 } catch (RemoteException e) { 12577 Slog.w(TAG, "Exception when sending broadcast to " 12578 + r.curComponent, e); 12579 } 12580 12581 // If a dead object exception was thrown -- fall through to 12582 // restart the application. 12583 } 12584 12585 // Not running -- get it started, to be executed when the app comes up. 12586 if (DEBUG_BROADCAST) Slog.v(TAG, 12587 "Need to start app " + targetProcess + " for broadcast " + r); 12588 if ((r.curApp=startProcessLocked(targetProcess, 12589 info.activityInfo.applicationInfo, true, 12590 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 12591 "broadcast", r.curComponent, 12592 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 12593 == null) { 12594 // Ah, this recipient is unavailable. Finish it if necessary, 12595 // and mark the broadcast record as ready for the next. 12596 Slog.w(TAG, "Unable to launch app " 12597 + info.activityInfo.applicationInfo.packageName + "/" 12598 + info.activityInfo.applicationInfo.uid + " for broadcast " 12599 + r.intent + ": process is bad"); 12600 logBroadcastReceiverDiscardLocked(r); 12601 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12602 r.resultExtras, r.resultAbort, true); 12603 scheduleBroadcastsLocked(); 12604 r.state = BroadcastRecord.IDLE; 12605 return; 12606 } 12607 12608 mPendingBroadcast = r; 12609 mPendingBroadcastRecvIndex = recIdx; 12610 } 12611 } 12612 12613 // ========================================================= 12614 // INSTRUMENTATION 12615 // ========================================================= 12616 12617 public boolean startInstrumentation(ComponentName className, 12618 String profileFile, int flags, Bundle arguments, 12619 IInstrumentationWatcher watcher) { 12620 // Refuse possible leaked file descriptors 12621 if (arguments != null && arguments.hasFileDescriptors()) { 12622 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12623 } 12624 12625 synchronized(this) { 12626 InstrumentationInfo ii = null; 12627 ApplicationInfo ai = null; 12628 try { 12629 ii = mContext.getPackageManager().getInstrumentationInfo( 12630 className, STOCK_PM_FLAGS); 12631 ai = mContext.getPackageManager().getApplicationInfo( 12632 ii.targetPackage, STOCK_PM_FLAGS); 12633 } catch (PackageManager.NameNotFoundException e) { 12634 } 12635 if (ii == null) { 12636 reportStartInstrumentationFailure(watcher, className, 12637 "Unable to find instrumentation info for: " + className); 12638 return false; 12639 } 12640 if (ai == null) { 12641 reportStartInstrumentationFailure(watcher, className, 12642 "Unable to find instrumentation target package: " + ii.targetPackage); 12643 return false; 12644 } 12645 12646 int match = mContext.getPackageManager().checkSignatures( 12647 ii.targetPackage, ii.packageName); 12648 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12649 String msg = "Permission Denial: starting instrumentation " 12650 + className + " from pid=" 12651 + Binder.getCallingPid() 12652 + ", uid=" + Binder.getCallingPid() 12653 + " not allowed because package " + ii.packageName 12654 + " does not have a signature matching the target " 12655 + ii.targetPackage; 12656 reportStartInstrumentationFailure(watcher, className, msg); 12657 throw new SecurityException(msg); 12658 } 12659 12660 final long origId = Binder.clearCallingIdentity(); 12661 // Instrumentation can kill and relaunch even persistent processes 12662 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true); 12663 ProcessRecord app = addAppLocked(ai); 12664 app.instrumentationClass = className; 12665 app.instrumentationInfo = ai; 12666 app.instrumentationProfileFile = profileFile; 12667 app.instrumentationArguments = arguments; 12668 app.instrumentationWatcher = watcher; 12669 app.instrumentationResultClass = className; 12670 Binder.restoreCallingIdentity(origId); 12671 } 12672 12673 return true; 12674 } 12675 12676 /** 12677 * Report errors that occur while attempting to start Instrumentation. Always writes the 12678 * error to the logs, but if somebody is watching, send the report there too. This enables 12679 * the "am" command to report errors with more information. 12680 * 12681 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12682 * @param cn The component name of the instrumentation. 12683 * @param report The error report. 12684 */ 12685 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12686 ComponentName cn, String report) { 12687 Slog.w(TAG, report); 12688 try { 12689 if (watcher != null) { 12690 Bundle results = new Bundle(); 12691 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12692 results.putString("Error", report); 12693 watcher.instrumentationStatus(cn, -1, results); 12694 } 12695 } catch (RemoteException e) { 12696 Slog.w(TAG, e); 12697 } 12698 } 12699 12700 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12701 if (app.instrumentationWatcher != null) { 12702 try { 12703 // NOTE: IInstrumentationWatcher *must* be oneway here 12704 app.instrumentationWatcher.instrumentationFinished( 12705 app.instrumentationClass, 12706 resultCode, 12707 results); 12708 } catch (RemoteException e) { 12709 } 12710 } 12711 app.instrumentationWatcher = null; 12712 app.instrumentationClass = null; 12713 app.instrumentationInfo = null; 12714 app.instrumentationProfileFile = null; 12715 app.instrumentationArguments = null; 12716 12717 forceStopPackageLocked(app.processName, -1, false, false, true, true); 12718 } 12719 12720 public void finishInstrumentation(IApplicationThread target, 12721 int resultCode, Bundle results) { 12722 // Refuse possible leaked file descriptors 12723 if (results != null && results.hasFileDescriptors()) { 12724 throw new IllegalArgumentException("File descriptors passed in Intent"); 12725 } 12726 12727 synchronized(this) { 12728 ProcessRecord app = getRecordForAppLocked(target); 12729 if (app == null) { 12730 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12731 return; 12732 } 12733 final long origId = Binder.clearCallingIdentity(); 12734 finishInstrumentationLocked(app, resultCode, results); 12735 Binder.restoreCallingIdentity(origId); 12736 } 12737 } 12738 12739 // ========================================================= 12740 // CONFIGURATION 12741 // ========================================================= 12742 12743 public ConfigurationInfo getDeviceConfigurationInfo() { 12744 ConfigurationInfo config = new ConfigurationInfo(); 12745 synchronized (this) { 12746 config.reqTouchScreen = mConfiguration.touchscreen; 12747 config.reqKeyboardType = mConfiguration.keyboard; 12748 config.reqNavigation = mConfiguration.navigation; 12749 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12750 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12751 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12752 } 12753 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12754 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12755 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12756 } 12757 config.reqGlEsVersion = GL_ES_VERSION; 12758 } 12759 return config; 12760 } 12761 12762 public Configuration getConfiguration() { 12763 Configuration ci; 12764 synchronized(this) { 12765 ci = new Configuration(mConfiguration); 12766 } 12767 return ci; 12768 } 12769 12770 public void updatePersistentConfiguration(Configuration values) { 12771 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12772 "updateConfiguration()"); 12773 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12774 "updateConfiguration()"); 12775 if (values == null) { 12776 throw new NullPointerException("Configuration must not be null"); 12777 } 12778 12779 synchronized(this) { 12780 final long origId = Binder.clearCallingIdentity(); 12781 updateConfigurationLocked(values, null, true); 12782 Binder.restoreCallingIdentity(origId); 12783 } 12784 } 12785 12786 public void updateConfiguration(Configuration values) { 12787 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12788 "updateConfiguration()"); 12789 12790 synchronized(this) { 12791 if (values == null && mWindowManager != null) { 12792 // sentinel: fetch the current configuration from the window manager 12793 values = mWindowManager.computeNewConfiguration(); 12794 } 12795 12796 if (mWindowManager != null) { 12797 mProcessList.applyDisplaySize(mWindowManager); 12798 } 12799 12800 final long origId = Binder.clearCallingIdentity(); 12801 if (values != null) { 12802 Settings.System.clearConfiguration(values); 12803 } 12804 updateConfigurationLocked(values, null, false); 12805 Binder.restoreCallingIdentity(origId); 12806 } 12807 } 12808 12809 /** 12810 * Do either or both things: (1) change the current configuration, and (2) 12811 * make sure the given activity is running with the (now) current 12812 * configuration. Returns true if the activity has been left running, or 12813 * false if <var>starting</var> is being destroyed to match the new 12814 * configuration. 12815 * @param persistent TODO 12816 */ 12817 public boolean updateConfigurationLocked(Configuration values, 12818 ActivityRecord starting, boolean persistent) { 12819 int changes = 0; 12820 12821 boolean kept = true; 12822 12823 if (values != null) { 12824 Configuration newConfig = new Configuration(mConfiguration); 12825 changes = newConfig.updateFrom(values); 12826 if (changes != 0) { 12827 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12828 Slog.i(TAG, "Updating configuration to: " + values); 12829 } 12830 12831 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12832 12833 if (values.locale != null) { 12834 saveLocaleLocked(values.locale, 12835 !values.locale.equals(mConfiguration.locale), 12836 values.userSetLocale); 12837 } 12838 12839 mConfigurationSeq++; 12840 if (mConfigurationSeq <= 0) { 12841 mConfigurationSeq = 1; 12842 } 12843 newConfig.seq = mConfigurationSeq; 12844 mConfiguration = newConfig; 12845 Slog.i(TAG, "Config changed: " + newConfig); 12846 12847 AttributeCache ac = AttributeCache.instance(); 12848 if (ac != null) { 12849 ac.updateConfiguration(mConfiguration); 12850 } 12851 12852 // Make sure all resources in our process are updated 12853 // right now, so that anyone who is going to retrieve 12854 // resource values after we return will be sure to get 12855 // the new ones. This is especially important during 12856 // boot, where the first config change needs to guarantee 12857 // all resources have that config before following boot 12858 // code is executed. 12859 mSystemThread.applyConfigurationToResources(newConfig); 12860 12861 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12862 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12863 msg.obj = new Configuration(mConfiguration); 12864 mHandler.sendMessage(msg); 12865 } 12866 12867 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12868 ProcessRecord app = mLruProcesses.get(i); 12869 try { 12870 if (app.thread != null) { 12871 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12872 + app.processName + " new config " + mConfiguration); 12873 app.thread.scheduleConfigurationChanged(mConfiguration); 12874 } 12875 } catch (Exception e) { 12876 } 12877 } 12878 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12879 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12880 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12881 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12882 null, false, false, MY_PID, Process.SYSTEM_UID); 12883 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12884 broadcastIntentLocked(null, null, 12885 new Intent(Intent.ACTION_LOCALE_CHANGED), 12886 null, null, 0, null, null, 12887 null, false, false, MY_PID, Process.SYSTEM_UID); 12888 } 12889 } 12890 } 12891 12892 if (changes != 0 && starting == null) { 12893 // If the configuration changed, and the caller is not already 12894 // in the process of starting an activity, then find the top 12895 // activity to check if its configuration needs to change. 12896 starting = mMainStack.topRunningActivityLocked(null); 12897 } 12898 12899 if (starting != null) { 12900 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12901 // And we need to make sure at this point that all other activities 12902 // are made visible with the correct configuration. 12903 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12904 } 12905 12906 if (values != null && mWindowManager != null) { 12907 mWindowManager.setNewConfiguration(mConfiguration); 12908 } 12909 12910 return kept; 12911 } 12912 12913 /** 12914 * Save the locale. You must be inside a synchronized (this) block. 12915 */ 12916 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12917 if(isDiff) { 12918 SystemProperties.set("user.language", l.getLanguage()); 12919 SystemProperties.set("user.region", l.getCountry()); 12920 } 12921 12922 if(isPersist) { 12923 SystemProperties.set("persist.sys.language", l.getLanguage()); 12924 SystemProperties.set("persist.sys.country", l.getCountry()); 12925 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12926 } 12927 } 12928 12929 // ========================================================= 12930 // LIFETIME MANAGEMENT 12931 // ========================================================= 12932 12933 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12934 ProcessRecord TOP_APP, boolean recursed) { 12935 if (mAdjSeq == app.adjSeq) { 12936 // This adjustment has already been computed. If we are calling 12937 // from the top, we may have already computed our adjustment with 12938 // an earlier hidden adjustment that isn't really for us... if 12939 // so, use the new hidden adjustment. 12940 if (!recursed && app.hidden) { 12941 app.curAdj = app.curRawAdj = hiddenAdj; 12942 } 12943 return app.curRawAdj; 12944 } 12945 12946 if (app.thread == null) { 12947 app.adjSeq = mAdjSeq; 12948 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12949 return (app.curAdj=ProcessList.EMPTY_APP_ADJ); 12950 } 12951 12952 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12953 app.adjSource = null; 12954 app.adjTarget = null; 12955 app.empty = false; 12956 app.hidden = false; 12957 12958 final int activitiesSize = app.activities.size(); 12959 12960 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12961 // The max adjustment doesn't allow this app to be anything 12962 // below foreground, so it is not worth doing work for it. 12963 app.adjType = "fixed"; 12964 app.adjSeq = mAdjSeq; 12965 app.curRawAdj = app.maxAdj; 12966 app.foregroundActivities = false; 12967 app.keeping = true; 12968 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12969 // System process can do UI, and when they do we want to have 12970 // them trim their memory after the user leaves the UI. To 12971 // facilitate this, here we need to determine whether or not it 12972 // is currently showing UI. 12973 app.systemNoUi = true; 12974 if (app == TOP_APP) { 12975 app.systemNoUi = false; 12976 } else if (activitiesSize > 0) { 12977 for (int j = 0; j < activitiesSize; j++) { 12978 final ActivityRecord r = app.activities.get(j); 12979 if (r.visible) { 12980 app.systemNoUi = false; 12981 break; 12982 } 12983 } 12984 } 12985 return (app.curAdj=app.maxAdj); 12986 } 12987 12988 final boolean hadForegroundActivities = app.foregroundActivities; 12989 12990 app.foregroundActivities = false; 12991 app.keeping = false; 12992 app.systemNoUi = false; 12993 12994 // Determine the importance of the process, starting with most 12995 // important to least, and assign an appropriate OOM adjustment. 12996 int adj; 12997 int schedGroup; 12998 if (app == TOP_APP) { 12999 // The last app on the list is the foreground app. 13000 adj = ProcessList.FOREGROUND_APP_ADJ; 13001 schedGroup = Process.THREAD_GROUP_DEFAULT; 13002 app.adjType = "top-activity"; 13003 app.foregroundActivities = true; 13004 } else if (app.instrumentationClass != null) { 13005 // Don't want to kill running instrumentation. 13006 adj = ProcessList.FOREGROUND_APP_ADJ; 13007 schedGroup = Process.THREAD_GROUP_DEFAULT; 13008 app.adjType = "instrumentation"; 13009 } else if (app.curReceiver != null || 13010 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13011 // An app that is currently receiving a broadcast also 13012 // counts as being in the foreground. 13013 adj = ProcessList.FOREGROUND_APP_ADJ; 13014 schedGroup = Process.THREAD_GROUP_DEFAULT; 13015 app.adjType = "broadcast"; 13016 } else if (app.executingServices.size() > 0) { 13017 // An app that is currently executing a service callback also 13018 // counts as being in the foreground. 13019 adj = ProcessList.FOREGROUND_APP_ADJ; 13020 schedGroup = Process.THREAD_GROUP_DEFAULT; 13021 app.adjType = "exec-service"; 13022 } else if (activitiesSize > 0) { 13023 // This app is in the background with paused activities. 13024 // We inspect activities to potentially upgrade adjustment further below. 13025 adj = hiddenAdj; 13026 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13027 app.hidden = true; 13028 app.adjType = "bg-activities"; 13029 } else { 13030 // A very not-needed process. If this is lower in the lru list, 13031 // we will push it in to the empty bucket. 13032 adj = hiddenAdj; 13033 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13034 app.hidden = true; 13035 app.empty = true; 13036 app.adjType = "bg-empty"; 13037 } 13038 13039 // Examine all activities if not already foreground. 13040 if (!app.foregroundActivities && activitiesSize > 0) { 13041 for (int j = 0; j < activitiesSize; j++) { 13042 final ActivityRecord r = app.activities.get(j); 13043 if (r.visible) { 13044 // App has a visible activity; only upgrade adjustment. 13045 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13046 adj = ProcessList.VISIBLE_APP_ADJ; 13047 app.adjType = "visible"; 13048 } 13049 schedGroup = Process.THREAD_GROUP_DEFAULT; 13050 app.hidden = false; 13051 app.foregroundActivities = true; 13052 break; 13053 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED 13054 || r.state == ActivityState.STOPPING) { 13055 // Only upgrade adjustment. 13056 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13057 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13058 app.adjType = "stopping"; 13059 } 13060 app.foregroundActivities = true; 13061 } 13062 } 13063 } 13064 13065 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13066 if (app.foregroundServices) { 13067 // The user is aware of this app, so make it visible. 13068 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13069 app.hidden = false; 13070 app.adjType = "foreground-service"; 13071 schedGroup = Process.THREAD_GROUP_DEFAULT; 13072 } else if (app.forcingToForeground != null) { 13073 // The user is aware of this app, so make it visible. 13074 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13075 app.hidden = false; 13076 app.adjType = "force-foreground"; 13077 app.adjSource = app.forcingToForeground; 13078 schedGroup = Process.THREAD_GROUP_DEFAULT; 13079 } 13080 } 13081 13082 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13083 // We don't want to kill the current heavy-weight process. 13084 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13085 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13086 app.hidden = false; 13087 app.adjType = "heavy"; 13088 } 13089 13090 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13091 // This process is hosting what we currently consider to be the 13092 // home app, so we don't want to let it go into the background. 13093 adj = ProcessList.HOME_APP_ADJ; 13094 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13095 app.hidden = false; 13096 app.adjType = "home"; 13097 } 13098 13099 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13100 + " reason=" + app.adjType); 13101 13102 // By default, we use the computed adjustment. It may be changed if 13103 // there are applications dependent on our services or providers, but 13104 // this gives us a baseline and makes sure we don't get into an 13105 // infinite recursion. 13106 app.adjSeq = mAdjSeq; 13107 app.curRawAdj = adj; 13108 13109 if (mBackupTarget != null && app == mBackupTarget.app) { 13110 // If possible we want to avoid killing apps while they're being backed up 13111 if (adj > ProcessList.BACKUP_APP_ADJ) { 13112 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13113 adj = ProcessList.BACKUP_APP_ADJ; 13114 app.adjType = "backup"; 13115 app.hidden = false; 13116 } 13117 } 13118 13119 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13120 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13121 final long now = SystemClock.uptimeMillis(); 13122 // This process is more important if the top activity is 13123 // bound to the service. 13124 Iterator<ServiceRecord> jt = app.services.iterator(); 13125 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13126 ServiceRecord s = jt.next(); 13127 if (s.startRequested) { 13128 if (app.hasShownUi && app != mHomeProcess) { 13129 // If this process has shown some UI, let it immediately 13130 // go to the LRU list because it may be pretty heavy with 13131 // UI stuff. We'll tag it with a label just to help 13132 // debug and understand what is going on. 13133 if (adj > ProcessList.SECONDARY_SERVER_ADJ) { 13134 app.adjType = "started-bg-ui-services"; 13135 } 13136 } else { 13137 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13138 // This service has seen some activity within 13139 // recent memory, so we will keep its process ahead 13140 // of the background processes. 13141 if (adj > ProcessList.SECONDARY_SERVER_ADJ) { 13142 adj = ProcessList.SECONDARY_SERVER_ADJ; 13143 app.adjType = "started-services"; 13144 app.hidden = false; 13145 } 13146 } 13147 // If we have let the service slide into the background 13148 // state, still have some text describing what it is doing 13149 // even though the service no longer has an impact. 13150 if (adj > ProcessList.SECONDARY_SERVER_ADJ) { 13151 app.adjType = "started-bg-services"; 13152 } 13153 } 13154 // Don't kill this process because it is doing work; it 13155 // has said it is doing work. 13156 app.keeping = true; 13157 } 13158 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13159 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13160 Iterator<ArrayList<ConnectionRecord>> kt 13161 = s.connections.values().iterator(); 13162 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13163 ArrayList<ConnectionRecord> clist = kt.next(); 13164 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 13165 // XXX should compute this based on the max of 13166 // all connected clients. 13167 ConnectionRecord cr = clist.get(i); 13168 if (cr.binding.client == app) { 13169 // Binding to ourself is not interesting. 13170 continue; 13171 } 13172 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 13173 ProcessRecord client = cr.binding.client; 13174 int clientAdj = adj; 13175 int myHiddenAdj = hiddenAdj; 13176 if (myHiddenAdj > client.hiddenAdj) { 13177 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 13178 myHiddenAdj = client.hiddenAdj; 13179 } else { 13180 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 13181 } 13182 } 13183 clientAdj = computeOomAdjLocked( 13184 client, myHiddenAdj, TOP_APP, true); 13185 String adjType = null; 13186 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 13187 // Not doing bind OOM management, so treat 13188 // this guy more like a started service. 13189 if (app.hasShownUi && app != mHomeProcess) { 13190 // If this process has shown some UI, let it immediately 13191 // go to the LRU list because it may be pretty heavy with 13192 // UI stuff. We'll tag it with a label just to help 13193 // debug and understand what is going on. 13194 if (adj > clientAdj) { 13195 adjType = "bound-bg-ui-services"; 13196 } 13197 app.hidden = false; 13198 clientAdj = adj; 13199 } else { 13200 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13201 // This service has not seen activity within 13202 // recent memory, so allow it to drop to the 13203 // LRU list if there is no other reason to keep 13204 // it around. We'll also tag it with a label just 13205 // to help debug and undertand what is going on. 13206 if (adj > clientAdj) { 13207 adjType = "bound-bg-services"; 13208 } 13209 clientAdj = adj; 13210 } 13211 } 13212 } 13213 if (adj > clientAdj) { 13214 // If this process has recently shown UI, and 13215 // the process that is binding to it is less 13216 // important than being visible, then we don't 13217 // care about the binding as much as we care 13218 // about letting this process get into the LRU 13219 // list to be killed and restarted if needed for 13220 // memory. 13221 if (app.hasShownUi && app != mHomeProcess 13222 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13223 adjType = "bound-bg-ui-services"; 13224 } else { 13225 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 13226 |Context.BIND_IMPORTANT)) != 0) { 13227 adj = clientAdj; 13228 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) { 13229 adj = clientAdj; 13230 } else { 13231 adj = ProcessList.VISIBLE_APP_ADJ; 13232 } 13233 if (!client.hidden) { 13234 app.hidden = false; 13235 } 13236 if (client.keeping) { 13237 app.keeping = true; 13238 } 13239 adjType = "service"; 13240 } 13241 } 13242 if (adjType != null) { 13243 app.adjType = adjType; 13244 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13245 .REASON_SERVICE_IN_USE; 13246 app.adjSource = cr.binding.client; 13247 app.adjSourceOom = clientAdj; 13248 app.adjTarget = s.name; 13249 } 13250 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13251 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13252 schedGroup = Process.THREAD_GROUP_DEFAULT; 13253 } 13254 } 13255 } 13256 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 13257 ActivityRecord a = cr.activity; 13258 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 13259 (a.visible || a.state == ActivityState.RESUMED 13260 || a.state == ActivityState.PAUSING)) { 13261 adj = ProcessList.FOREGROUND_APP_ADJ; 13262 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13263 schedGroup = Process.THREAD_GROUP_DEFAULT; 13264 } 13265 app.hidden = false; 13266 app.adjType = "service"; 13267 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13268 .REASON_SERVICE_IN_USE; 13269 app.adjSource = a; 13270 app.adjSourceOom = adj; 13271 app.adjTarget = s.name; 13272 } 13273 } 13274 } 13275 } 13276 } 13277 } 13278 13279 // Finally, if this process has active services running in it, we 13280 // would like to avoid killing it unless it would prevent the current 13281 // application from running. By default we put the process in 13282 // with the rest of the background processes; as we scan through 13283 // its services we may bump it up from there. 13284 if (adj > hiddenAdj) { 13285 adj = hiddenAdj; 13286 app.hidden = false; 13287 app.adjType = "bg-services"; 13288 } 13289 } 13290 13291 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13292 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13293 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13294 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13295 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13296 ContentProviderRecord cpr = jt.next(); 13297 if (cpr.clients.size() != 0) { 13298 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13299 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13300 ProcessRecord client = kt.next(); 13301 if (client == app) { 13302 // Being our own client is not interesting. 13303 continue; 13304 } 13305 int myHiddenAdj = hiddenAdj; 13306 if (myHiddenAdj > client.hiddenAdj) { 13307 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13308 myHiddenAdj = client.hiddenAdj; 13309 } else { 13310 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13311 } 13312 } 13313 int clientAdj = computeOomAdjLocked( 13314 client, myHiddenAdj, TOP_APP, true); 13315 if (adj > clientAdj) { 13316 if (app.hasShownUi && app != mHomeProcess 13317 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13318 app.adjType = "bg-ui-provider"; 13319 } else { 13320 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13321 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13322 app.adjType = "provider"; 13323 } 13324 if (!client.hidden) { 13325 app.hidden = false; 13326 } 13327 if (client.keeping) { 13328 app.keeping = true; 13329 } 13330 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13331 .REASON_PROVIDER_IN_USE; 13332 app.adjSource = client; 13333 app.adjSourceOom = clientAdj; 13334 app.adjTarget = cpr.name; 13335 } 13336 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13337 schedGroup = Process.THREAD_GROUP_DEFAULT; 13338 } 13339 } 13340 } 13341 // If the provider has external (non-framework) process 13342 // dependencies, ensure that its adjustment is at least 13343 // FOREGROUND_APP_ADJ. 13344 if (cpr.externals != 0) { 13345 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13346 adj = ProcessList.FOREGROUND_APP_ADJ; 13347 schedGroup = Process.THREAD_GROUP_DEFAULT; 13348 app.hidden = false; 13349 app.keeping = true; 13350 app.adjType = "provider"; 13351 app.adjTarget = cpr.name; 13352 } 13353 } 13354 } 13355 } 13356 13357 app.curRawAdj = adj; 13358 13359 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13360 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13361 if (adj > app.maxAdj) { 13362 adj = app.maxAdj; 13363 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13364 schedGroup = Process.THREAD_GROUP_DEFAULT; 13365 } 13366 } 13367 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13368 app.keeping = true; 13369 } 13370 13371 if (app.hasAboveClient) { 13372 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13373 // then we need to drop its adjustment to be lower than the service's 13374 // in order to honor the request. We want to drop it by one adjustment 13375 // level... but there is special meaning applied to various levels so 13376 // we will skip some of them. 13377 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13378 // System process will not get dropped, ever 13379 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13380 adj = ProcessList.VISIBLE_APP_ADJ; 13381 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13382 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13383 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13384 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13385 } else if (adj < ProcessList.EMPTY_APP_ADJ) { 13386 adj++; 13387 } 13388 } 13389 13390 app.curAdj = adj; 13391 app.curSchedGroup = schedGroup; 13392 13393 if (hadForegroundActivities != app.foregroundActivities) { 13394 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid, 13395 app.foregroundActivities).sendToTarget(); 13396 } 13397 13398 return app.curRawAdj; 13399 } 13400 13401 /** 13402 * Ask a given process to GC right now. 13403 */ 13404 final void performAppGcLocked(ProcessRecord app) { 13405 try { 13406 app.lastRequestedGc = SystemClock.uptimeMillis(); 13407 if (app.thread != null) { 13408 if (app.reportLowMemory) { 13409 app.reportLowMemory = false; 13410 app.thread.scheduleLowMemory(); 13411 } else { 13412 app.thread.processInBackground(); 13413 } 13414 } 13415 } catch (Exception e) { 13416 // whatever. 13417 } 13418 } 13419 13420 /** 13421 * Returns true if things are idle enough to perform GCs. 13422 */ 13423 private final boolean canGcNowLocked() { 13424 return mParallelBroadcasts.size() == 0 13425 && mOrderedBroadcasts.size() == 0 13426 && (mSleeping || (mMainStack.mResumedActivity != null && 13427 mMainStack.mResumedActivity.idle)); 13428 } 13429 13430 /** 13431 * Perform GCs on all processes that are waiting for it, but only 13432 * if things are idle. 13433 */ 13434 final void performAppGcsLocked() { 13435 final int N = mProcessesToGc.size(); 13436 if (N <= 0) { 13437 return; 13438 } 13439 if (canGcNowLocked()) { 13440 while (mProcessesToGc.size() > 0) { 13441 ProcessRecord proc = mProcessesToGc.remove(0); 13442 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13443 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13444 <= SystemClock.uptimeMillis()) { 13445 // To avoid spamming the system, we will GC processes one 13446 // at a time, waiting a few seconds between each. 13447 performAppGcLocked(proc); 13448 scheduleAppGcsLocked(); 13449 return; 13450 } else { 13451 // It hasn't been long enough since we last GCed this 13452 // process... put it in the list to wait for its time. 13453 addProcessToGcListLocked(proc); 13454 break; 13455 } 13456 } 13457 } 13458 13459 scheduleAppGcsLocked(); 13460 } 13461 } 13462 13463 /** 13464 * If all looks good, perform GCs on all processes waiting for them. 13465 */ 13466 final void performAppGcsIfAppropriateLocked() { 13467 if (canGcNowLocked()) { 13468 performAppGcsLocked(); 13469 return; 13470 } 13471 // Still not idle, wait some more. 13472 scheduleAppGcsLocked(); 13473 } 13474 13475 /** 13476 * Schedule the execution of all pending app GCs. 13477 */ 13478 final void scheduleAppGcsLocked() { 13479 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13480 13481 if (mProcessesToGc.size() > 0) { 13482 // Schedule a GC for the time to the next process. 13483 ProcessRecord proc = mProcessesToGc.get(0); 13484 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13485 13486 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13487 long now = SystemClock.uptimeMillis(); 13488 if (when < (now+GC_TIMEOUT)) { 13489 when = now + GC_TIMEOUT; 13490 } 13491 mHandler.sendMessageAtTime(msg, when); 13492 } 13493 } 13494 13495 /** 13496 * Add a process to the array of processes waiting to be GCed. Keeps the 13497 * list in sorted order by the last GC time. The process can't already be 13498 * on the list. 13499 */ 13500 final void addProcessToGcListLocked(ProcessRecord proc) { 13501 boolean added = false; 13502 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13503 if (mProcessesToGc.get(i).lastRequestedGc < 13504 proc.lastRequestedGc) { 13505 added = true; 13506 mProcessesToGc.add(i+1, proc); 13507 break; 13508 } 13509 } 13510 if (!added) { 13511 mProcessesToGc.add(0, proc); 13512 } 13513 } 13514 13515 /** 13516 * Set up to ask a process to GC itself. This will either do it 13517 * immediately, or put it on the list of processes to gc the next 13518 * time things are idle. 13519 */ 13520 final void scheduleAppGcLocked(ProcessRecord app) { 13521 long now = SystemClock.uptimeMillis(); 13522 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13523 return; 13524 } 13525 if (!mProcessesToGc.contains(app)) { 13526 addProcessToGcListLocked(app); 13527 scheduleAppGcsLocked(); 13528 } 13529 } 13530 13531 final void checkExcessivePowerUsageLocked(boolean doKills) { 13532 updateCpuStatsNow(); 13533 13534 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13535 boolean doWakeKills = doKills; 13536 boolean doCpuKills = doKills; 13537 if (mLastPowerCheckRealtime == 0) { 13538 doWakeKills = false; 13539 } 13540 if (mLastPowerCheckUptime == 0) { 13541 doCpuKills = false; 13542 } 13543 if (stats.isScreenOn()) { 13544 doWakeKills = false; 13545 } 13546 final long curRealtime = SystemClock.elapsedRealtime(); 13547 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13548 final long curUptime = SystemClock.uptimeMillis(); 13549 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13550 mLastPowerCheckRealtime = curRealtime; 13551 mLastPowerCheckUptime = curUptime; 13552 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13553 doWakeKills = false; 13554 } 13555 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13556 doCpuKills = false; 13557 } 13558 int i = mLruProcesses.size(); 13559 while (i > 0) { 13560 i--; 13561 ProcessRecord app = mLruProcesses.get(i); 13562 if (!app.keeping) { 13563 long wtime; 13564 synchronized (stats) { 13565 wtime = stats.getProcessWakeTime(app.info.uid, 13566 app.pid, curRealtime); 13567 } 13568 long wtimeUsed = wtime - app.lastWakeTime; 13569 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13570 if (DEBUG_POWER) { 13571 StringBuilder sb = new StringBuilder(128); 13572 sb.append("Wake for "); 13573 app.toShortString(sb); 13574 sb.append(": over "); 13575 TimeUtils.formatDuration(realtimeSince, sb); 13576 sb.append(" used "); 13577 TimeUtils.formatDuration(wtimeUsed, sb); 13578 sb.append(" ("); 13579 sb.append((wtimeUsed*100)/realtimeSince); 13580 sb.append("%)"); 13581 Slog.i(TAG, sb.toString()); 13582 sb.setLength(0); 13583 sb.append("CPU for "); 13584 app.toShortString(sb); 13585 sb.append(": over "); 13586 TimeUtils.formatDuration(uptimeSince, sb); 13587 sb.append(" used "); 13588 TimeUtils.formatDuration(cputimeUsed, sb); 13589 sb.append(" ("); 13590 sb.append((cputimeUsed*100)/uptimeSince); 13591 sb.append("%)"); 13592 Slog.i(TAG, sb.toString()); 13593 } 13594 // If a process has held a wake lock for more 13595 // than 50% of the time during this period, 13596 // that sounds pad. Kill! 13597 if (doWakeKills && realtimeSince > 0 13598 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13599 synchronized (stats) { 13600 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13601 realtimeSince, wtimeUsed); 13602 } 13603 Slog.w(TAG, "Excessive wake lock in " + app.processName 13604 + " (pid " + app.pid + "): held " + wtimeUsed 13605 + " during " + realtimeSince); 13606 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13607 app.processName, app.setAdj, "excessive wake lock"); 13608 Process.killProcessQuiet(app.pid); 13609 } else if (doCpuKills && uptimeSince > 0 13610 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13611 synchronized (stats) { 13612 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13613 uptimeSince, cputimeUsed); 13614 } 13615 Slog.w(TAG, "Excessive CPU in " + app.processName 13616 + " (pid " + app.pid + "): used " + cputimeUsed 13617 + " during " + uptimeSince); 13618 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13619 app.processName, app.setAdj, "excessive cpu"); 13620 Process.killProcessQuiet(app.pid); 13621 } else { 13622 app.lastWakeTime = wtime; 13623 app.lastCpuTime = app.curCpuTime; 13624 } 13625 } 13626 } 13627 } 13628 13629 private final boolean updateOomAdjLocked( 13630 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13631 app.hiddenAdj = hiddenAdj; 13632 13633 if (app.thread == null) { 13634 return false; 13635 } 13636 13637 final boolean wasKeeping = app.keeping; 13638 13639 boolean success = true; 13640 13641 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); 13642 13643 if (app.curRawAdj != app.setRawAdj) { 13644 if (false) { 13645 // Removing for now. Forcing GCs is not so useful anymore 13646 // with Dalvik, and the new memory level hint facility is 13647 // better for what we need to do these days. 13648 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ 13649 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13650 // If this app is transitioning from foreground to 13651 // non-foreground, have it do a gc. 13652 scheduleAppGcLocked(app); 13653 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13654 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13655 // Likewise do a gc when an app is moving in to the 13656 // background (such as a service stopping). 13657 scheduleAppGcLocked(app); 13658 } 13659 } 13660 13661 if (wasKeeping && !app.keeping) { 13662 // This app is no longer something we want to keep. Note 13663 // its current wake lock time to later know to kill it if 13664 // it is not behaving well. 13665 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13666 synchronized (stats) { 13667 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13668 app.pid, SystemClock.elapsedRealtime()); 13669 } 13670 app.lastCpuTime = app.curCpuTime; 13671 } 13672 13673 app.setRawAdj = app.curRawAdj; 13674 } 13675 if (app.curAdj != app.setAdj) { 13676 if (Process.setOomAdj(app.pid, app.curAdj)) { 13677 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13678 TAG, "Set app " + app.processName + 13679 " oom adj to " + app.curAdj + " because " + app.adjType); 13680 app.setAdj = app.curAdj; 13681 } else { 13682 success = false; 13683 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13684 } 13685 } 13686 if (app.setSchedGroup != app.curSchedGroup) { 13687 app.setSchedGroup = app.curSchedGroup; 13688 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13689 "Setting process group of " + app.processName 13690 + " to " + app.curSchedGroup); 13691 if (app.waitingToKill != null && 13692 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13693 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13694 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13695 app.processName, app.setAdj, app.waitingToKill); 13696 Process.killProcessQuiet(app.pid); 13697 success = false; 13698 } else { 13699 if (true) { 13700 long oldId = Binder.clearCallingIdentity(); 13701 try { 13702 Process.setProcessGroup(app.pid, app.curSchedGroup); 13703 } catch (Exception e) { 13704 Slog.w(TAG, "Failed setting process group of " + app.pid 13705 + " to " + app.curSchedGroup); 13706 e.printStackTrace(); 13707 } finally { 13708 Binder.restoreCallingIdentity(oldId); 13709 } 13710 } else { 13711 if (app.thread != null) { 13712 try { 13713 app.thread.setSchedulingGroup(app.curSchedGroup); 13714 } catch (RemoteException e) { 13715 } 13716 } 13717 } 13718 } 13719 } 13720 return success; 13721 } 13722 13723 private final ActivityRecord resumedAppLocked() { 13724 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13725 if (resumedActivity == null || resumedActivity.app == null) { 13726 resumedActivity = mMainStack.mPausingActivity; 13727 if (resumedActivity == null || resumedActivity.app == null) { 13728 resumedActivity = mMainStack.topRunningActivityLocked(null); 13729 } 13730 } 13731 return resumedActivity; 13732 } 13733 13734 private final boolean updateOomAdjLocked(ProcessRecord app) { 13735 final ActivityRecord TOP_ACT = resumedAppLocked(); 13736 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13737 int curAdj = app.curAdj; 13738 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13739 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13740 13741 mAdjSeq++; 13742 13743 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 13744 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13745 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13746 if (nowHidden != wasHidden) { 13747 // Changed to/from hidden state, so apps after it in the LRU 13748 // list may also be changed. 13749 updateOomAdjLocked(); 13750 } 13751 return success; 13752 } 13753 13754 final void updateOomAdjLocked() { 13755 final ActivityRecord TOP_ACT = resumedAppLocked(); 13756 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13757 13758 if (false) { 13759 RuntimeException e = new RuntimeException(); 13760 e.fillInStackTrace(); 13761 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13762 } 13763 13764 mAdjSeq++; 13765 13766 // Let's determine how many processes we have running vs. 13767 // how many slots we have for background processes; we may want 13768 // to put multiple processes in a slot of there are enough of 13769 // them. 13770 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 13771 int factor = (mLruProcesses.size()-4)/numSlots; 13772 if (factor < 1) factor = 1; 13773 int step = 0; 13774 int numHidden = 0; 13775 13776 // First update the OOM adjustment for each of the 13777 // application processes based on their current state. 13778 int i = mLruProcesses.size(); 13779 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13780 int numBg = 0; 13781 while (i > 0) { 13782 i--; 13783 ProcessRecord app = mLruProcesses.get(i); 13784 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13785 updateOomAdjLocked(app, curHiddenAdj, TOP_APP); 13786 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ 13787 && app.curAdj == curHiddenAdj) { 13788 step++; 13789 if (step >= factor) { 13790 step = 0; 13791 curHiddenAdj++; 13792 } 13793 } 13794 if (!app.killedBackground) { 13795 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13796 numHidden++; 13797 if (numHidden > mProcessLimit) { 13798 Slog.i(TAG, "No longer want " + app.processName 13799 + " (pid " + app.pid + "): hidden #" + numHidden); 13800 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13801 app.processName, app.setAdj, "too many background"); 13802 app.killedBackground = true; 13803 Process.killProcessQuiet(app.pid); 13804 } else { 13805 numBg++; 13806 } 13807 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) { 13808 numBg++; 13809 } 13810 } 13811 } 13812 13813 // Now determine the memory trimming level of background processes. 13814 // Unfortunately we need to start at the back of the list to do this 13815 // properly. We only do this if the number of background apps we 13816 // are managing to keep around is less than half the maximum we desire; 13817 // if we are keeping a good number around, we'll let them use whatever 13818 // memory they want. 13819 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 13820 final int N = mLruProcesses.size(); 13821 factor = numBg/3; 13822 step = 0; 13823 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13824 for (i=0; i<N; i++) { 13825 ProcessRecord app = mLruProcesses.get(i); 13826 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) { 13827 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13828 try { 13829 app.thread.scheduleTrimMemory(curLevel); 13830 } catch (RemoteException e) { 13831 } 13832 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { 13833 // For these apps we will also finish their activities 13834 // to help them free memory. 13835 mMainStack.destroyActivitiesLocked(app, false); 13836 } 13837 } 13838 app.trimMemoryLevel = curLevel; 13839 step++; 13840 if (step >= factor) { 13841 switch (curLevel) { 13842 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13843 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13844 break; 13845 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13846 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13847 break; 13848 } 13849 } 13850 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13851 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13852 && app.thread != null) { 13853 try { 13854 app.thread.scheduleTrimMemory( 13855 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13856 } catch (RemoteException e) { 13857 } 13858 } 13859 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13860 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13861 && app.pendingUiClean) { 13862 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13863 && app.thread != null) { 13864 try { 13865 app.thread.scheduleTrimMemory( 13866 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13867 } catch (RemoteException e) { 13868 } 13869 } 13870 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13871 app.pendingUiClean = false; 13872 } else { 13873 app.trimMemoryLevel = 0; 13874 } 13875 } 13876 } else { 13877 final int N = mLruProcesses.size(); 13878 for (i=0; i<N; i++) { 13879 ProcessRecord app = mLruProcesses.get(i); 13880 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13881 && app.pendingUiClean) { 13882 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13883 && app.thread != null) { 13884 try { 13885 app.thread.scheduleTrimMemory( 13886 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13887 } catch (RemoteException e) { 13888 } 13889 } 13890 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13891 app.pendingUiClean = false; 13892 } else { 13893 app.trimMemoryLevel = 0; 13894 } 13895 } 13896 } 13897 13898 if (mAlwaysFinishActivities) { 13899 mMainStack.destroyActivitiesLocked(null, false); 13900 } 13901 } 13902 13903 final void trimApplications() { 13904 synchronized (this) { 13905 int i; 13906 13907 // First remove any unused application processes whose package 13908 // has been removed. 13909 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13910 final ProcessRecord app = mRemovedProcesses.get(i); 13911 if (app.activities.size() == 0 13912 && app.curReceiver == null && app.services.size() == 0) { 13913 Slog.i( 13914 TAG, "Exiting empty application process " 13915 + app.processName + " (" 13916 + (app.thread != null ? app.thread.asBinder() : null) 13917 + ")\n"); 13918 if (app.pid > 0 && app.pid != MY_PID) { 13919 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13920 app.processName, app.setAdj, "empty"); 13921 Process.killProcessQuiet(app.pid); 13922 } else { 13923 try { 13924 app.thread.scheduleExit(); 13925 } catch (Exception e) { 13926 // Ignore exceptions. 13927 } 13928 } 13929 cleanUpApplicationRecordLocked(app, false, true, -1); 13930 mRemovedProcesses.remove(i); 13931 13932 if (app.persistent) { 13933 if (app.persistent) { 13934 addAppLocked(app.info); 13935 } 13936 } 13937 } 13938 } 13939 13940 // Now update the oom adj for all processes. 13941 updateOomAdjLocked(); 13942 } 13943 } 13944 13945 /** This method sends the specified signal to each of the persistent apps */ 13946 public void signalPersistentProcesses(int sig) throws RemoteException { 13947 if (sig != Process.SIGNAL_USR1) { 13948 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13949 } 13950 13951 synchronized (this) { 13952 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13953 != PackageManager.PERMISSION_GRANTED) { 13954 throw new SecurityException("Requires permission " 13955 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13956 } 13957 13958 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13959 ProcessRecord r = mLruProcesses.get(i); 13960 if (r.thread != null && r.persistent) { 13961 Process.sendSignal(r.pid, sig); 13962 } 13963 } 13964 } 13965 } 13966 13967 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13968 if (proc == null || proc == mProfileProc) { 13969 proc = mProfileProc; 13970 path = mProfileFile; 13971 profileType = mProfileType; 13972 clearProfilerLocked(); 13973 } 13974 if (proc == null) { 13975 return; 13976 } 13977 try { 13978 proc.thread.profilerControl(false, path, null, profileType); 13979 } catch (RemoteException e) { 13980 throw new IllegalStateException("Process disappeared"); 13981 } 13982 } 13983 13984 private void clearProfilerLocked() { 13985 if (mProfileFd != null) { 13986 try { 13987 mProfileFd.close(); 13988 } catch (IOException e) { 13989 } 13990 } 13991 mProfileApp = null; 13992 mProfileProc = null; 13993 mProfileFile = null; 13994 mProfileType = 0; 13995 mAutoStopProfiler = false; 13996 } 13997 13998 public boolean profileControl(String process, boolean start, 13999 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14000 14001 try { 14002 synchronized (this) { 14003 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14004 // its own permission. 14005 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14006 != PackageManager.PERMISSION_GRANTED) { 14007 throw new SecurityException("Requires permission " 14008 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14009 } 14010 14011 if (start && fd == null) { 14012 throw new IllegalArgumentException("null fd"); 14013 } 14014 14015 ProcessRecord proc = null; 14016 if (process != null) { 14017 try { 14018 int pid = Integer.parseInt(process); 14019 synchronized (mPidsSelfLocked) { 14020 proc = mPidsSelfLocked.get(pid); 14021 } 14022 } catch (NumberFormatException e) { 14023 } 14024 14025 if (proc == null) { 14026 HashMap<String, SparseArray<ProcessRecord>> all 14027 = mProcessNames.getMap(); 14028 SparseArray<ProcessRecord> procs = all.get(process); 14029 if (procs != null && procs.size() > 0) { 14030 proc = procs.valueAt(0); 14031 } 14032 } 14033 } 14034 14035 if (start && (proc == null || proc.thread == null)) { 14036 throw new IllegalArgumentException("Unknown process: " + process); 14037 } 14038 14039 if (start) { 14040 stopProfilerLocked(null, null, 0); 14041 setProfileApp(proc.info, proc.processName, path, fd, false); 14042 mProfileProc = proc; 14043 mProfileType = profileType; 14044 try { 14045 fd = fd.dup(); 14046 } catch (IOException e) { 14047 fd = null; 14048 } 14049 proc.thread.profilerControl(start, path, fd, profileType); 14050 fd = null; 14051 mProfileFd = null; 14052 } else { 14053 stopProfilerLocked(proc, path, profileType); 14054 if (fd != null) { 14055 try { 14056 fd.close(); 14057 } catch (IOException e) { 14058 } 14059 } 14060 } 14061 14062 return true; 14063 } 14064 } catch (RemoteException e) { 14065 throw new IllegalStateException("Process disappeared"); 14066 } finally { 14067 if (fd != null) { 14068 try { 14069 fd.close(); 14070 } catch (IOException e) { 14071 } 14072 } 14073 } 14074 } 14075 14076 public boolean dumpHeap(String process, boolean managed, 14077 String path, ParcelFileDescriptor fd) throws RemoteException { 14078 14079 try { 14080 synchronized (this) { 14081 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14082 // its own permission (same as profileControl). 14083 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14084 != PackageManager.PERMISSION_GRANTED) { 14085 throw new SecurityException("Requires permission " 14086 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14087 } 14088 14089 if (fd == null) { 14090 throw new IllegalArgumentException("null fd"); 14091 } 14092 14093 ProcessRecord proc = null; 14094 try { 14095 int pid = Integer.parseInt(process); 14096 synchronized (mPidsSelfLocked) { 14097 proc = mPidsSelfLocked.get(pid); 14098 } 14099 } catch (NumberFormatException e) { 14100 } 14101 14102 if (proc == null) { 14103 HashMap<String, SparseArray<ProcessRecord>> all 14104 = mProcessNames.getMap(); 14105 SparseArray<ProcessRecord> procs = all.get(process); 14106 if (procs != null && procs.size() > 0) { 14107 proc = procs.valueAt(0); 14108 } 14109 } 14110 14111 if (proc == null || proc.thread == null) { 14112 throw new IllegalArgumentException("Unknown process: " + process); 14113 } 14114 14115 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14116 if (!isDebuggable) { 14117 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14118 throw new SecurityException("Process not debuggable: " + proc); 14119 } 14120 } 14121 14122 proc.thread.dumpHeap(managed, path, fd); 14123 fd = null; 14124 return true; 14125 } 14126 } catch (RemoteException e) { 14127 throw new IllegalStateException("Process disappeared"); 14128 } finally { 14129 if (fd != null) { 14130 try { 14131 fd.close(); 14132 } catch (IOException e) { 14133 } 14134 } 14135 } 14136 } 14137 14138 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14139 public void monitor() { 14140 synchronized (this) { } 14141 } 14142 14143 public void onCoreSettingsChange(Bundle settings) { 14144 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14145 ProcessRecord processRecord = mLruProcesses.get(i); 14146 try { 14147 if (processRecord.thread != null) { 14148 processRecord.thread.setCoreSettings(settings); 14149 } 14150 } catch (RemoteException re) { 14151 /* ignore */ 14152 } 14153 } 14154 } 14155 14156 // Multi-user methods 14157 14158 public boolean switchUser(int userid) { 14159 // TODO 14160 return true; 14161 } 14162 } 14163