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 static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21 import com.android.internal.R; 22 import com.android.internal.os.BatteryStatsImpl; 23 import com.android.internal.os.ProcessStats; 24 import com.android.server.AttributeCache; 25 import com.android.server.IntentResolver; 26 import com.android.server.ProcessMap; 27 import com.android.server.SystemServer; 28 import com.android.server.Watchdog; 29 import com.android.server.am.ActivityStack.ActivityState; 30 import com.android.server.wm.WindowManagerService; 31 32 import dalvik.system.Zygote; 33 34 import android.app.Activity; 35 import android.app.ActivityManager; 36 import android.app.ActivityManagerNative; 37 import android.app.ActivityOptions; 38 import android.app.ActivityThread; 39 import android.app.AlertDialog; 40 import android.app.AppGlobals; 41 import android.app.ApplicationErrorReport; 42 import android.app.Dialog; 43 import android.app.IActivityController; 44 import android.app.IApplicationThread; 45 import android.app.IInstrumentationWatcher; 46 import android.app.INotificationManager; 47 import android.app.IProcessObserver; 48 import android.app.IServiceConnection; 49 import android.app.IThumbnailReceiver; 50 import android.app.Instrumentation; 51 import android.app.Notification; 52 import android.app.NotificationManager; 53 import android.app.PendingIntent; 54 import android.app.Service; 55 import android.app.backup.IBackupManager; 56 import android.content.ActivityNotFoundException; 57 import android.content.BroadcastReceiver; 58 import android.content.ClipData; 59 import android.content.ComponentCallbacks2; 60 import android.content.ComponentName; 61 import android.content.ContentProvider; 62 import android.content.ContentResolver; 63 import android.content.Context; 64 import android.content.DialogInterface; 65 import android.content.IContentProvider; 66 import android.content.IIntentReceiver; 67 import android.content.IIntentSender; 68 import android.content.Intent; 69 import android.content.IntentFilter; 70 import android.content.IntentSender; 71 import android.content.pm.ActivityInfo; 72 import android.content.pm.ApplicationInfo; 73 import android.content.pm.ConfigurationInfo; 74 import android.content.pm.IPackageDataObserver; 75 import android.content.pm.IPackageManager; 76 import android.content.pm.InstrumentationInfo; 77 import android.content.pm.PackageInfo; 78 import android.content.pm.PackageManager; 79 import android.content.pm.PackageManager.NameNotFoundException; 80 import android.content.pm.PathPermission; 81 import android.content.pm.ProviderInfo; 82 import android.content.pm.ResolveInfo; 83 import android.content.pm.ServiceInfo; 84 import android.content.pm.UserInfo; 85 import android.content.res.CompatibilityInfo; 86 import android.content.res.Configuration; 87 import android.graphics.Bitmap; 88 import android.net.Proxy; 89 import android.net.ProxyProperties; 90 import android.net.Uri; 91 import android.os.Binder; 92 import android.os.Build; 93 import android.os.Bundle; 94 import android.os.Debug; 95 import android.os.DropBoxManager; 96 import android.os.Environment; 97 import android.os.FileObserver; 98 import android.os.FileUtils; 99 import android.os.Handler; 100 import android.os.IBinder; 101 import android.os.IPermissionController; 102 import android.os.Looper; 103 import android.os.Message; 104 import android.os.Parcel; 105 import android.os.ParcelFileDescriptor; 106 import android.os.Process; 107 import android.os.RemoteCallbackList; 108 import android.os.RemoteException; 109 import android.os.ServiceManager; 110 import android.os.StrictMode; 111 import android.os.SystemClock; 112 import android.os.SystemProperties; 113 import android.os.UserId; 114 import android.provider.Settings; 115 import android.text.format.Time; 116 import android.util.EventLog; 117 import android.util.Log; 118 import android.util.Pair; 119 import android.util.PrintWriterPrinter; 120 import android.util.Slog; 121 import android.util.SparseArray; 122 import android.util.SparseIntArray; 123 import android.util.TimeUtils; 124 import android.view.Gravity; 125 import android.view.LayoutInflater; 126 import android.view.View; 127 import android.view.WindowManager; 128 import android.view.WindowManagerPolicy; 129 130 import java.io.BufferedInputStream; 131 import java.io.BufferedOutputStream; 132 import java.io.BufferedReader; 133 import java.io.DataInputStream; 134 import java.io.DataOutputStream; 135 import java.io.File; 136 import java.io.FileDescriptor; 137 import java.io.FileInputStream; 138 import java.io.FileNotFoundException; 139 import java.io.FileOutputStream; 140 import java.io.IOException; 141 import java.io.InputStreamReader; 142 import java.io.PrintWriter; 143 import java.io.StringWriter; 144 import java.lang.ref.WeakReference; 145 import java.util.ArrayList; 146 import java.util.Collection; 147 import java.util.Collections; 148 import java.util.Comparator; 149 import java.util.HashMap; 150 import java.util.HashSet; 151 import java.util.Iterator; 152 import java.util.List; 153 import java.util.Locale; 154 import java.util.Map; 155 import java.util.Map.Entry; 156 import java.util.Set; 157 import java.util.concurrent.atomic.AtomicBoolean; 158 import java.util.concurrent.atomic.AtomicLong; 159 160 public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait for a service to finish executing. 245 static final int SERVICE_TIMEOUT = 20*1000; 246 247 // How long a service needs to be running until restarting its process 248 // is no longer considered to be a relaunch of the service. 249 static final int SERVICE_RESTART_DURATION = 5*1000; 250 251 // How long a service needs to be running until it will start back at 252 // SERVICE_RESTART_DURATION after being killed. 253 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 254 255 // Multiplying factor to increase restart duration time by, for each time 256 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 257 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 258 259 // The minimum amount of time between restarting services that we allow. 260 // That is, when multiple services are restarting, we won't allow each 261 // to restart less than this amount of time from the last one. 262 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 263 264 // Maximum amount of time for there to be no activity on a service before 265 // we consider it non-essential and allow its process to go on the 266 // LRU background list. 267 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 268 269 // How long we wait until we timeout on key dispatching. 270 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 271 272 // How long we wait until we timeout on key dispatching during instrumentation. 273 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 274 275 static final int MY_PID = Process.myPid(); 276 277 static final String[] EMPTY_STRING_ARRAY = new String[0]; 278 279 public ActivityStack mMainStack; 280 281 private final boolean mHeadless; 282 283 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 284 // default actuion automatically. Important for devices without direct input 285 // devices. 286 private boolean mShowDialogs = true; 287 288 /** 289 * Description of a request to start a new activity, which has been held 290 * due to app switches being disabled. 291 */ 292 static class PendingActivityLaunch { 293 ActivityRecord r; 294 ActivityRecord sourceRecord; 295 int startFlags; 296 } 297 298 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 299 = new ArrayList<PendingActivityLaunch>(); 300 301 302 BroadcastQueue mFgBroadcastQueue; 303 BroadcastQueue mBgBroadcastQueue; 304 // Convenient for easy iteration over the queues. Foreground is first 305 // so that dispatch of foreground broadcasts gets precedence. 306 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 307 308 BroadcastQueue broadcastQueueForIntent(Intent intent) { 309 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 310 if (DEBUG_BACKGROUND_BROADCAST) { 311 Slog.i(TAG, "Broadcast intent " + intent + " on " 312 + (isFg ? "foreground" : "background") 313 + " queue"); 314 } 315 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 316 } 317 318 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 319 for (BroadcastQueue queue : mBroadcastQueues) { 320 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 321 if (r != null) { 322 return r; 323 } 324 } 325 return null; 326 } 327 328 /** 329 * Activity we have told the window manager to have key focus. 330 */ 331 ActivityRecord mFocusedActivity = null; 332 /** 333 * List of intents that were used to start the most recent tasks. 334 */ 335 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 336 337 /** 338 * Process management. 339 */ 340 final ProcessList mProcessList = new ProcessList(); 341 342 /** 343 * All of the applications we currently have running organized by name. 344 * The keys are strings of the application package name (as 345 * returned by the package manager), and the keys are ApplicationRecord 346 * objects. 347 */ 348 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 349 350 /** 351 * The currently running isolated processes. 352 */ 353 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 354 355 /** 356 * Counter for assigning isolated process uids, to avoid frequently reusing the 357 * same ones. 358 */ 359 int mNextIsolatedProcessUid = 0; 360 361 /** 362 * The currently running heavy-weight process, if any. 363 */ 364 ProcessRecord mHeavyWeightProcess = null; 365 366 /** 367 * The last time that various processes have crashed. 368 */ 369 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 370 371 /** 372 * Set of applications that we consider to be bad, and will reject 373 * incoming broadcasts from (which the user has no control over). 374 * Processes are added to this set when they have crashed twice within 375 * a minimum amount of time; they are removed from it when they are 376 * later restarted (hopefully due to some user action). The value is the 377 * time it was added to the list. 378 */ 379 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 380 381 /** 382 * All of the processes we currently have running organized by pid. 383 * The keys are the pid running the application. 384 * 385 * <p>NOTE: This object is protected by its own lock, NOT the global 386 * activity manager lock! 387 */ 388 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 389 390 /** 391 * All of the processes that have been forced to be foreground. The key 392 * is the pid of the caller who requested it (we hold a death 393 * link on it). 394 */ 395 abstract class ForegroundToken implements IBinder.DeathRecipient { 396 int pid; 397 IBinder token; 398 } 399 final SparseArray<ForegroundToken> mForegroundProcesses 400 = new SparseArray<ForegroundToken>(); 401 402 /** 403 * List of records for processes that someone had tried to start before the 404 * system was ready. We don't start them at that point, but ensure they 405 * are started by the time booting is complete. 406 */ 407 final ArrayList<ProcessRecord> mProcessesOnHold 408 = new ArrayList<ProcessRecord>(); 409 410 /** 411 * List of persistent applications that are in the process 412 * of being started. 413 */ 414 final ArrayList<ProcessRecord> mPersistentStartingProcesses 415 = new ArrayList<ProcessRecord>(); 416 417 /** 418 * Processes that are being forcibly torn down. 419 */ 420 final ArrayList<ProcessRecord> mRemovedProcesses 421 = new ArrayList<ProcessRecord>(); 422 423 /** 424 * List of running applications, sorted by recent usage. 425 * The first entry in the list is the least recently used. 426 * It contains ApplicationRecord objects. This list does NOT include 427 * any persistent application records (since we never want to exit them). 428 */ 429 final ArrayList<ProcessRecord> mLruProcesses 430 = new ArrayList<ProcessRecord>(); 431 432 /** 433 * List of processes that should gc as soon as things are idle. 434 */ 435 final ArrayList<ProcessRecord> mProcessesToGc 436 = new ArrayList<ProcessRecord>(); 437 438 /** 439 * This is the process holding what we currently consider to be 440 * the "home" activity. 441 */ 442 ProcessRecord mHomeProcess; 443 444 /** 445 * This is the process holding the activity the user last visited that 446 * is in a different process from the one they are currently in. 447 */ 448 ProcessRecord mPreviousProcess; 449 450 /** 451 * The time at which the previous process was last visible. 452 */ 453 long mPreviousProcessVisibleTime; 454 455 /** 456 * Packages that the user has asked to have run in screen size 457 * compatibility mode instead of filling the screen. 458 */ 459 final CompatModePackages mCompatModePackages; 460 461 /** 462 * Set of PendingResultRecord objects that are currently active. 463 */ 464 final HashSet mPendingResultRecords = new HashSet(); 465 466 /** 467 * Set of IntentSenderRecord objects that are currently active. 468 */ 469 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 470 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 471 472 /** 473 * Fingerprints (hashCode()) of stack traces that we've 474 * already logged DropBox entries for. Guarded by itself. If 475 * something (rogue user app) forces this over 476 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 477 */ 478 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 479 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 480 481 /** 482 * Strict Mode background batched logging state. 483 * 484 * The string buffer is guarded by itself, and its lock is also 485 * used to determine if another batched write is already 486 * in-flight. 487 */ 488 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 489 490 /** 491 * Keeps track of all IIntentReceivers that have been registered for 492 * broadcasts. Hash keys are the receiver IBinder, hash value is 493 * a ReceiverList. 494 */ 495 final HashMap mRegisteredReceivers = new HashMap(); 496 497 /** 498 * Resolver for broadcast intents to registered receivers. 499 * Holds BroadcastFilter (subclass of IntentFilter). 500 */ 501 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 502 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 503 @Override 504 protected boolean allowFilterResult( 505 BroadcastFilter filter, List<BroadcastFilter> dest) { 506 IBinder target = filter.receiverList.receiver.asBinder(); 507 for (int i=dest.size()-1; i>=0; i--) { 508 if (dest.get(i).receiverList.receiver.asBinder() == target) { 509 return false; 510 } 511 } 512 return true; 513 } 514 515 @Override 516 protected String packageForFilter(BroadcastFilter filter) { 517 return filter.packageName; 518 } 519 }; 520 521 /** 522 * State of all active sticky broadcasts. Keys are the action of the 523 * sticky Intent, values are an ArrayList of all broadcasted intents with 524 * that action (which should usually be one). 525 */ 526 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 527 new HashMap<String, ArrayList<Intent>>(); 528 529 final ServiceMap mServiceMap = new ServiceMap(); 530 531 /** 532 * All currently bound service connections. Keys are the IBinder of 533 * the client's IServiceConnection. 534 */ 535 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections 536 = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); 537 538 /** 539 * List of services that we have been asked to start, 540 * but haven't yet been able to. It is used to hold start requests 541 * while waiting for their corresponding application thread to get 542 * going. 543 */ 544 final ArrayList<ServiceRecord> mPendingServices 545 = new ArrayList<ServiceRecord>(); 546 547 /** 548 * List of services that are scheduled to restart following a crash. 549 */ 550 final ArrayList<ServiceRecord> mRestartingServices 551 = new ArrayList<ServiceRecord>(); 552 553 /** 554 * List of services that are in the process of being stopped. 555 */ 556 final ArrayList<ServiceRecord> mStoppingServices 557 = new ArrayList<ServiceRecord>(); 558 559 /** 560 * Backup/restore process management 561 */ 562 String mBackupAppName = null; 563 BackupRecord mBackupTarget = null; 564 565 /** 566 * List of PendingThumbnailsRecord objects of clients who are still 567 * waiting to receive all of the thumbnails for a task. 568 */ 569 final ArrayList mPendingThumbnails = new ArrayList(); 570 571 /** 572 * List of HistoryRecord objects that have been finished and must 573 * still report back to a pending thumbnail receiver. 574 */ 575 final ArrayList mCancelledThumbnails = new ArrayList(); 576 577 final ProviderMap mProviderMap = new ProviderMap(); 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 610 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 611 612 /** 613 * All information we have collected about the runtime performance of 614 * any user id that can impact battery performance. 615 */ 616 final BatteryStatsService mBatteryStatsService; 617 618 /** 619 * information about component usage 620 */ 621 final UsageStatsService mUsageStatsService; 622 623 /** 624 * Current configuration information. HistoryRecord objects are given 625 * a reference to this object to indicate which configuration they are 626 * currently running in, so this object must be kept immutable. 627 */ 628 Configuration mConfiguration = new Configuration(); 629 630 /** 631 * Current sequencing integer of the configuration, for skipping old 632 * configurations. 633 */ 634 int mConfigurationSeq = 0; 635 636 /** 637 * Hardware-reported OpenGLES version. 638 */ 639 final int GL_ES_VERSION; 640 641 /** 642 * List of initialization arguments to pass to all processes when binding applications to them. 643 * For example, references to the commonly used services. 644 */ 645 HashMap<String, IBinder> mAppBindArgs; 646 647 /** 648 * Temporary to avoid allocations. Protected by main lock. 649 */ 650 final StringBuilder mStringBuilder = new StringBuilder(256); 651 652 /** 653 * Used to control how we initialize the service. 654 */ 655 boolean mStartRunning = false; 656 ComponentName mTopComponent; 657 String mTopAction; 658 String mTopData; 659 boolean mProcessesReady = false; 660 boolean mSystemReady = false; 661 boolean mBooting = false; 662 boolean mWaitingUpdate = false; 663 boolean mDidUpdate = false; 664 boolean mOnBattery = false; 665 boolean mLaunchWarningShown = false; 666 667 Context mContext; 668 669 int mFactoryTest; 670 671 boolean mCheckedForSetup; 672 673 /** 674 * The time at which we will allow normal application switches again, 675 * after a call to {@link #stopAppSwitches()}. 676 */ 677 long mAppSwitchesAllowedTime; 678 679 /** 680 * This is set to true after the first switch after mAppSwitchesAllowedTime 681 * is set; any switches after that will clear the time. 682 */ 683 boolean mDidAppSwitch; 684 685 /** 686 * Last time (in realtime) at which we checked for power usage. 687 */ 688 long mLastPowerCheckRealtime; 689 690 /** 691 * Last time (in uptime) at which we checked for power usage. 692 */ 693 long mLastPowerCheckUptime; 694 695 /** 696 * Set while we are wanting to sleep, to prevent any 697 * activities from being started/resumed. 698 */ 699 boolean mSleeping = false; 700 701 /** 702 * State of external calls telling us if the device is asleep. 703 */ 704 boolean mWentToSleep = false; 705 706 /** 707 * State of external call telling us if the lock screen is shown. 708 */ 709 boolean mLockScreenShown = false; 710 711 /** 712 * Set if we are shutting down the system, similar to sleeping. 713 */ 714 boolean mShuttingDown = false; 715 716 /** 717 * Task identifier that activities are currently being started 718 * in. Incremented each time a new task is created. 719 * todo: Replace this with a TokenSpace class that generates non-repeating 720 * integers that won't wrap. 721 */ 722 int mCurTask = 1; 723 724 /** 725 * Current sequence id for oom_adj computation traversal. 726 */ 727 int mAdjSeq = 0; 728 729 /** 730 * Current sequence id for process LRU updating. 731 */ 732 int mLruSeq = 0; 733 734 /** 735 * Keep track of the number of service processes we last found, to 736 * determine on the next iteration which should be B services. 737 */ 738 int mNumServiceProcs = 0; 739 int mNewNumServiceProcs = 0; 740 741 /** 742 * System monitoring: number of processes that died since the last 743 * N procs were started. 744 */ 745 int[] mProcDeaths = new int[20]; 746 747 /** 748 * This is set if we had to do a delayed dexopt of an app before launching 749 * it, to increasing the ANR timeouts in that case. 750 */ 751 boolean mDidDexOpt; 752 753 String mDebugApp = null; 754 boolean mWaitForDebugger = false; 755 boolean mDebugTransient = false; 756 String mOrigDebugApp = null; 757 boolean mOrigWaitForDebugger = false; 758 boolean mAlwaysFinishActivities = false; 759 IActivityController mController = null; 760 String mProfileApp = null; 761 ProcessRecord mProfileProc = null; 762 String mProfileFile; 763 ParcelFileDescriptor mProfileFd; 764 int mProfileType = 0; 765 boolean mAutoStopProfiler = false; 766 String mOpenGlTraceApp = null; 767 768 static class ProcessChangeItem { 769 static final int CHANGE_ACTIVITIES = 1<<0; 770 static final int CHANGE_IMPORTANCE= 1<<1; 771 int changes; 772 int uid; 773 int pid; 774 int importance; 775 boolean foregroundActivities; 776 } 777 778 final RemoteCallbackList<IProcessObserver> mProcessObservers 779 = new RemoteCallbackList<IProcessObserver>(); 780 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 781 782 final ArrayList<ProcessChangeItem> mPendingProcessChanges 783 = new ArrayList<ProcessChangeItem>(); 784 final ArrayList<ProcessChangeItem> mAvailProcessChanges 785 = new ArrayList<ProcessChangeItem>(); 786 787 /** 788 * Callback of last caller to {@link #requestPss}. 789 */ 790 Runnable mRequestPssCallback; 791 792 /** 793 * Remaining processes for which we are waiting results from the last 794 * call to {@link #requestPss}. 795 */ 796 final ArrayList<ProcessRecord> mRequestPssList 797 = new ArrayList<ProcessRecord>(); 798 799 /** 800 * Runtime statistics collection thread. This object's lock is used to 801 * protect all related state. 802 */ 803 final Thread mProcessStatsThread; 804 805 /** 806 * Used to collect process stats when showing not responding dialog. 807 * Protected by mProcessStatsThread. 808 */ 809 final ProcessStats mProcessStats = new ProcessStats( 810 MONITOR_THREAD_CPU_USAGE); 811 final AtomicLong mLastCpuTime = new AtomicLong(0); 812 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 813 814 long mLastWriteTime = 0; 815 816 /** 817 * Set to true after the system has finished booting. 818 */ 819 boolean mBooted = false; 820 821 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 822 int mProcessLimitOverride = -1; 823 824 WindowManagerService mWindowManager; 825 826 static ActivityManagerService mSelf; 827 static ActivityThread mSystemThread; 828 829 private final class AppDeathRecipient implements IBinder.DeathRecipient { 830 final ProcessRecord mApp; 831 final int mPid; 832 final IApplicationThread mAppThread; 833 834 AppDeathRecipient(ProcessRecord app, int pid, 835 IApplicationThread thread) { 836 if (localLOGV) Slog.v( 837 TAG, "New death recipient " + this 838 + " for thread " + thread.asBinder()); 839 mApp = app; 840 mPid = pid; 841 mAppThread = thread; 842 } 843 844 public void binderDied() { 845 if (localLOGV) Slog.v( 846 TAG, "Death received in " + this 847 + " for thread " + mAppThread.asBinder()); 848 synchronized(ActivityManagerService.this) { 849 appDiedLocked(mApp, mPid, mAppThread); 850 } 851 } 852 } 853 854 static final int SHOW_ERROR_MSG = 1; 855 static final int SHOW_NOT_RESPONDING_MSG = 2; 856 static final int SHOW_FACTORY_ERROR_MSG = 3; 857 static final int UPDATE_CONFIGURATION_MSG = 4; 858 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 859 static final int WAIT_FOR_DEBUGGER_MSG = 6; 860 static final int SERVICE_TIMEOUT_MSG = 12; 861 static final int UPDATE_TIME_ZONE = 13; 862 static final int SHOW_UID_ERROR_MSG = 14; 863 static final int IM_FEELING_LUCKY_MSG = 15; 864 static final int PROC_START_TIMEOUT_MSG = 20; 865 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 866 static final int KILL_APPLICATION_MSG = 22; 867 static final int FINALIZE_PENDING_INTENT_MSG = 23; 868 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 869 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 870 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 871 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 872 static final int CLEAR_DNS_CACHE = 28; 873 static final int UPDATE_HTTP_PROXY = 29; 874 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 875 static final int DISPATCH_PROCESSES_CHANGED = 31; 876 static final int DISPATCH_PROCESS_DIED = 32; 877 static final int REPORT_MEM_USAGE = 33; 878 879 static final int FIRST_ACTIVITY_STACK_MSG = 100; 880 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 881 static final int FIRST_COMPAT_MODE_MSG = 300; 882 883 AlertDialog mUidAlert; 884 CompatModeDialog mCompatModeDialog; 885 long mLastMemUsageReportTime = 0; 886 887 final Handler mHandler = new Handler() { 888 //public Handler() { 889 // if (localLOGV) Slog.v(TAG, "Handler started!"); 890 //} 891 892 public void handleMessage(Message msg) { 893 switch (msg.what) { 894 case SHOW_ERROR_MSG: { 895 HashMap data = (HashMap) msg.obj; 896 synchronized (ActivityManagerService.this) { 897 ProcessRecord proc = (ProcessRecord)data.get("app"); 898 if (proc != null && proc.crashDialog != null) { 899 Slog.e(TAG, "App already has crash dialog: " + proc); 900 return; 901 } 902 AppErrorResult res = (AppErrorResult) data.get("result"); 903 if (mShowDialogs && !mSleeping && !mShuttingDown) { 904 Dialog d = new AppErrorDialog(mContext, res, proc); 905 d.show(); 906 proc.crashDialog = d; 907 } else { 908 // The device is asleep, so just pretend that the user 909 // saw a crash dialog and hit "force quit". 910 res.set(0); 911 } 912 } 913 914 ensureBootCompleted(); 915 } break; 916 case SHOW_NOT_RESPONDING_MSG: { 917 synchronized (ActivityManagerService.this) { 918 HashMap data = (HashMap) msg.obj; 919 ProcessRecord proc = (ProcessRecord)data.get("app"); 920 if (proc != null && proc.anrDialog != null) { 921 Slog.e(TAG, "App already has anr dialog: " + proc); 922 return; 923 } 924 925 Intent intent = new Intent("android.intent.action.ANR"); 926 if (!mProcessesReady) { 927 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 928 | Intent.FLAG_RECEIVER_FOREGROUND); 929 } 930 broadcastIntentLocked(null, null, intent, 931 null, null, 0, null, null, null, 932 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 933 934 if (mShowDialogs) { 935 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 936 mContext, proc, (ActivityRecord)data.get("activity")); 937 d.show(); 938 proc.anrDialog = d; 939 } else { 940 // Just kill the app if there is no dialog to be shown. 941 killAppAtUsersRequest(proc, null); 942 } 943 } 944 945 ensureBootCompleted(); 946 } break; 947 case SHOW_STRICT_MODE_VIOLATION_MSG: { 948 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 949 synchronized (ActivityManagerService.this) { 950 ProcessRecord proc = (ProcessRecord) data.get("app"); 951 if (proc == null) { 952 Slog.e(TAG, "App not found when showing strict mode dialog."); 953 break; 954 } 955 if (proc.crashDialog != null) { 956 Slog.e(TAG, "App already has strict mode dialog: " + proc); 957 return; 958 } 959 AppErrorResult res = (AppErrorResult) data.get("result"); 960 if (mShowDialogs && !mSleeping && !mShuttingDown) { 961 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 962 d.show(); 963 proc.crashDialog = d; 964 } else { 965 // The device is asleep, so just pretend that the user 966 // saw a crash dialog and hit "force quit". 967 res.set(0); 968 } 969 } 970 ensureBootCompleted(); 971 } break; 972 case SHOW_FACTORY_ERROR_MSG: { 973 Dialog d = new FactoryErrorDialog( 974 mContext, msg.getData().getCharSequence("msg")); 975 d.show(); 976 ensureBootCompleted(); 977 } break; 978 case UPDATE_CONFIGURATION_MSG: { 979 final ContentResolver resolver = mContext.getContentResolver(); 980 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 981 } break; 982 case GC_BACKGROUND_PROCESSES_MSG: { 983 synchronized (ActivityManagerService.this) { 984 performAppGcsIfAppropriateLocked(); 985 } 986 } break; 987 case WAIT_FOR_DEBUGGER_MSG: { 988 synchronized (ActivityManagerService.this) { 989 ProcessRecord app = (ProcessRecord)msg.obj; 990 if (msg.arg1 != 0) { 991 if (!app.waitedForDebugger) { 992 Dialog d = new AppWaitingForDebuggerDialog( 993 ActivityManagerService.this, 994 mContext, app); 995 app.waitDialog = d; 996 app.waitedForDebugger = true; 997 d.show(); 998 } 999 } else { 1000 if (app.waitDialog != null) { 1001 app.waitDialog.dismiss(); 1002 app.waitDialog = null; 1003 } 1004 } 1005 } 1006 } break; 1007 case SERVICE_TIMEOUT_MSG: { 1008 if (mDidDexOpt) { 1009 mDidDexOpt = false; 1010 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1011 nmsg.obj = msg.obj; 1012 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1013 return; 1014 } 1015 serviceTimeout((ProcessRecord)msg.obj); 1016 } break; 1017 case UPDATE_TIME_ZONE: { 1018 synchronized (ActivityManagerService.this) { 1019 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1020 ProcessRecord r = mLruProcesses.get(i); 1021 if (r.thread != null) { 1022 try { 1023 r.thread.updateTimeZone(); 1024 } catch (RemoteException ex) { 1025 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1026 } 1027 } 1028 } 1029 } 1030 } break; 1031 case CLEAR_DNS_CACHE: { 1032 synchronized (ActivityManagerService.this) { 1033 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1034 ProcessRecord r = mLruProcesses.get(i); 1035 if (r.thread != null) { 1036 try { 1037 r.thread.clearDnsCache(); 1038 } catch (RemoteException ex) { 1039 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1040 } 1041 } 1042 } 1043 } 1044 } break; 1045 case UPDATE_HTTP_PROXY: { 1046 ProxyProperties proxy = (ProxyProperties)msg.obj; 1047 String host = ""; 1048 String port = ""; 1049 String exclList = ""; 1050 if (proxy != null) { 1051 host = proxy.getHost(); 1052 port = Integer.toString(proxy.getPort()); 1053 exclList = proxy.getExclusionList(); 1054 } 1055 synchronized (ActivityManagerService.this) { 1056 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1057 ProcessRecord r = mLruProcesses.get(i); 1058 if (r.thread != null) { 1059 try { 1060 r.thread.setHttpProxy(host, port, exclList); 1061 } catch (RemoteException ex) { 1062 Slog.w(TAG, "Failed to update http proxy for: " + 1063 r.info.processName); 1064 } 1065 } 1066 } 1067 } 1068 } break; 1069 case SHOW_UID_ERROR_MSG: { 1070 String title = "System UIDs Inconsistent"; 1071 String text = "UIDs on the system are inconsistent, you need to wipe your" 1072 + " data partition or your device will be unstable."; 1073 Log.e(TAG, title + ": " + text); 1074 if (mShowDialogs) { 1075 // XXX This is a temporary dialog, no need to localize. 1076 AlertDialog d = new BaseErrorDialog(mContext); 1077 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1078 d.setCancelable(false); 1079 d.setTitle(title); 1080 d.setMessage(text); 1081 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1082 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1083 mUidAlert = d; 1084 d.show(); 1085 } 1086 } break; 1087 case IM_FEELING_LUCKY_MSG: { 1088 if (mUidAlert != null) { 1089 mUidAlert.dismiss(); 1090 mUidAlert = null; 1091 } 1092 } break; 1093 case PROC_START_TIMEOUT_MSG: { 1094 if (mDidDexOpt) { 1095 mDidDexOpt = false; 1096 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1097 nmsg.obj = msg.obj; 1098 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1099 return; 1100 } 1101 ProcessRecord app = (ProcessRecord)msg.obj; 1102 synchronized (ActivityManagerService.this) { 1103 processStartTimedOutLocked(app); 1104 } 1105 } break; 1106 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1107 synchronized (ActivityManagerService.this) { 1108 doPendingActivityLaunchesLocked(true); 1109 } 1110 } break; 1111 case KILL_APPLICATION_MSG: { 1112 synchronized (ActivityManagerService.this) { 1113 int uid = msg.arg1; 1114 boolean restart = (msg.arg2 == 1); 1115 String pkg = (String) msg.obj; 1116 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1117 UserId.getUserId(uid)); 1118 } 1119 } break; 1120 case FINALIZE_PENDING_INTENT_MSG: { 1121 ((PendingIntentRecord)msg.obj).completeFinalize(); 1122 } break; 1123 case POST_HEAVY_NOTIFICATION_MSG: { 1124 INotificationManager inm = NotificationManager.getService(); 1125 if (inm == null) { 1126 return; 1127 } 1128 1129 ActivityRecord root = (ActivityRecord)msg.obj; 1130 ProcessRecord process = root.app; 1131 if (process == null) { 1132 return; 1133 } 1134 1135 try { 1136 Context context = mContext.createPackageContext(process.info.packageName, 0); 1137 String text = mContext.getString(R.string.heavy_weight_notification, 1138 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1139 Notification notification = new Notification(); 1140 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1141 notification.when = 0; 1142 notification.flags = Notification.FLAG_ONGOING_EVENT; 1143 notification.tickerText = text; 1144 notification.defaults = 0; // please be quiet 1145 notification.sound = null; 1146 notification.vibrate = null; 1147 notification.setLatestEventInfo(context, text, 1148 mContext.getText(R.string.heavy_weight_notification_detail), 1149 PendingIntent.getActivity(mContext, 0, root.intent, 1150 PendingIntent.FLAG_CANCEL_CURRENT)); 1151 1152 try { 1153 int[] outId = new int[1]; 1154 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1155 notification, outId); 1156 } catch (RuntimeException e) { 1157 Slog.w(ActivityManagerService.TAG, 1158 "Error showing notification for heavy-weight app", e); 1159 } catch (RemoteException e) { 1160 } 1161 } catch (NameNotFoundException e) { 1162 Slog.w(TAG, "Unable to create context for heavy notification", e); 1163 } 1164 } break; 1165 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1166 INotificationManager inm = NotificationManager.getService(); 1167 if (inm == null) { 1168 return; 1169 } 1170 try { 1171 inm.cancelNotification("android", 1172 R.string.heavy_weight_notification); 1173 } catch (RuntimeException e) { 1174 Slog.w(ActivityManagerService.TAG, 1175 "Error canceling notification for service", e); 1176 } catch (RemoteException e) { 1177 } 1178 } break; 1179 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1180 synchronized (ActivityManagerService.this) { 1181 checkExcessivePowerUsageLocked(true); 1182 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1183 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1184 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1185 } 1186 } break; 1187 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1188 synchronized (ActivityManagerService.this) { 1189 ActivityRecord ar = (ActivityRecord)msg.obj; 1190 if (mCompatModeDialog != null) { 1191 if (mCompatModeDialog.mAppInfo.packageName.equals( 1192 ar.info.applicationInfo.packageName)) { 1193 return; 1194 } 1195 mCompatModeDialog.dismiss(); 1196 mCompatModeDialog = null; 1197 } 1198 if (ar != null && false) { 1199 if (mCompatModePackages.getPackageAskCompatModeLocked( 1200 ar.packageName)) { 1201 int mode = mCompatModePackages.computeCompatModeLocked( 1202 ar.info.applicationInfo); 1203 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1204 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1205 mCompatModeDialog = new CompatModeDialog( 1206 ActivityManagerService.this, mContext, 1207 ar.info.applicationInfo); 1208 mCompatModeDialog.show(); 1209 } 1210 } 1211 } 1212 } 1213 break; 1214 } 1215 case DISPATCH_PROCESSES_CHANGED: { 1216 dispatchProcessesChanged(); 1217 break; 1218 } 1219 case DISPATCH_PROCESS_DIED: { 1220 final int pid = msg.arg1; 1221 final int uid = msg.arg2; 1222 dispatchProcessDied(pid, uid); 1223 break; 1224 } 1225 case REPORT_MEM_USAGE: { 1226 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1227 if (!isDebuggable) { 1228 return; 1229 } 1230 synchronized (ActivityManagerService.this) { 1231 long now = SystemClock.uptimeMillis(); 1232 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1233 // Don't report more than every 5 minutes to somewhat 1234 // avoid spamming. 1235 return; 1236 } 1237 mLastMemUsageReportTime = now; 1238 } 1239 Thread thread = new Thread() { 1240 @Override public void run() { 1241 StringBuilder dropBuilder = new StringBuilder(1024); 1242 StringBuilder logBuilder = new StringBuilder(1024); 1243 StringWriter oomSw = new StringWriter(); 1244 PrintWriter oomPw = new PrintWriter(oomSw); 1245 StringWriter catSw = new StringWriter(); 1246 PrintWriter catPw = new PrintWriter(catSw); 1247 String[] emptyArgs = new String[] { }; 1248 StringBuilder tag = new StringBuilder(128); 1249 StringBuilder stack = new StringBuilder(128); 1250 tag.append("Low on memory -- "); 1251 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1252 tag, stack); 1253 dropBuilder.append(stack); 1254 dropBuilder.append('\n'); 1255 dropBuilder.append('\n'); 1256 String oomString = oomSw.toString(); 1257 dropBuilder.append(oomString); 1258 dropBuilder.append('\n'); 1259 logBuilder.append(oomString); 1260 try { 1261 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1262 "procrank", }); 1263 final InputStreamReader converter = new InputStreamReader( 1264 proc.getInputStream()); 1265 BufferedReader in = new BufferedReader(converter); 1266 String line; 1267 while (true) { 1268 line = in.readLine(); 1269 if (line == null) { 1270 break; 1271 } 1272 if (line.length() > 0) { 1273 logBuilder.append(line); 1274 logBuilder.append('\n'); 1275 } 1276 dropBuilder.append(line); 1277 dropBuilder.append('\n'); 1278 } 1279 converter.close(); 1280 } catch (IOException e) { 1281 } 1282 synchronized (ActivityManagerService.this) { 1283 catPw.println(); 1284 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1285 catPw.println(); 1286 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null); 1287 catPw.println(); 1288 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1289 } 1290 dropBuilder.append(catSw.toString()); 1291 addErrorToDropBox("lowmem", null, "system_server", null, 1292 null, tag.toString(), dropBuilder.toString(), null, null); 1293 Slog.i(TAG, logBuilder.toString()); 1294 synchronized (ActivityManagerService.this) { 1295 long now = SystemClock.uptimeMillis(); 1296 if (mLastMemUsageReportTime < now) { 1297 mLastMemUsageReportTime = now; 1298 } 1299 } 1300 } 1301 }; 1302 thread.start(); 1303 break; 1304 } 1305 } 1306 } 1307 }; 1308 1309 public static void setSystemProcess() { 1310 try { 1311 ActivityManagerService m = mSelf; 1312 1313 ServiceManager.addService("activity", m, true); 1314 ServiceManager.addService("meminfo", new MemBinder(m)); 1315 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1316 ServiceManager.addService("dbinfo", new DbBinder(m)); 1317 if (MONITOR_CPU_USAGE) { 1318 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1319 } 1320 ServiceManager.addService("permission", new PermissionController(m)); 1321 1322 ApplicationInfo info = 1323 mSelf.mContext.getPackageManager().getApplicationInfo( 1324 "android", STOCK_PM_FLAGS); 1325 mSystemThread.installSystemApplicationInfo(info); 1326 1327 synchronized (mSelf) { 1328 ProcessRecord app = mSelf.newProcessRecordLocked( 1329 mSystemThread.getApplicationThread(), info, 1330 info.processName, false); 1331 app.persistent = true; 1332 app.pid = MY_PID; 1333 app.maxAdj = ProcessList.SYSTEM_ADJ; 1334 mSelf.mProcessNames.put(app.processName, app.uid, app); 1335 synchronized (mSelf.mPidsSelfLocked) { 1336 mSelf.mPidsSelfLocked.put(app.pid, app); 1337 } 1338 mSelf.updateLruProcessLocked(app, true, true); 1339 } 1340 } catch (PackageManager.NameNotFoundException e) { 1341 throw new RuntimeException( 1342 "Unable to find android system package", e); 1343 } 1344 } 1345 1346 public void setWindowManager(WindowManagerService wm) { 1347 mWindowManager = wm; 1348 } 1349 1350 public static final Context main(int factoryTest) { 1351 AThread thr = new AThread(); 1352 thr.start(); 1353 1354 synchronized (thr) { 1355 while (thr.mService == null) { 1356 try { 1357 thr.wait(); 1358 } catch (InterruptedException e) { 1359 } 1360 } 1361 } 1362 1363 ActivityManagerService m = thr.mService; 1364 mSelf = m; 1365 ActivityThread at = ActivityThread.systemMain(); 1366 mSystemThread = at; 1367 Context context = at.getSystemContext(); 1368 context.setTheme(android.R.style.Theme_Holo); 1369 m.mContext = context; 1370 m.mFactoryTest = factoryTest; 1371 m.mMainStack = new ActivityStack(m, context, true); 1372 1373 m.mBatteryStatsService.publish(context); 1374 m.mUsageStatsService.publish(context); 1375 1376 synchronized (thr) { 1377 thr.mReady = true; 1378 thr.notifyAll(); 1379 } 1380 1381 m.startRunning(null, null, null, null); 1382 1383 return context; 1384 } 1385 1386 public static ActivityManagerService self() { 1387 return mSelf; 1388 } 1389 1390 static class AThread extends Thread { 1391 ActivityManagerService mService; 1392 boolean mReady = false; 1393 1394 public AThread() { 1395 super("ActivityManager"); 1396 } 1397 1398 public void run() { 1399 Looper.prepare(); 1400 1401 android.os.Process.setThreadPriority( 1402 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1403 android.os.Process.setCanSelfBackground(false); 1404 1405 ActivityManagerService m = new ActivityManagerService(); 1406 1407 synchronized (this) { 1408 mService = m; 1409 notifyAll(); 1410 } 1411 1412 synchronized (this) { 1413 while (!mReady) { 1414 try { 1415 wait(); 1416 } catch (InterruptedException e) { 1417 } 1418 } 1419 } 1420 1421 // For debug builds, log event loop stalls to dropbox for analysis. 1422 if (StrictMode.conditionallyEnableDebugLogging()) { 1423 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1424 } 1425 1426 Looper.loop(); 1427 } 1428 } 1429 1430 static class MemBinder extends Binder { 1431 ActivityManagerService mActivityManagerService; 1432 MemBinder(ActivityManagerService activityManagerService) { 1433 mActivityManagerService = activityManagerService; 1434 } 1435 1436 @Override 1437 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1438 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1439 != PackageManager.PERMISSION_GRANTED) { 1440 pw.println("Permission Denial: can't dump meminfo from from pid=" 1441 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1442 + " without permission " + android.Manifest.permission.DUMP); 1443 return; 1444 } 1445 1446 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1447 false, null, null, null); 1448 } 1449 } 1450 1451 static class GraphicsBinder extends Binder { 1452 ActivityManagerService mActivityManagerService; 1453 GraphicsBinder(ActivityManagerService activityManagerService) { 1454 mActivityManagerService = activityManagerService; 1455 } 1456 1457 @Override 1458 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1459 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1460 != PackageManager.PERMISSION_GRANTED) { 1461 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1462 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1463 + " without permission " + android.Manifest.permission.DUMP); 1464 return; 1465 } 1466 1467 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1468 } 1469 } 1470 1471 static class DbBinder extends Binder { 1472 ActivityManagerService mActivityManagerService; 1473 DbBinder(ActivityManagerService activityManagerService) { 1474 mActivityManagerService = activityManagerService; 1475 } 1476 1477 @Override 1478 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1479 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1480 != PackageManager.PERMISSION_GRANTED) { 1481 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1482 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1483 + " without permission " + android.Manifest.permission.DUMP); 1484 return; 1485 } 1486 1487 mActivityManagerService.dumpDbInfo(fd, pw, args); 1488 } 1489 } 1490 1491 static class CpuBinder extends Binder { 1492 ActivityManagerService mActivityManagerService; 1493 CpuBinder(ActivityManagerService activityManagerService) { 1494 mActivityManagerService = activityManagerService; 1495 } 1496 1497 @Override 1498 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1499 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1500 != PackageManager.PERMISSION_GRANTED) { 1501 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1502 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1503 + " without permission " + android.Manifest.permission.DUMP); 1504 return; 1505 } 1506 1507 synchronized (mActivityManagerService.mProcessStatsThread) { 1508 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1509 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1510 SystemClock.uptimeMillis())); 1511 } 1512 } 1513 } 1514 1515 private ActivityManagerService() { 1516 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1517 1518 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1519 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1520 mBroadcastQueues[0] = mFgBroadcastQueue; 1521 mBroadcastQueues[1] = mBgBroadcastQueue; 1522 1523 File dataDir = Environment.getDataDirectory(); 1524 File systemDir = new File(dataDir, "system"); 1525 systemDir.mkdirs(); 1526 mBatteryStatsService = new BatteryStatsService(new File( 1527 systemDir, "batterystats.bin").toString()); 1528 mBatteryStatsService.getActiveStatistics().readLocked(); 1529 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1530 mOnBattery = DEBUG_POWER ? true 1531 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1532 mBatteryStatsService.getActiveStatistics().setCallback(this); 1533 1534 mUsageStatsService = new UsageStatsService(new File( 1535 systemDir, "usagestats").toString()); 1536 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1537 1538 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1539 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1540 1541 mConfiguration.setToDefaults(); 1542 mConfiguration.locale = Locale.getDefault(); 1543 mConfigurationSeq = mConfiguration.seq = 1; 1544 mProcessStats.init(); 1545 1546 mCompatModePackages = new CompatModePackages(this, systemDir); 1547 1548 // Add ourself to the Watchdog monitors. 1549 Watchdog.getInstance().addMonitor(this); 1550 1551 mProcessStatsThread = new Thread("ProcessStats") { 1552 public void run() { 1553 while (true) { 1554 try { 1555 try { 1556 synchronized(this) { 1557 final long now = SystemClock.uptimeMillis(); 1558 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1559 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1560 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1561 // + ", write delay=" + nextWriteDelay); 1562 if (nextWriteDelay < nextCpuDelay) { 1563 nextCpuDelay = nextWriteDelay; 1564 } 1565 if (nextCpuDelay > 0) { 1566 mProcessStatsMutexFree.set(true); 1567 this.wait(nextCpuDelay); 1568 } 1569 } 1570 } catch (InterruptedException e) { 1571 } 1572 updateCpuStatsNow(); 1573 } catch (Exception e) { 1574 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1575 } 1576 } 1577 } 1578 }; 1579 mProcessStatsThread.start(); 1580 } 1581 1582 @Override 1583 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1584 throws RemoteException { 1585 if (code == SYSPROPS_TRANSACTION) { 1586 // We need to tell all apps about the system property change. 1587 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1588 synchronized(this) { 1589 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1590 final int NA = apps.size(); 1591 for (int ia=0; ia<NA; ia++) { 1592 ProcessRecord app = apps.valueAt(ia); 1593 if (app.thread != null) { 1594 procs.add(app.thread.asBinder()); 1595 } 1596 } 1597 } 1598 } 1599 1600 int N = procs.size(); 1601 for (int i=0; i<N; i++) { 1602 Parcel data2 = Parcel.obtain(); 1603 try { 1604 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1605 } catch (RemoteException e) { 1606 } 1607 data2.recycle(); 1608 } 1609 } 1610 try { 1611 return super.onTransact(code, data, reply, flags); 1612 } catch (RuntimeException e) { 1613 // The activity manager only throws security exceptions, so let's 1614 // log all others. 1615 if (!(e instanceof SecurityException)) { 1616 Slog.e(TAG, "Activity Manager Crash", e); 1617 } 1618 throw e; 1619 } 1620 } 1621 1622 void updateCpuStats() { 1623 final long now = SystemClock.uptimeMillis(); 1624 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1625 return; 1626 } 1627 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1628 synchronized (mProcessStatsThread) { 1629 mProcessStatsThread.notify(); 1630 } 1631 } 1632 } 1633 1634 void updateCpuStatsNow() { 1635 synchronized (mProcessStatsThread) { 1636 mProcessStatsMutexFree.set(false); 1637 final long now = SystemClock.uptimeMillis(); 1638 boolean haveNewCpuStats = false; 1639 1640 if (MONITOR_CPU_USAGE && 1641 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1642 mLastCpuTime.set(now); 1643 haveNewCpuStats = true; 1644 mProcessStats.update(); 1645 //Slog.i(TAG, mProcessStats.printCurrentState()); 1646 //Slog.i(TAG, "Total CPU usage: " 1647 // + mProcessStats.getTotalCpuPercent() + "%"); 1648 1649 // Slog the cpu usage if the property is set. 1650 if ("true".equals(SystemProperties.get("events.cpu"))) { 1651 int user = mProcessStats.getLastUserTime(); 1652 int system = mProcessStats.getLastSystemTime(); 1653 int iowait = mProcessStats.getLastIoWaitTime(); 1654 int irq = mProcessStats.getLastIrqTime(); 1655 int softIrq = mProcessStats.getLastSoftIrqTime(); 1656 int idle = mProcessStats.getLastIdleTime(); 1657 1658 int total = user + system + iowait + irq + softIrq + idle; 1659 if (total == 0) total = 1; 1660 1661 EventLog.writeEvent(EventLogTags.CPU, 1662 ((user+system+iowait+irq+softIrq) * 100) / total, 1663 (user * 100) / total, 1664 (system * 100) / total, 1665 (iowait * 100) / total, 1666 (irq * 100) / total, 1667 (softIrq * 100) / total); 1668 } 1669 } 1670 1671 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1672 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1673 synchronized(bstats) { 1674 synchronized(mPidsSelfLocked) { 1675 if (haveNewCpuStats) { 1676 if (mOnBattery) { 1677 int perc = bstats.startAddingCpuLocked(); 1678 int totalUTime = 0; 1679 int totalSTime = 0; 1680 final int N = mProcessStats.countStats(); 1681 for (int i=0; i<N; i++) { 1682 ProcessStats.Stats st = mProcessStats.getStats(i); 1683 if (!st.working) { 1684 continue; 1685 } 1686 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1687 int otherUTime = (st.rel_utime*perc)/100; 1688 int otherSTime = (st.rel_stime*perc)/100; 1689 totalUTime += otherUTime; 1690 totalSTime += otherSTime; 1691 if (pr != null) { 1692 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1693 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1694 st.rel_stime-otherSTime); 1695 ps.addSpeedStepTimes(cpuSpeedTimes); 1696 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1697 } else { 1698 BatteryStatsImpl.Uid.Proc ps = 1699 bstats.getProcessStatsLocked(st.name, st.pid); 1700 if (ps != null) { 1701 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1702 st.rel_stime-otherSTime); 1703 ps.addSpeedStepTimes(cpuSpeedTimes); 1704 } 1705 } 1706 } 1707 bstats.finishAddingCpuLocked(perc, totalUTime, 1708 totalSTime, cpuSpeedTimes); 1709 } 1710 } 1711 } 1712 1713 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1714 mLastWriteTime = now; 1715 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1716 } 1717 } 1718 } 1719 } 1720 1721 @Override 1722 public void batteryNeedsCpuUpdate() { 1723 updateCpuStatsNow(); 1724 } 1725 1726 @Override 1727 public void batteryPowerChanged(boolean onBattery) { 1728 // When plugging in, update the CPU stats first before changing 1729 // the plug state. 1730 updateCpuStatsNow(); 1731 synchronized (this) { 1732 synchronized(mPidsSelfLocked) { 1733 mOnBattery = DEBUG_POWER ? true : onBattery; 1734 } 1735 } 1736 } 1737 1738 /** 1739 * Initialize the application bind args. These are passed to each 1740 * process when the bindApplication() IPC is sent to the process. They're 1741 * lazily setup to make sure the services are running when they're asked for. 1742 */ 1743 private HashMap<String, IBinder> getCommonServicesLocked() { 1744 if (mAppBindArgs == null) { 1745 mAppBindArgs = new HashMap<String, IBinder>(); 1746 1747 // Setup the application init args 1748 mAppBindArgs.put("package", ServiceManager.getService("package")); 1749 mAppBindArgs.put("window", ServiceManager.getService("window")); 1750 mAppBindArgs.put(Context.ALARM_SERVICE, 1751 ServiceManager.getService(Context.ALARM_SERVICE)); 1752 } 1753 return mAppBindArgs; 1754 } 1755 1756 final void setFocusedActivityLocked(ActivityRecord r) { 1757 if (mFocusedActivity != r) { 1758 mFocusedActivity = r; 1759 if (r != null) { 1760 mWindowManager.setFocusedApp(r.appToken, true); 1761 } 1762 } 1763 } 1764 1765 private final void updateLruProcessInternalLocked(ProcessRecord app, 1766 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1767 // put it on the LRU to keep track of when it should be exited. 1768 int lrui = mLruProcesses.indexOf(app); 1769 if (lrui >= 0) mLruProcesses.remove(lrui); 1770 1771 int i = mLruProcesses.size()-1; 1772 int skipTop = 0; 1773 1774 app.lruSeq = mLruSeq; 1775 1776 // compute the new weight for this process. 1777 if (updateActivityTime) { 1778 app.lastActivityTime = SystemClock.uptimeMillis(); 1779 } 1780 if (app.activities.size() > 0) { 1781 // If this process has activities, we more strongly want to keep 1782 // it around. 1783 app.lruWeight = app.lastActivityTime; 1784 } else if (app.pubProviders.size() > 0) { 1785 // If this process contains content providers, we want to keep 1786 // it a little more strongly. 1787 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1788 // Also don't let it kick out the first few "real" hidden processes. 1789 skipTop = ProcessList.MIN_HIDDEN_APPS; 1790 } else { 1791 // If this process doesn't have activities, we less strongly 1792 // want to keep it around, and generally want to avoid getting 1793 // in front of any very recently used activities. 1794 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1795 // Also don't let it kick out the first few "real" hidden processes. 1796 skipTop = ProcessList.MIN_HIDDEN_APPS; 1797 } 1798 1799 while (i >= 0) { 1800 ProcessRecord p = mLruProcesses.get(i); 1801 // If this app shouldn't be in front of the first N background 1802 // apps, then skip over that many that are currently hidden. 1803 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1804 skipTop--; 1805 } 1806 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1807 mLruProcesses.add(i+1, app); 1808 break; 1809 } 1810 i--; 1811 } 1812 if (i < 0) { 1813 mLruProcesses.add(0, app); 1814 } 1815 1816 // If the app is currently using a content provider or service, 1817 // bump those processes as well. 1818 if (app.connections.size() > 0) { 1819 for (ConnectionRecord cr : app.connections) { 1820 if (cr.binding != null && cr.binding.service != null 1821 && cr.binding.service.app != null 1822 && cr.binding.service.app.lruSeq != mLruSeq) { 1823 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, 1824 updateActivityTime, i+1); 1825 } 1826 } 1827 } 1828 for (int j=app.conProviders.size()-1; j>=0; j--) { 1829 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1830 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1831 updateLruProcessInternalLocked(cpr.proc, oomAdj, 1832 updateActivityTime, i+1); 1833 } 1834 } 1835 1836 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1837 if (oomAdj) { 1838 updateOomAdjLocked(); 1839 } 1840 } 1841 1842 final void updateLruProcessLocked(ProcessRecord app, 1843 boolean oomAdj, boolean updateActivityTime) { 1844 mLruSeq++; 1845 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1846 } 1847 1848 final ProcessRecord getProcessRecordLocked( 1849 String processName, int uid) { 1850 if (uid == Process.SYSTEM_UID) { 1851 // The system gets to run in any process. If there are multiple 1852 // processes with the same uid, just pick the first (this 1853 // should never happen). 1854 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1855 processName); 1856 if (procs == null) return null; 1857 final int N = procs.size(); 1858 for (int i = 0; i < N; i++) { 1859 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1860 } 1861 } 1862 ProcessRecord proc = mProcessNames.get(processName, uid); 1863 return proc; 1864 } 1865 1866 void ensurePackageDexOpt(String packageName) { 1867 IPackageManager pm = AppGlobals.getPackageManager(); 1868 try { 1869 if (pm.performDexOpt(packageName)) { 1870 mDidDexOpt = true; 1871 } 1872 } catch (RemoteException e) { 1873 } 1874 } 1875 1876 boolean isNextTransitionForward() { 1877 int transit = mWindowManager.getPendingAppTransition(); 1878 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1879 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1880 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1881 } 1882 1883 final ProcessRecord startProcessLocked(String processName, 1884 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1885 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1886 boolean isolated) { 1887 ProcessRecord app; 1888 if (!isolated) { 1889 app = getProcessRecordLocked(processName, info.uid); 1890 } else { 1891 // If this is an isolated process, it can't re-use an existing process. 1892 app = null; 1893 } 1894 // We don't have to do anything more if: 1895 // (1) There is an existing application record; and 1896 // (2) The caller doesn't think it is dead, OR there is no thread 1897 // object attached to it so we know it couldn't have crashed; and 1898 // (3) There is a pid assigned to it, so it is either starting or 1899 // already running. 1900 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1901 + " app=" + app + " knownToBeDead=" + knownToBeDead 1902 + " thread=" + (app != null ? app.thread : null) 1903 + " pid=" + (app != null ? app.pid : -1)); 1904 if (app != null && app.pid > 0) { 1905 if (!knownToBeDead || app.thread == null) { 1906 // We already have the app running, or are waiting for it to 1907 // come up (we have a pid but not yet its thread), so keep it. 1908 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1909 // If this is a new package in the process, add the package to the list 1910 app.addPackage(info.packageName); 1911 return app; 1912 } else { 1913 // An application record is attached to a previous process, 1914 // clean it up now. 1915 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1916 handleAppDiedLocked(app, true, true); 1917 } 1918 } 1919 1920 String hostingNameStr = hostingName != null 1921 ? hostingName.flattenToShortString() : null; 1922 1923 if (!isolated) { 1924 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1925 // If we are in the background, then check to see if this process 1926 // is bad. If so, we will just silently fail. 1927 if (mBadProcesses.get(info.processName, info.uid) != null) { 1928 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1929 + "/" + info.processName); 1930 return null; 1931 } 1932 } else { 1933 // When the user is explicitly starting a process, then clear its 1934 // crash count so that we won't make it bad until they see at 1935 // least one crash dialog again, and make the process good again 1936 // if it had been bad. 1937 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1938 + "/" + info.processName); 1939 mProcessCrashTimes.remove(info.processName, info.uid); 1940 if (mBadProcesses.get(info.processName, info.uid) != null) { 1941 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1942 info.processName); 1943 mBadProcesses.remove(info.processName, info.uid); 1944 if (app != null) { 1945 app.bad = false; 1946 } 1947 } 1948 } 1949 } 1950 1951 if (app == null) { 1952 app = newProcessRecordLocked(null, info, processName, isolated); 1953 if (app == null) { 1954 Slog.w(TAG, "Failed making new process record for " 1955 + processName + "/" + info.uid + " isolated=" + isolated); 1956 return null; 1957 } 1958 mProcessNames.put(processName, app.uid, app); 1959 if (isolated) { 1960 mIsolatedProcesses.put(app.uid, app); 1961 } 1962 } else { 1963 // If this is a new package in the process, add the package to the list 1964 app.addPackage(info.packageName); 1965 } 1966 1967 // If the system is not ready yet, then hold off on starting this 1968 // process until it is. 1969 if (!mProcessesReady 1970 && !isAllowedWhileBooting(info) 1971 && !allowWhileBooting) { 1972 if (!mProcessesOnHold.contains(app)) { 1973 mProcessesOnHold.add(app); 1974 } 1975 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1976 return app; 1977 } 1978 1979 startProcessLocked(app, hostingType, hostingNameStr); 1980 return (app.pid != 0) ? app : null; 1981 } 1982 1983 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1984 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1985 } 1986 1987 private final void startProcessLocked(ProcessRecord app, 1988 String hostingType, String hostingNameStr) { 1989 if (app.pid > 0 && app.pid != MY_PID) { 1990 synchronized (mPidsSelfLocked) { 1991 mPidsSelfLocked.remove(app.pid); 1992 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1993 } 1994 app.pid = 0; 1995 } 1996 1997 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1998 "startProcessLocked removing on hold: " + app); 1999 mProcessesOnHold.remove(app); 2000 2001 updateCpuStats(); 2002 2003 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2004 mProcDeaths[0] = 0; 2005 2006 try { 2007 int uid = app.uid; 2008 2009 int[] gids = null; 2010 if (!app.isolated) { 2011 try { 2012 gids = mContext.getPackageManager().getPackageGids( 2013 app.info.packageName); 2014 } catch (PackageManager.NameNotFoundException e) { 2015 Slog.w(TAG, "Unable to retrieve gids", e); 2016 } 2017 } 2018 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2019 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2020 && mTopComponent != null 2021 && app.processName.equals(mTopComponent.getPackageName())) { 2022 uid = 0; 2023 } 2024 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2025 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2026 uid = 0; 2027 } 2028 } 2029 int debugFlags = 0; 2030 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2031 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2032 // Also turn on CheckJNI for debuggable apps. It's quite 2033 // awkward to turn on otherwise. 2034 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2035 } 2036 // Run the app in safe mode if its manifest requests so or the 2037 // system is booted in safe mode. 2038 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2039 Zygote.systemInSafeMode == true) { 2040 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2041 } 2042 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2043 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2044 } 2045 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2046 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2047 } 2048 if ("1".equals(SystemProperties.get("debug.assert"))) { 2049 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2050 } 2051 2052 // Start the process. It will either succeed and return a result containing 2053 // the PID of the new process, or else throw a RuntimeException. 2054 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2055 app.processName, uid, uid, gids, debugFlags, 2056 app.info.targetSdkVersion, null); 2057 2058 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2059 synchronized (bs) { 2060 if (bs.isOnBattery()) { 2061 app.batteryStats.incStartsLocked(); 2062 } 2063 } 2064 2065 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2066 app.processName, hostingType, 2067 hostingNameStr != null ? hostingNameStr : ""); 2068 2069 if (app.persistent) { 2070 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2071 } 2072 2073 StringBuilder buf = mStringBuilder; 2074 buf.setLength(0); 2075 buf.append("Start proc "); 2076 buf.append(app.processName); 2077 buf.append(" for "); 2078 buf.append(hostingType); 2079 if (hostingNameStr != null) { 2080 buf.append(" "); 2081 buf.append(hostingNameStr); 2082 } 2083 buf.append(": pid="); 2084 buf.append(startResult.pid); 2085 buf.append(" uid="); 2086 buf.append(uid); 2087 buf.append(" gids={"); 2088 if (gids != null) { 2089 for (int gi=0; gi<gids.length; gi++) { 2090 if (gi != 0) buf.append(", "); 2091 buf.append(gids[gi]); 2092 2093 } 2094 } 2095 buf.append("}"); 2096 Slog.i(TAG, buf.toString()); 2097 app.pid = startResult.pid; 2098 app.usingWrapper = startResult.usingWrapper; 2099 app.removed = false; 2100 synchronized (mPidsSelfLocked) { 2101 this.mPidsSelfLocked.put(startResult.pid, app); 2102 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2103 msg.obj = app; 2104 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2105 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2106 } 2107 } catch (RuntimeException e) { 2108 // XXX do better error recovery. 2109 app.pid = 0; 2110 Slog.e(TAG, "Failure starting process " + app.processName, e); 2111 } 2112 } 2113 2114 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2115 if (resumed) { 2116 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2117 } else { 2118 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2119 } 2120 } 2121 2122 boolean startHomeActivityLocked(int userId) { 2123 if (mHeadless) { 2124 // Added because none of the other calls to ensureBootCompleted seem to fire 2125 // when running headless. 2126 ensureBootCompleted(); 2127 return false; 2128 } 2129 2130 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2131 && mTopAction == null) { 2132 // We are running in factory test mode, but unable to find 2133 // the factory test app, so just sit around displaying the 2134 // error message and don't try to start anything. 2135 return false; 2136 } 2137 Intent intent = new Intent( 2138 mTopAction, 2139 mTopData != null ? Uri.parse(mTopData) : null); 2140 intent.setComponent(mTopComponent); 2141 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2142 intent.addCategory(Intent.CATEGORY_HOME); 2143 } 2144 ActivityInfo aInfo = 2145 intent.resolveActivityInfo(mContext.getPackageManager(), 2146 STOCK_PM_FLAGS); 2147 if (aInfo != null) { 2148 intent.setComponent(new ComponentName( 2149 aInfo.applicationInfo.packageName, aInfo.name)); 2150 // Don't do this if the home app is currently being 2151 // instrumented. 2152 aInfo = new ActivityInfo(aInfo); 2153 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2154 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2155 aInfo.applicationInfo.uid); 2156 if (app == null || app.instrumentationClass == null) { 2157 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2158 mMainStack.startActivityLocked(null, intent, null, aInfo, 2159 null, null, 0, 0, 0, 0, null, false, null); 2160 } 2161 } 2162 2163 return true; 2164 } 2165 2166 /** 2167 * Starts the "new version setup screen" if appropriate. 2168 */ 2169 void startSetupActivityLocked() { 2170 // Only do this once per boot. 2171 if (mCheckedForSetup) { 2172 return; 2173 } 2174 2175 // We will show this screen if the current one is a different 2176 // version than the last one shown, and we are not running in 2177 // low-level factory test mode. 2178 final ContentResolver resolver = mContext.getContentResolver(); 2179 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2180 Settings.Secure.getInt(resolver, 2181 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2182 mCheckedForSetup = true; 2183 2184 // See if we should be showing the platform update setup UI. 2185 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2186 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2187 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2188 2189 // We don't allow third party apps to replace this. 2190 ResolveInfo ri = null; 2191 for (int i=0; ris != null && i<ris.size(); i++) { 2192 if ((ris.get(i).activityInfo.applicationInfo.flags 2193 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2194 ri = ris.get(i); 2195 break; 2196 } 2197 } 2198 2199 if (ri != null) { 2200 String vers = ri.activityInfo.metaData != null 2201 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2202 : null; 2203 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2204 vers = ri.activityInfo.applicationInfo.metaData.getString( 2205 Intent.METADATA_SETUP_VERSION); 2206 } 2207 String lastVers = Settings.Secure.getString( 2208 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2209 if (vers != null && !vers.equals(lastVers)) { 2210 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2211 intent.setComponent(new ComponentName( 2212 ri.activityInfo.packageName, ri.activityInfo.name)); 2213 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2214 null, null, 0, 0, 0, 0, null, false, null); 2215 } 2216 } 2217 } 2218 } 2219 2220 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2221 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2222 } 2223 2224 void enforceNotIsolatedCaller(String caller) { 2225 if (UserId.isIsolated(Binder.getCallingUid())) { 2226 throw new SecurityException("Isolated process not allowed to call " + caller); 2227 } 2228 } 2229 2230 public int getFrontActivityScreenCompatMode() { 2231 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2232 synchronized (this) { 2233 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2234 } 2235 } 2236 2237 public void setFrontActivityScreenCompatMode(int mode) { 2238 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2239 "setFrontActivityScreenCompatMode"); 2240 synchronized (this) { 2241 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2242 } 2243 } 2244 2245 public int getPackageScreenCompatMode(String packageName) { 2246 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2247 synchronized (this) { 2248 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2249 } 2250 } 2251 2252 public void setPackageScreenCompatMode(String packageName, int mode) { 2253 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2254 "setPackageScreenCompatMode"); 2255 synchronized (this) { 2256 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2257 } 2258 } 2259 2260 public boolean getPackageAskScreenCompat(String packageName) { 2261 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2262 synchronized (this) { 2263 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2264 } 2265 } 2266 2267 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2268 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2269 "setPackageAskScreenCompat"); 2270 synchronized (this) { 2271 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2272 } 2273 } 2274 2275 void reportResumedActivityLocked(ActivityRecord r) { 2276 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2277 updateUsageStats(r, true); 2278 } 2279 2280 private void dispatchProcessesChanged() { 2281 int N; 2282 synchronized (this) { 2283 N = mPendingProcessChanges.size(); 2284 if (mActiveProcessChanges.length < N) { 2285 mActiveProcessChanges = new ProcessChangeItem[N]; 2286 } 2287 mPendingProcessChanges.toArray(mActiveProcessChanges); 2288 mAvailProcessChanges.addAll(mPendingProcessChanges); 2289 mPendingProcessChanges.clear(); 2290 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2291 } 2292 int i = mProcessObservers.beginBroadcast(); 2293 while (i > 0) { 2294 i--; 2295 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2296 if (observer != null) { 2297 try { 2298 for (int j=0; j<N; j++) { 2299 ProcessChangeItem item = mActiveProcessChanges[j]; 2300 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2301 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2302 + item.pid + " uid=" + item.uid + ": " 2303 + item.foregroundActivities); 2304 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2305 item.foregroundActivities); 2306 } 2307 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2308 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2309 + item.pid + " uid=" + item.uid + ": " + item.importance); 2310 observer.onImportanceChanged(item.pid, item.uid, 2311 item.importance); 2312 } 2313 } 2314 } catch (RemoteException e) { 2315 } 2316 } 2317 } 2318 mProcessObservers.finishBroadcast(); 2319 } 2320 2321 private void dispatchProcessDied(int pid, int uid) { 2322 int i = mProcessObservers.beginBroadcast(); 2323 while (i > 0) { 2324 i--; 2325 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2326 if (observer != null) { 2327 try { 2328 observer.onProcessDied(pid, uid); 2329 } catch (RemoteException e) { 2330 } 2331 } 2332 } 2333 mProcessObservers.finishBroadcast(); 2334 } 2335 2336 final void doPendingActivityLaunchesLocked(boolean doResume) { 2337 final int N = mPendingActivityLaunches.size(); 2338 if (N <= 0) { 2339 return; 2340 } 2341 for (int i=0; i<N; i++) { 2342 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2343 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2344 pal.startFlags, doResume && i == (N-1), null); 2345 } 2346 mPendingActivityLaunches.clear(); 2347 } 2348 2349 public final int startActivity(IApplicationThread caller, 2350 Intent intent, String resolvedType, IBinder resultTo, 2351 String resultWho, int requestCode, int startFlags, 2352 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2353 enforceNotIsolatedCaller("startActivity"); 2354 int userId = 0; 2355 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2356 // Requesting home, set the identity to the current user 2357 // HACK! 2358 userId = mCurrentUserId; 2359 } else { 2360 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2361 // the current user's userId 2362 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2363 userId = 0; 2364 } else { 2365 userId = Binder.getOrigCallingUser(); 2366 } 2367 } 2368 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2369 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2370 null, null, options, userId); 2371 } 2372 2373 public final WaitResult startActivityAndWait(IApplicationThread caller, 2374 Intent intent, String resolvedType, IBinder resultTo, 2375 String resultWho, int requestCode, int startFlags, String profileFile, 2376 ParcelFileDescriptor profileFd, Bundle options) { 2377 enforceNotIsolatedCaller("startActivityAndWait"); 2378 WaitResult res = new WaitResult(); 2379 int userId = Binder.getOrigCallingUser(); 2380 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2381 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2382 res, null, options, userId); 2383 return res; 2384 } 2385 2386 public final int startActivityWithConfig(IApplicationThread caller, 2387 Intent intent, String resolvedType, IBinder resultTo, 2388 String resultWho, int requestCode, int startFlags, Configuration config, 2389 Bundle options) { 2390 enforceNotIsolatedCaller("startActivityWithConfig"); 2391 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2392 resultTo, resultWho, requestCode, startFlags, 2393 null, null, null, config, options, Binder.getOrigCallingUser()); 2394 return ret; 2395 } 2396 2397 public int startActivityIntentSender(IApplicationThread caller, 2398 IntentSender intent, Intent fillInIntent, String resolvedType, 2399 IBinder resultTo, String resultWho, int requestCode, 2400 int flagsMask, int flagsValues, Bundle options) { 2401 enforceNotIsolatedCaller("startActivityIntentSender"); 2402 // Refuse possible leaked file descriptors 2403 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2404 throw new IllegalArgumentException("File descriptors passed in Intent"); 2405 } 2406 2407 IIntentSender sender = intent.getTarget(); 2408 if (!(sender instanceof PendingIntentRecord)) { 2409 throw new IllegalArgumentException("Bad PendingIntent object"); 2410 } 2411 2412 PendingIntentRecord pir = (PendingIntentRecord)sender; 2413 2414 synchronized (this) { 2415 // If this is coming from the currently resumed activity, it is 2416 // effectively saying that app switches are allowed at this point. 2417 if (mMainStack.mResumedActivity != null 2418 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2419 Binder.getCallingUid()) { 2420 mAppSwitchesAllowedTime = 0; 2421 } 2422 } 2423 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2424 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2425 return ret; 2426 } 2427 2428 public boolean startNextMatchingActivity(IBinder callingActivity, 2429 Intent intent, Bundle options) { 2430 // Refuse possible leaked file descriptors 2431 if (intent != null && intent.hasFileDescriptors() == true) { 2432 throw new IllegalArgumentException("File descriptors passed in Intent"); 2433 } 2434 2435 synchronized (this) { 2436 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2437 if (r == null) { 2438 ActivityOptions.abort(options); 2439 return false; 2440 } 2441 if (r.app == null || r.app.thread == null) { 2442 // The caller is not running... d'oh! 2443 ActivityOptions.abort(options); 2444 return false; 2445 } 2446 intent = new Intent(intent); 2447 // The caller is not allowed to change the data. 2448 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2449 // And we are resetting to find the next component... 2450 intent.setComponent(null); 2451 2452 ActivityInfo aInfo = null; 2453 try { 2454 List<ResolveInfo> resolves = 2455 AppGlobals.getPackageManager().queryIntentActivities( 2456 intent, r.resolvedType, 2457 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2458 UserId.getCallingUserId()); 2459 2460 // Look for the original activity in the list... 2461 final int N = resolves != null ? resolves.size() : 0; 2462 for (int i=0; i<N; i++) { 2463 ResolveInfo rInfo = resolves.get(i); 2464 if (rInfo.activityInfo.packageName.equals(r.packageName) 2465 && rInfo.activityInfo.name.equals(r.info.name)) { 2466 // We found the current one... the next matching is 2467 // after it. 2468 i++; 2469 if (i<N) { 2470 aInfo = resolves.get(i).activityInfo; 2471 } 2472 break; 2473 } 2474 } 2475 } catch (RemoteException e) { 2476 } 2477 2478 if (aInfo == null) { 2479 // Nobody who is next! 2480 ActivityOptions.abort(options); 2481 return false; 2482 } 2483 2484 intent.setComponent(new ComponentName( 2485 aInfo.applicationInfo.packageName, aInfo.name)); 2486 intent.setFlags(intent.getFlags()&~( 2487 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2488 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2489 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2490 Intent.FLAG_ACTIVITY_NEW_TASK)); 2491 2492 // Okay now we need to start the new activity, replacing the 2493 // currently running activity. This is a little tricky because 2494 // we want to start the new one as if the current one is finished, 2495 // but not finish the current one first so that there is no flicker. 2496 // And thus... 2497 final boolean wasFinishing = r.finishing; 2498 r.finishing = true; 2499 2500 // Propagate reply information over to the new activity. 2501 final ActivityRecord resultTo = r.resultTo; 2502 final String resultWho = r.resultWho; 2503 final int requestCode = r.requestCode; 2504 r.resultTo = null; 2505 if (resultTo != null) { 2506 resultTo.removeResultsLocked(r, resultWho, requestCode); 2507 } 2508 2509 final long origId = Binder.clearCallingIdentity(); 2510 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2511 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2512 resultWho, requestCode, -1, r.launchedFromUid, 0, 2513 options, false, null); 2514 Binder.restoreCallingIdentity(origId); 2515 2516 r.finishing = wasFinishing; 2517 if (res != ActivityManager.START_SUCCESS) { 2518 return false; 2519 } 2520 return true; 2521 } 2522 } 2523 2524 public final int startActivityInPackage(int uid, 2525 Intent intent, String resolvedType, IBinder resultTo, 2526 String resultWho, int requestCode, int startFlags, Bundle options) { 2527 2528 // This is so super not safe, that only the system (or okay root) 2529 // can do it. 2530 int userId = Binder.getOrigCallingUser(); 2531 final int callingUid = Binder.getCallingUid(); 2532 if (callingUid != 0 && callingUid != Process.myUid()) { 2533 throw new SecurityException( 2534 "startActivityInPackage only available to the system"); 2535 } 2536 2537 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2538 resultTo, resultWho, requestCode, startFlags, 2539 null, null, null, null, options, userId); 2540 return ret; 2541 } 2542 2543 public final int startActivities(IApplicationThread caller, 2544 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2545 enforceNotIsolatedCaller("startActivities"); 2546 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2547 options, Binder.getOrigCallingUser()); 2548 return ret; 2549 } 2550 2551 public final int startActivitiesInPackage(int uid, 2552 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2553 Bundle options) { 2554 2555 // This is so super not safe, that only the system (or okay root) 2556 // can do it. 2557 final int callingUid = Binder.getCallingUid(); 2558 if (callingUid != 0 && callingUid != Process.myUid()) { 2559 throw new SecurityException( 2560 "startActivityInPackage only available to the system"); 2561 } 2562 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2563 options, UserId.getUserId(uid)); 2564 return ret; 2565 } 2566 2567 final void addRecentTaskLocked(TaskRecord task) { 2568 int N = mRecentTasks.size(); 2569 // Quick case: check if the top-most recent task is the same. 2570 if (N > 0 && mRecentTasks.get(0) == task) { 2571 return; 2572 } 2573 // Remove any existing entries that are the same kind of task. 2574 for (int i=0; i<N; i++) { 2575 TaskRecord tr = mRecentTasks.get(i); 2576 if (task.userId == tr.userId 2577 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2578 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2579 mRecentTasks.remove(i); 2580 i--; 2581 N--; 2582 if (task.intent == null) { 2583 // If the new recent task we are adding is not fully 2584 // specified, then replace it with the existing recent task. 2585 task = tr; 2586 } 2587 } 2588 } 2589 if (N >= MAX_RECENT_TASKS) { 2590 mRecentTasks.remove(N-1); 2591 } 2592 mRecentTasks.add(0, task); 2593 } 2594 2595 public void setRequestedOrientation(IBinder token, 2596 int requestedOrientation) { 2597 synchronized (this) { 2598 ActivityRecord r = mMainStack.isInStackLocked(token); 2599 if (r == null) { 2600 return; 2601 } 2602 final long origId = Binder.clearCallingIdentity(); 2603 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2604 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2605 mConfiguration, 2606 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2607 if (config != null) { 2608 r.frozenBeforeDestroy = true; 2609 if (!updateConfigurationLocked(config, r, false, false)) { 2610 mMainStack.resumeTopActivityLocked(null); 2611 } 2612 } 2613 Binder.restoreCallingIdentity(origId); 2614 } 2615 } 2616 2617 public int getRequestedOrientation(IBinder token) { 2618 synchronized (this) { 2619 ActivityRecord r = mMainStack.isInStackLocked(token); 2620 if (r == null) { 2621 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2622 } 2623 return mWindowManager.getAppOrientation(r.appToken); 2624 } 2625 } 2626 2627 /** 2628 * This is the internal entry point for handling Activity.finish(). 2629 * 2630 * @param token The Binder token referencing the Activity we want to finish. 2631 * @param resultCode Result code, if any, from this Activity. 2632 * @param resultData Result data (Intent), if any, from this Activity. 2633 * 2634 * @return Returns true if the activity successfully finished, or false if it is still running. 2635 */ 2636 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2637 // Refuse possible leaked file descriptors 2638 if (resultData != null && resultData.hasFileDescriptors() == true) { 2639 throw new IllegalArgumentException("File descriptors passed in Intent"); 2640 } 2641 2642 synchronized(this) { 2643 if (mController != null) { 2644 // Find the first activity that is not finishing. 2645 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2646 if (next != null) { 2647 // ask watcher if this is allowed 2648 boolean resumeOK = true; 2649 try { 2650 resumeOK = mController.activityResuming(next.packageName); 2651 } catch (RemoteException e) { 2652 mController = null; 2653 } 2654 2655 if (!resumeOK) { 2656 return false; 2657 } 2658 } 2659 } 2660 final long origId = Binder.clearCallingIdentity(); 2661 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2662 resultData, "app-request"); 2663 Binder.restoreCallingIdentity(origId); 2664 return res; 2665 } 2666 } 2667 2668 public final void finishHeavyWeightApp() { 2669 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2670 != PackageManager.PERMISSION_GRANTED) { 2671 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2672 + Binder.getCallingPid() 2673 + ", uid=" + Binder.getCallingUid() 2674 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2675 Slog.w(TAG, msg); 2676 throw new SecurityException(msg); 2677 } 2678 2679 synchronized(this) { 2680 if (mHeavyWeightProcess == null) { 2681 return; 2682 } 2683 2684 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2685 mHeavyWeightProcess.activities); 2686 for (int i=0; i<activities.size(); i++) { 2687 ActivityRecord r = activities.get(i); 2688 if (!r.finishing) { 2689 int index = mMainStack.indexOfTokenLocked(r.appToken); 2690 if (index >= 0) { 2691 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2692 null, "finish-heavy"); 2693 } 2694 } 2695 } 2696 2697 mHeavyWeightProcess = null; 2698 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2699 } 2700 } 2701 2702 public void crashApplication(int uid, int initialPid, String packageName, 2703 String message) { 2704 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2705 != PackageManager.PERMISSION_GRANTED) { 2706 String msg = "Permission Denial: crashApplication() from pid=" 2707 + Binder.getCallingPid() 2708 + ", uid=" + Binder.getCallingUid() 2709 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2710 Slog.w(TAG, msg); 2711 throw new SecurityException(msg); 2712 } 2713 2714 synchronized(this) { 2715 ProcessRecord proc = null; 2716 2717 // Figure out which process to kill. We don't trust that initialPid 2718 // still has any relation to current pids, so must scan through the 2719 // list. 2720 synchronized (mPidsSelfLocked) { 2721 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2722 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2723 if (p.uid != uid) { 2724 continue; 2725 } 2726 if (p.pid == initialPid) { 2727 proc = p; 2728 break; 2729 } 2730 for (String str : p.pkgList) { 2731 if (str.equals(packageName)) { 2732 proc = p; 2733 } 2734 } 2735 } 2736 } 2737 2738 if (proc == null) { 2739 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2740 + " initialPid=" + initialPid 2741 + " packageName=" + packageName); 2742 return; 2743 } 2744 2745 if (proc.thread != null) { 2746 if (proc.pid == Process.myPid()) { 2747 Log.w(TAG, "crashApplication: trying to crash self!"); 2748 return; 2749 } 2750 long ident = Binder.clearCallingIdentity(); 2751 try { 2752 proc.thread.scheduleCrash(message); 2753 } catch (RemoteException e) { 2754 } 2755 Binder.restoreCallingIdentity(ident); 2756 } 2757 } 2758 } 2759 2760 public final void finishSubActivity(IBinder token, String resultWho, 2761 int requestCode) { 2762 synchronized(this) { 2763 final long origId = Binder.clearCallingIdentity(); 2764 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2765 Binder.restoreCallingIdentity(origId); 2766 } 2767 } 2768 2769 public boolean finishActivityAffinity(IBinder token) { 2770 synchronized(this) { 2771 final long origId = Binder.clearCallingIdentity(); 2772 boolean res = mMainStack.finishActivityAffinityLocked(token); 2773 Binder.restoreCallingIdentity(origId); 2774 return res; 2775 } 2776 } 2777 2778 public boolean willActivityBeVisible(IBinder token) { 2779 synchronized(this) { 2780 int i; 2781 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2782 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2783 if (r.appToken == token) { 2784 return true; 2785 } 2786 if (r.fullscreen && !r.finishing) { 2787 return false; 2788 } 2789 } 2790 return true; 2791 } 2792 } 2793 2794 public void overridePendingTransition(IBinder token, String packageName, 2795 int enterAnim, int exitAnim) { 2796 synchronized(this) { 2797 ActivityRecord self = mMainStack.isInStackLocked(token); 2798 if (self == null) { 2799 return; 2800 } 2801 2802 final long origId = Binder.clearCallingIdentity(); 2803 2804 if (self.state == ActivityState.RESUMED 2805 || self.state == ActivityState.PAUSING) { 2806 mWindowManager.overridePendingAppTransition(packageName, 2807 enterAnim, exitAnim, null); 2808 } 2809 2810 Binder.restoreCallingIdentity(origId); 2811 } 2812 } 2813 2814 /** 2815 * Main function for removing an existing process from the activity manager 2816 * as a result of that process going away. Clears out all connections 2817 * to the process. 2818 */ 2819 private final void handleAppDiedLocked(ProcessRecord app, 2820 boolean restarting, boolean allowRestart) { 2821 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2822 if (!restarting) { 2823 mLruProcesses.remove(app); 2824 } 2825 2826 if (mProfileProc == app) { 2827 clearProfilerLocked(); 2828 } 2829 2830 // Just in case... 2831 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2832 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2833 mMainStack.mPausingActivity = null; 2834 } 2835 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2836 mMainStack.mLastPausedActivity = null; 2837 } 2838 2839 // Remove this application's activities from active lists. 2840 mMainStack.removeHistoryRecordsForAppLocked(app); 2841 2842 boolean atTop = true; 2843 boolean hasVisibleActivities = false; 2844 2845 // Clean out the history list. 2846 int i = mMainStack.mHistory.size(); 2847 if (localLOGV) Slog.v( 2848 TAG, "Removing app " + app + " from history with " + i + " entries"); 2849 while (i > 0) { 2850 i--; 2851 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2852 if (localLOGV) Slog.v( 2853 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2854 if (r.app == app) { 2855 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2856 if (ActivityStack.DEBUG_ADD_REMOVE) { 2857 RuntimeException here = new RuntimeException("here"); 2858 here.fillInStackTrace(); 2859 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2860 + ": haveState=" + r.haveState 2861 + " stateNotNeeded=" + r.stateNotNeeded 2862 + " finishing=" + r.finishing 2863 + " state=" + r.state, here); 2864 } 2865 if (!r.finishing) { 2866 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2867 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2868 System.identityHashCode(r), 2869 r.task.taskId, r.shortComponentName, 2870 "proc died without state saved"); 2871 } 2872 mMainStack.removeActivityFromHistoryLocked(r); 2873 2874 } else { 2875 // We have the current state for this activity, so 2876 // it can be restarted later when needed. 2877 if (localLOGV) Slog.v( 2878 TAG, "Keeping entry, setting app to null"); 2879 if (r.visible) { 2880 hasVisibleActivities = true; 2881 } 2882 r.app = null; 2883 r.nowVisible = false; 2884 if (!r.haveState) { 2885 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2886 "App died, clearing saved state of " + r); 2887 r.icicle = null; 2888 } 2889 } 2890 2891 r.stack.cleanUpActivityLocked(r, true, true); 2892 } 2893 atTop = false; 2894 } 2895 2896 app.activities.clear(); 2897 2898 if (app.instrumentationClass != null) { 2899 Slog.w(TAG, "Crash of app " + app.processName 2900 + " running instrumentation " + app.instrumentationClass); 2901 Bundle info = new Bundle(); 2902 info.putString("shortMsg", "Process crashed."); 2903 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2904 } 2905 2906 if (!restarting) { 2907 if (!mMainStack.resumeTopActivityLocked(null)) { 2908 // If there was nothing to resume, and we are not already 2909 // restarting this process, but there is a visible activity that 2910 // is hosted by the process... then make sure all visible 2911 // activities are running, taking care of restarting this 2912 // process. 2913 if (hasVisibleActivities) { 2914 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2915 } 2916 } 2917 } 2918 } 2919 2920 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2921 IBinder threadBinder = thread.asBinder(); 2922 // Find the application record. 2923 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2924 ProcessRecord rec = mLruProcesses.get(i); 2925 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2926 return i; 2927 } 2928 } 2929 return -1; 2930 } 2931 2932 final ProcessRecord getRecordForAppLocked( 2933 IApplicationThread thread) { 2934 if (thread == null) { 2935 return null; 2936 } 2937 2938 int appIndex = getLRURecordIndexForAppLocked(thread); 2939 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2940 } 2941 2942 final void appDiedLocked(ProcessRecord app, int pid, 2943 IApplicationThread thread) { 2944 2945 mProcDeaths[0]++; 2946 2947 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2948 synchronized (stats) { 2949 stats.noteProcessDiedLocked(app.info.uid, pid); 2950 } 2951 2952 // Clean up already done if the process has been re-started. 2953 if (app.pid == pid && app.thread != null && 2954 app.thread.asBinder() == thread.asBinder()) { 2955 if (!app.killedBackground) { 2956 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2957 + ") has died."); 2958 } 2959 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2960 if (localLOGV) Slog.v( 2961 TAG, "Dying app: " + app + ", pid: " + pid 2962 + ", thread: " + thread.asBinder()); 2963 boolean doLowMem = app.instrumentationClass == null; 2964 handleAppDiedLocked(app, false, true); 2965 2966 if (doLowMem) { 2967 // If there are no longer any background processes running, 2968 // and the app that died was not running instrumentation, 2969 // then tell everyone we are now low on memory. 2970 boolean haveBg = false; 2971 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2972 ProcessRecord rec = mLruProcesses.get(i); 2973 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2974 haveBg = true; 2975 break; 2976 } 2977 } 2978 2979 if (!haveBg) { 2980 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2981 long now = SystemClock.uptimeMillis(); 2982 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2983 ProcessRecord rec = mLruProcesses.get(i); 2984 if (rec != app && rec.thread != null && 2985 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2986 // The low memory report is overriding any current 2987 // state for a GC request. Make sure to do 2988 // heavy/important/visible/foreground processes first. 2989 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2990 rec.lastRequestedGc = 0; 2991 } else { 2992 rec.lastRequestedGc = rec.lastLowMemory; 2993 } 2994 rec.reportLowMemory = true; 2995 rec.lastLowMemory = now; 2996 mProcessesToGc.remove(rec); 2997 addProcessToGcListLocked(rec); 2998 } 2999 } 3000 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3001 scheduleAppGcsLocked(); 3002 } 3003 } 3004 } else if (app.pid != pid) { 3005 // A new process has already been started. 3006 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3007 + ") has died and restarted (pid " + app.pid + ")."); 3008 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3009 } else if (DEBUG_PROCESSES) { 3010 Slog.d(TAG, "Received spurious death notification for thread " 3011 + thread.asBinder()); 3012 } 3013 } 3014 3015 /** 3016 * If a stack trace dump file is configured, dump process stack traces. 3017 * @param clearTraces causes the dump file to be erased prior to the new 3018 * traces being written, if true; when false, the new traces will be 3019 * appended to any existing file content. 3020 * @param firstPids of dalvik VM processes to dump stack traces for first 3021 * @param lastPids of dalvik VM processes to dump stack traces for last 3022 * @param nativeProcs optional list of native process names to dump stack crawls 3023 * @return file containing stack traces, or null if no dump file is configured 3024 */ 3025 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3026 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3027 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3028 if (tracesPath == null || tracesPath.length() == 0) { 3029 return null; 3030 } 3031 3032 File tracesFile = new File(tracesPath); 3033 try { 3034 File tracesDir = tracesFile.getParentFile(); 3035 if (!tracesDir.exists()) tracesFile.mkdirs(); 3036 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3037 3038 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3039 tracesFile.createNewFile(); 3040 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3041 } catch (IOException e) { 3042 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3043 return null; 3044 } 3045 3046 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3047 return tracesFile; 3048 } 3049 3050 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3051 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3052 // Use a FileObserver to detect when traces finish writing. 3053 // The order of traces is considered important to maintain for legibility. 3054 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3055 public synchronized void onEvent(int event, String path) { notify(); } 3056 }; 3057 3058 try { 3059 observer.startWatching(); 3060 3061 // First collect all of the stacks of the most important pids. 3062 if (firstPids != null) { 3063 try { 3064 int num = firstPids.size(); 3065 for (int i = 0; i < num; i++) { 3066 synchronized (observer) { 3067 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3068 observer.wait(200); // Wait for write-close, give up after 200msec 3069 } 3070 } 3071 } catch (InterruptedException e) { 3072 Log.wtf(TAG, e); 3073 } 3074 } 3075 3076 // Next measure CPU usage. 3077 if (processStats != null) { 3078 processStats.init(); 3079 System.gc(); 3080 processStats.update(); 3081 try { 3082 synchronized (processStats) { 3083 processStats.wait(500); // measure over 1/2 second. 3084 } 3085 } catch (InterruptedException e) { 3086 } 3087 processStats.update(); 3088 3089 // We'll take the stack crawls of just the top apps using CPU. 3090 final int N = processStats.countWorkingStats(); 3091 int numProcs = 0; 3092 for (int i=0; i<N && numProcs<5; i++) { 3093 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3094 if (lastPids.indexOfKey(stats.pid) >= 0) { 3095 numProcs++; 3096 try { 3097 synchronized (observer) { 3098 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3099 observer.wait(200); // Wait for write-close, give up after 200msec 3100 } 3101 } catch (InterruptedException e) { 3102 Log.wtf(TAG, e); 3103 } 3104 3105 } 3106 } 3107 } 3108 3109 } finally { 3110 observer.stopWatching(); 3111 } 3112 3113 if (nativeProcs != null) { 3114 int[] pids = Process.getPidsForCommands(nativeProcs); 3115 if (pids != null) { 3116 for (int pid : pids) { 3117 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3118 } 3119 } 3120 } 3121 } 3122 3123 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3124 if (true || IS_USER_BUILD) { 3125 return; 3126 } 3127 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3128 if (tracesPath == null || tracesPath.length() == 0) { 3129 return; 3130 } 3131 3132 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3133 StrictMode.allowThreadDiskWrites(); 3134 try { 3135 final File tracesFile = new File(tracesPath); 3136 final File tracesDir = tracesFile.getParentFile(); 3137 final File tracesTmp = new File(tracesDir, "__tmp__"); 3138 try { 3139 if (!tracesDir.exists()) tracesFile.mkdirs(); 3140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3141 3142 if (tracesFile.exists()) { 3143 tracesTmp.delete(); 3144 tracesFile.renameTo(tracesTmp); 3145 } 3146 StringBuilder sb = new StringBuilder(); 3147 Time tobj = new Time(); 3148 tobj.set(System.currentTimeMillis()); 3149 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3150 sb.append(": "); 3151 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3152 sb.append(" since "); 3153 sb.append(msg); 3154 FileOutputStream fos = new FileOutputStream(tracesFile); 3155 fos.write(sb.toString().getBytes()); 3156 if (app == null) { 3157 fos.write("\n*** No application process!".getBytes()); 3158 } 3159 fos.close(); 3160 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3161 } catch (IOException e) { 3162 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3163 return; 3164 } 3165 3166 if (app != null) { 3167 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3168 firstPids.add(app.pid); 3169 dumpStackTraces(tracesPath, firstPids, null, null, null); 3170 } 3171 3172 File lastTracesFile = null; 3173 File curTracesFile = null; 3174 for (int i=9; i>=0; i--) { 3175 String name = String.format("slow%02d.txt", i); 3176 curTracesFile = new File(tracesDir, name); 3177 if (curTracesFile.exists()) { 3178 if (lastTracesFile != null) { 3179 curTracesFile.renameTo(lastTracesFile); 3180 } else { 3181 curTracesFile.delete(); 3182 } 3183 } 3184 lastTracesFile = curTracesFile; 3185 } 3186 tracesFile.renameTo(curTracesFile); 3187 if (tracesTmp.exists()) { 3188 tracesTmp.renameTo(tracesFile); 3189 } 3190 } finally { 3191 StrictMode.setThreadPolicy(oldPolicy); 3192 } 3193 } 3194 3195 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3196 ActivityRecord parent, final String annotation) { 3197 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3198 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3199 3200 if (mController != null) { 3201 try { 3202 // 0 == continue, -1 = kill process immediately 3203 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3204 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3205 } catch (RemoteException e) { 3206 mController = null; 3207 } 3208 } 3209 3210 long anrTime = SystemClock.uptimeMillis(); 3211 if (MONITOR_CPU_USAGE) { 3212 updateCpuStatsNow(); 3213 } 3214 3215 synchronized (this) { 3216 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3217 if (mShuttingDown) { 3218 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3219 return; 3220 } else if (app.notResponding) { 3221 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3222 return; 3223 } else if (app.crashing) { 3224 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3225 return; 3226 } 3227 3228 // In case we come through here for the same app before completing 3229 // this one, mark as anring now so we will bail out. 3230 app.notResponding = true; 3231 3232 // Log the ANR to the event log. 3233 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3234 annotation); 3235 3236 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3237 firstPids.add(app.pid); 3238 3239 int parentPid = app.pid; 3240 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3241 if (parentPid != app.pid) firstPids.add(parentPid); 3242 3243 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3244 3245 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3246 ProcessRecord r = mLruProcesses.get(i); 3247 if (r != null && r.thread != null) { 3248 int pid = r.pid; 3249 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3250 if (r.persistent) { 3251 firstPids.add(pid); 3252 } else { 3253 lastPids.put(pid, Boolean.TRUE); 3254 } 3255 } 3256 } 3257 } 3258 } 3259 3260 // Log the ANR to the main log. 3261 StringBuilder info = new StringBuilder(); 3262 info.setLength(0); 3263 info.append("ANR in ").append(app.processName); 3264 if (activity != null && activity.shortComponentName != null) { 3265 info.append(" (").append(activity.shortComponentName).append(")"); 3266 } 3267 info.append("\n"); 3268 if (annotation != null) { 3269 info.append("Reason: ").append(annotation).append("\n"); 3270 } 3271 if (parent != null && parent != activity) { 3272 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3273 } 3274 3275 final ProcessStats processStats = new ProcessStats(true); 3276 3277 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3278 3279 String cpuInfo = null; 3280 if (MONITOR_CPU_USAGE) { 3281 updateCpuStatsNow(); 3282 synchronized (mProcessStatsThread) { 3283 cpuInfo = mProcessStats.printCurrentState(anrTime); 3284 } 3285 info.append(processStats.printCurrentLoad()); 3286 info.append(cpuInfo); 3287 } 3288 3289 info.append(processStats.printCurrentState(anrTime)); 3290 3291 Slog.e(TAG, info.toString()); 3292 if (tracesFile == null) { 3293 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3294 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3295 } 3296 3297 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3298 cpuInfo, tracesFile, null); 3299 3300 if (mController != null) { 3301 try { 3302 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3303 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3304 if (res != 0) { 3305 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3306 return; 3307 } 3308 } catch (RemoteException e) { 3309 mController = null; 3310 } 3311 } 3312 3313 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3314 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3315 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3316 3317 synchronized (this) { 3318 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3319 Slog.w(TAG, "Killing " + app + ": background ANR"); 3320 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3321 app.processName, app.setAdj, "background ANR"); 3322 Process.killProcessQuiet(app.pid); 3323 return; 3324 } 3325 3326 // Set the app's notResponding state, and look up the errorReportReceiver 3327 makeAppNotRespondingLocked(app, 3328 activity != null ? activity.shortComponentName : null, 3329 annotation != null ? "ANR " + annotation : "ANR", 3330 info.toString()); 3331 3332 // Bring up the infamous App Not Responding dialog 3333 Message msg = Message.obtain(); 3334 HashMap map = new HashMap(); 3335 msg.what = SHOW_NOT_RESPONDING_MSG; 3336 msg.obj = map; 3337 map.put("app", app); 3338 if (activity != null) { 3339 map.put("activity", activity); 3340 } 3341 3342 mHandler.sendMessage(msg); 3343 } 3344 } 3345 3346 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3347 if (!mLaunchWarningShown) { 3348 mLaunchWarningShown = true; 3349 mHandler.post(new Runnable() { 3350 @Override 3351 public void run() { 3352 synchronized (ActivityManagerService.this) { 3353 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3354 d.show(); 3355 mHandler.postDelayed(new Runnable() { 3356 @Override 3357 public void run() { 3358 synchronized (ActivityManagerService.this) { 3359 d.dismiss(); 3360 mLaunchWarningShown = false; 3361 } 3362 } 3363 }, 4000); 3364 } 3365 } 3366 }); 3367 } 3368 } 3369 3370 public boolean clearApplicationUserData(final String packageName, 3371 final IPackageDataObserver observer, final int userId) { 3372 enforceNotIsolatedCaller("clearApplicationUserData"); 3373 int uid = Binder.getCallingUid(); 3374 int pid = Binder.getCallingPid(); 3375 long callingId = Binder.clearCallingIdentity(); 3376 try { 3377 IPackageManager pm = AppGlobals.getPackageManager(); 3378 int pkgUid = -1; 3379 synchronized(this) { 3380 try { 3381 pkgUid = pm.getPackageUid(packageName, userId); 3382 } catch (RemoteException e) { 3383 } 3384 if (pkgUid == -1) { 3385 Slog.w(TAG, "Invalid packageName:" + packageName); 3386 return false; 3387 } 3388 if (uid == pkgUid || checkComponentPermission( 3389 android.Manifest.permission.CLEAR_APP_USER_DATA, 3390 pid, uid, -1, true) 3391 == PackageManager.PERMISSION_GRANTED) { 3392 forceStopPackageLocked(packageName, pkgUid); 3393 } else { 3394 throw new SecurityException(pid+" does not have permission:"+ 3395 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3396 "for process:"+packageName); 3397 } 3398 } 3399 3400 try { 3401 //clear application user data 3402 pm.clearApplicationUserData(packageName, observer, userId); 3403 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3404 Uri.fromParts("package", packageName, null)); 3405 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3406 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3407 null, null, 0, null, null, null, false, false, userId); 3408 } catch (RemoteException e) { 3409 } 3410 } finally { 3411 Binder.restoreCallingIdentity(callingId); 3412 } 3413 return true; 3414 } 3415 3416 public void killBackgroundProcesses(final String packageName) { 3417 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3418 != PackageManager.PERMISSION_GRANTED && 3419 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3420 != PackageManager.PERMISSION_GRANTED) { 3421 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3422 + Binder.getCallingPid() 3423 + ", uid=" + Binder.getCallingUid() 3424 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3425 Slog.w(TAG, msg); 3426 throw new SecurityException(msg); 3427 } 3428 3429 int userId = UserId.getCallingUserId(); 3430 long callingId = Binder.clearCallingIdentity(); 3431 try { 3432 IPackageManager pm = AppGlobals.getPackageManager(); 3433 int pkgUid = -1; 3434 synchronized(this) { 3435 try { 3436 pkgUid = pm.getPackageUid(packageName, userId); 3437 } catch (RemoteException e) { 3438 } 3439 if (pkgUid == -1) { 3440 Slog.w(TAG, "Invalid packageName: " + packageName); 3441 return; 3442 } 3443 killPackageProcessesLocked(packageName, pkgUid, 3444 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3445 } 3446 } finally { 3447 Binder.restoreCallingIdentity(callingId); 3448 } 3449 } 3450 3451 public void killAllBackgroundProcesses() { 3452 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 long callingId = Binder.clearCallingIdentity(); 3463 try { 3464 synchronized(this) { 3465 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3466 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3467 final int NA = apps.size(); 3468 for (int ia=0; ia<NA; ia++) { 3469 ProcessRecord app = apps.valueAt(ia); 3470 if (app.persistent) { 3471 // we don't kill persistent processes 3472 continue; 3473 } 3474 if (app.removed) { 3475 procs.add(app); 3476 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3477 app.removed = true; 3478 procs.add(app); 3479 } 3480 } 3481 } 3482 3483 int N = procs.size(); 3484 for (int i=0; i<N; i++) { 3485 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3486 } 3487 } 3488 } finally { 3489 Binder.restoreCallingIdentity(callingId); 3490 } 3491 } 3492 3493 public void forceStopPackage(final String packageName) { 3494 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3495 != PackageManager.PERMISSION_GRANTED) { 3496 String msg = "Permission Denial: forceStopPackage() from pid=" 3497 + Binder.getCallingPid() 3498 + ", uid=" + Binder.getCallingUid() 3499 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3500 Slog.w(TAG, msg); 3501 throw new SecurityException(msg); 3502 } 3503 final int userId = UserId.getCallingUserId(); 3504 long callingId = Binder.clearCallingIdentity(); 3505 try { 3506 IPackageManager pm = AppGlobals.getPackageManager(); 3507 int pkgUid = -1; 3508 synchronized(this) { 3509 try { 3510 pkgUid = pm.getPackageUid(packageName, userId); 3511 } catch (RemoteException e) { 3512 } 3513 if (pkgUid == -1) { 3514 Slog.w(TAG, "Invalid packageName: " + packageName); 3515 return; 3516 } 3517 forceStopPackageLocked(packageName, pkgUid); 3518 try { 3519 pm.setPackageStoppedState(packageName, true, userId); 3520 } catch (RemoteException e) { 3521 } catch (IllegalArgumentException e) { 3522 Slog.w(TAG, "Failed trying to unstop package " 3523 + packageName + ": " + e); 3524 } 3525 } 3526 } finally { 3527 Binder.restoreCallingIdentity(callingId); 3528 } 3529 } 3530 3531 /* 3532 * The pkg name and uid have to be specified. 3533 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3534 */ 3535 public void killApplicationWithUid(String pkg, int uid) { 3536 if (pkg == null) { 3537 return; 3538 } 3539 // Make sure the uid is valid. 3540 if (uid < 0) { 3541 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3542 return; 3543 } 3544 int callerUid = Binder.getCallingUid(); 3545 // Only the system server can kill an application 3546 if (callerUid == Process.SYSTEM_UID) { 3547 // Post an aysnc message to kill the application 3548 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3549 msg.arg1 = uid; 3550 msg.arg2 = 0; 3551 msg.obj = pkg; 3552 mHandler.sendMessage(msg); 3553 } else { 3554 throw new SecurityException(callerUid + " cannot kill pkg: " + 3555 pkg); 3556 } 3557 } 3558 3559 public void closeSystemDialogs(String reason) { 3560 enforceNotIsolatedCaller("closeSystemDialogs"); 3561 3562 final int uid = Binder.getCallingUid(); 3563 final long origId = Binder.clearCallingIdentity(); 3564 synchronized (this) { 3565 closeSystemDialogsLocked(uid, reason); 3566 } 3567 Binder.restoreCallingIdentity(origId); 3568 } 3569 3570 void closeSystemDialogsLocked(int callingUid, String reason) { 3571 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3572 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3573 if (reason != null) { 3574 intent.putExtra("reason", reason); 3575 } 3576 mWindowManager.closeSystemDialogs(reason); 3577 3578 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3579 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3580 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3581 r.stack.finishActivityLocked(r, i, 3582 Activity.RESULT_CANCELED, null, "close-sys"); 3583 } 3584 } 3585 3586 broadcastIntentLocked(null, null, intent, null, 3587 null, 0, null, null, null, false, false, -1, 3588 callingUid, 0 /* TODO: Verify */); 3589 } 3590 3591 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3592 throws RemoteException { 3593 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3594 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3595 for (int i=pids.length-1; i>=0; i--) { 3596 infos[i] = new Debug.MemoryInfo(); 3597 Debug.getMemoryInfo(pids[i], infos[i]); 3598 } 3599 return infos; 3600 } 3601 3602 public long[] getProcessPss(int[] pids) throws RemoteException { 3603 enforceNotIsolatedCaller("getProcessPss"); 3604 long[] pss = new long[pids.length]; 3605 for (int i=pids.length-1; i>=0; i--) { 3606 pss[i] = Debug.getPss(pids[i]); 3607 } 3608 return pss; 3609 } 3610 3611 public void killApplicationProcess(String processName, int uid) { 3612 if (processName == null) { 3613 return; 3614 } 3615 3616 int callerUid = Binder.getCallingUid(); 3617 // Only the system server can kill an application 3618 if (callerUid == Process.SYSTEM_UID) { 3619 synchronized (this) { 3620 ProcessRecord app = getProcessRecordLocked(processName, uid); 3621 if (app != null && app.thread != null) { 3622 try { 3623 app.thread.scheduleSuicide(); 3624 } catch (RemoteException e) { 3625 // If the other end already died, then our work here is done. 3626 } 3627 } else { 3628 Slog.w(TAG, "Process/uid not found attempting kill of " 3629 + processName + " / " + uid); 3630 } 3631 } 3632 } else { 3633 throw new SecurityException(callerUid + " cannot kill app process: " + 3634 processName); 3635 } 3636 } 3637 3638 private void forceStopPackageLocked(final String packageName, int uid) { 3639 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3640 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3641 Uri.fromParts("package", packageName, null)); 3642 if (!mProcessesReady) { 3643 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3644 } 3645 intent.putExtra(Intent.EXTRA_UID, uid); 3646 broadcastIntentLocked(null, null, intent, 3647 null, null, 0, null, null, null, 3648 false, false, 3649 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3650 } 3651 3652 private final boolean killPackageProcessesLocked(String packageName, int uid, 3653 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3654 boolean evenPersistent, String reason) { 3655 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3656 3657 // Remove all processes this package may have touched: all with the 3658 // same UID (except for the system or root user), and all whose name 3659 // matches the package name. 3660 final String procNamePrefix = packageName + ":"; 3661 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3662 final int NA = apps.size(); 3663 for (int ia=0; ia<NA; ia++) { 3664 ProcessRecord app = apps.valueAt(ia); 3665 if (app.persistent && !evenPersistent) { 3666 // we don't kill persistent processes 3667 continue; 3668 } 3669 if (app.removed) { 3670 if (doit) { 3671 procs.add(app); 3672 } 3673 // If uid is specified and the uid and process name match 3674 // Or, the uid is not specified and the process name matches 3675 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3676 || ((app.processName.equals(packageName) 3677 || app.processName.startsWith(procNamePrefix)) 3678 && uid < 0))) { 3679 if (app.setAdj >= minOomAdj) { 3680 if (!doit) { 3681 return true; 3682 } 3683 app.removed = true; 3684 procs.add(app); 3685 } 3686 } 3687 } 3688 } 3689 3690 int N = procs.size(); 3691 for (int i=0; i<N; i++) { 3692 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3693 } 3694 return N > 0; 3695 } 3696 3697 private final boolean forceStopPackageLocked(String name, int uid, 3698 boolean callerWillRestart, boolean purgeCache, boolean doit, 3699 boolean evenPersistent, int userId) { 3700 int i; 3701 int N; 3702 3703 if (uid < 0) { 3704 try { 3705 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3706 } catch (RemoteException e) { 3707 } 3708 } 3709 3710 if (doit) { 3711 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3712 3713 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3714 while (badApps.hasNext()) { 3715 SparseArray<Long> ba = badApps.next(); 3716 if (ba.get(uid) != null) { 3717 badApps.remove(); 3718 } 3719 } 3720 } 3721 3722 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3723 callerWillRestart, false, doit, evenPersistent, "force stop"); 3724 3725 TaskRecord lastTask = null; 3726 for (i=0; i<mMainStack.mHistory.size(); i++) { 3727 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3728 final boolean samePackage = r.packageName.equals(name); 3729 if (r.userId == userId 3730 && (samePackage || r.task == lastTask) 3731 && (r.app == null || evenPersistent || !r.app.persistent)) { 3732 if (!doit) { 3733 if (r.finishing) { 3734 // If this activity is just finishing, then it is not 3735 // interesting as far as something to stop. 3736 continue; 3737 } 3738 return true; 3739 } 3740 didSomething = true; 3741 Slog.i(TAG, " Force finishing activity " + r); 3742 if (samePackage) { 3743 if (r.app != null) { 3744 r.app.removed = true; 3745 } 3746 r.app = null; 3747 } 3748 lastTask = r.task; 3749 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3750 null, "force-stop", true)) { 3751 i--; 3752 } 3753 } 3754 } 3755 3756 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 3757 for (ServiceRecord service : mServiceMap.getAllServices(userId)) { 3758 if (service.packageName.equals(name) 3759 && (service.app == null || evenPersistent || !service.app.persistent)) { 3760 if (!doit) { 3761 return true; 3762 } 3763 didSomething = true; 3764 Slog.i(TAG, " Force stopping service " + service); 3765 if (service.app != null) { 3766 service.app.removed = true; 3767 } 3768 service.app = null; 3769 service.isolatedProc = null; 3770 services.add(service); 3771 } 3772 } 3773 3774 N = services.size(); 3775 for (i=0; i<N; i++) { 3776 bringDownServiceLocked(services.get(i), true); 3777 } 3778 3779 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3780 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3781 if (provider.info.packageName.equals(name) 3782 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3783 if (!doit) { 3784 return true; 3785 } 3786 didSomething = true; 3787 providers.add(provider); 3788 } 3789 } 3790 3791 N = providers.size(); 3792 for (i=0; i<N; i++) { 3793 removeDyingProviderLocked(null, providers.get(i), true); 3794 } 3795 3796 if (doit) { 3797 if (purgeCache) { 3798 AttributeCache ac = AttributeCache.instance(); 3799 if (ac != null) { 3800 ac.removePackage(name); 3801 } 3802 } 3803 if (mBooted) { 3804 mMainStack.resumeTopActivityLocked(null); 3805 mMainStack.scheduleIdleLocked(); 3806 } 3807 } 3808 3809 return didSomething; 3810 } 3811 3812 private final boolean removeProcessLocked(ProcessRecord app, 3813 boolean callerWillRestart, boolean allowRestart, String reason) { 3814 final String name = app.processName; 3815 final int uid = app.uid; 3816 if (DEBUG_PROCESSES) Slog.d( 3817 TAG, "Force removing proc " + app.toShortString() + " (" + name 3818 + "/" + uid + ")"); 3819 3820 mProcessNames.remove(name, uid); 3821 mIsolatedProcesses.remove(app.uid); 3822 if (mHeavyWeightProcess == app) { 3823 mHeavyWeightProcess = null; 3824 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3825 } 3826 boolean needRestart = false; 3827 if (app.pid > 0 && app.pid != MY_PID) { 3828 int pid = app.pid; 3829 synchronized (mPidsSelfLocked) { 3830 mPidsSelfLocked.remove(pid); 3831 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3832 } 3833 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3834 handleAppDiedLocked(app, true, allowRestart); 3835 mLruProcesses.remove(app); 3836 Process.killProcessQuiet(pid); 3837 3838 if (app.persistent && !app.isolated) { 3839 if (!callerWillRestart) { 3840 addAppLocked(app.info, false); 3841 } else { 3842 needRestart = true; 3843 } 3844 } 3845 } else { 3846 mRemovedProcesses.add(app); 3847 } 3848 3849 return needRestart; 3850 } 3851 3852 private final void processStartTimedOutLocked(ProcessRecord app) { 3853 final int pid = app.pid; 3854 boolean gone = false; 3855 synchronized (mPidsSelfLocked) { 3856 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3857 if (knownApp != null && knownApp.thread == null) { 3858 mPidsSelfLocked.remove(pid); 3859 gone = true; 3860 } 3861 } 3862 3863 if (gone) { 3864 Slog.w(TAG, "Process " + app + " failed to attach"); 3865 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3866 app.processName); 3867 mProcessNames.remove(app.processName, app.uid); 3868 mIsolatedProcesses.remove(app.uid); 3869 if (mHeavyWeightProcess == app) { 3870 mHeavyWeightProcess = null; 3871 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3872 } 3873 // Take care of any launching providers waiting for this process. 3874 checkAppInLaunchingProvidersLocked(app, true); 3875 // Take care of any services that are waiting for the process. 3876 for (int i=0; i<mPendingServices.size(); i++) { 3877 ServiceRecord sr = mPendingServices.get(i); 3878 if ((app.uid == sr.appInfo.uid 3879 && app.processName.equals(sr.processName)) 3880 || sr.isolatedProc == app) { 3881 Slog.w(TAG, "Forcing bringing down service: " + sr); 3882 sr.isolatedProc = null; 3883 mPendingServices.remove(i); 3884 i--; 3885 bringDownServiceLocked(sr, true); 3886 } 3887 } 3888 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3889 app.processName, app.setAdj, "start timeout"); 3890 Process.killProcessQuiet(pid); 3891 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3892 Slog.w(TAG, "Unattached app died before backup, skipping"); 3893 try { 3894 IBackupManager bm = IBackupManager.Stub.asInterface( 3895 ServiceManager.getService(Context.BACKUP_SERVICE)); 3896 bm.agentDisconnected(app.info.packageName); 3897 } catch (RemoteException e) { 3898 // Can't happen; the backup manager is local 3899 } 3900 } 3901 if (isPendingBroadcastProcessLocked(pid)) { 3902 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3903 skipPendingBroadcastLocked(pid); 3904 } 3905 } else { 3906 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3907 } 3908 } 3909 3910 private final boolean attachApplicationLocked(IApplicationThread thread, 3911 int pid) { 3912 3913 // Find the application record that is being attached... either via 3914 // the pid if we are running in multiple processes, or just pull the 3915 // next app record if we are emulating process with anonymous threads. 3916 ProcessRecord app; 3917 if (pid != MY_PID && pid >= 0) { 3918 synchronized (mPidsSelfLocked) { 3919 app = mPidsSelfLocked.get(pid); 3920 } 3921 } else { 3922 app = null; 3923 } 3924 3925 if (app == null) { 3926 Slog.w(TAG, "No pending application record for pid " + pid 3927 + " (IApplicationThread " + thread + "); dropping process"); 3928 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3929 if (pid > 0 && pid != MY_PID) { 3930 Process.killProcessQuiet(pid); 3931 } else { 3932 try { 3933 thread.scheduleExit(); 3934 } catch (Exception e) { 3935 // Ignore exceptions. 3936 } 3937 } 3938 return false; 3939 } 3940 3941 // If this application record is still attached to a previous 3942 // process, clean it up now. 3943 if (app.thread != null) { 3944 handleAppDiedLocked(app, true, true); 3945 } 3946 3947 // Tell the process all about itself. 3948 3949 if (localLOGV) Slog.v( 3950 TAG, "Binding process pid " + pid + " to record " + app); 3951 3952 String processName = app.processName; 3953 try { 3954 AppDeathRecipient adr = new AppDeathRecipient( 3955 app, pid, thread); 3956 thread.asBinder().linkToDeath(adr, 0); 3957 app.deathRecipient = adr; 3958 } catch (RemoteException e) { 3959 app.resetPackageList(); 3960 startProcessLocked(app, "link fail", processName); 3961 return false; 3962 } 3963 3964 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3965 3966 app.thread = thread; 3967 app.curAdj = app.setAdj = -100; 3968 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3969 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3970 app.forcingToForeground = null; 3971 app.foregroundServices = false; 3972 app.hasShownUi = false; 3973 app.debugging = false; 3974 3975 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3976 3977 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3978 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3979 3980 if (!normalMode) { 3981 Slog.i(TAG, "Launching preboot mode app: " + app); 3982 } 3983 3984 if (localLOGV) Slog.v( 3985 TAG, "New app record " + app 3986 + " thread=" + thread.asBinder() + " pid=" + pid); 3987 try { 3988 int testMode = IApplicationThread.DEBUG_OFF; 3989 if (mDebugApp != null && mDebugApp.equals(processName)) { 3990 testMode = mWaitForDebugger 3991 ? IApplicationThread.DEBUG_WAIT 3992 : IApplicationThread.DEBUG_ON; 3993 app.debugging = true; 3994 if (mDebugTransient) { 3995 mDebugApp = mOrigDebugApp; 3996 mWaitForDebugger = mOrigWaitForDebugger; 3997 } 3998 } 3999 String profileFile = app.instrumentationProfileFile; 4000 ParcelFileDescriptor profileFd = null; 4001 boolean profileAutoStop = false; 4002 if (mProfileApp != null && mProfileApp.equals(processName)) { 4003 mProfileProc = app; 4004 profileFile = mProfileFile; 4005 profileFd = mProfileFd; 4006 profileAutoStop = mAutoStopProfiler; 4007 } 4008 boolean enableOpenGlTrace = false; 4009 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4010 enableOpenGlTrace = true; 4011 mOpenGlTraceApp = null; 4012 } 4013 4014 // If the app is being launched for restore or full backup, set it up specially 4015 boolean isRestrictedBackupMode = false; 4016 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4017 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4018 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4019 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4020 } 4021 4022 ensurePackageDexOpt(app.instrumentationInfo != null 4023 ? app.instrumentationInfo.packageName 4024 : app.info.packageName); 4025 if (app.instrumentationClass != null) { 4026 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4027 } 4028 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4029 + processName + " with config " + mConfiguration); 4030 ApplicationInfo appInfo = app.instrumentationInfo != null 4031 ? app.instrumentationInfo : app.info; 4032 app.compat = compatibilityInfoForPackageLocked(appInfo); 4033 if (profileFd != null) { 4034 profileFd = profileFd.dup(); 4035 } 4036 thread.bindApplication(processName, appInfo, providers, 4037 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4038 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4039 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4040 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4041 mCoreSettingsObserver.getCoreSettingsLocked()); 4042 updateLruProcessLocked(app, false, true); 4043 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4044 } catch (Exception e) { 4045 // todo: Yikes! What should we do? For now we will try to 4046 // start another process, but that could easily get us in 4047 // an infinite loop of restarting processes... 4048 Slog.w(TAG, "Exception thrown during bind!", e); 4049 4050 app.resetPackageList(); 4051 app.unlinkDeathRecipient(); 4052 startProcessLocked(app, "bind fail", processName); 4053 return false; 4054 } 4055 4056 // Remove this record from the list of starting applications. 4057 mPersistentStartingProcesses.remove(app); 4058 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4059 "Attach application locked removing on hold: " + app); 4060 mProcessesOnHold.remove(app); 4061 4062 boolean badApp = false; 4063 boolean didSomething = false; 4064 4065 // See if the top visible activity is waiting to run in this process... 4066 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4067 if (hr != null && normalMode) { 4068 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4069 && processName.equals(hr.processName)) { 4070 try { 4071 if (mHeadless) { 4072 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4073 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4074 didSomething = true; 4075 } 4076 } catch (Exception e) { 4077 Slog.w(TAG, "Exception in new application when starting activity " 4078 + hr.intent.getComponent().flattenToShortString(), e); 4079 badApp = true; 4080 } 4081 } else { 4082 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4083 } 4084 } 4085 4086 // Find any services that should be running in this process... 4087 if (!badApp && mPendingServices.size() > 0) { 4088 ServiceRecord sr = null; 4089 try { 4090 for (int i=0; i<mPendingServices.size(); i++) { 4091 sr = mPendingServices.get(i); 4092 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid 4093 || !processName.equals(sr.processName))) { 4094 continue; 4095 } 4096 4097 mPendingServices.remove(i); 4098 i--; 4099 realStartServiceLocked(sr, app); 4100 didSomething = true; 4101 } 4102 } catch (Exception e) { 4103 Slog.w(TAG, "Exception in new application when starting service " 4104 + sr.shortName, e); 4105 badApp = true; 4106 } 4107 } 4108 4109 // Check if a next-broadcast receiver is in this process... 4110 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4111 try { 4112 didSomething = sendPendingBroadcastsLocked(app); 4113 } catch (Exception e) { 4114 // If the app died trying to launch the receiver we declare it 'bad' 4115 badApp = true; 4116 } 4117 } 4118 4119 // Check whether the next backup agent is in this process... 4120 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4121 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4122 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4123 try { 4124 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4125 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4126 mBackupTarget.backupMode); 4127 } catch (Exception e) { 4128 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4129 e.printStackTrace(); 4130 } 4131 } 4132 4133 if (badApp) { 4134 // todo: Also need to kill application to deal with all 4135 // kinds of exceptions. 4136 handleAppDiedLocked(app, false, true); 4137 return false; 4138 } 4139 4140 if (!didSomething) { 4141 updateOomAdjLocked(); 4142 } 4143 4144 return true; 4145 } 4146 4147 public final void attachApplication(IApplicationThread thread) { 4148 synchronized (this) { 4149 int callingPid = Binder.getCallingPid(); 4150 final long origId = Binder.clearCallingIdentity(); 4151 attachApplicationLocked(thread, callingPid); 4152 Binder.restoreCallingIdentity(origId); 4153 } 4154 } 4155 4156 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4157 final long origId = Binder.clearCallingIdentity(); 4158 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4159 if (stopProfiling) { 4160 synchronized (this) { 4161 if (mProfileProc == r.app) { 4162 if (mProfileFd != null) { 4163 try { 4164 mProfileFd.close(); 4165 } catch (IOException e) { 4166 } 4167 clearProfilerLocked(); 4168 } 4169 } 4170 } 4171 } 4172 Binder.restoreCallingIdentity(origId); 4173 } 4174 4175 void enableScreenAfterBoot() { 4176 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4177 SystemClock.uptimeMillis()); 4178 mWindowManager.enableScreenAfterBoot(); 4179 4180 synchronized (this) { 4181 updateEventDispatchingLocked(); 4182 } 4183 } 4184 4185 public void showBootMessage(final CharSequence msg, final boolean always) { 4186 enforceNotIsolatedCaller("showBootMessage"); 4187 mWindowManager.showBootMessage(msg, always); 4188 } 4189 4190 public void dismissKeyguardOnNextActivity() { 4191 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4192 final long token = Binder.clearCallingIdentity(); 4193 try { 4194 synchronized (this) { 4195 if (mLockScreenShown) { 4196 mLockScreenShown = false; 4197 comeOutOfSleepIfNeededLocked(); 4198 } 4199 mMainStack.dismissKeyguardOnNextActivityLocked(); 4200 } 4201 } finally { 4202 Binder.restoreCallingIdentity(token); 4203 } 4204 } 4205 4206 final void finishBooting() { 4207 IntentFilter pkgFilter = new IntentFilter(); 4208 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4209 pkgFilter.addDataScheme("package"); 4210 mContext.registerReceiver(new BroadcastReceiver() { 4211 @Override 4212 public void onReceive(Context context, Intent intent) { 4213 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4214 if (pkgs != null) { 4215 for (String pkg : pkgs) { 4216 synchronized (ActivityManagerService.this) { 4217 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4218 setResultCode(Activity.RESULT_OK); 4219 return; 4220 } 4221 } 4222 } 4223 } 4224 } 4225 }, pkgFilter); 4226 4227 IntentFilter userFilter = new IntentFilter(); 4228 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4229 mContext.registerReceiver(new BroadcastReceiver() { 4230 @Override 4231 public void onReceive(Context context, Intent intent) { 4232 onUserRemoved(intent); 4233 } 4234 }, userFilter); 4235 4236 synchronized (this) { 4237 // Ensure that any processes we had put on hold are now started 4238 // up. 4239 final int NP = mProcessesOnHold.size(); 4240 if (NP > 0) { 4241 ArrayList<ProcessRecord> procs = 4242 new ArrayList<ProcessRecord>(mProcessesOnHold); 4243 for (int ip=0; ip<NP; ip++) { 4244 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4245 + procs.get(ip)); 4246 startProcessLocked(procs.get(ip), "on-hold", null); 4247 } 4248 } 4249 4250 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4251 // Start looking for apps that are abusing wake locks. 4252 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4253 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4254 // Tell anyone interested that we are done booting! 4255 SystemProperties.set("sys.boot_completed", "1"); 4256 SystemProperties.set("dev.bootcomplete", "1"); 4257 /* TODO: Send this to all users that are to be logged in on startup */ 4258 broadcastIntentLocked(null, null, 4259 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4260 null, null, 0, null, null, 4261 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4262 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser()); 4263 } 4264 } 4265 } 4266 4267 final void ensureBootCompleted() { 4268 boolean booting; 4269 boolean enableScreen; 4270 synchronized (this) { 4271 booting = mBooting; 4272 mBooting = false; 4273 enableScreen = !mBooted; 4274 mBooted = true; 4275 } 4276 4277 if (booting) { 4278 finishBooting(); 4279 } 4280 4281 if (enableScreen) { 4282 enableScreenAfterBoot(); 4283 } 4284 } 4285 4286 public final void activityPaused(IBinder token) { 4287 final long origId = Binder.clearCallingIdentity(); 4288 mMainStack.activityPaused(token, false); 4289 Binder.restoreCallingIdentity(origId); 4290 } 4291 4292 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4293 CharSequence description) { 4294 if (localLOGV) Slog.v( 4295 TAG, "Activity stopped: token=" + token); 4296 4297 // Refuse possible leaked file descriptors 4298 if (icicle != null && icicle.hasFileDescriptors()) { 4299 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4300 } 4301 4302 ActivityRecord r = null; 4303 4304 final long origId = Binder.clearCallingIdentity(); 4305 4306 synchronized (this) { 4307 r = mMainStack.isInStackLocked(token); 4308 if (r != null) { 4309 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4310 } 4311 } 4312 4313 if (r != null) { 4314 sendPendingThumbnail(r, null, null, null, false); 4315 } 4316 4317 trimApplications(); 4318 4319 Binder.restoreCallingIdentity(origId); 4320 } 4321 4322 public final void activityDestroyed(IBinder token) { 4323 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4324 mMainStack.activityDestroyed(token); 4325 } 4326 4327 public String getCallingPackage(IBinder token) { 4328 synchronized (this) { 4329 ActivityRecord r = getCallingRecordLocked(token); 4330 return r != null && r.app != null ? r.info.packageName : null; 4331 } 4332 } 4333 4334 public ComponentName getCallingActivity(IBinder token) { 4335 synchronized (this) { 4336 ActivityRecord r = getCallingRecordLocked(token); 4337 return r != null ? r.intent.getComponent() : null; 4338 } 4339 } 4340 4341 private ActivityRecord getCallingRecordLocked(IBinder token) { 4342 ActivityRecord r = mMainStack.isInStackLocked(token); 4343 if (r == null) { 4344 return null; 4345 } 4346 return r.resultTo; 4347 } 4348 4349 public ComponentName getActivityClassForToken(IBinder token) { 4350 synchronized(this) { 4351 ActivityRecord r = mMainStack.isInStackLocked(token); 4352 if (r == null) { 4353 return null; 4354 } 4355 return r.intent.getComponent(); 4356 } 4357 } 4358 4359 public String getPackageForToken(IBinder token) { 4360 synchronized(this) { 4361 ActivityRecord r = mMainStack.isInStackLocked(token); 4362 if (r == null) { 4363 return null; 4364 } 4365 return r.packageName; 4366 } 4367 } 4368 4369 public IIntentSender getIntentSender(int type, 4370 String packageName, IBinder token, String resultWho, 4371 int requestCode, Intent[] intents, String[] resolvedTypes, 4372 int flags, Bundle options) { 4373 enforceNotIsolatedCaller("getIntentSender"); 4374 // Refuse possible leaked file descriptors 4375 if (intents != null) { 4376 if (intents.length < 1) { 4377 throw new IllegalArgumentException("Intents array length must be >= 1"); 4378 } 4379 for (int i=0; i<intents.length; i++) { 4380 Intent intent = intents[i]; 4381 if (intent != null) { 4382 if (intent.hasFileDescriptors()) { 4383 throw new IllegalArgumentException("File descriptors passed in Intent"); 4384 } 4385 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4386 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4387 throw new IllegalArgumentException( 4388 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4389 } 4390 intents[i] = new Intent(intent); 4391 } 4392 } 4393 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4394 throw new IllegalArgumentException( 4395 "Intent array length does not match resolvedTypes length"); 4396 } 4397 } 4398 if (options != null) { 4399 if (options.hasFileDescriptors()) { 4400 throw new IllegalArgumentException("File descriptors passed in options"); 4401 } 4402 } 4403 4404 synchronized(this) { 4405 int callingUid = Binder.getCallingUid(); 4406 try { 4407 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4408 int uid = AppGlobals.getPackageManager() 4409 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4410 if (!UserId.isSameApp(callingUid, uid)) { 4411 String msg = "Permission Denial: getIntentSender() from pid=" 4412 + Binder.getCallingPid() 4413 + ", uid=" + Binder.getCallingUid() 4414 + ", (need uid=" + uid + ")" 4415 + " is not allowed to send as package " + packageName; 4416 Slog.w(TAG, msg); 4417 throw new SecurityException(msg); 4418 } 4419 } 4420 4421 if (DEBUG_MU) 4422 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4423 + Binder.getOrigCallingUid()); 4424 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4425 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4426 4427 } catch (RemoteException e) { 4428 throw new SecurityException(e); 4429 } 4430 } 4431 } 4432 4433 IIntentSender getIntentSenderLocked(int type, 4434 String packageName, int callingUid, IBinder token, String resultWho, 4435 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4436 Bundle options) { 4437 if (DEBUG_MU) 4438 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4439 ActivityRecord activity = null; 4440 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4441 activity = mMainStack.isInStackLocked(token); 4442 if (activity == null) { 4443 return null; 4444 } 4445 if (activity.finishing) { 4446 return null; 4447 } 4448 } 4449 4450 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4451 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4452 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4453 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4454 |PendingIntent.FLAG_UPDATE_CURRENT); 4455 4456 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4457 type, packageName, activity, resultWho, 4458 requestCode, intents, resolvedTypes, flags, options); 4459 WeakReference<PendingIntentRecord> ref; 4460 ref = mIntentSenderRecords.get(key); 4461 PendingIntentRecord rec = ref != null ? ref.get() : null; 4462 if (rec != null) { 4463 if (!cancelCurrent) { 4464 if (updateCurrent) { 4465 if (rec.key.requestIntent != null) { 4466 rec.key.requestIntent.replaceExtras(intents != null ? 4467 intents[intents.length - 1] : null); 4468 } 4469 if (intents != null) { 4470 intents[intents.length-1] = rec.key.requestIntent; 4471 rec.key.allIntents = intents; 4472 rec.key.allResolvedTypes = resolvedTypes; 4473 } else { 4474 rec.key.allIntents = null; 4475 rec.key.allResolvedTypes = null; 4476 } 4477 } 4478 return rec; 4479 } 4480 rec.canceled = true; 4481 mIntentSenderRecords.remove(key); 4482 } 4483 if (noCreate) { 4484 return rec; 4485 } 4486 rec = new PendingIntentRecord(this, key, callingUid); 4487 mIntentSenderRecords.put(key, rec.ref); 4488 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4489 if (activity.pendingResults == null) { 4490 activity.pendingResults 4491 = new HashSet<WeakReference<PendingIntentRecord>>(); 4492 } 4493 activity.pendingResults.add(rec.ref); 4494 } 4495 return rec; 4496 } 4497 4498 public void cancelIntentSender(IIntentSender sender) { 4499 if (!(sender instanceof PendingIntentRecord)) { 4500 return; 4501 } 4502 synchronized(this) { 4503 PendingIntentRecord rec = (PendingIntentRecord)sender; 4504 try { 4505 int uid = AppGlobals.getPackageManager() 4506 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4507 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4508 String msg = "Permission Denial: cancelIntentSender() from pid=" 4509 + Binder.getCallingPid() 4510 + ", uid=" + Binder.getCallingUid() 4511 + " is not allowed to cancel packges " 4512 + rec.key.packageName; 4513 Slog.w(TAG, msg); 4514 throw new SecurityException(msg); 4515 } 4516 } catch (RemoteException e) { 4517 throw new SecurityException(e); 4518 } 4519 cancelIntentSenderLocked(rec, true); 4520 } 4521 } 4522 4523 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4524 rec.canceled = true; 4525 mIntentSenderRecords.remove(rec.key); 4526 if (cleanActivity && rec.key.activity != null) { 4527 rec.key.activity.pendingResults.remove(rec.ref); 4528 } 4529 } 4530 4531 public String getPackageForIntentSender(IIntentSender pendingResult) { 4532 if (!(pendingResult instanceof PendingIntentRecord)) { 4533 return null; 4534 } 4535 try { 4536 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4537 return res.key.packageName; 4538 } catch (ClassCastException e) { 4539 } 4540 return null; 4541 } 4542 4543 public int getUidForIntentSender(IIntentSender sender) { 4544 if (sender instanceof PendingIntentRecord) { 4545 try { 4546 PendingIntentRecord res = (PendingIntentRecord)sender; 4547 return res.uid; 4548 } catch (ClassCastException e) { 4549 } 4550 } 4551 return -1; 4552 } 4553 4554 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4555 if (!(pendingResult instanceof PendingIntentRecord)) { 4556 return false; 4557 } 4558 try { 4559 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4560 if (res.key.allIntents == null) { 4561 return false; 4562 } 4563 for (int i=0; i<res.key.allIntents.length; i++) { 4564 Intent intent = res.key.allIntents[i]; 4565 if (intent.getPackage() != null && intent.getComponent() != null) { 4566 return false; 4567 } 4568 } 4569 return true; 4570 } catch (ClassCastException e) { 4571 } 4572 return false; 4573 } 4574 4575 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4576 if (!(pendingResult instanceof PendingIntentRecord)) { 4577 return false; 4578 } 4579 try { 4580 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4581 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4582 return true; 4583 } 4584 return false; 4585 } catch (ClassCastException e) { 4586 } 4587 return false; 4588 } 4589 4590 public void setProcessLimit(int max) { 4591 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4592 "setProcessLimit()"); 4593 synchronized (this) { 4594 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4595 mProcessLimitOverride = max; 4596 } 4597 trimApplications(); 4598 } 4599 4600 public int getProcessLimit() { 4601 synchronized (this) { 4602 return mProcessLimitOverride; 4603 } 4604 } 4605 4606 void foregroundTokenDied(ForegroundToken token) { 4607 synchronized (ActivityManagerService.this) { 4608 synchronized (mPidsSelfLocked) { 4609 ForegroundToken cur 4610 = mForegroundProcesses.get(token.pid); 4611 if (cur != token) { 4612 return; 4613 } 4614 mForegroundProcesses.remove(token.pid); 4615 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4616 if (pr == null) { 4617 return; 4618 } 4619 pr.forcingToForeground = null; 4620 pr.foregroundServices = false; 4621 } 4622 updateOomAdjLocked(); 4623 } 4624 } 4625 4626 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4627 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4628 "setProcessForeground()"); 4629 synchronized(this) { 4630 boolean changed = false; 4631 4632 synchronized (mPidsSelfLocked) { 4633 ProcessRecord pr = mPidsSelfLocked.get(pid); 4634 if (pr == null && isForeground) { 4635 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4636 return; 4637 } 4638 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4639 if (oldToken != null) { 4640 oldToken.token.unlinkToDeath(oldToken, 0); 4641 mForegroundProcesses.remove(pid); 4642 if (pr != null) { 4643 pr.forcingToForeground = null; 4644 } 4645 changed = true; 4646 } 4647 if (isForeground && token != null) { 4648 ForegroundToken newToken = new ForegroundToken() { 4649 public void binderDied() { 4650 foregroundTokenDied(this); 4651 } 4652 }; 4653 newToken.pid = pid; 4654 newToken.token = token; 4655 try { 4656 token.linkToDeath(newToken, 0); 4657 mForegroundProcesses.put(pid, newToken); 4658 pr.forcingToForeground = token; 4659 changed = true; 4660 } catch (RemoteException e) { 4661 // If the process died while doing this, we will later 4662 // do the cleanup with the process death link. 4663 } 4664 } 4665 } 4666 4667 if (changed) { 4668 updateOomAdjLocked(); 4669 } 4670 } 4671 } 4672 4673 // ========================================================= 4674 // PERMISSIONS 4675 // ========================================================= 4676 4677 static class PermissionController extends IPermissionController.Stub { 4678 ActivityManagerService mActivityManagerService; 4679 PermissionController(ActivityManagerService activityManagerService) { 4680 mActivityManagerService = activityManagerService; 4681 } 4682 4683 public boolean checkPermission(String permission, int pid, int uid) { 4684 return mActivityManagerService.checkPermission(permission, pid, 4685 uid) == PackageManager.PERMISSION_GRANTED; 4686 } 4687 } 4688 4689 /** 4690 * This can be called with or without the global lock held. 4691 */ 4692 int checkComponentPermission(String permission, int pid, int uid, 4693 int owningUid, boolean exported) { 4694 // We might be performing an operation on behalf of an indirect binder 4695 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4696 // client identity accordingly before proceeding. 4697 Identity tlsIdentity = sCallerIdentity.get(); 4698 if (tlsIdentity != null) { 4699 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4700 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4701 uid = tlsIdentity.uid; 4702 pid = tlsIdentity.pid; 4703 } 4704 4705 if (pid == MY_PID) { 4706 return PackageManager.PERMISSION_GRANTED; 4707 } 4708 4709 return ActivityManager.checkComponentPermission(permission, uid, 4710 owningUid, exported); 4711 } 4712 4713 /** 4714 * As the only public entry point for permissions checking, this method 4715 * can enforce the semantic that requesting a check on a null global 4716 * permission is automatically denied. (Internally a null permission 4717 * string is used when calling {@link #checkComponentPermission} in cases 4718 * when only uid-based security is needed.) 4719 * 4720 * This can be called with or without the global lock held. 4721 */ 4722 public int checkPermission(String permission, int pid, int uid) { 4723 if (permission == null) { 4724 return PackageManager.PERMISSION_DENIED; 4725 } 4726 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4727 } 4728 4729 /** 4730 * Binder IPC calls go through the public entry point. 4731 * This can be called with or without the global lock held. 4732 */ 4733 int checkCallingPermission(String permission) { 4734 return checkPermission(permission, 4735 Binder.getCallingPid(), 4736 UserId.getAppId(Binder.getCallingUid())); 4737 } 4738 4739 /** 4740 * This can be called with or without the global lock held. 4741 */ 4742 void enforceCallingPermission(String permission, String func) { 4743 if (checkCallingPermission(permission) 4744 == PackageManager.PERMISSION_GRANTED) { 4745 return; 4746 } 4747 4748 String msg = "Permission Denial: " + func + " from pid=" 4749 + Binder.getCallingPid() 4750 + ", uid=" + Binder.getCallingUid() 4751 + " requires " + permission; 4752 Slog.w(TAG, msg); 4753 throw new SecurityException(msg); 4754 } 4755 4756 /** 4757 * Determine if UID is holding permissions required to access {@link Uri} in 4758 * the given {@link ProviderInfo}. Final permission checking is always done 4759 * in {@link ContentProvider}. 4760 */ 4761 private final boolean checkHoldingPermissionsLocked( 4762 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4763 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4764 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4765 4766 if (pi.applicationInfo.uid == uid) { 4767 return true; 4768 } else if (!pi.exported) { 4769 return false; 4770 } 4771 4772 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4773 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4774 try { 4775 // check if target holds top-level <provider> permissions 4776 if (!readMet && pi.readPermission != null 4777 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4778 readMet = true; 4779 } 4780 if (!writeMet && pi.writePermission != null 4781 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4782 writeMet = true; 4783 } 4784 4785 // track if unprotected read/write is allowed; any denied 4786 // <path-permission> below removes this ability 4787 boolean allowDefaultRead = pi.readPermission == null; 4788 boolean allowDefaultWrite = pi.writePermission == null; 4789 4790 // check if target holds any <path-permission> that match uri 4791 final PathPermission[] pps = pi.pathPermissions; 4792 if (pps != null) { 4793 final String path = uri.getPath(); 4794 int i = pps.length; 4795 while (i > 0 && (!readMet || !writeMet)) { 4796 i--; 4797 PathPermission pp = pps[i]; 4798 if (pp.match(path)) { 4799 if (!readMet) { 4800 final String pprperm = pp.getReadPermission(); 4801 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4802 + pprperm + " for " + pp.getPath() 4803 + ": match=" + pp.match(path) 4804 + " check=" + pm.checkUidPermission(pprperm, uid)); 4805 if (pprperm != null) { 4806 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4807 readMet = true; 4808 } else { 4809 allowDefaultRead = false; 4810 } 4811 } 4812 } 4813 if (!writeMet) { 4814 final String ppwperm = pp.getWritePermission(); 4815 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4816 + ppwperm + " for " + pp.getPath() 4817 + ": match=" + pp.match(path) 4818 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4819 if (ppwperm != null) { 4820 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4821 writeMet = true; 4822 } else { 4823 allowDefaultWrite = false; 4824 } 4825 } 4826 } 4827 } 4828 } 4829 } 4830 4831 // grant unprotected <provider> read/write, if not blocked by 4832 // <path-permission> above 4833 if (allowDefaultRead) readMet = true; 4834 if (allowDefaultWrite) writeMet = true; 4835 4836 } catch (RemoteException e) { 4837 return false; 4838 } 4839 4840 return readMet && writeMet; 4841 } 4842 4843 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4844 int modeFlags) { 4845 // Root gets to do everything. 4846 if (uid == 0) { 4847 return true; 4848 } 4849 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4850 if (perms == null) return false; 4851 UriPermission perm = perms.get(uri); 4852 if (perm == null) return false; 4853 return (modeFlags&perm.modeFlags) == modeFlags; 4854 } 4855 4856 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4857 enforceNotIsolatedCaller("checkUriPermission"); 4858 4859 // Another redirected-binder-call permissions check as in 4860 // {@link checkComponentPermission}. 4861 Identity tlsIdentity = sCallerIdentity.get(); 4862 if (tlsIdentity != null) { 4863 uid = tlsIdentity.uid; 4864 pid = tlsIdentity.pid; 4865 } 4866 4867 uid = UserId.getAppId(uid); 4868 // Our own process gets to do everything. 4869 if (pid == MY_PID) { 4870 return PackageManager.PERMISSION_GRANTED; 4871 } 4872 synchronized(this) { 4873 return checkUriPermissionLocked(uri, uid, modeFlags) 4874 ? PackageManager.PERMISSION_GRANTED 4875 : PackageManager.PERMISSION_DENIED; 4876 } 4877 } 4878 4879 /** 4880 * Check if the targetPkg can be granted permission to access uri by 4881 * the callingUid using the given modeFlags. Throws a security exception 4882 * if callingUid is not allowed to do this. Returns the uid of the target 4883 * if the URI permission grant should be performed; returns -1 if it is not 4884 * needed (for example targetPkg already has permission to access the URI). 4885 * If you already know the uid of the target, you can supply it in 4886 * lastTargetUid else set that to -1. 4887 */ 4888 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4889 Uri uri, int modeFlags, int lastTargetUid) { 4890 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4891 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4892 if (modeFlags == 0) { 4893 return -1; 4894 } 4895 4896 if (targetPkg != null) { 4897 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4898 "Checking grant " + targetPkg + " permission to " + uri); 4899 } 4900 4901 final IPackageManager pm = AppGlobals.getPackageManager(); 4902 4903 // If this is not a content: uri, we can't do anything with it. 4904 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4905 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4906 "Can't grant URI permission for non-content URI: " + uri); 4907 return -1; 4908 } 4909 4910 String name = uri.getAuthority(); 4911 ProviderInfo pi = null; 4912 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4913 UserId.getUserId(callingUid)); 4914 if (cpr != null) { 4915 pi = cpr.info; 4916 } else { 4917 try { 4918 pi = pm.resolveContentProvider(name, 4919 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4920 } catch (RemoteException ex) { 4921 } 4922 } 4923 if (pi == null) { 4924 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4925 return -1; 4926 } 4927 4928 int targetUid = lastTargetUid; 4929 if (targetUid < 0 && targetPkg != null) { 4930 try { 4931 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4932 if (targetUid < 0) { 4933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4934 "Can't grant URI permission no uid for: " + targetPkg); 4935 return -1; 4936 } 4937 } catch (RemoteException ex) { 4938 return -1; 4939 } 4940 } 4941 4942 if (targetUid >= 0) { 4943 // First... does the target actually need this permission? 4944 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4945 // No need to grant the target this permission. 4946 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4947 "Target " + targetPkg + " already has full permission to " + uri); 4948 return -1; 4949 } 4950 } else { 4951 // First... there is no target package, so can anyone access it? 4952 boolean allowed = pi.exported; 4953 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4954 if (pi.readPermission != null) { 4955 allowed = false; 4956 } 4957 } 4958 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4959 if (pi.writePermission != null) { 4960 allowed = false; 4961 } 4962 } 4963 if (allowed) { 4964 return -1; 4965 } 4966 } 4967 4968 // Second... is the provider allowing granting of URI permissions? 4969 if (!pi.grantUriPermissions) { 4970 throw new SecurityException("Provider " + pi.packageName 4971 + "/" + pi.name 4972 + " does not allow granting of Uri permissions (uri " 4973 + uri + ")"); 4974 } 4975 if (pi.uriPermissionPatterns != null) { 4976 final int N = pi.uriPermissionPatterns.length; 4977 boolean allowed = false; 4978 for (int i=0; i<N; i++) { 4979 if (pi.uriPermissionPatterns[i] != null 4980 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4981 allowed = true; 4982 break; 4983 } 4984 } 4985 if (!allowed) { 4986 throw new SecurityException("Provider " + pi.packageName 4987 + "/" + pi.name 4988 + " does not allow granting of permission to path of Uri " 4989 + uri); 4990 } 4991 } 4992 4993 // Third... does the caller itself have permission to access 4994 // this uri? 4995 if (callingUid != Process.myUid()) { 4996 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4997 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4998 throw new SecurityException("Uid " + callingUid 4999 + " does not have permission to uri " + uri); 5000 } 5001 } 5002 } 5003 5004 return targetUid; 5005 } 5006 5007 public int checkGrantUriPermission(int callingUid, String targetPkg, 5008 Uri uri, int modeFlags) { 5009 enforceNotIsolatedCaller("checkGrantUriPermission"); 5010 synchronized(this) { 5011 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5012 } 5013 } 5014 5015 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5016 Uri uri, int modeFlags, UriPermissionOwner owner) { 5017 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5018 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5019 if (modeFlags == 0) { 5020 return; 5021 } 5022 5023 // So here we are: the caller has the assumed permission 5024 // to the uri, and the target doesn't. Let's now give this to 5025 // the target. 5026 5027 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5028 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5029 5030 HashMap<Uri, UriPermission> targetUris 5031 = mGrantedUriPermissions.get(targetUid); 5032 if (targetUris == null) { 5033 targetUris = new HashMap<Uri, UriPermission>(); 5034 mGrantedUriPermissions.put(targetUid, targetUris); 5035 } 5036 5037 UriPermission perm = targetUris.get(uri); 5038 if (perm == null) { 5039 perm = new UriPermission(targetUid, uri); 5040 targetUris.put(uri, perm); 5041 } 5042 5043 perm.modeFlags |= modeFlags; 5044 if (owner == null) { 5045 perm.globalModeFlags |= modeFlags; 5046 } else { 5047 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5048 perm.readOwners.add(owner); 5049 owner.addReadPermission(perm); 5050 } 5051 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5052 perm.writeOwners.add(owner); 5053 owner.addWritePermission(perm); 5054 } 5055 } 5056 } 5057 5058 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5059 int modeFlags, UriPermissionOwner owner) { 5060 if (targetPkg == null) { 5061 throw new NullPointerException("targetPkg"); 5062 } 5063 5064 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5065 if (targetUid < 0) { 5066 return; 5067 } 5068 5069 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5070 } 5071 5072 static class NeededUriGrants extends ArrayList<Uri> { 5073 final String targetPkg; 5074 final int targetUid; 5075 final int flags; 5076 5077 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5078 targetPkg = _targetPkg; 5079 targetUid = _targetUid; 5080 flags = _flags; 5081 } 5082 } 5083 5084 /** 5085 * Like checkGrantUriPermissionLocked, but takes an Intent. 5086 */ 5087 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5088 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5090 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5091 + " clip=" + (intent != null ? intent.getClipData() : null) 5092 + " from " + intent + "; flags=0x" 5093 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5094 5095 if (targetPkg == null) { 5096 throw new NullPointerException("targetPkg"); 5097 } 5098 5099 if (intent == null) { 5100 return null; 5101 } 5102 Uri data = intent.getData(); 5103 ClipData clip = intent.getClipData(); 5104 if (data == null && clip == null) { 5105 return null; 5106 } 5107 if (data != null) { 5108 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5109 mode, needed != null ? needed.targetUid : -1); 5110 if (target > 0) { 5111 if (needed == null) { 5112 needed = new NeededUriGrants(targetPkg, target, mode); 5113 } 5114 needed.add(data); 5115 } 5116 } 5117 if (clip != null) { 5118 for (int i=0; i<clip.getItemCount(); i++) { 5119 Uri uri = clip.getItemAt(i).getUri(); 5120 if (uri != null) { 5121 int target = -1; 5122 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5123 mode, needed != null ? needed.targetUid : -1); 5124 if (target > 0) { 5125 if (needed == null) { 5126 needed = new NeededUriGrants(targetPkg, target, mode); 5127 } 5128 needed.add(uri); 5129 } 5130 } else { 5131 Intent clipIntent = clip.getItemAt(i).getIntent(); 5132 if (clipIntent != null) { 5133 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5134 callingUid, targetPkg, clipIntent, mode, needed); 5135 if (newNeeded != null) { 5136 needed = newNeeded; 5137 } 5138 } 5139 } 5140 } 5141 } 5142 5143 return needed; 5144 } 5145 5146 /** 5147 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5148 */ 5149 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5150 UriPermissionOwner owner) { 5151 if (needed != null) { 5152 for (int i=0; i<needed.size(); i++) { 5153 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5154 needed.get(i), needed.flags, owner); 5155 } 5156 } 5157 } 5158 5159 void grantUriPermissionFromIntentLocked(int callingUid, 5160 String targetPkg, Intent intent, UriPermissionOwner owner) { 5161 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5162 intent, intent != null ? intent.getFlags() : 0, null); 5163 if (needed == null) { 5164 return; 5165 } 5166 5167 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5168 } 5169 5170 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5171 Uri uri, int modeFlags) { 5172 enforceNotIsolatedCaller("grantUriPermission"); 5173 synchronized(this) { 5174 final ProcessRecord r = getRecordForAppLocked(caller); 5175 if (r == null) { 5176 throw new SecurityException("Unable to find app for caller " 5177 + caller 5178 + " when granting permission to uri " + uri); 5179 } 5180 if (targetPkg == null) { 5181 throw new IllegalArgumentException("null target"); 5182 } 5183 if (uri == null) { 5184 throw new IllegalArgumentException("null uri"); 5185 } 5186 5187 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5188 null); 5189 } 5190 } 5191 5192 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5193 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5194 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5195 HashMap<Uri, UriPermission> perms 5196 = mGrantedUriPermissions.get(perm.uid); 5197 if (perms != null) { 5198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5199 "Removing " + perm.uid + " permission to " + perm.uri); 5200 perms.remove(perm.uri); 5201 if (perms.size() == 0) { 5202 mGrantedUriPermissions.remove(perm.uid); 5203 } 5204 } 5205 } 5206 } 5207 5208 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5209 int modeFlags) { 5210 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5211 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5212 if (modeFlags == 0) { 5213 return; 5214 } 5215 5216 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5217 "Revoking all granted permissions to " + uri); 5218 5219 final IPackageManager pm = AppGlobals.getPackageManager(); 5220 5221 final String authority = uri.getAuthority(); 5222 ProviderInfo pi = null; 5223 int userId = UserId.getUserId(callingUid); 5224 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5225 if (cpr != null) { 5226 pi = cpr.info; 5227 } else { 5228 try { 5229 pi = pm.resolveContentProvider(authority, 5230 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5231 } catch (RemoteException ex) { 5232 } 5233 } 5234 if (pi == null) { 5235 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5236 return; 5237 } 5238 5239 // Does the caller have this permission on the URI? 5240 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5241 // Right now, if you are not the original owner of the permission, 5242 // you are not allowed to revoke it. 5243 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5244 throw new SecurityException("Uid " + callingUid 5245 + " does not have permission to uri " + uri); 5246 //} 5247 } 5248 5249 // Go through all of the permissions and remove any that match. 5250 final List<String> SEGMENTS = uri.getPathSegments(); 5251 if (SEGMENTS != null) { 5252 final int NS = SEGMENTS.size(); 5253 int N = mGrantedUriPermissions.size(); 5254 for (int i=0; i<N; i++) { 5255 HashMap<Uri, UriPermission> perms 5256 = mGrantedUriPermissions.valueAt(i); 5257 Iterator<UriPermission> it = perms.values().iterator(); 5258 toploop: 5259 while (it.hasNext()) { 5260 UriPermission perm = it.next(); 5261 Uri targetUri = perm.uri; 5262 if (!authority.equals(targetUri.getAuthority())) { 5263 continue; 5264 } 5265 List<String> targetSegments = targetUri.getPathSegments(); 5266 if (targetSegments == null) { 5267 continue; 5268 } 5269 if (targetSegments.size() < NS) { 5270 continue; 5271 } 5272 for (int j=0; j<NS; j++) { 5273 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5274 continue toploop; 5275 } 5276 } 5277 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5278 "Revoking " + perm.uid + " permission to " + perm.uri); 5279 perm.clearModes(modeFlags); 5280 if (perm.modeFlags == 0) { 5281 it.remove(); 5282 } 5283 } 5284 if (perms.size() == 0) { 5285 mGrantedUriPermissions.remove( 5286 mGrantedUriPermissions.keyAt(i)); 5287 N--; 5288 i--; 5289 } 5290 } 5291 } 5292 } 5293 5294 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5295 int modeFlags) { 5296 enforceNotIsolatedCaller("revokeUriPermission"); 5297 synchronized(this) { 5298 final ProcessRecord r = getRecordForAppLocked(caller); 5299 if (r == null) { 5300 throw new SecurityException("Unable to find app for caller " 5301 + caller 5302 + " when revoking permission to uri " + uri); 5303 } 5304 if (uri == null) { 5305 Slog.w(TAG, "revokeUriPermission: null uri"); 5306 return; 5307 } 5308 5309 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5310 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5311 if (modeFlags == 0) { 5312 return; 5313 } 5314 5315 final IPackageManager pm = AppGlobals.getPackageManager(); 5316 5317 final String authority = uri.getAuthority(); 5318 ProviderInfo pi = null; 5319 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5320 if (cpr != null) { 5321 pi = cpr.info; 5322 } else { 5323 try { 5324 pi = pm.resolveContentProvider(authority, 5325 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5326 } catch (RemoteException ex) { 5327 } 5328 } 5329 if (pi == null) { 5330 Slog.w(TAG, "No content provider found for permission revoke: " 5331 + uri.toSafeString()); 5332 return; 5333 } 5334 5335 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5336 } 5337 } 5338 5339 @Override 5340 public IBinder newUriPermissionOwner(String name) { 5341 enforceNotIsolatedCaller("newUriPermissionOwner"); 5342 synchronized(this) { 5343 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5344 return owner.getExternalTokenLocked(); 5345 } 5346 } 5347 5348 @Override 5349 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5350 Uri uri, int modeFlags) { 5351 synchronized(this) { 5352 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5353 if (owner == null) { 5354 throw new IllegalArgumentException("Unknown owner: " + token); 5355 } 5356 if (fromUid != Binder.getCallingUid()) { 5357 if (Binder.getCallingUid() != Process.myUid()) { 5358 // Only system code can grant URI permissions on behalf 5359 // of other users. 5360 throw new SecurityException("nice try"); 5361 } 5362 } 5363 if (targetPkg == null) { 5364 throw new IllegalArgumentException("null target"); 5365 } 5366 if (uri == null) { 5367 throw new IllegalArgumentException("null uri"); 5368 } 5369 5370 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5371 } 5372 } 5373 5374 @Override 5375 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5376 synchronized(this) { 5377 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5378 if (owner == null) { 5379 throw new IllegalArgumentException("Unknown owner: " + token); 5380 } 5381 5382 if (uri == null) { 5383 owner.removeUriPermissionsLocked(mode); 5384 } else { 5385 owner.removeUriPermissionLocked(uri, mode); 5386 } 5387 } 5388 } 5389 5390 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5391 synchronized (this) { 5392 ProcessRecord app = 5393 who != null ? getRecordForAppLocked(who) : null; 5394 if (app == null) return; 5395 5396 Message msg = Message.obtain(); 5397 msg.what = WAIT_FOR_DEBUGGER_MSG; 5398 msg.obj = app; 5399 msg.arg1 = waiting ? 1 : 0; 5400 mHandler.sendMessage(msg); 5401 } 5402 } 5403 5404 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5405 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5406 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5407 outInfo.availMem = Process.getFreeMemory(); 5408 outInfo.totalMem = Process.getTotalMemory(); 5409 outInfo.threshold = homeAppMem; 5410 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5411 outInfo.hiddenAppThreshold = hiddenAppMem; 5412 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5413 ProcessList.SERVICE_ADJ); 5414 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5415 ProcessList.VISIBLE_APP_ADJ); 5416 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5417 ProcessList.FOREGROUND_APP_ADJ); 5418 } 5419 5420 // ========================================================= 5421 // TASK MANAGEMENT 5422 // ========================================================= 5423 5424 public List getTasks(int maxNum, int flags, 5425 IThumbnailReceiver receiver) { 5426 ArrayList list = new ArrayList(); 5427 5428 PendingThumbnailsRecord pending = null; 5429 IApplicationThread topThumbnail = null; 5430 ActivityRecord topRecord = null; 5431 5432 synchronized(this) { 5433 if (localLOGV) Slog.v( 5434 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5435 + ", receiver=" + receiver); 5436 5437 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5438 != PackageManager.PERMISSION_GRANTED) { 5439 if (receiver != null) { 5440 // If the caller wants to wait for pending thumbnails, 5441 // it ain't gonna get them. 5442 try { 5443 receiver.finished(); 5444 } catch (RemoteException ex) { 5445 } 5446 } 5447 String msg = "Permission Denial: getTasks() from pid=" 5448 + Binder.getCallingPid() 5449 + ", uid=" + Binder.getCallingUid() 5450 + " requires " + android.Manifest.permission.GET_TASKS; 5451 Slog.w(TAG, msg); 5452 throw new SecurityException(msg); 5453 } 5454 5455 int pos = mMainStack.mHistory.size()-1; 5456 ActivityRecord next = 5457 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5458 ActivityRecord top = null; 5459 TaskRecord curTask = null; 5460 int numActivities = 0; 5461 int numRunning = 0; 5462 while (pos >= 0 && maxNum > 0) { 5463 final ActivityRecord r = next; 5464 pos--; 5465 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5466 5467 // Initialize state for next task if needed. 5468 if (top == null || 5469 (top.state == ActivityState.INITIALIZING 5470 && top.task == r.task)) { 5471 top = r; 5472 curTask = r.task; 5473 numActivities = numRunning = 0; 5474 } 5475 5476 // Add 'r' into the current task. 5477 numActivities++; 5478 if (r.app != null && r.app.thread != null) { 5479 numRunning++; 5480 } 5481 5482 if (localLOGV) Slog.v( 5483 TAG, r.intent.getComponent().flattenToShortString() 5484 + ": task=" + r.task); 5485 5486 // If the next one is a different task, generate a new 5487 // TaskInfo entry for what we have. 5488 if (next == null || next.task != curTask) { 5489 ActivityManager.RunningTaskInfo ci 5490 = new ActivityManager.RunningTaskInfo(); 5491 ci.id = curTask.taskId; 5492 ci.baseActivity = r.intent.getComponent(); 5493 ci.topActivity = top.intent.getComponent(); 5494 if (top.thumbHolder != null) { 5495 ci.description = top.thumbHolder.lastDescription; 5496 } 5497 ci.numActivities = numActivities; 5498 ci.numRunning = numRunning; 5499 //System.out.println( 5500 // "#" + maxNum + ": " + " descr=" + ci.description); 5501 if (ci.thumbnail == null && receiver != null) { 5502 if (localLOGV) Slog.v( 5503 TAG, "State=" + top.state + "Idle=" + top.idle 5504 + " app=" + top.app 5505 + " thr=" + (top.app != null ? top.app.thread : null)); 5506 if (top.state == ActivityState.RESUMED 5507 || top.state == ActivityState.PAUSING) { 5508 if (top.idle && top.app != null 5509 && top.app.thread != null) { 5510 topRecord = top; 5511 topThumbnail = top.app.thread; 5512 } else { 5513 top.thumbnailNeeded = true; 5514 } 5515 } 5516 if (pending == null) { 5517 pending = new PendingThumbnailsRecord(receiver); 5518 } 5519 pending.pendingRecords.add(top); 5520 } 5521 list.add(ci); 5522 maxNum--; 5523 top = null; 5524 } 5525 } 5526 5527 if (pending != null) { 5528 mPendingThumbnails.add(pending); 5529 } 5530 } 5531 5532 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5533 5534 if (topThumbnail != null) { 5535 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5536 try { 5537 topThumbnail.requestThumbnail(topRecord.appToken); 5538 } catch (Exception e) { 5539 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5540 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5541 } 5542 } 5543 5544 if (pending == null && receiver != null) { 5545 // In this case all thumbnails were available and the client 5546 // is being asked to be told when the remaining ones come in... 5547 // which is unusually, since the top-most currently running 5548 // activity should never have a canned thumbnail! Oh well. 5549 try { 5550 receiver.finished(); 5551 } catch (RemoteException ex) { 5552 } 5553 } 5554 5555 return list; 5556 } 5557 5558 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5559 int flags) { 5560 final int callingUid = Binder.getCallingUid(); 5561 // If it's the system uid asking, then use the current user id. 5562 // TODO: Make sure that there aren't any other legitimate calls from the system uid that 5563 // require the entire list. 5564 final int callingUserId = callingUid == Process.SYSTEM_UID 5565 ? mCurrentUserId : UserId.getUserId(callingUid); 5566 synchronized (this) { 5567 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5568 "getRecentTasks()"); 5569 final boolean detailed = checkCallingPermission( 5570 android.Manifest.permission.GET_DETAILED_TASKS) 5571 == PackageManager.PERMISSION_GRANTED; 5572 5573 IPackageManager pm = AppGlobals.getPackageManager(); 5574 5575 final int N = mRecentTasks.size(); 5576 ArrayList<ActivityManager.RecentTaskInfo> res 5577 = new ArrayList<ActivityManager.RecentTaskInfo>( 5578 maxNum < N ? maxNum : N); 5579 for (int i=0; i<N && maxNum > 0; i++) { 5580 TaskRecord tr = mRecentTasks.get(i); 5581 // Only add calling user's recent tasks 5582 if (tr.userId != callingUserId) continue; 5583 // Return the entry if desired by the caller. We always return 5584 // the first entry, because callers always expect this to be the 5585 // foreground app. We may filter others if the caller has 5586 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5587 // we should exclude the entry. 5588 5589 if (i == 0 5590 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5591 || (tr.intent == null) 5592 || ((tr.intent.getFlags() 5593 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5594 ActivityManager.RecentTaskInfo rti 5595 = new ActivityManager.RecentTaskInfo(); 5596 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5597 rti.persistentId = tr.taskId; 5598 rti.baseIntent = new Intent( 5599 tr.intent != null ? tr.intent : tr.affinityIntent); 5600 if (!detailed) { 5601 rti.baseIntent.replaceExtras((Bundle)null); 5602 } 5603 rti.origActivity = tr.origActivity; 5604 rti.description = tr.lastDescription; 5605 5606 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5607 // Check whether this activity is currently available. 5608 try { 5609 if (rti.origActivity != null) { 5610 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId) 5611 == null) { 5612 continue; 5613 } 5614 } else if (rti.baseIntent != null) { 5615 if (pm.queryIntentActivities(rti.baseIntent, 5616 null, 0, callingUserId) == null) { 5617 continue; 5618 } 5619 } 5620 } catch (RemoteException e) { 5621 // Will never happen. 5622 } 5623 } 5624 5625 res.add(rti); 5626 maxNum--; 5627 } 5628 } 5629 return res; 5630 } 5631 } 5632 5633 private TaskRecord taskForIdLocked(int id) { 5634 final int N = mRecentTasks.size(); 5635 for (int i=0; i<N; i++) { 5636 TaskRecord tr = mRecentTasks.get(i); 5637 if (tr.taskId == id) { 5638 return tr; 5639 } 5640 } 5641 return null; 5642 } 5643 5644 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5645 synchronized (this) { 5646 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5647 "getTaskThumbnails()"); 5648 TaskRecord tr = taskForIdLocked(id); 5649 if (tr != null) { 5650 return mMainStack.getTaskThumbnailsLocked(tr); 5651 } 5652 } 5653 return null; 5654 } 5655 5656 public boolean removeSubTask(int taskId, int subTaskIndex) { 5657 synchronized (this) { 5658 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5659 "removeSubTask()"); 5660 long ident = Binder.clearCallingIdentity(); 5661 try { 5662 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5663 true) != null; 5664 } finally { 5665 Binder.restoreCallingIdentity(ident); 5666 } 5667 } 5668 } 5669 5670 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5671 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5672 Intent baseIntent = new Intent( 5673 tr.intent != null ? tr.intent : tr.affinityIntent); 5674 ComponentName component = baseIntent.getComponent(); 5675 if (component == null) { 5676 Slog.w(TAG, "Now component for base intent of task: " + tr); 5677 return; 5678 } 5679 5680 // Find any running services associated with this app. 5681 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5682 for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) { 5683 if (sr.packageName.equals(component.getPackageName())) { 5684 services.add(sr); 5685 } 5686 } 5687 5688 // Take care of any running services associated with the app. 5689 for (int i=0; i<services.size(); i++) { 5690 ServiceRecord sr = services.get(i); 5691 if (sr.startRequested) { 5692 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { 5693 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); 5694 stopServiceLocked(sr); 5695 } else { 5696 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, 5697 sr.makeNextStartId(), baseIntent, null)); 5698 if (sr.app != null && sr.app.thread != null) { 5699 sendServiceArgsLocked(sr, false); 5700 } 5701 } 5702 } 5703 } 5704 5705 if (killProcesses) { 5706 // Find any running processes associated with this app. 5707 final String pkg = component.getPackageName(); 5708 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5709 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5710 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5711 for (int i=0; i<uids.size(); i++) { 5712 ProcessRecord proc = uids.valueAt(i); 5713 if (proc.userId != tr.userId) { 5714 continue; 5715 } 5716 if (!proc.pkgList.contains(pkg)) { 5717 continue; 5718 } 5719 procs.add(proc); 5720 } 5721 } 5722 5723 // Kill the running processes. 5724 for (int i=0; i<procs.size(); i++) { 5725 ProcessRecord pr = procs.get(i); 5726 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5727 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5728 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5729 pr.processName, pr.setAdj, "remove task"); 5730 pr.killedBackground = true; 5731 Process.killProcessQuiet(pr.pid); 5732 } else { 5733 pr.waitingToKill = "remove task"; 5734 } 5735 } 5736 } 5737 } 5738 5739 public boolean removeTask(int taskId, int flags) { 5740 synchronized (this) { 5741 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5742 "removeTask()"); 5743 long ident = Binder.clearCallingIdentity(); 5744 try { 5745 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5746 false); 5747 if (r != null) { 5748 mRecentTasks.remove(r.task); 5749 cleanUpRemovedTaskLocked(r.task, flags); 5750 return true; 5751 } else { 5752 TaskRecord tr = null; 5753 int i=0; 5754 while (i < mRecentTasks.size()) { 5755 TaskRecord t = mRecentTasks.get(i); 5756 if (t.taskId == taskId) { 5757 tr = t; 5758 break; 5759 } 5760 i++; 5761 } 5762 if (tr != null) { 5763 if (tr.numActivities <= 0) { 5764 // Caller is just removing a recent task that is 5765 // not actively running. That is easy! 5766 mRecentTasks.remove(i); 5767 cleanUpRemovedTaskLocked(tr, flags); 5768 return true; 5769 } else { 5770 Slog.w(TAG, "removeTask: task " + taskId 5771 + " does not have activities to remove, " 5772 + " but numActivities=" + tr.numActivities 5773 + ": " + tr); 5774 } 5775 } 5776 } 5777 } finally { 5778 Binder.restoreCallingIdentity(ident); 5779 } 5780 } 5781 return false; 5782 } 5783 5784 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5785 int j; 5786 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5787 TaskRecord jt = startTask; 5788 5789 // First look backwards 5790 for (j=startIndex-1; j>=0; j--) { 5791 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5792 if (r.task != jt) { 5793 jt = r.task; 5794 if (affinity.equals(jt.affinity)) { 5795 return j; 5796 } 5797 } 5798 } 5799 5800 // Now look forwards 5801 final int N = mMainStack.mHistory.size(); 5802 jt = startTask; 5803 for (j=startIndex+1; j<N; j++) { 5804 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5805 if (r.task != jt) { 5806 if (affinity.equals(jt.affinity)) { 5807 return j; 5808 } 5809 jt = r.task; 5810 } 5811 } 5812 5813 // Might it be at the top? 5814 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5815 return N-1; 5816 } 5817 5818 return -1; 5819 } 5820 5821 /** 5822 * TODO: Add mController hook 5823 */ 5824 public void moveTaskToFront(int task, int flags, Bundle options) { 5825 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5826 "moveTaskToFront()"); 5827 5828 synchronized(this) { 5829 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5830 Binder.getCallingUid(), "Task to front")) { 5831 ActivityOptions.abort(options); 5832 return; 5833 } 5834 final long origId = Binder.clearCallingIdentity(); 5835 try { 5836 TaskRecord tr = taskForIdLocked(task); 5837 if (tr != null) { 5838 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5839 mMainStack.mUserLeaving = true; 5840 } 5841 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5842 // Caller wants the home activity moved with it. To accomplish this, 5843 // we'll just move the home task to the top first. 5844 mMainStack.moveHomeToFrontLocked(); 5845 } 5846 mMainStack.moveTaskToFrontLocked(tr, null, options); 5847 return; 5848 } 5849 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5850 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5851 if (hr.task.taskId == task) { 5852 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5853 mMainStack.mUserLeaving = true; 5854 } 5855 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5856 // Caller wants the home activity moved with it. To accomplish this, 5857 // we'll just move the home task to the top first. 5858 mMainStack.moveHomeToFrontLocked(); 5859 } 5860 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5861 return; 5862 } 5863 } 5864 } finally { 5865 Binder.restoreCallingIdentity(origId); 5866 } 5867 ActivityOptions.abort(options); 5868 } 5869 } 5870 5871 public void moveTaskToBack(int task) { 5872 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5873 "moveTaskToBack()"); 5874 5875 synchronized(this) { 5876 if (mMainStack.mResumedActivity != null 5877 && mMainStack.mResumedActivity.task.taskId == task) { 5878 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5879 Binder.getCallingUid(), "Task to back")) { 5880 return; 5881 } 5882 } 5883 final long origId = Binder.clearCallingIdentity(); 5884 mMainStack.moveTaskToBackLocked(task, null); 5885 Binder.restoreCallingIdentity(origId); 5886 } 5887 } 5888 5889 /** 5890 * Moves an activity, and all of the other activities within the same task, to the bottom 5891 * of the history stack. The activity's order within the task is unchanged. 5892 * 5893 * @param token A reference to the activity we wish to move 5894 * @param nonRoot If false then this only works if the activity is the root 5895 * of a task; if true it will work for any activity in a task. 5896 * @return Returns true if the move completed, false if not. 5897 */ 5898 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5899 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5900 synchronized(this) { 5901 final long origId = Binder.clearCallingIdentity(); 5902 int taskId = getTaskForActivityLocked(token, !nonRoot); 5903 if (taskId >= 0) { 5904 return mMainStack.moveTaskToBackLocked(taskId, null); 5905 } 5906 Binder.restoreCallingIdentity(origId); 5907 } 5908 return false; 5909 } 5910 5911 public void moveTaskBackwards(int task) { 5912 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5913 "moveTaskBackwards()"); 5914 5915 synchronized(this) { 5916 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5917 Binder.getCallingUid(), "Task backwards")) { 5918 return; 5919 } 5920 final long origId = Binder.clearCallingIdentity(); 5921 moveTaskBackwardsLocked(task); 5922 Binder.restoreCallingIdentity(origId); 5923 } 5924 } 5925 5926 private final void moveTaskBackwardsLocked(int task) { 5927 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5928 } 5929 5930 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5931 synchronized(this) { 5932 return getTaskForActivityLocked(token, onlyRoot); 5933 } 5934 } 5935 5936 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5937 final int N = mMainStack.mHistory.size(); 5938 TaskRecord lastTask = null; 5939 for (int i=0; i<N; i++) { 5940 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5941 if (r.appToken == token) { 5942 if (!onlyRoot || lastTask != r.task) { 5943 return r.task.taskId; 5944 } 5945 return -1; 5946 } 5947 lastTask = r.task; 5948 } 5949 5950 return -1; 5951 } 5952 5953 // ========================================================= 5954 // THUMBNAILS 5955 // ========================================================= 5956 5957 public void reportThumbnail(IBinder token, 5958 Bitmap thumbnail, CharSequence description) { 5959 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5960 final long origId = Binder.clearCallingIdentity(); 5961 sendPendingThumbnail(null, token, thumbnail, description, true); 5962 Binder.restoreCallingIdentity(origId); 5963 } 5964 5965 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5966 Bitmap thumbnail, CharSequence description, boolean always) { 5967 TaskRecord task = null; 5968 ArrayList receivers = null; 5969 5970 //System.out.println("Send pending thumbnail: " + r); 5971 5972 synchronized(this) { 5973 if (r == null) { 5974 r = mMainStack.isInStackLocked(token); 5975 if (r == null) { 5976 return; 5977 } 5978 } 5979 if (thumbnail == null && r.thumbHolder != null) { 5980 thumbnail = r.thumbHolder.lastThumbnail; 5981 description = r.thumbHolder.lastDescription; 5982 } 5983 if (thumbnail == null && !always) { 5984 // If there is no thumbnail, and this entry is not actually 5985 // going away, then abort for now and pick up the next 5986 // thumbnail we get. 5987 return; 5988 } 5989 task = r.task; 5990 5991 int N = mPendingThumbnails.size(); 5992 int i=0; 5993 while (i<N) { 5994 PendingThumbnailsRecord pr = 5995 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5996 //System.out.println("Looking in " + pr.pendingRecords); 5997 if (pr.pendingRecords.remove(r)) { 5998 if (receivers == null) { 5999 receivers = new ArrayList(); 6000 } 6001 receivers.add(pr); 6002 if (pr.pendingRecords.size() == 0) { 6003 pr.finished = true; 6004 mPendingThumbnails.remove(i); 6005 N--; 6006 continue; 6007 } 6008 } 6009 i++; 6010 } 6011 } 6012 6013 if (receivers != null) { 6014 final int N = receivers.size(); 6015 for (int i=0; i<N; i++) { 6016 try { 6017 PendingThumbnailsRecord pr = 6018 (PendingThumbnailsRecord)receivers.get(i); 6019 pr.receiver.newThumbnail( 6020 task != null ? task.taskId : -1, thumbnail, description); 6021 if (pr.finished) { 6022 pr.receiver.finished(); 6023 } 6024 } catch (Exception e) { 6025 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6026 } 6027 } 6028 } 6029 } 6030 6031 // ========================================================= 6032 // CONTENT PROVIDERS 6033 // ========================================================= 6034 6035 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6036 List<ProviderInfo> providers = null; 6037 try { 6038 providers = AppGlobals.getPackageManager(). 6039 queryContentProviders(app.processName, app.uid, 6040 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6041 } catch (RemoteException ex) { 6042 } 6043 if (DEBUG_MU) 6044 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6045 int userId = app.userId; 6046 if (providers != null) { 6047 final int N = providers.size(); 6048 for (int i=0; i<N; i++) { 6049 ProviderInfo cpi = 6050 (ProviderInfo)providers.get(i); 6051 6052 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6053 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6054 if (cpr == null) { 6055 cpr = new ContentProviderRecord(this, cpi, app.info, comp); 6056 mProviderMap.putProviderByClass(comp, cpr); 6057 } 6058 if (DEBUG_MU) 6059 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6060 app.pubProviders.put(cpi.name, cpr); 6061 app.addPackage(cpi.applicationInfo.packageName); 6062 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6063 } 6064 } 6065 return providers; 6066 } 6067 6068 /** 6069 * Check if {@link ProcessRecord} has a possible chance at accessing the 6070 * given {@link ProviderInfo}. Final permission checking is always done 6071 * in {@link ContentProvider}. 6072 */ 6073 private final String checkContentProviderPermissionLocked( 6074 ProviderInfo cpi, ProcessRecord r) { 6075 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6076 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6077 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6078 cpi.applicationInfo.uid, cpi.exported) 6079 == PackageManager.PERMISSION_GRANTED) { 6080 return null; 6081 } 6082 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6083 cpi.applicationInfo.uid, cpi.exported) 6084 == PackageManager.PERMISSION_GRANTED) { 6085 return null; 6086 } 6087 6088 PathPermission[] pps = cpi.pathPermissions; 6089 if (pps != null) { 6090 int i = pps.length; 6091 while (i > 0) { 6092 i--; 6093 PathPermission pp = pps[i]; 6094 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6095 cpi.applicationInfo.uid, cpi.exported) 6096 == PackageManager.PERMISSION_GRANTED) { 6097 return null; 6098 } 6099 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6100 cpi.applicationInfo.uid, cpi.exported) 6101 == PackageManager.PERMISSION_GRANTED) { 6102 return null; 6103 } 6104 } 6105 } 6106 6107 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6108 if (perms != null) { 6109 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6110 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6111 return null; 6112 } 6113 } 6114 } 6115 6116 String msg; 6117 if (!cpi.exported) { 6118 msg = "Permission Denial: opening provider " + cpi.name 6119 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6120 + ", uid=" + callingUid + ") that is not exported from uid " 6121 + cpi.applicationInfo.uid; 6122 } else { 6123 msg = "Permission Denial: opening provider " + cpi.name 6124 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6125 + ", uid=" + callingUid + ") requires " 6126 + cpi.readPermission + " or " + cpi.writePermission; 6127 } 6128 Slog.w(TAG, msg); 6129 return msg; 6130 } 6131 6132 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6133 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6134 if (r != null) { 6135 for (int i=0; i<r.conProviders.size(); i++) { 6136 ContentProviderConnection conn = r.conProviders.get(i); 6137 if (conn.provider == cpr) { 6138 if (DEBUG_PROVIDER) Slog.v(TAG, 6139 "Adding provider requested by " 6140 + r.processName + " from process " 6141 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6142 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6143 if (stable) { 6144 conn.stableCount++; 6145 conn.numStableIncs++; 6146 } else { 6147 conn.unstableCount++; 6148 conn.numUnstableIncs++; 6149 } 6150 return conn; 6151 } 6152 } 6153 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6154 if (stable) { 6155 conn.stableCount = 1; 6156 conn.numStableIncs = 1; 6157 } else { 6158 conn.unstableCount = 1; 6159 conn.numUnstableIncs = 1; 6160 } 6161 cpr.connections.add(conn); 6162 r.conProviders.add(conn); 6163 return conn; 6164 } 6165 cpr.addExternalProcessHandleLocked(externalProcessToken); 6166 return null; 6167 } 6168 6169 boolean decProviderCountLocked(ContentProviderConnection conn, 6170 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6171 if (conn != null) { 6172 cpr = conn.provider; 6173 if (DEBUG_PROVIDER) Slog.v(TAG, 6174 "Removing provider requested by " 6175 + conn.client.processName + " from process " 6176 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6177 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6178 if (stable) { 6179 conn.stableCount--; 6180 } else { 6181 conn.unstableCount--; 6182 } 6183 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6184 cpr.connections.remove(conn); 6185 conn.client.conProviders.remove(conn); 6186 return true; 6187 } 6188 return false; 6189 } 6190 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6191 return false; 6192 } 6193 6194 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6195 String name, IBinder token, boolean stable) { 6196 ContentProviderRecord cpr; 6197 ContentProviderConnection conn = null; 6198 ProviderInfo cpi = null; 6199 6200 synchronized(this) { 6201 ProcessRecord r = null; 6202 if (caller != null) { 6203 r = getRecordForAppLocked(caller); 6204 if (r == null) { 6205 throw new SecurityException( 6206 "Unable to find app for caller " + caller 6207 + " (pid=" + Binder.getCallingPid() 6208 + ") when getting content provider " + name); 6209 } 6210 } 6211 6212 // First check if this content provider has been published... 6213 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6214 cpr = mProviderMap.getProviderByName(name, userId); 6215 boolean providerRunning = cpr != null; 6216 if (providerRunning) { 6217 cpi = cpr.info; 6218 String msg; 6219 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6220 throw new SecurityException(msg); 6221 } 6222 6223 if (r != null && cpr.canRunHere(r)) { 6224 // This provider has been published or is in the process 6225 // of being published... but it is also allowed to run 6226 // in the caller's process, so don't make a connection 6227 // and just let the caller instantiate its own instance. 6228 ContentProviderHolder holder = cpr.newHolder(null); 6229 // don't give caller the provider object, it needs 6230 // to make its own. 6231 holder.provider = null; 6232 return holder; 6233 } 6234 6235 final long origId = Binder.clearCallingIdentity(); 6236 6237 // In this case the provider instance already exists, so we can 6238 // return it right away. 6239 conn = incProviderCountLocked(r, cpr, token, stable); 6240 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6241 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6242 // If this is a perceptible app accessing the provider, 6243 // make sure to count it as being accessed and thus 6244 // back up on the LRU list. This is good because 6245 // content providers are often expensive to start. 6246 updateLruProcessLocked(cpr.proc, false, true); 6247 } 6248 } 6249 6250 if (cpr.proc != null) { 6251 if (false) { 6252 if (cpr.name.flattenToShortString().equals( 6253 "com.android.providers.calendar/.CalendarProvider2")) { 6254 Slog.v(TAG, "****************** KILLING " 6255 + cpr.name.flattenToShortString()); 6256 Process.killProcess(cpr.proc.pid); 6257 } 6258 } 6259 boolean success = updateOomAdjLocked(cpr.proc); 6260 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6261 // NOTE: there is still a race here where a signal could be 6262 // pending on the process even though we managed to update its 6263 // adj level. Not sure what to do about this, but at least 6264 // the race is now smaller. 6265 if (!success) { 6266 // Uh oh... it looks like the provider's process 6267 // has been killed on us. We need to wait for a new 6268 // process to be started, and make sure its death 6269 // doesn't kill our process. 6270 Slog.i(TAG, 6271 "Existing provider " + cpr.name.flattenToShortString() 6272 + " is crashing; detaching " + r); 6273 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6274 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6275 if (!lastRef) { 6276 // This wasn't the last ref our process had on 6277 // the provider... we have now been killed, bail. 6278 return null; 6279 } 6280 providerRunning = false; 6281 conn = null; 6282 } 6283 } 6284 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 if (!providerRunning) { 6289 try { 6290 cpi = AppGlobals.getPackageManager(). 6291 resolveContentProvider(name, 6292 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6293 } catch (RemoteException ex) { 6294 } 6295 if (cpi == null) { 6296 return null; 6297 } 6298 if (isSingleton(cpi.processName, cpi.applicationInfo)) { 6299 userId = 0; 6300 } 6301 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6302 6303 String msg; 6304 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6305 throw new SecurityException(msg); 6306 } 6307 6308 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6309 && !cpi.processName.equals("system")) { 6310 // If this content provider does not run in the system 6311 // process, and the system is not yet ready to run other 6312 // processes, then fail fast instead of hanging. 6313 throw new IllegalArgumentException( 6314 "Attempt to launch content provider before system ready"); 6315 } 6316 6317 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6318 cpr = mProviderMap.getProviderByClass(comp, userId); 6319 final boolean firstClass = cpr == null; 6320 if (firstClass) { 6321 try { 6322 ApplicationInfo ai = 6323 AppGlobals.getPackageManager(). 6324 getApplicationInfo( 6325 cpi.applicationInfo.packageName, 6326 STOCK_PM_FLAGS, userId); 6327 if (ai == null) { 6328 Slog.w(TAG, "No package info for content provider " 6329 + cpi.name); 6330 return null; 6331 } 6332 ai = getAppInfoForUser(ai, userId); 6333 cpr = new ContentProviderRecord(this, cpi, ai, comp); 6334 } catch (RemoteException ex) { 6335 // pm is in same process, this will never happen. 6336 } 6337 } 6338 6339 if (r != null && cpr.canRunHere(r)) { 6340 // If this is a multiprocess provider, then just return its 6341 // info and allow the caller to instantiate it. Only do 6342 // this if the provider is the same user as the caller's 6343 // process, or can run as root (so can be in any process). 6344 return cpr.newHolder(null); 6345 } 6346 6347 if (DEBUG_PROVIDER) { 6348 RuntimeException e = new RuntimeException("here"); 6349 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6350 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6351 } 6352 6353 // This is single process, and our app is now connecting to it. 6354 // See if we are already in the process of launching this 6355 // provider. 6356 final int N = mLaunchingProviders.size(); 6357 int i; 6358 for (i=0; i<N; i++) { 6359 if (mLaunchingProviders.get(i) == cpr) { 6360 break; 6361 } 6362 } 6363 6364 // If the provider is not already being launched, then get it 6365 // started. 6366 if (i >= N) { 6367 final long origId = Binder.clearCallingIdentity(); 6368 6369 try { 6370 // Content provider is now in use, its package can't be stopped. 6371 try { 6372 AppGlobals.getPackageManager().setPackageStoppedState( 6373 cpr.appInfo.packageName, false, userId); 6374 } catch (RemoteException e) { 6375 } catch (IllegalArgumentException e) { 6376 Slog.w(TAG, "Failed trying to unstop package " 6377 + cpr.appInfo.packageName + ": " + e); 6378 } 6379 6380 ProcessRecord proc = startProcessLocked(cpi.processName, 6381 cpr.appInfo, false, 0, "content provider", 6382 new ComponentName(cpi.applicationInfo.packageName, 6383 cpi.name), false, false); 6384 if (proc == null) { 6385 Slog.w(TAG, "Unable to launch app " 6386 + cpi.applicationInfo.packageName + "/" 6387 + cpi.applicationInfo.uid + " for provider " 6388 + name + ": process is bad"); 6389 return null; 6390 } 6391 cpr.launchingApp = proc; 6392 mLaunchingProviders.add(cpr); 6393 } finally { 6394 Binder.restoreCallingIdentity(origId); 6395 } 6396 } 6397 6398 // Make sure the provider is published (the same provider class 6399 // may be published under multiple names). 6400 if (firstClass) { 6401 mProviderMap.putProviderByClass(comp, cpr); 6402 } 6403 6404 mProviderMap.putProviderByName(name, cpr); 6405 conn = incProviderCountLocked(r, cpr, token, stable); 6406 if (conn != null) { 6407 conn.waiting = true; 6408 } 6409 } 6410 } 6411 6412 // Wait for the provider to be published... 6413 synchronized (cpr) { 6414 while (cpr.provider == null) { 6415 if (cpr.launchingApp == null) { 6416 Slog.w(TAG, "Unable to launch app " 6417 + cpi.applicationInfo.packageName + "/" 6418 + cpi.applicationInfo.uid + " for provider " 6419 + name + ": launching app became null"); 6420 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6421 cpi.applicationInfo.packageName, 6422 cpi.applicationInfo.uid, name); 6423 return null; 6424 } 6425 try { 6426 if (DEBUG_MU) { 6427 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6428 + cpr.launchingApp); 6429 } 6430 if (conn != null) { 6431 conn.waiting = true; 6432 } 6433 cpr.wait(); 6434 } catch (InterruptedException ex) { 6435 } finally { 6436 if (conn != null) { 6437 conn.waiting = false; 6438 } 6439 } 6440 } 6441 } 6442 return cpr != null ? cpr.newHolder(conn) : null; 6443 } 6444 6445 public final ContentProviderHolder getContentProvider( 6446 IApplicationThread caller, String name, boolean stable) { 6447 enforceNotIsolatedCaller("getContentProvider"); 6448 if (caller == null) { 6449 String msg = "null IApplicationThread when getting content provider " 6450 + name; 6451 Slog.w(TAG, msg); 6452 throw new SecurityException(msg); 6453 } 6454 6455 return getContentProviderImpl(caller, name, null, stable); 6456 } 6457 6458 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6459 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6460 "Do not have permission in call getContentProviderExternal()"); 6461 return getContentProviderExternalUnchecked(name, token); 6462 } 6463 6464 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6465 return getContentProviderImpl(null, name, token, true); 6466 } 6467 6468 /** 6469 * Drop a content provider from a ProcessRecord's bookkeeping 6470 * @param cpr 6471 */ 6472 public void removeContentProvider(IBinder connection, boolean stable) { 6473 enforceNotIsolatedCaller("removeContentProvider"); 6474 synchronized (this) { 6475 ContentProviderConnection conn; 6476 try { 6477 conn = (ContentProviderConnection)connection; 6478 } catch (ClassCastException e) { 6479 String msg ="removeContentProvider: " + connection 6480 + " not a ContentProviderConnection"; 6481 Slog.w(TAG, msg); 6482 throw new IllegalArgumentException(msg); 6483 } 6484 if (conn == null) { 6485 throw new NullPointerException("connection is null"); 6486 } 6487 if (decProviderCountLocked(conn, null, null, stable)) { 6488 updateOomAdjLocked(); 6489 } 6490 } 6491 } 6492 6493 public void removeContentProviderExternal(String name, IBinder token) { 6494 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6495 "Do not have permission in call removeContentProviderExternal()"); 6496 removeContentProviderExternalUnchecked(name, token); 6497 } 6498 6499 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6500 synchronized (this) { 6501 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6502 Binder.getOrigCallingUser()); 6503 if(cpr == null) { 6504 //remove from mProvidersByClass 6505 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6506 return; 6507 } 6508 6509 //update content provider record entry info 6510 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6511 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6512 Binder.getOrigCallingUser()); 6513 if (localCpr.hasExternalProcessHandles()) { 6514 if (localCpr.removeExternalProcessHandleLocked(token)) { 6515 updateOomAdjLocked(); 6516 } else { 6517 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6518 + " with no external reference for token: " 6519 + token + "."); 6520 } 6521 } else { 6522 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6523 + " with no external references."); 6524 } 6525 } 6526 } 6527 6528 public final void publishContentProviders(IApplicationThread caller, 6529 List<ContentProviderHolder> providers) { 6530 if (providers == null) { 6531 return; 6532 } 6533 6534 enforceNotIsolatedCaller("publishContentProviders"); 6535 synchronized (this) { 6536 final ProcessRecord r = getRecordForAppLocked(caller); 6537 if (DEBUG_MU) 6538 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6539 if (r == null) { 6540 throw new SecurityException( 6541 "Unable to find app for caller " + caller 6542 + " (pid=" + Binder.getCallingPid() 6543 + ") when publishing content providers"); 6544 } 6545 6546 final long origId = Binder.clearCallingIdentity(); 6547 6548 final int N = providers.size(); 6549 for (int i=0; i<N; i++) { 6550 ContentProviderHolder src = providers.get(i); 6551 if (src == null || src.info == null || src.provider == null) { 6552 continue; 6553 } 6554 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6555 if (DEBUG_MU) 6556 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6557 if (dst != null) { 6558 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6559 mProviderMap.putProviderByClass(comp, dst); 6560 String names[] = dst.info.authority.split(";"); 6561 for (int j = 0; j < names.length; j++) { 6562 mProviderMap.putProviderByName(names[j], dst); 6563 } 6564 6565 int NL = mLaunchingProviders.size(); 6566 int j; 6567 for (j=0; j<NL; j++) { 6568 if (mLaunchingProviders.get(j) == dst) { 6569 mLaunchingProviders.remove(j); 6570 j--; 6571 NL--; 6572 } 6573 } 6574 synchronized (dst) { 6575 dst.provider = src.provider; 6576 dst.proc = r; 6577 dst.notifyAll(); 6578 } 6579 updateOomAdjLocked(r); 6580 } 6581 } 6582 6583 Binder.restoreCallingIdentity(origId); 6584 } 6585 } 6586 6587 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6588 ContentProviderConnection conn; 6589 try { 6590 conn = (ContentProviderConnection)connection; 6591 } catch (ClassCastException e) { 6592 String msg ="refContentProvider: " + connection 6593 + " not a ContentProviderConnection"; 6594 Slog.w(TAG, msg); 6595 throw new IllegalArgumentException(msg); 6596 } 6597 if (conn == null) { 6598 throw new NullPointerException("connection is null"); 6599 } 6600 6601 synchronized (this) { 6602 if (stable > 0) { 6603 conn.numStableIncs += stable; 6604 } 6605 stable = conn.stableCount + stable; 6606 if (stable < 0) { 6607 throw new IllegalStateException("stableCount < 0: " + stable); 6608 } 6609 6610 if (unstable > 0) { 6611 conn.numUnstableIncs += unstable; 6612 } 6613 unstable = conn.unstableCount + unstable; 6614 if (unstable < 0) { 6615 throw new IllegalStateException("unstableCount < 0: " + unstable); 6616 } 6617 6618 if ((stable+unstable) <= 0) { 6619 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6620 + stable + " unstable=" + unstable); 6621 } 6622 conn.stableCount = stable; 6623 conn.unstableCount = unstable; 6624 return !conn.dead; 6625 } 6626 } 6627 6628 public void unstableProviderDied(IBinder connection) { 6629 ContentProviderConnection conn; 6630 try { 6631 conn = (ContentProviderConnection)connection; 6632 } catch (ClassCastException e) { 6633 String msg ="refContentProvider: " + connection 6634 + " not a ContentProviderConnection"; 6635 Slog.w(TAG, msg); 6636 throw new IllegalArgumentException(msg); 6637 } 6638 if (conn == null) { 6639 throw new NullPointerException("connection is null"); 6640 } 6641 6642 // Safely retrieve the content provider associated with the connection. 6643 IContentProvider provider; 6644 synchronized (this) { 6645 provider = conn.provider.provider; 6646 } 6647 6648 if (provider == null) { 6649 // Um, yeah, we're way ahead of you. 6650 return; 6651 } 6652 6653 // Make sure the caller is being honest with us. 6654 if (provider.asBinder().pingBinder()) { 6655 // Er, no, still looks good to us. 6656 synchronized (this) { 6657 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6658 + " says " + conn + " died, but we don't agree"); 6659 return; 6660 } 6661 } 6662 6663 // Well look at that! It's dead! 6664 synchronized (this) { 6665 if (conn.provider.provider != provider) { 6666 // But something changed... good enough. 6667 return; 6668 } 6669 6670 ProcessRecord proc = conn.provider.proc; 6671 if (proc == null || proc.thread == null) { 6672 // Seems like the process is already cleaned up. 6673 return; 6674 } 6675 6676 // As far as we're concerned, this is just like receiving a 6677 // death notification... just a bit prematurely. 6678 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6679 + ") early provider death"); 6680 final long ident = Binder.clearCallingIdentity(); 6681 try { 6682 appDiedLocked(proc, proc.pid, proc.thread); 6683 } finally { 6684 Binder.restoreCallingIdentity(ident); 6685 } 6686 } 6687 } 6688 6689 public static final void installSystemProviders() { 6690 List<ProviderInfo> providers; 6691 synchronized (mSelf) { 6692 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6693 providers = mSelf.generateApplicationProvidersLocked(app); 6694 if (providers != null) { 6695 for (int i=providers.size()-1; i>=0; i--) { 6696 ProviderInfo pi = (ProviderInfo)providers.get(i); 6697 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6698 Slog.w(TAG, "Not installing system proc provider " + pi.name 6699 + ": not system .apk"); 6700 providers.remove(i); 6701 } 6702 } 6703 } 6704 } 6705 if (providers != null) { 6706 mSystemThread.installSystemProviders(providers); 6707 } 6708 6709 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6710 6711 mSelf.mUsageStatsService.monitorPackages(); 6712 } 6713 6714 /** 6715 * Allows app to retrieve the MIME type of a URI without having permission 6716 * to access its content provider. 6717 * 6718 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6719 * 6720 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6721 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6722 */ 6723 public String getProviderMimeType(Uri uri) { 6724 enforceNotIsolatedCaller("getProviderMimeType"); 6725 final String name = uri.getAuthority(); 6726 final long ident = Binder.clearCallingIdentity(); 6727 ContentProviderHolder holder = null; 6728 6729 try { 6730 holder = getContentProviderExternalUnchecked(name, null); 6731 if (holder != null) { 6732 return holder.provider.getType(uri); 6733 } 6734 } catch (RemoteException e) { 6735 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6736 return null; 6737 } finally { 6738 if (holder != null) { 6739 removeContentProviderExternalUnchecked(name, null); 6740 } 6741 Binder.restoreCallingIdentity(ident); 6742 } 6743 6744 return null; 6745 } 6746 6747 // ========================================================= 6748 // GLOBAL MANAGEMENT 6749 // ========================================================= 6750 6751 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6752 ApplicationInfo info, String customProcess, boolean isolated) { 6753 String proc = customProcess != null ? customProcess : info.processName; 6754 BatteryStatsImpl.Uid.Proc ps = null; 6755 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6756 int uid = info.uid; 6757 if (isolated) { 6758 int userId = UserId.getUserId(uid); 6759 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6760 uid = 0; 6761 while (true) { 6762 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6763 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6764 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6765 } 6766 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6767 mNextIsolatedProcessUid++; 6768 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6769 // No process for this uid, use it. 6770 break; 6771 } 6772 stepsLeft--; 6773 if (stepsLeft <= 0) { 6774 return null; 6775 } 6776 } 6777 } 6778 synchronized (stats) { 6779 ps = stats.getProcessStatsLocked(info.uid, proc); 6780 } 6781 return new ProcessRecord(ps, thread, info, proc, uid); 6782 } 6783 6784 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6785 ProcessRecord app; 6786 if (!isolated) { 6787 app = getProcessRecordLocked(info.processName, info.uid); 6788 } else { 6789 app = null; 6790 } 6791 6792 if (app == null) { 6793 app = newProcessRecordLocked(null, info, null, isolated); 6794 mProcessNames.put(info.processName, app.uid, app); 6795 if (isolated) { 6796 mIsolatedProcesses.put(app.uid, app); 6797 } 6798 updateLruProcessLocked(app, true, true); 6799 } 6800 6801 // This package really, really can not be stopped. 6802 try { 6803 AppGlobals.getPackageManager().setPackageStoppedState( 6804 info.packageName, false, UserId.getUserId(app.uid)); 6805 } catch (RemoteException e) { 6806 } catch (IllegalArgumentException e) { 6807 Slog.w(TAG, "Failed trying to unstop package " 6808 + info.packageName + ": " + e); 6809 } 6810 6811 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6812 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6813 app.persistent = true; 6814 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6815 } 6816 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6817 mPersistentStartingProcesses.add(app); 6818 startProcessLocked(app, "added application", app.processName); 6819 } 6820 6821 return app; 6822 } 6823 6824 public void unhandledBack() { 6825 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6826 "unhandledBack()"); 6827 6828 synchronized(this) { 6829 int count = mMainStack.mHistory.size(); 6830 if (DEBUG_SWITCH) Slog.d( 6831 TAG, "Performing unhandledBack(): stack size = " + count); 6832 if (count > 1) { 6833 final long origId = Binder.clearCallingIdentity(); 6834 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6835 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6836 Binder.restoreCallingIdentity(origId); 6837 } 6838 } 6839 } 6840 6841 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6842 enforceNotIsolatedCaller("openContentUri"); 6843 String name = uri.getAuthority(); 6844 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6845 ParcelFileDescriptor pfd = null; 6846 if (cph != null) { 6847 // We record the binder invoker's uid in thread-local storage before 6848 // going to the content provider to open the file. Later, in the code 6849 // that handles all permissions checks, we look for this uid and use 6850 // that rather than the Activity Manager's own uid. The effect is that 6851 // we do the check against the caller's permissions even though it looks 6852 // to the content provider like the Activity Manager itself is making 6853 // the request. 6854 sCallerIdentity.set(new Identity( 6855 Binder.getCallingPid(), Binder.getCallingUid())); 6856 try { 6857 pfd = cph.provider.openFile(uri, "r"); 6858 } catch (FileNotFoundException e) { 6859 // do nothing; pfd will be returned null 6860 } finally { 6861 // Ensure that whatever happens, we clean up the identity state 6862 sCallerIdentity.remove(); 6863 } 6864 6865 // We've got the fd now, so we're done with the provider. 6866 removeContentProviderExternalUnchecked(name, null); 6867 } else { 6868 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6869 } 6870 return pfd; 6871 } 6872 6873 // Actually is sleeping or shutting down or whatever else in the future 6874 // is an inactive state. 6875 public boolean isSleeping() { 6876 return mSleeping || mShuttingDown; 6877 } 6878 6879 public void goingToSleep() { 6880 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6881 != PackageManager.PERMISSION_GRANTED) { 6882 throw new SecurityException("Requires permission " 6883 + android.Manifest.permission.DEVICE_POWER); 6884 } 6885 6886 synchronized(this) { 6887 mWentToSleep = true; 6888 updateEventDispatchingLocked(); 6889 6890 if (!mSleeping) { 6891 mSleeping = true; 6892 mMainStack.stopIfSleepingLocked(); 6893 6894 // Initialize the wake times of all processes. 6895 checkExcessivePowerUsageLocked(false); 6896 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6897 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6898 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6899 } 6900 } 6901 } 6902 6903 public boolean shutdown(int timeout) { 6904 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6905 != PackageManager.PERMISSION_GRANTED) { 6906 throw new SecurityException("Requires permission " 6907 + android.Manifest.permission.SHUTDOWN); 6908 } 6909 6910 boolean timedout = false; 6911 6912 synchronized(this) { 6913 mShuttingDown = true; 6914 updateEventDispatchingLocked(); 6915 6916 if (mMainStack.mResumedActivity != null) { 6917 mMainStack.stopIfSleepingLocked(); 6918 final long endTime = System.currentTimeMillis() + timeout; 6919 while (mMainStack.mResumedActivity != null 6920 || mMainStack.mPausingActivity != null) { 6921 long delay = endTime - System.currentTimeMillis(); 6922 if (delay <= 0) { 6923 Slog.w(TAG, "Activity manager shutdown timed out"); 6924 timedout = true; 6925 break; 6926 } 6927 try { 6928 this.wait(); 6929 } catch (InterruptedException e) { 6930 } 6931 } 6932 } 6933 } 6934 6935 mUsageStatsService.shutdown(); 6936 mBatteryStatsService.shutdown(); 6937 6938 return timedout; 6939 } 6940 6941 public final void activitySlept(IBinder token) { 6942 if (localLOGV) Slog.v( 6943 TAG, "Activity slept: token=" + token); 6944 6945 ActivityRecord r = null; 6946 6947 final long origId = Binder.clearCallingIdentity(); 6948 6949 synchronized (this) { 6950 r = mMainStack.isInStackLocked(token); 6951 if (r != null) { 6952 mMainStack.activitySleptLocked(r); 6953 } 6954 } 6955 6956 Binder.restoreCallingIdentity(origId); 6957 } 6958 6959 private void comeOutOfSleepIfNeededLocked() { 6960 if (!mWentToSleep && !mLockScreenShown) { 6961 if (mSleeping) { 6962 mSleeping = false; 6963 mMainStack.awakeFromSleepingLocked(); 6964 mMainStack.resumeTopActivityLocked(null); 6965 } 6966 } 6967 } 6968 6969 public void wakingUp() { 6970 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6971 != PackageManager.PERMISSION_GRANTED) { 6972 throw new SecurityException("Requires permission " 6973 + android.Manifest.permission.DEVICE_POWER); 6974 } 6975 6976 synchronized(this) { 6977 mWentToSleep = false; 6978 updateEventDispatchingLocked(); 6979 comeOutOfSleepIfNeededLocked(); 6980 } 6981 } 6982 6983 private void updateEventDispatchingLocked() { 6984 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6985 } 6986 6987 public void setLockScreenShown(boolean shown) { 6988 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6989 != PackageManager.PERMISSION_GRANTED) { 6990 throw new SecurityException("Requires permission " 6991 + android.Manifest.permission.DEVICE_POWER); 6992 } 6993 6994 synchronized(this) { 6995 mLockScreenShown = shown; 6996 comeOutOfSleepIfNeededLocked(); 6997 } 6998 } 6999 7000 public void stopAppSwitches() { 7001 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7002 != PackageManager.PERMISSION_GRANTED) { 7003 throw new SecurityException("Requires permission " 7004 + android.Manifest.permission.STOP_APP_SWITCHES); 7005 } 7006 7007 synchronized(this) { 7008 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7009 + APP_SWITCH_DELAY_TIME; 7010 mDidAppSwitch = false; 7011 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7012 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7013 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7014 } 7015 } 7016 7017 public void resumeAppSwitches() { 7018 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7019 != PackageManager.PERMISSION_GRANTED) { 7020 throw new SecurityException("Requires permission " 7021 + android.Manifest.permission.STOP_APP_SWITCHES); 7022 } 7023 7024 synchronized(this) { 7025 // Note that we don't execute any pending app switches... we will 7026 // let those wait until either the timeout, or the next start 7027 // activity request. 7028 mAppSwitchesAllowedTime = 0; 7029 } 7030 } 7031 7032 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7033 String name) { 7034 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7035 return true; 7036 } 7037 7038 final int perm = checkComponentPermission( 7039 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7040 callingUid, -1, true); 7041 if (perm == PackageManager.PERMISSION_GRANTED) { 7042 return true; 7043 } 7044 7045 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7046 return false; 7047 } 7048 7049 public void setDebugApp(String packageName, boolean waitForDebugger, 7050 boolean persistent) { 7051 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7052 "setDebugApp()"); 7053 7054 // Note that this is not really thread safe if there are multiple 7055 // callers into it at the same time, but that's not a situation we 7056 // care about. 7057 if (persistent) { 7058 final ContentResolver resolver = mContext.getContentResolver(); 7059 Settings.System.putString( 7060 resolver, Settings.System.DEBUG_APP, 7061 packageName); 7062 Settings.System.putInt( 7063 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7064 waitForDebugger ? 1 : 0); 7065 } 7066 7067 synchronized (this) { 7068 if (!persistent) { 7069 mOrigDebugApp = mDebugApp; 7070 mOrigWaitForDebugger = mWaitForDebugger; 7071 } 7072 mDebugApp = packageName; 7073 mWaitForDebugger = waitForDebugger; 7074 mDebugTransient = !persistent; 7075 if (packageName != null) { 7076 final long origId = Binder.clearCallingIdentity(); 7077 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7078 Binder.restoreCallingIdentity(origId); 7079 } 7080 } 7081 } 7082 7083 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7084 synchronized (this) { 7085 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7086 if (!isDebuggable) { 7087 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7088 throw new SecurityException("Process not debuggable: " + app.packageName); 7089 } 7090 } 7091 7092 mOpenGlTraceApp = processName; 7093 } 7094 } 7095 7096 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7097 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7098 synchronized (this) { 7099 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7100 if (!isDebuggable) { 7101 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7102 throw new SecurityException("Process not debuggable: " + app.packageName); 7103 } 7104 } 7105 mProfileApp = processName; 7106 mProfileFile = profileFile; 7107 if (mProfileFd != null) { 7108 try { 7109 mProfileFd.close(); 7110 } catch (IOException e) { 7111 } 7112 mProfileFd = null; 7113 } 7114 mProfileFd = profileFd; 7115 mProfileType = 0; 7116 mAutoStopProfiler = autoStopProfiler; 7117 } 7118 } 7119 7120 public void setAlwaysFinish(boolean enabled) { 7121 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7122 "setAlwaysFinish()"); 7123 7124 Settings.System.putInt( 7125 mContext.getContentResolver(), 7126 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7127 7128 synchronized (this) { 7129 mAlwaysFinishActivities = enabled; 7130 } 7131 } 7132 7133 public void setActivityController(IActivityController controller) { 7134 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7135 "setActivityController()"); 7136 synchronized (this) { 7137 mController = controller; 7138 } 7139 } 7140 7141 public boolean isUserAMonkey() { 7142 // For now the fact that there is a controller implies 7143 // we have a monkey. 7144 synchronized (this) { 7145 return mController != null; 7146 } 7147 } 7148 7149 public void registerProcessObserver(IProcessObserver observer) { 7150 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7151 "registerProcessObserver()"); 7152 synchronized (this) { 7153 mProcessObservers.register(observer); 7154 } 7155 } 7156 7157 public void unregisterProcessObserver(IProcessObserver observer) { 7158 synchronized (this) { 7159 mProcessObservers.unregister(observer); 7160 } 7161 } 7162 7163 public void setImmersive(IBinder token, boolean immersive) { 7164 synchronized(this) { 7165 ActivityRecord r = mMainStack.isInStackLocked(token); 7166 if (r == null) { 7167 throw new IllegalArgumentException(); 7168 } 7169 r.immersive = immersive; 7170 } 7171 } 7172 7173 public boolean isImmersive(IBinder token) { 7174 synchronized (this) { 7175 ActivityRecord r = mMainStack.isInStackLocked(token); 7176 if (r == null) { 7177 throw new IllegalArgumentException(); 7178 } 7179 return r.immersive; 7180 } 7181 } 7182 7183 public boolean isTopActivityImmersive() { 7184 enforceNotIsolatedCaller("startActivity"); 7185 synchronized (this) { 7186 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7187 return (r != null) ? r.immersive : false; 7188 } 7189 } 7190 7191 public final void enterSafeMode() { 7192 synchronized(this) { 7193 // It only makes sense to do this before the system is ready 7194 // and started launching other packages. 7195 if (!mSystemReady) { 7196 try { 7197 AppGlobals.getPackageManager().enterSafeMode(); 7198 } catch (RemoteException e) { 7199 } 7200 } 7201 } 7202 } 7203 7204 public final void showSafeModeOverlay() { 7205 View v = LayoutInflater.from(mContext).inflate( 7206 com.android.internal.R.layout.safe_mode, null); 7207 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7208 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7209 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7210 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7211 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 7212 lp.format = v.getBackground().getOpacity(); 7213 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7214 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7215 ((WindowManager)mContext.getSystemService( 7216 Context.WINDOW_SERVICE)).addView(v, lp); 7217 } 7218 7219 public void noteWakeupAlarm(IIntentSender sender) { 7220 if (!(sender instanceof PendingIntentRecord)) { 7221 return; 7222 } 7223 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7224 synchronized (stats) { 7225 if (mBatteryStatsService.isOnBattery()) { 7226 mBatteryStatsService.enforceCallingPermission(); 7227 PendingIntentRecord rec = (PendingIntentRecord)sender; 7228 int MY_UID = Binder.getCallingUid(); 7229 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7230 BatteryStatsImpl.Uid.Pkg pkg = 7231 stats.getPackageStatsLocked(uid, rec.key.packageName); 7232 pkg.incWakeupsLocked(); 7233 } 7234 } 7235 } 7236 7237 public boolean killPids(int[] pids, String pReason, boolean secure) { 7238 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7239 throw new SecurityException("killPids only available to the system"); 7240 } 7241 String reason = (pReason == null) ? "Unknown" : pReason; 7242 // XXX Note: don't acquire main activity lock here, because the window 7243 // manager calls in with its locks held. 7244 7245 boolean killed = false; 7246 synchronized (mPidsSelfLocked) { 7247 int[] types = new int[pids.length]; 7248 int worstType = 0; 7249 for (int i=0; i<pids.length; i++) { 7250 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7251 if (proc != null) { 7252 int type = proc.setAdj; 7253 types[i] = type; 7254 if (type > worstType) { 7255 worstType = type; 7256 } 7257 } 7258 } 7259 7260 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7261 // then constrain it so we will kill all hidden procs. 7262 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7263 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7264 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7265 } 7266 7267 // If this is not a secure call, don't let it kill processes that 7268 // are important. 7269 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7270 worstType = ProcessList.SERVICE_ADJ; 7271 } 7272 7273 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7274 for (int i=0; i<pids.length; i++) { 7275 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7276 if (proc == null) { 7277 continue; 7278 } 7279 int adj = proc.setAdj; 7280 if (adj >= worstType && !proc.killedBackground) { 7281 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7282 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7283 proc.processName, adj, reason); 7284 killed = true; 7285 proc.killedBackground = true; 7286 Process.killProcessQuiet(pids[i]); 7287 } 7288 } 7289 } 7290 return killed; 7291 } 7292 7293 @Override 7294 public boolean killProcessesBelowForeground(String reason) { 7295 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7296 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7297 } 7298 7299 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7300 } 7301 7302 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7303 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7304 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7305 } 7306 7307 boolean killed = false; 7308 synchronized (mPidsSelfLocked) { 7309 final int size = mPidsSelfLocked.size(); 7310 for (int i = 0; i < size; i++) { 7311 final int pid = mPidsSelfLocked.keyAt(i); 7312 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7313 if (proc == null) continue; 7314 7315 final int adj = proc.setAdj; 7316 if (adj > belowAdj && !proc.killedBackground) { 7317 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7318 EventLog.writeEvent( 7319 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7320 killed = true; 7321 proc.killedBackground = true; 7322 Process.killProcessQuiet(pid); 7323 } 7324 } 7325 } 7326 return killed; 7327 } 7328 7329 public final void startRunning(String pkg, String cls, String action, 7330 String data) { 7331 synchronized(this) { 7332 if (mStartRunning) { 7333 return; 7334 } 7335 mStartRunning = true; 7336 mTopComponent = pkg != null && cls != null 7337 ? new ComponentName(pkg, cls) : null; 7338 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7339 mTopData = data; 7340 if (!mSystemReady) { 7341 return; 7342 } 7343 } 7344 7345 systemReady(null); 7346 } 7347 7348 private void retrieveSettings() { 7349 final ContentResolver resolver = mContext.getContentResolver(); 7350 String debugApp = Settings.System.getString( 7351 resolver, Settings.System.DEBUG_APP); 7352 boolean waitForDebugger = Settings.System.getInt( 7353 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7354 boolean alwaysFinishActivities = Settings.System.getInt( 7355 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7356 7357 Configuration configuration = new Configuration(); 7358 Settings.System.getConfiguration(resolver, configuration); 7359 7360 synchronized (this) { 7361 mDebugApp = mOrigDebugApp = debugApp; 7362 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7363 mAlwaysFinishActivities = alwaysFinishActivities; 7364 // This happens before any activities are started, so we can 7365 // change mConfiguration in-place. 7366 updateConfigurationLocked(configuration, null, false, true); 7367 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7368 } 7369 } 7370 7371 public boolean testIsSystemReady() { 7372 // no need to synchronize(this) just to read & return the value 7373 return mSystemReady; 7374 } 7375 7376 private static File getCalledPreBootReceiversFile() { 7377 File dataDir = Environment.getDataDirectory(); 7378 File systemDir = new File(dataDir, "system"); 7379 File fname = new File(systemDir, "called_pre_boots.dat"); 7380 return fname; 7381 } 7382 7383 static final int LAST_DONE_VERSION = 10000; 7384 7385 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7386 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7387 File file = getCalledPreBootReceiversFile(); 7388 FileInputStream fis = null; 7389 try { 7390 fis = new FileInputStream(file); 7391 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7392 int fvers = dis.readInt(); 7393 if (fvers == LAST_DONE_VERSION) { 7394 String vers = dis.readUTF(); 7395 String codename = dis.readUTF(); 7396 String build = dis.readUTF(); 7397 if (android.os.Build.VERSION.RELEASE.equals(vers) 7398 && android.os.Build.VERSION.CODENAME.equals(codename) 7399 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7400 int num = dis.readInt(); 7401 while (num > 0) { 7402 num--; 7403 String pkg = dis.readUTF(); 7404 String cls = dis.readUTF(); 7405 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7406 } 7407 } 7408 } 7409 } catch (FileNotFoundException e) { 7410 } catch (IOException e) { 7411 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7412 } finally { 7413 if (fis != null) { 7414 try { 7415 fis.close(); 7416 } catch (IOException e) { 7417 } 7418 } 7419 } 7420 return lastDoneReceivers; 7421 } 7422 7423 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7424 File file = getCalledPreBootReceiversFile(); 7425 FileOutputStream fos = null; 7426 DataOutputStream dos = null; 7427 try { 7428 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7429 fos = new FileOutputStream(file); 7430 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7431 dos.writeInt(LAST_DONE_VERSION); 7432 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7433 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7434 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7435 dos.writeInt(list.size()); 7436 for (int i=0; i<list.size(); i++) { 7437 dos.writeUTF(list.get(i).getPackageName()); 7438 dos.writeUTF(list.get(i).getClassName()); 7439 } 7440 } catch (IOException e) { 7441 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7442 file.delete(); 7443 } finally { 7444 FileUtils.sync(fos); 7445 if (dos != null) { 7446 try { 7447 dos.close(); 7448 } catch (IOException e) { 7449 // TODO Auto-generated catch block 7450 e.printStackTrace(); 7451 } 7452 } 7453 } 7454 } 7455 7456 public void systemReady(final Runnable goingCallback) { 7457 synchronized(this) { 7458 if (mSystemReady) { 7459 if (goingCallback != null) goingCallback.run(); 7460 return; 7461 } 7462 7463 // Check to see if there are any update receivers to run. 7464 if (!mDidUpdate) { 7465 if (mWaitingUpdate) { 7466 return; 7467 } 7468 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7469 List<ResolveInfo> ris = null; 7470 try { 7471 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7472 intent, null, 0, 0); 7473 } catch (RemoteException e) { 7474 } 7475 if (ris != null) { 7476 for (int i=ris.size()-1; i>=0; i--) { 7477 if ((ris.get(i).activityInfo.applicationInfo.flags 7478 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7479 ris.remove(i); 7480 } 7481 } 7482 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7483 7484 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7485 7486 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7487 for (int i=0; i<ris.size(); i++) { 7488 ActivityInfo ai = ris.get(i).activityInfo; 7489 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7490 if (lastDoneReceivers.contains(comp)) { 7491 ris.remove(i); 7492 i--; 7493 } 7494 } 7495 7496 for (int i=0; i<ris.size(); i++) { 7497 ActivityInfo ai = ris.get(i).activityInfo; 7498 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7499 doneReceivers.add(comp); 7500 intent.setComponent(comp); 7501 IIntentReceiver finisher = null; 7502 if (i == ris.size()-1) { 7503 finisher = new IIntentReceiver.Stub() { 7504 public void performReceive(Intent intent, int resultCode, 7505 String data, Bundle extras, boolean ordered, 7506 boolean sticky) { 7507 // The raw IIntentReceiver interface is called 7508 // with the AM lock held, so redispatch to 7509 // execute our code without the lock. 7510 mHandler.post(new Runnable() { 7511 public void run() { 7512 synchronized (ActivityManagerService.this) { 7513 mDidUpdate = true; 7514 } 7515 writeLastDonePreBootReceivers(doneReceivers); 7516 showBootMessage(mContext.getText( 7517 R.string.android_upgrading_complete), 7518 false); 7519 systemReady(goingCallback); 7520 } 7521 }); 7522 } 7523 }; 7524 } 7525 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7526 /* TODO: Send this to all users */ 7527 broadcastIntentLocked(null, null, intent, null, finisher, 7528 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7529 0 /* UserId zero */); 7530 if (finisher != null) { 7531 mWaitingUpdate = true; 7532 } 7533 } 7534 } 7535 if (mWaitingUpdate) { 7536 return; 7537 } 7538 mDidUpdate = true; 7539 } 7540 7541 mSystemReady = true; 7542 if (!mStartRunning) { 7543 return; 7544 } 7545 } 7546 7547 ArrayList<ProcessRecord> procsToKill = null; 7548 synchronized(mPidsSelfLocked) { 7549 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7550 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7551 if (!isAllowedWhileBooting(proc.info)){ 7552 if (procsToKill == null) { 7553 procsToKill = new ArrayList<ProcessRecord>(); 7554 } 7555 procsToKill.add(proc); 7556 } 7557 } 7558 } 7559 7560 synchronized(this) { 7561 if (procsToKill != null) { 7562 for (int i=procsToKill.size()-1; i>=0; i--) { 7563 ProcessRecord proc = procsToKill.get(i); 7564 Slog.i(TAG, "Removing system update proc: " + proc); 7565 removeProcessLocked(proc, true, false, "system update done"); 7566 } 7567 } 7568 7569 // Now that we have cleaned up any update processes, we 7570 // are ready to start launching real processes and know that 7571 // we won't trample on them any more. 7572 mProcessesReady = true; 7573 } 7574 7575 Slog.i(TAG, "System now ready"); 7576 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7577 SystemClock.uptimeMillis()); 7578 7579 synchronized(this) { 7580 // Make sure we have no pre-ready processes sitting around. 7581 7582 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7583 ResolveInfo ri = mContext.getPackageManager() 7584 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7585 STOCK_PM_FLAGS); 7586 CharSequence errorMsg = null; 7587 if (ri != null) { 7588 ActivityInfo ai = ri.activityInfo; 7589 ApplicationInfo app = ai.applicationInfo; 7590 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7591 mTopAction = Intent.ACTION_FACTORY_TEST; 7592 mTopData = null; 7593 mTopComponent = new ComponentName(app.packageName, 7594 ai.name); 7595 } else { 7596 errorMsg = mContext.getResources().getText( 7597 com.android.internal.R.string.factorytest_not_system); 7598 } 7599 } else { 7600 errorMsg = mContext.getResources().getText( 7601 com.android.internal.R.string.factorytest_no_action); 7602 } 7603 if (errorMsg != null) { 7604 mTopAction = null; 7605 mTopData = null; 7606 mTopComponent = null; 7607 Message msg = Message.obtain(); 7608 msg.what = SHOW_FACTORY_ERROR_MSG; 7609 msg.getData().putCharSequence("msg", errorMsg); 7610 mHandler.sendMessage(msg); 7611 } 7612 } 7613 } 7614 7615 retrieveSettings(); 7616 7617 if (goingCallback != null) goingCallback.run(); 7618 7619 synchronized (this) { 7620 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7621 try { 7622 List apps = AppGlobals.getPackageManager(). 7623 getPersistentApplications(STOCK_PM_FLAGS); 7624 if (apps != null) { 7625 int N = apps.size(); 7626 int i; 7627 for (i=0; i<N; i++) { 7628 ApplicationInfo info 7629 = (ApplicationInfo)apps.get(i); 7630 if (info != null && 7631 !info.packageName.equals("android")) { 7632 addAppLocked(info, false); 7633 } 7634 } 7635 } 7636 } catch (RemoteException ex) { 7637 // pm is in same process, this will never happen. 7638 } 7639 } 7640 7641 // Start up initial activity. 7642 mBooting = true; 7643 7644 try { 7645 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7646 Message msg = Message.obtain(); 7647 msg.what = SHOW_UID_ERROR_MSG; 7648 mHandler.sendMessage(msg); 7649 } 7650 } catch (RemoteException e) { 7651 } 7652 7653 mMainStack.resumeTopActivityLocked(null); 7654 } 7655 } 7656 7657 private boolean makeAppCrashingLocked(ProcessRecord app, 7658 String shortMsg, String longMsg, String stackTrace) { 7659 app.crashing = true; 7660 app.crashingReport = generateProcessError(app, 7661 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7662 startAppProblemLocked(app); 7663 app.stopFreezingAllLocked(); 7664 return handleAppCrashLocked(app); 7665 } 7666 7667 private void makeAppNotRespondingLocked(ProcessRecord app, 7668 String activity, String shortMsg, String longMsg) { 7669 app.notResponding = true; 7670 app.notRespondingReport = generateProcessError(app, 7671 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7672 activity, shortMsg, longMsg, null); 7673 startAppProblemLocked(app); 7674 app.stopFreezingAllLocked(); 7675 } 7676 7677 /** 7678 * Generate a process error record, suitable for attachment to a ProcessRecord. 7679 * 7680 * @param app The ProcessRecord in which the error occurred. 7681 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7682 * ActivityManager.AppErrorStateInfo 7683 * @param activity The activity associated with the crash, if known. 7684 * @param shortMsg Short message describing the crash. 7685 * @param longMsg Long message describing the crash. 7686 * @param stackTrace Full crash stack trace, may be null. 7687 * 7688 * @return Returns a fully-formed AppErrorStateInfo record. 7689 */ 7690 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7691 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7692 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7693 7694 report.condition = condition; 7695 report.processName = app.processName; 7696 report.pid = app.pid; 7697 report.uid = app.info.uid; 7698 report.tag = activity; 7699 report.shortMsg = shortMsg; 7700 report.longMsg = longMsg; 7701 report.stackTrace = stackTrace; 7702 7703 return report; 7704 } 7705 7706 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7707 synchronized (this) { 7708 app.crashing = false; 7709 app.crashingReport = null; 7710 app.notResponding = false; 7711 app.notRespondingReport = null; 7712 if (app.anrDialog == fromDialog) { 7713 app.anrDialog = null; 7714 } 7715 if (app.waitDialog == fromDialog) { 7716 app.waitDialog = null; 7717 } 7718 if (app.pid > 0 && app.pid != MY_PID) { 7719 handleAppCrashLocked(app); 7720 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7721 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7722 app.processName, app.setAdj, "user's request after error"); 7723 Process.killProcessQuiet(app.pid); 7724 } 7725 } 7726 } 7727 7728 private boolean handleAppCrashLocked(ProcessRecord app) { 7729 if (mHeadless) { 7730 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7731 return false; 7732 } 7733 long now = SystemClock.uptimeMillis(); 7734 7735 Long crashTime; 7736 if (!app.isolated) { 7737 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7738 } else { 7739 crashTime = null; 7740 } 7741 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7742 // This process loses! 7743 Slog.w(TAG, "Process " + app.info.processName 7744 + " has crashed too many times: killing!"); 7745 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7746 app.info.processName, app.uid); 7747 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7748 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7749 if (r.app == app) { 7750 Slog.w(TAG, " Force finishing activity " 7751 + r.intent.getComponent().flattenToShortString()); 7752 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7753 } 7754 } 7755 if (!app.persistent) { 7756 // We don't want to start this process again until the user 7757 // explicitly does so... but for persistent process, we really 7758 // need to keep it running. If a persistent process is actually 7759 // repeatedly crashing, then badness for everyone. 7760 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7761 app.info.processName); 7762 if (!app.isolated) { 7763 // XXX We don't have a way to mark isolated processes 7764 // as bad, since they don't have a peristent identity. 7765 mBadProcesses.put(app.info.processName, app.uid, now); 7766 mProcessCrashTimes.remove(app.info.processName, app.uid); 7767 } 7768 app.bad = true; 7769 app.removed = true; 7770 // Don't let services in this process be restarted and potentially 7771 // annoy the user repeatedly. Unless it is persistent, since those 7772 // processes run critical code. 7773 removeProcessLocked(app, false, false, "crash"); 7774 mMainStack.resumeTopActivityLocked(null); 7775 return false; 7776 } 7777 mMainStack.resumeTopActivityLocked(null); 7778 } else { 7779 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7780 if (r != null && r.app == app) { 7781 // If the top running activity is from this crashing 7782 // process, then terminate it to avoid getting in a loop. 7783 Slog.w(TAG, " Force finishing activity " 7784 + r.intent.getComponent().flattenToShortString()); 7785 int index = mMainStack.indexOfActivityLocked(r); 7786 r.stack.finishActivityLocked(r, index, 7787 Activity.RESULT_CANCELED, null, "crashed"); 7788 // Also terminate any activities below it that aren't yet 7789 // stopped, to avoid a situation where one will get 7790 // re-start our crashing activity once it gets resumed again. 7791 index--; 7792 if (index >= 0) { 7793 r = (ActivityRecord)mMainStack.mHistory.get(index); 7794 if (r.state == ActivityState.RESUMED 7795 || r.state == ActivityState.PAUSING 7796 || r.state == ActivityState.PAUSED) { 7797 if (!r.isHomeActivity || mHomeProcess != r.app) { 7798 Slog.w(TAG, " Force finishing activity " 7799 + r.intent.getComponent().flattenToShortString()); 7800 r.stack.finishActivityLocked(r, index, 7801 Activity.RESULT_CANCELED, null, "crashed"); 7802 } 7803 } 7804 } 7805 } 7806 } 7807 7808 // Bump up the crash count of any services currently running in the proc. 7809 if (app.services.size() != 0) { 7810 // Any services running in the application need to be placed 7811 // back in the pending list. 7812 Iterator<ServiceRecord> it = app.services.iterator(); 7813 while (it.hasNext()) { 7814 ServiceRecord sr = it.next(); 7815 sr.crashCount++; 7816 } 7817 } 7818 7819 // If the crashing process is what we consider to be the "home process" and it has been 7820 // replaced by a third-party app, clear the package preferred activities from packages 7821 // with a home activity running in the process to prevent a repeatedly crashing app 7822 // from blocking the user to manually clear the list. 7823 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7824 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7825 Iterator it = mHomeProcess.activities.iterator(); 7826 while (it.hasNext()) { 7827 ActivityRecord r = (ActivityRecord)it.next(); 7828 if (r.isHomeActivity) { 7829 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7830 try { 7831 ActivityThread.getPackageManager() 7832 .clearPackagePreferredActivities(r.packageName); 7833 } catch (RemoteException c) { 7834 // pm is in same process, this will never happen. 7835 } 7836 } 7837 } 7838 } 7839 7840 if (!app.isolated) { 7841 // XXX Can't keep track of crash times for isolated processes, 7842 // because they don't have a perisistent identity. 7843 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7844 } 7845 7846 return true; 7847 } 7848 7849 void startAppProblemLocked(ProcessRecord app) { 7850 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7851 mContext, app.info.packageName, app.info.flags); 7852 skipCurrentReceiverLocked(app); 7853 } 7854 7855 void skipCurrentReceiverLocked(ProcessRecord app) { 7856 for (BroadcastQueue queue : mBroadcastQueues) { 7857 queue.skipCurrentReceiverLocked(app); 7858 } 7859 } 7860 7861 /** 7862 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7863 * The application process will exit immediately after this call returns. 7864 * @param app object of the crashing app, null for the system server 7865 * @param crashInfo describing the exception 7866 */ 7867 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7868 ProcessRecord r = findAppProcess(app, "Crash"); 7869 final String processName = app == null ? "system_server" 7870 : (r == null ? "unknown" : r.processName); 7871 7872 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7873 processName, 7874 r == null ? -1 : r.info.flags, 7875 crashInfo.exceptionClassName, 7876 crashInfo.exceptionMessage, 7877 crashInfo.throwFileName, 7878 crashInfo.throwLineNumber); 7879 7880 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7881 7882 crashApplication(r, crashInfo); 7883 } 7884 7885 public void handleApplicationStrictModeViolation( 7886 IBinder app, 7887 int violationMask, 7888 StrictMode.ViolationInfo info) { 7889 ProcessRecord r = findAppProcess(app, "StrictMode"); 7890 if (r == null) { 7891 return; 7892 } 7893 7894 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7895 Integer stackFingerprint = info.hashCode(); 7896 boolean logIt = true; 7897 synchronized (mAlreadyLoggedViolatedStacks) { 7898 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7899 logIt = false; 7900 // TODO: sub-sample into EventLog for these, with 7901 // the info.durationMillis? Then we'd get 7902 // the relative pain numbers, without logging all 7903 // the stack traces repeatedly. We'd want to do 7904 // likewise in the client code, which also does 7905 // dup suppression, before the Binder call. 7906 } else { 7907 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7908 mAlreadyLoggedViolatedStacks.clear(); 7909 } 7910 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7911 } 7912 } 7913 if (logIt) { 7914 logStrictModeViolationToDropBox(r, info); 7915 } 7916 } 7917 7918 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7919 AppErrorResult result = new AppErrorResult(); 7920 synchronized (this) { 7921 final long origId = Binder.clearCallingIdentity(); 7922 7923 Message msg = Message.obtain(); 7924 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7925 HashMap<String, Object> data = new HashMap<String, Object>(); 7926 data.put("result", result); 7927 data.put("app", r); 7928 data.put("violationMask", violationMask); 7929 data.put("info", info); 7930 msg.obj = data; 7931 mHandler.sendMessage(msg); 7932 7933 Binder.restoreCallingIdentity(origId); 7934 } 7935 int res = result.get(); 7936 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7937 } 7938 } 7939 7940 // Depending on the policy in effect, there could be a bunch of 7941 // these in quick succession so we try to batch these together to 7942 // minimize disk writes, number of dropbox entries, and maximize 7943 // compression, by having more fewer, larger records. 7944 private void logStrictModeViolationToDropBox( 7945 ProcessRecord process, 7946 StrictMode.ViolationInfo info) { 7947 if (info == null) { 7948 return; 7949 } 7950 final boolean isSystemApp = process == null || 7951 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7952 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7953 final String processName = process == null ? "unknown" : process.processName; 7954 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7955 final DropBoxManager dbox = (DropBoxManager) 7956 mContext.getSystemService(Context.DROPBOX_SERVICE); 7957 7958 // Exit early if the dropbox isn't configured to accept this report type. 7959 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7960 7961 boolean bufferWasEmpty; 7962 boolean needsFlush; 7963 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7964 synchronized (sb) { 7965 bufferWasEmpty = sb.length() == 0; 7966 appendDropBoxProcessHeaders(process, processName, sb); 7967 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7968 sb.append("System-App: ").append(isSystemApp).append("\n"); 7969 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7970 if (info.violationNumThisLoop != 0) { 7971 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7972 } 7973 if (info.numAnimationsRunning != 0) { 7974 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7975 } 7976 if (info.broadcastIntentAction != null) { 7977 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7978 } 7979 if (info.durationMillis != -1) { 7980 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7981 } 7982 if (info.numInstances != -1) { 7983 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7984 } 7985 if (info.tags != null) { 7986 for (String tag : info.tags) { 7987 sb.append("Span-Tag: ").append(tag).append("\n"); 7988 } 7989 } 7990 sb.append("\n"); 7991 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7992 sb.append(info.crashInfo.stackTrace); 7993 } 7994 sb.append("\n"); 7995 7996 // Only buffer up to ~64k. Various logging bits truncate 7997 // things at 128k. 7998 needsFlush = (sb.length() > 64 * 1024); 7999 } 8000 8001 // Flush immediately if the buffer's grown too large, or this 8002 // is a non-system app. Non-system apps are isolated with a 8003 // different tag & policy and not batched. 8004 // 8005 // Batching is useful during internal testing with 8006 // StrictMode settings turned up high. Without batching, 8007 // thousands of separate files could be created on boot. 8008 if (!isSystemApp || needsFlush) { 8009 new Thread("Error dump: " + dropboxTag) { 8010 @Override 8011 public void run() { 8012 String report; 8013 synchronized (sb) { 8014 report = sb.toString(); 8015 sb.delete(0, sb.length()); 8016 sb.trimToSize(); 8017 } 8018 if (report.length() != 0) { 8019 dbox.addText(dropboxTag, report); 8020 } 8021 } 8022 }.start(); 8023 return; 8024 } 8025 8026 // System app batching: 8027 if (!bufferWasEmpty) { 8028 // An existing dropbox-writing thread is outstanding, so 8029 // we don't need to start it up. The existing thread will 8030 // catch the buffer appends we just did. 8031 return; 8032 } 8033 8034 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8035 // (After this point, we shouldn't access AMS internal data structures.) 8036 new Thread("Error dump: " + dropboxTag) { 8037 @Override 8038 public void run() { 8039 // 5 second sleep to let stacks arrive and be batched together 8040 try { 8041 Thread.sleep(5000); // 5 seconds 8042 } catch (InterruptedException e) {} 8043 8044 String errorReport; 8045 synchronized (mStrictModeBuffer) { 8046 errorReport = mStrictModeBuffer.toString(); 8047 if (errorReport.length() == 0) { 8048 return; 8049 } 8050 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8051 mStrictModeBuffer.trimToSize(); 8052 } 8053 dbox.addText(dropboxTag, errorReport); 8054 } 8055 }.start(); 8056 } 8057 8058 /** 8059 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8060 * @param app object of the crashing app, null for the system server 8061 * @param tag reported by the caller 8062 * @param crashInfo describing the context of the error 8063 * @return true if the process should exit immediately (WTF is fatal) 8064 */ 8065 public boolean handleApplicationWtf(IBinder app, String tag, 8066 ApplicationErrorReport.CrashInfo crashInfo) { 8067 ProcessRecord r = findAppProcess(app, "WTF"); 8068 final String processName = app == null ? "system_server" 8069 : (r == null ? "unknown" : r.processName); 8070 8071 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8072 processName, 8073 r == null ? -1 : r.info.flags, 8074 tag, crashInfo.exceptionMessage); 8075 8076 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8077 8078 if (r != null && r.pid != Process.myPid() && 8079 Settings.Secure.getInt(mContext.getContentResolver(), 8080 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8081 crashApplication(r, crashInfo); 8082 return true; 8083 } else { 8084 return false; 8085 } 8086 } 8087 8088 /** 8089 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8090 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8091 */ 8092 private ProcessRecord findAppProcess(IBinder app, String reason) { 8093 if (app == null) { 8094 return null; 8095 } 8096 8097 synchronized (this) { 8098 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8099 final int NA = apps.size(); 8100 for (int ia=0; ia<NA; ia++) { 8101 ProcessRecord p = apps.valueAt(ia); 8102 if (p.thread != null && p.thread.asBinder() == app) { 8103 return p; 8104 } 8105 } 8106 } 8107 8108 Slog.w(TAG, "Can't find mystery application for " + reason 8109 + " from pid=" + Binder.getCallingPid() 8110 + " uid=" + Binder.getCallingUid() + ": " + app); 8111 return null; 8112 } 8113 } 8114 8115 /** 8116 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8117 * to append various headers to the dropbox log text. 8118 */ 8119 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8120 StringBuilder sb) { 8121 // Watchdog thread ends up invoking this function (with 8122 // a null ProcessRecord) to add the stack file to dropbox. 8123 // Do not acquire a lock on this (am) in such cases, as it 8124 // could cause a potential deadlock, if and when watchdog 8125 // is invoked due to unavailability of lock on am and it 8126 // would prevent watchdog from killing system_server. 8127 if (process == null) { 8128 sb.append("Process: ").append(processName).append("\n"); 8129 return; 8130 } 8131 // Note: ProcessRecord 'process' is guarded by the service 8132 // instance. (notably process.pkgList, which could otherwise change 8133 // concurrently during execution of this method) 8134 synchronized (this) { 8135 sb.append("Process: ").append(processName).append("\n"); 8136 int flags = process.info.flags; 8137 IPackageManager pm = AppGlobals.getPackageManager(); 8138 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8139 for (String pkg : process.pkgList) { 8140 sb.append("Package: ").append(pkg); 8141 try { 8142 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8143 if (pi != null) { 8144 sb.append(" v").append(pi.versionCode); 8145 if (pi.versionName != null) { 8146 sb.append(" (").append(pi.versionName).append(")"); 8147 } 8148 } 8149 } catch (RemoteException e) { 8150 Slog.e(TAG, "Error getting package info: " + pkg, e); 8151 } 8152 sb.append("\n"); 8153 } 8154 } 8155 } 8156 8157 private static String processClass(ProcessRecord process) { 8158 if (process == null || process.pid == MY_PID) { 8159 return "system_server"; 8160 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8161 return "system_app"; 8162 } else { 8163 return "data_app"; 8164 } 8165 } 8166 8167 /** 8168 * Write a description of an error (crash, WTF, ANR) to the drop box. 8169 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8170 * @param process which caused the error, null means the system server 8171 * @param activity which triggered the error, null if unknown 8172 * @param parent activity related to the error, null if unknown 8173 * @param subject line related to the error, null if absent 8174 * @param report in long form describing the error, null if absent 8175 * @param logFile to include in the report, null if none 8176 * @param crashInfo giving an application stack trace, null if absent 8177 */ 8178 public void addErrorToDropBox(String eventType, 8179 ProcessRecord process, String processName, ActivityRecord activity, 8180 ActivityRecord parent, String subject, 8181 final String report, final File logFile, 8182 final ApplicationErrorReport.CrashInfo crashInfo) { 8183 // NOTE -- this must never acquire the ActivityManagerService lock, 8184 // otherwise the watchdog may be prevented from resetting the system. 8185 8186 final String dropboxTag = processClass(process) + "_" + eventType; 8187 final DropBoxManager dbox = (DropBoxManager) 8188 mContext.getSystemService(Context.DROPBOX_SERVICE); 8189 8190 // Exit early if the dropbox isn't configured to accept this report type. 8191 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8192 8193 final StringBuilder sb = new StringBuilder(1024); 8194 appendDropBoxProcessHeaders(process, processName, sb); 8195 if (activity != null) { 8196 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8197 } 8198 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8199 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8200 } 8201 if (parent != null && parent != activity) { 8202 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8203 } 8204 if (subject != null) { 8205 sb.append("Subject: ").append(subject).append("\n"); 8206 } 8207 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8208 if (Debug.isDebuggerConnected()) { 8209 sb.append("Debugger: Connected\n"); 8210 } 8211 sb.append("\n"); 8212 8213 // Do the rest in a worker thread to avoid blocking the caller on I/O 8214 // (After this point, we shouldn't access AMS internal data structures.) 8215 Thread worker = new Thread("Error dump: " + dropboxTag) { 8216 @Override 8217 public void run() { 8218 if (report != null) { 8219 sb.append(report); 8220 } 8221 if (logFile != null) { 8222 try { 8223 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8224 } catch (IOException e) { 8225 Slog.e(TAG, "Error reading " + logFile, e); 8226 } 8227 } 8228 if (crashInfo != null && crashInfo.stackTrace != null) { 8229 sb.append(crashInfo.stackTrace); 8230 } 8231 8232 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8233 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8234 if (lines > 0) { 8235 sb.append("\n"); 8236 8237 // Merge several logcat streams, and take the last N lines 8238 InputStreamReader input = null; 8239 try { 8240 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8241 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8242 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8243 8244 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8245 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8246 input = new InputStreamReader(logcat.getInputStream()); 8247 8248 int num; 8249 char[] buf = new char[8192]; 8250 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8251 } catch (IOException e) { 8252 Slog.e(TAG, "Error running logcat", e); 8253 } finally { 8254 if (input != null) try { input.close(); } catch (IOException e) {} 8255 } 8256 } 8257 8258 dbox.addText(dropboxTag, sb.toString()); 8259 } 8260 }; 8261 8262 if (process == null) { 8263 // If process is null, we are being called from some internal code 8264 // and may be about to die -- run this synchronously. 8265 worker.run(); 8266 } else { 8267 worker.start(); 8268 } 8269 } 8270 8271 /** 8272 * Bring up the "unexpected error" dialog box for a crashing app. 8273 * Deal with edge cases (intercepts from instrumented applications, 8274 * ActivityController, error intent receivers, that sort of thing). 8275 * @param r the application crashing 8276 * @param crashInfo describing the failure 8277 */ 8278 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8279 long timeMillis = System.currentTimeMillis(); 8280 String shortMsg = crashInfo.exceptionClassName; 8281 String longMsg = crashInfo.exceptionMessage; 8282 String stackTrace = crashInfo.stackTrace; 8283 if (shortMsg != null && longMsg != null) { 8284 longMsg = shortMsg + ": " + longMsg; 8285 } else if (shortMsg != null) { 8286 longMsg = shortMsg; 8287 } 8288 8289 AppErrorResult result = new AppErrorResult(); 8290 synchronized (this) { 8291 if (mController != null) { 8292 try { 8293 String name = r != null ? r.processName : null; 8294 int pid = r != null ? r.pid : Binder.getCallingPid(); 8295 if (!mController.appCrashed(name, pid, 8296 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8297 Slog.w(TAG, "Force-killing crashed app " + name 8298 + " at watcher's request"); 8299 Process.killProcess(pid); 8300 return; 8301 } 8302 } catch (RemoteException e) { 8303 mController = null; 8304 } 8305 } 8306 8307 final long origId = Binder.clearCallingIdentity(); 8308 8309 // If this process is running instrumentation, finish it. 8310 if (r != null && r.instrumentationClass != null) { 8311 Slog.w(TAG, "Error in app " + r.processName 8312 + " running instrumentation " + r.instrumentationClass + ":"); 8313 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8314 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8315 Bundle info = new Bundle(); 8316 info.putString("shortMsg", shortMsg); 8317 info.putString("longMsg", longMsg); 8318 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8319 Binder.restoreCallingIdentity(origId); 8320 return; 8321 } 8322 8323 // If we can't identify the process or it's already exceeded its crash quota, 8324 // quit right away without showing a crash dialog. 8325 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8326 Binder.restoreCallingIdentity(origId); 8327 return; 8328 } 8329 8330 Message msg = Message.obtain(); 8331 msg.what = SHOW_ERROR_MSG; 8332 HashMap data = new HashMap(); 8333 data.put("result", result); 8334 data.put("app", r); 8335 msg.obj = data; 8336 mHandler.sendMessage(msg); 8337 8338 Binder.restoreCallingIdentity(origId); 8339 } 8340 8341 int res = result.get(); 8342 8343 Intent appErrorIntent = null; 8344 synchronized (this) { 8345 if (r != null && !r.isolated) { 8346 // XXX Can't keep track of crash time for isolated processes, 8347 // since they don't have a persistent identity. 8348 mProcessCrashTimes.put(r.info.processName, r.uid, 8349 SystemClock.uptimeMillis()); 8350 } 8351 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8352 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8353 } 8354 } 8355 8356 if (appErrorIntent != null) { 8357 try { 8358 mContext.startActivity(appErrorIntent); 8359 } catch (ActivityNotFoundException e) { 8360 Slog.w(TAG, "bug report receiver dissappeared", e); 8361 } 8362 } 8363 } 8364 8365 Intent createAppErrorIntentLocked(ProcessRecord r, 8366 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8367 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8368 if (report == null) { 8369 return null; 8370 } 8371 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8372 result.setComponent(r.errorReportReceiver); 8373 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8374 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8375 return result; 8376 } 8377 8378 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8379 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8380 if (r.errorReportReceiver == null) { 8381 return null; 8382 } 8383 8384 if (!r.crashing && !r.notResponding) { 8385 return null; 8386 } 8387 8388 ApplicationErrorReport report = new ApplicationErrorReport(); 8389 report.packageName = r.info.packageName; 8390 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8391 report.processName = r.processName; 8392 report.time = timeMillis; 8393 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8394 8395 if (r.crashing) { 8396 report.type = ApplicationErrorReport.TYPE_CRASH; 8397 report.crashInfo = crashInfo; 8398 } else if (r.notResponding) { 8399 report.type = ApplicationErrorReport.TYPE_ANR; 8400 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8401 8402 report.anrInfo.activity = r.notRespondingReport.tag; 8403 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8404 report.anrInfo.info = r.notRespondingReport.longMsg; 8405 } 8406 8407 return report; 8408 } 8409 8410 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8411 enforceNotIsolatedCaller("getProcessesInErrorState"); 8412 // assume our apps are happy - lazy create the list 8413 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8414 8415 synchronized (this) { 8416 8417 // iterate across all processes 8418 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8419 ProcessRecord app = mLruProcesses.get(i); 8420 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8421 // This one's in trouble, so we'll generate a report for it 8422 // crashes are higher priority (in case there's a crash *and* an anr) 8423 ActivityManager.ProcessErrorStateInfo report = null; 8424 if (app.crashing) { 8425 report = app.crashingReport; 8426 } else if (app.notResponding) { 8427 report = app.notRespondingReport; 8428 } 8429 8430 if (report != null) { 8431 if (errList == null) { 8432 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8433 } 8434 errList.add(report); 8435 } else { 8436 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8437 " crashing = " + app.crashing + 8438 " notResponding = " + app.notResponding); 8439 } 8440 } 8441 } 8442 } 8443 8444 return errList; 8445 } 8446 8447 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8448 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8449 if (currApp != null) { 8450 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8451 } 8452 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8453 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8454 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8455 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8456 if (currApp != null) { 8457 currApp.lru = 0; 8458 } 8459 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8460 } else if (adj >= ProcessList.SERVICE_ADJ) { 8461 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8462 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8463 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8464 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8465 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8466 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8467 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8468 } else { 8469 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8470 } 8471 } 8472 8473 private void fillInProcMemInfo(ProcessRecord app, 8474 ActivityManager.RunningAppProcessInfo outInfo) { 8475 outInfo.pid = app.pid; 8476 outInfo.uid = app.info.uid; 8477 if (mHeavyWeightProcess == app) { 8478 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8479 } 8480 if (app.persistent) { 8481 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8482 } 8483 outInfo.lastTrimLevel = app.trimMemoryLevel; 8484 int adj = app.curAdj; 8485 outInfo.importance = oomAdjToImportance(adj, outInfo); 8486 outInfo.importanceReasonCode = app.adjTypeCode; 8487 } 8488 8489 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8490 enforceNotIsolatedCaller("getRunningAppProcesses"); 8491 // Lazy instantiation of list 8492 List<ActivityManager.RunningAppProcessInfo> runList = null; 8493 synchronized (this) { 8494 // Iterate across all processes 8495 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8496 ProcessRecord app = mLruProcesses.get(i); 8497 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8498 // Generate process state info for running application 8499 ActivityManager.RunningAppProcessInfo currApp = 8500 new ActivityManager.RunningAppProcessInfo(app.processName, 8501 app.pid, app.getPackageList()); 8502 fillInProcMemInfo(app, currApp); 8503 if (app.adjSource instanceof ProcessRecord) { 8504 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8505 currApp.importanceReasonImportance = oomAdjToImportance( 8506 app.adjSourceOom, null); 8507 } else if (app.adjSource instanceof ActivityRecord) { 8508 ActivityRecord r = (ActivityRecord)app.adjSource; 8509 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8510 } 8511 if (app.adjTarget instanceof ComponentName) { 8512 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8513 } 8514 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8515 // + " lru=" + currApp.lru); 8516 if (runList == null) { 8517 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8518 } 8519 runList.add(currApp); 8520 } 8521 } 8522 } 8523 return runList; 8524 } 8525 8526 public List<ApplicationInfo> getRunningExternalApplications() { 8527 enforceNotIsolatedCaller("getRunningExternalApplications"); 8528 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8529 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8530 if (runningApps != null && runningApps.size() > 0) { 8531 Set<String> extList = new HashSet<String>(); 8532 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8533 if (app.pkgList != null) { 8534 for (String pkg : app.pkgList) { 8535 extList.add(pkg); 8536 } 8537 } 8538 } 8539 IPackageManager pm = AppGlobals.getPackageManager(); 8540 for (String pkg : extList) { 8541 try { 8542 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8543 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8544 retList.add(info); 8545 } 8546 } catch (RemoteException e) { 8547 } 8548 } 8549 } 8550 return retList; 8551 } 8552 8553 @Override 8554 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8555 enforceNotIsolatedCaller("getMyMemoryState"); 8556 synchronized (this) { 8557 ProcessRecord proc; 8558 synchronized (mPidsSelfLocked) { 8559 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8560 } 8561 fillInProcMemInfo(proc, outInfo); 8562 } 8563 } 8564 8565 @Override 8566 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8567 if (checkCallingPermission(android.Manifest.permission.DUMP) 8568 != PackageManager.PERMISSION_GRANTED) { 8569 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8570 + Binder.getCallingPid() 8571 + ", uid=" + Binder.getCallingUid() 8572 + " without permission " 8573 + android.Manifest.permission.DUMP); 8574 return; 8575 } 8576 8577 boolean dumpAll = false; 8578 boolean dumpClient = false; 8579 String dumpPackage = null; 8580 8581 int opti = 0; 8582 while (opti < args.length) { 8583 String opt = args[opti]; 8584 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8585 break; 8586 } 8587 opti++; 8588 if ("-a".equals(opt)) { 8589 dumpAll = true; 8590 } else if ("-c".equals(opt)) { 8591 dumpClient = true; 8592 } else if ("-h".equals(opt)) { 8593 pw.println("Activity manager dump options:"); 8594 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8595 pw.println(" cmd may be one of:"); 8596 pw.println(" a[ctivities]: activity stack state"); 8597 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8598 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8599 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8600 pw.println(" o[om]: out of memory management"); 8601 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8602 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8603 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8604 pw.println(" service [COMP_SPEC]: service client-side state"); 8605 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8606 pw.println(" all: dump all activities"); 8607 pw.println(" top: dump the top activity"); 8608 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8609 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8610 pw.println(" a partial substring in a component name, a"); 8611 pw.println(" hex object identifier."); 8612 pw.println(" -a: include all available server state."); 8613 pw.println(" -c: include client state."); 8614 return; 8615 } else { 8616 pw.println("Unknown argument: " + opt + "; use -h for help"); 8617 } 8618 } 8619 8620 long origId = Binder.clearCallingIdentity(); 8621 boolean more = false; 8622 // Is the caller requesting to dump a particular piece of data? 8623 if (opti < args.length) { 8624 String cmd = args[opti]; 8625 opti++; 8626 if ("activities".equals(cmd) || "a".equals(cmd)) { 8627 synchronized (this) { 8628 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8629 } 8630 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8631 String[] newArgs; 8632 String name; 8633 if (opti >= args.length) { 8634 name = null; 8635 newArgs = EMPTY_STRING_ARRAY; 8636 } else { 8637 name = args[opti]; 8638 opti++; 8639 newArgs = new String[args.length - opti]; 8640 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8641 args.length - opti); 8642 } 8643 synchronized (this) { 8644 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8645 } 8646 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8647 String[] newArgs; 8648 String name; 8649 if (opti >= args.length) { 8650 name = null; 8651 newArgs = EMPTY_STRING_ARRAY; 8652 } else { 8653 name = args[opti]; 8654 opti++; 8655 newArgs = new String[args.length - opti]; 8656 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8657 args.length - opti); 8658 } 8659 synchronized (this) { 8660 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8661 } 8662 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8663 String[] newArgs; 8664 String name; 8665 if (opti >= args.length) { 8666 name = null; 8667 newArgs = EMPTY_STRING_ARRAY; 8668 } else { 8669 name = args[opti]; 8670 opti++; 8671 newArgs = new String[args.length - opti]; 8672 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8673 args.length - opti); 8674 } 8675 synchronized (this) { 8676 dumpProcessesLocked(fd, pw, args, opti, true, name); 8677 } 8678 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8679 synchronized (this) { 8680 dumpOomLocked(fd, pw, args, opti, true); 8681 } 8682 } else if ("provider".equals(cmd)) { 8683 String[] newArgs; 8684 String name; 8685 if (opti >= args.length) { 8686 name = null; 8687 newArgs = EMPTY_STRING_ARRAY; 8688 } else { 8689 name = args[opti]; 8690 opti++; 8691 newArgs = new String[args.length - opti]; 8692 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8693 } 8694 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8695 pw.println("No providers match: " + name); 8696 pw.println("Use -h for help."); 8697 } 8698 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8699 synchronized (this) { 8700 dumpProvidersLocked(fd, pw, args, opti, true, null); 8701 } 8702 } else if ("service".equals(cmd)) { 8703 String[] newArgs; 8704 String name; 8705 if (opti >= args.length) { 8706 name = null; 8707 newArgs = EMPTY_STRING_ARRAY; 8708 } else { 8709 name = args[opti]; 8710 opti++; 8711 newArgs = new String[args.length - opti]; 8712 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8713 args.length - opti); 8714 } 8715 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8716 pw.println("No services match: " + name); 8717 pw.println("Use -h for help."); 8718 } 8719 } else if ("package".equals(cmd)) { 8720 String[] newArgs; 8721 if (opti >= args.length) { 8722 pw.println("package: no package name specified"); 8723 pw.println("Use -h for help."); 8724 } else { 8725 dumpPackage = args[opti]; 8726 opti++; 8727 newArgs = new String[args.length - opti]; 8728 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8729 args.length - opti); 8730 args = newArgs; 8731 opti = 0; 8732 more = true; 8733 } 8734 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8735 synchronized (this) { 8736 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8737 } 8738 } else { 8739 // Dumping a single activity? 8740 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8741 pw.println("Bad activity command, or no activities match: " + cmd); 8742 pw.println("Use -h for help."); 8743 } 8744 } 8745 if (!more) { 8746 Binder.restoreCallingIdentity(origId); 8747 return; 8748 } 8749 } 8750 8751 // No piece of data specified, dump everything. 8752 synchronized (this) { 8753 boolean needSep; 8754 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8755 if (needSep) { 8756 pw.println(" "); 8757 } 8758 if (dumpAll) { 8759 pw.println("-------------------------------------------------------------------------------"); 8760 } 8761 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8762 if (needSep) { 8763 pw.println(" "); 8764 } 8765 if (dumpAll) { 8766 pw.println("-------------------------------------------------------------------------------"); 8767 } 8768 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8769 if (needSep) { 8770 pw.println(" "); 8771 } 8772 if (dumpAll) { 8773 pw.println("-------------------------------------------------------------------------------"); 8774 } 8775 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8776 if (needSep) { 8777 pw.println(" "); 8778 } 8779 if (dumpAll) { 8780 pw.println("-------------------------------------------------------------------------------"); 8781 } 8782 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8783 if (needSep) { 8784 pw.println(" "); 8785 } 8786 if (dumpAll) { 8787 pw.println("-------------------------------------------------------------------------------"); 8788 } 8789 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8790 } 8791 Binder.restoreCallingIdentity(origId); 8792 } 8793 8794 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8795 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8796 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8797 pw.println(" Main stack:"); 8798 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8799 dumpPackage); 8800 pw.println(" "); 8801 pw.println(" Running activities (most recent first):"); 8802 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8803 dumpPackage); 8804 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8805 pw.println(" "); 8806 pw.println(" Activities waiting for another to become visible:"); 8807 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8808 !dumpAll, false, dumpPackage); 8809 } 8810 if (mMainStack.mStoppingActivities.size() > 0) { 8811 pw.println(" "); 8812 pw.println(" Activities waiting to stop:"); 8813 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8814 !dumpAll, false, dumpPackage); 8815 } 8816 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8817 pw.println(" "); 8818 pw.println(" Activities waiting to sleep:"); 8819 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8820 !dumpAll, false, dumpPackage); 8821 } 8822 if (mMainStack.mFinishingActivities.size() > 0) { 8823 pw.println(" "); 8824 pw.println(" Activities waiting to finish:"); 8825 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8826 !dumpAll, false, dumpPackage); 8827 } 8828 8829 pw.println(" "); 8830 if (mMainStack.mPausingActivity != null) { 8831 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8832 } 8833 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8834 pw.println(" mFocusedActivity: " + mFocusedActivity); 8835 if (dumpAll) { 8836 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8837 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8838 pw.println(" mDismissKeyguardOnNextActivity: " 8839 + mMainStack.mDismissKeyguardOnNextActivity); 8840 } 8841 8842 if (mRecentTasks.size() > 0) { 8843 pw.println(); 8844 pw.println(" Recent tasks:"); 8845 8846 final int N = mRecentTasks.size(); 8847 for (int i=0; i<N; i++) { 8848 TaskRecord tr = mRecentTasks.get(i); 8849 if (dumpPackage != null) { 8850 if (tr.realActivity == null || 8851 !dumpPackage.equals(tr.realActivity)) { 8852 continue; 8853 } 8854 } 8855 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8856 pw.println(tr); 8857 if (dumpAll) { 8858 mRecentTasks.get(i).dump(pw, " "); 8859 } 8860 } 8861 } 8862 8863 if (dumpAll) { 8864 pw.println(" "); 8865 pw.println(" mCurTask: " + mCurTask); 8866 } 8867 8868 return true; 8869 } 8870 8871 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8872 int opti, boolean dumpAll, String dumpPackage) { 8873 boolean needSep = false; 8874 int numPers = 0; 8875 8876 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8877 8878 if (dumpAll) { 8879 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8880 final int NA = procs.size(); 8881 for (int ia=0; ia<NA; ia++) { 8882 ProcessRecord r = procs.valueAt(ia); 8883 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8884 continue; 8885 } 8886 if (!needSep) { 8887 pw.println(" All known processes:"); 8888 needSep = true; 8889 } 8890 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8891 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8892 pw.print(" "); pw.println(r); 8893 r.dump(pw, " "); 8894 if (r.persistent) { 8895 numPers++; 8896 } 8897 } 8898 } 8899 } 8900 8901 if (mIsolatedProcesses.size() > 0) { 8902 if (needSep) pw.println(" "); 8903 needSep = true; 8904 pw.println(" Isolated process list (sorted by uid):"); 8905 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8906 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8907 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8908 continue; 8909 } 8910 pw.println(String.format("%sIsolated #%2d: %s", 8911 " ", i, r.toString())); 8912 } 8913 } 8914 8915 if (mLruProcesses.size() > 0) { 8916 if (needSep) pw.println(" "); 8917 needSep = true; 8918 pw.println(" Process LRU list (sorted by oom_adj):"); 8919 dumpProcessOomList(pw, this, mLruProcesses, " ", 8920 "Proc", "PERS", false, dumpPackage); 8921 needSep = true; 8922 } 8923 8924 if (dumpAll) { 8925 synchronized (mPidsSelfLocked) { 8926 boolean printed = false; 8927 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8928 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8929 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8930 continue; 8931 } 8932 if (!printed) { 8933 if (needSep) pw.println(" "); 8934 needSep = true; 8935 pw.println(" PID mappings:"); 8936 printed = true; 8937 } 8938 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8939 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8940 } 8941 } 8942 } 8943 8944 if (mForegroundProcesses.size() > 0) { 8945 synchronized (mPidsSelfLocked) { 8946 boolean printed = false; 8947 for (int i=0; i<mForegroundProcesses.size(); i++) { 8948 ProcessRecord r = mPidsSelfLocked.get( 8949 mForegroundProcesses.valueAt(i).pid); 8950 if (dumpPackage != null && (r == null 8951 || !dumpPackage.equals(r.info.packageName))) { 8952 continue; 8953 } 8954 if (!printed) { 8955 if (needSep) pw.println(" "); 8956 needSep = true; 8957 pw.println(" Foreground Processes:"); 8958 printed = true; 8959 } 8960 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8961 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8962 } 8963 } 8964 } 8965 8966 if (mPersistentStartingProcesses.size() > 0) { 8967 if (needSep) pw.println(" "); 8968 needSep = true; 8969 pw.println(" Persisent processes that are starting:"); 8970 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8971 "Starting Norm", "Restarting PERS", dumpPackage); 8972 } 8973 8974 if (mRemovedProcesses.size() > 0) { 8975 if (needSep) pw.println(" "); 8976 needSep = true; 8977 pw.println(" Processes that are being removed:"); 8978 dumpProcessList(pw, this, mRemovedProcesses, " ", 8979 "Removed Norm", "Removed PERS", dumpPackage); 8980 } 8981 8982 if (mProcessesOnHold.size() > 0) { 8983 if (needSep) pw.println(" "); 8984 needSep = true; 8985 pw.println(" Processes that are on old until the system is ready:"); 8986 dumpProcessList(pw, this, mProcessesOnHold, " ", 8987 "OnHold Norm", "OnHold PERS", dumpPackage); 8988 } 8989 8990 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8991 8992 if (mProcessCrashTimes.getMap().size() > 0) { 8993 boolean printed = false; 8994 long now = SystemClock.uptimeMillis(); 8995 for (Map.Entry<String, SparseArray<Long>> procs 8996 : mProcessCrashTimes.getMap().entrySet()) { 8997 String pname = procs.getKey(); 8998 SparseArray<Long> uids = procs.getValue(); 8999 final int N = uids.size(); 9000 for (int i=0; i<N; i++) { 9001 int puid = uids.keyAt(i); 9002 ProcessRecord r = mProcessNames.get(pname, puid); 9003 if (dumpPackage != null && (r == null 9004 || !dumpPackage.equals(r.info.packageName))) { 9005 continue; 9006 } 9007 if (!printed) { 9008 if (needSep) pw.println(" "); 9009 needSep = true; 9010 pw.println(" Time since processes crashed:"); 9011 printed = true; 9012 } 9013 pw.print(" Process "); pw.print(pname); 9014 pw.print(" uid "); pw.print(puid); 9015 pw.print(": last crashed "); 9016 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9017 pw.println(" ago"); 9018 } 9019 } 9020 } 9021 9022 if (mBadProcesses.getMap().size() > 0) { 9023 boolean printed = false; 9024 for (Map.Entry<String, SparseArray<Long>> procs 9025 : mBadProcesses.getMap().entrySet()) { 9026 String pname = procs.getKey(); 9027 SparseArray<Long> uids = procs.getValue(); 9028 final int N = uids.size(); 9029 for (int i=0; i<N; i++) { 9030 int puid = uids.keyAt(i); 9031 ProcessRecord r = mProcessNames.get(pname, puid); 9032 if (dumpPackage != null && (r == null 9033 || !dumpPackage.equals(r.info.packageName))) { 9034 continue; 9035 } 9036 if (!printed) { 9037 if (needSep) pw.println(" "); 9038 needSep = true; 9039 pw.println(" Bad processes:"); 9040 } 9041 pw.print(" Bad process "); pw.print(pname); 9042 pw.print(" uid "); pw.print(puid); 9043 pw.print(": crashed at time "); 9044 pw.println(uids.valueAt(i)); 9045 } 9046 } 9047 } 9048 9049 pw.println(); 9050 pw.println(" mHomeProcess: " + mHomeProcess); 9051 pw.println(" mPreviousProcess: " + mPreviousProcess); 9052 if (dumpAll) { 9053 StringBuilder sb = new StringBuilder(128); 9054 sb.append(" mPreviousProcessVisibleTime: "); 9055 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9056 pw.println(sb); 9057 } 9058 if (mHeavyWeightProcess != null) { 9059 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9060 } 9061 pw.println(" mConfiguration: " + mConfiguration); 9062 if (dumpAll) { 9063 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9064 if (mCompatModePackages.getPackages().size() > 0) { 9065 boolean printed = false; 9066 for (Map.Entry<String, Integer> entry 9067 : mCompatModePackages.getPackages().entrySet()) { 9068 String pkg = entry.getKey(); 9069 int mode = entry.getValue(); 9070 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9071 continue; 9072 } 9073 if (!printed) { 9074 pw.println(" mScreenCompatPackages:"); 9075 printed = true; 9076 } 9077 pw.print(" "); pw.print(pkg); pw.print(": "); 9078 pw.print(mode); pw.println(); 9079 } 9080 } 9081 } 9082 if (mSleeping || mWentToSleep || mLockScreenShown) { 9083 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9084 + " mLockScreenShown " + mLockScreenShown); 9085 } 9086 if (mShuttingDown) { 9087 pw.println(" mShuttingDown=" + mShuttingDown); 9088 } 9089 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9090 || mOrigWaitForDebugger) { 9091 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9092 + " mDebugTransient=" + mDebugTransient 9093 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9094 } 9095 if (mOpenGlTraceApp != null) { 9096 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9097 } 9098 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9099 || mProfileFd != null) { 9100 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9101 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9102 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9103 + mAutoStopProfiler); 9104 } 9105 if (mAlwaysFinishActivities || mController != null) { 9106 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9107 + " mController=" + mController); 9108 } 9109 if (dumpAll) { 9110 pw.println(" Total persistent processes: " + numPers); 9111 pw.println(" mStartRunning=" + mStartRunning 9112 + " mProcessesReady=" + mProcessesReady 9113 + " mSystemReady=" + mSystemReady); 9114 pw.println(" mBooting=" + mBooting 9115 + " mBooted=" + mBooted 9116 + " mFactoryTest=" + mFactoryTest); 9117 pw.print(" mLastPowerCheckRealtime="); 9118 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9119 pw.println(""); 9120 pw.print(" mLastPowerCheckUptime="); 9121 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9122 pw.println(""); 9123 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9124 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9125 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9126 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9127 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9128 } 9129 9130 return true; 9131 } 9132 9133 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9134 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9135 if (mProcessesToGc.size() > 0) { 9136 boolean printed = false; 9137 long now = SystemClock.uptimeMillis(); 9138 for (int i=0; i<mProcessesToGc.size(); i++) { 9139 ProcessRecord proc = mProcessesToGc.get(i); 9140 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9141 continue; 9142 } 9143 if (!printed) { 9144 if (needSep) pw.println(" "); 9145 needSep = true; 9146 pw.println(" Processes that are waiting to GC:"); 9147 printed = true; 9148 } 9149 pw.print(" Process "); pw.println(proc); 9150 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9151 pw.print(", last gced="); 9152 pw.print(now-proc.lastRequestedGc); 9153 pw.print(" ms ago, last lowMem="); 9154 pw.print(now-proc.lastLowMemory); 9155 pw.println(" ms ago"); 9156 9157 } 9158 } 9159 return needSep; 9160 } 9161 9162 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9163 int opti, boolean dumpAll) { 9164 boolean needSep = false; 9165 9166 if (mLruProcesses.size() > 0) { 9167 if (needSep) pw.println(" "); 9168 needSep = true; 9169 pw.println(" OOM levels:"); 9170 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9171 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9172 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9173 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9174 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9175 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9176 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9177 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9178 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9179 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9180 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9181 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9182 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9183 9184 if (needSep) pw.println(" "); 9185 needSep = true; 9186 pw.println(" Process OOM control:"); 9187 dumpProcessOomList(pw, this, mLruProcesses, " ", 9188 "Proc", "PERS", true, null); 9189 needSep = true; 9190 } 9191 9192 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9193 9194 pw.println(); 9195 pw.println(" mHomeProcess: " + mHomeProcess); 9196 pw.println(" mPreviousProcess: " + mPreviousProcess); 9197 if (mHeavyWeightProcess != null) { 9198 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9199 } 9200 9201 return true; 9202 } 9203 9204 /** 9205 * There are three ways to call this: 9206 * - no service specified: dump all the services 9207 * - a flattened component name that matched an existing service was specified as the 9208 * first arg: dump that one service 9209 * - the first arg isn't the flattened component name of an existing service: 9210 * dump all services whose component contains the first arg as a substring 9211 */ 9212 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9213 int opti, boolean dumpAll) { 9214 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 9215 9216 if ("all".equals(name)) { 9217 synchronized (this) { 9218 try { 9219 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9220 for (UserInfo user : users) { 9221 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9222 services.add(r1); 9223 } 9224 } 9225 } catch (RemoteException re) { 9226 } 9227 } 9228 } else { 9229 ComponentName componentName = name != null 9230 ? ComponentName.unflattenFromString(name) : null; 9231 int objectId = 0; 9232 if (componentName == null) { 9233 // Not a '/' separated full component name; maybe an object ID? 9234 try { 9235 objectId = Integer.parseInt(name, 16); 9236 name = null; 9237 componentName = null; 9238 } catch (RuntimeException e) { 9239 } 9240 } 9241 9242 synchronized (this) { 9243 try { 9244 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9245 for (UserInfo user : users) { 9246 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9247 if (componentName != null) { 9248 if (r1.name.equals(componentName)) { 9249 services.add(r1); 9250 } 9251 } else if (name != null) { 9252 if (r1.name.flattenToString().contains(name)) { 9253 services.add(r1); 9254 } 9255 } else if (System.identityHashCode(r1) == objectId) { 9256 services.add(r1); 9257 } 9258 } 9259 } 9260 } catch (RemoteException re) { 9261 } 9262 } 9263 } 9264 9265 if (services.size() <= 0) { 9266 return false; 9267 } 9268 9269 boolean needSep = false; 9270 for (int i=0; i<services.size(); i++) { 9271 if (needSep) { 9272 pw.println(); 9273 } 9274 needSep = true; 9275 dumpService("", fd, pw, services.get(i), args, dumpAll); 9276 } 9277 return true; 9278 } 9279 9280 /** 9281 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9282 * there is a thread associated with the service. 9283 */ 9284 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 9285 final ServiceRecord r, String[] args, boolean dumpAll) { 9286 String innerPrefix = prefix + " "; 9287 synchronized (this) { 9288 pw.print(prefix); pw.print("SERVICE "); 9289 pw.print(r.shortName); pw.print(" "); 9290 pw.print(Integer.toHexString(System.identityHashCode(r))); 9291 pw.print(" pid="); 9292 if (r.app != null) pw.println(r.app.pid); 9293 else pw.println("(not running)"); 9294 if (dumpAll) { 9295 r.dump(pw, innerPrefix); 9296 } 9297 } 9298 if (r.app != null && r.app.thread != null) { 9299 pw.print(prefix); pw.println(" Client:"); 9300 pw.flush(); 9301 try { 9302 TransferPipe tp = new TransferPipe(); 9303 try { 9304 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 9305 tp.setBufferPrefix(prefix + " "); 9306 tp.go(fd); 9307 } finally { 9308 tp.kill(); 9309 } 9310 } catch (IOException e) { 9311 pw.println(prefix + " Failure while dumping the service: " + e); 9312 } catch (RemoteException e) { 9313 pw.println(prefix + " Got a RemoteException while dumping the service"); 9314 } 9315 } 9316 } 9317 9318 /** 9319 * There are three ways to call this: 9320 * - no provider specified: dump all the providers 9321 * - a flattened component name that matched an existing provider was specified as the 9322 * first arg: dump that one provider 9323 * - the first arg isn't the flattened component name of an existing provider: 9324 * dump all providers whose component contains the first arg as a substring 9325 */ 9326 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9327 int opti, boolean dumpAll) { 9328 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9329 } 9330 9331 static class ItemMatcher { 9332 ArrayList<ComponentName> components; 9333 ArrayList<String> strings; 9334 ArrayList<Integer> objects; 9335 boolean all; 9336 9337 ItemMatcher() { 9338 all = true; 9339 } 9340 9341 void build(String name) { 9342 ComponentName componentName = ComponentName.unflattenFromString(name); 9343 if (componentName != null) { 9344 if (components == null) { 9345 components = new ArrayList<ComponentName>(); 9346 } 9347 components.add(componentName); 9348 all = false; 9349 } else { 9350 int objectId = 0; 9351 // Not a '/' separated full component name; maybe an object ID? 9352 try { 9353 objectId = Integer.parseInt(name, 16); 9354 if (objects == null) { 9355 objects = new ArrayList<Integer>(); 9356 } 9357 objects.add(objectId); 9358 all = false; 9359 } catch (RuntimeException e) { 9360 // Not an integer; just do string match. 9361 if (strings == null) { 9362 strings = new ArrayList<String>(); 9363 } 9364 strings.add(name); 9365 all = false; 9366 } 9367 } 9368 } 9369 9370 int build(String[] args, int opti) { 9371 for (; opti<args.length; opti++) { 9372 String name = args[opti]; 9373 if ("--".equals(name)) { 9374 return opti+1; 9375 } 9376 build(name); 9377 } 9378 return opti; 9379 } 9380 9381 boolean match(Object object, ComponentName comp) { 9382 if (all) { 9383 return true; 9384 } 9385 if (components != null) { 9386 for (int i=0; i<components.size(); i++) { 9387 if (components.get(i).equals(comp)) { 9388 return true; 9389 } 9390 } 9391 } 9392 if (objects != null) { 9393 for (int i=0; i<objects.size(); i++) { 9394 if (System.identityHashCode(object) == objects.get(i)) { 9395 return true; 9396 } 9397 } 9398 } 9399 if (strings != null) { 9400 String flat = comp.flattenToString(); 9401 for (int i=0; i<strings.size(); i++) { 9402 if (flat.contains(strings.get(i))) { 9403 return true; 9404 } 9405 } 9406 } 9407 return false; 9408 } 9409 } 9410 9411 /** 9412 * There are three things that cmd can be: 9413 * - a flattened component name that matches an existing activity 9414 * - the cmd arg isn't the flattened component name of an existing activity: 9415 * dump all activity whose component contains the cmd as a substring 9416 * - A hex number of the ActivityRecord object instance. 9417 */ 9418 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9419 int opti, boolean dumpAll) { 9420 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9421 9422 if ("all".equals(name)) { 9423 synchronized (this) { 9424 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9425 activities.add(r1); 9426 } 9427 } 9428 } else if ("top".equals(name)) { 9429 synchronized (this) { 9430 final int N = mMainStack.mHistory.size(); 9431 if (N > 0) { 9432 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9433 } 9434 } 9435 } else { 9436 ItemMatcher matcher = new ItemMatcher(); 9437 matcher.build(name); 9438 9439 synchronized (this) { 9440 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9441 if (matcher.match(r1, r1.intent.getComponent())) { 9442 activities.add(r1); 9443 } 9444 } 9445 } 9446 } 9447 9448 if (activities.size() <= 0) { 9449 return false; 9450 } 9451 9452 String[] newArgs = new String[args.length - opti]; 9453 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9454 9455 TaskRecord lastTask = null; 9456 boolean needSep = false; 9457 for (int i=activities.size()-1; i>=0; i--) { 9458 ActivityRecord r = (ActivityRecord)activities.get(i); 9459 if (needSep) { 9460 pw.println(); 9461 } 9462 needSep = true; 9463 synchronized (this) { 9464 if (lastTask != r.task) { 9465 lastTask = r.task; 9466 pw.print("TASK "); pw.print(lastTask.affinity); 9467 pw.print(" id="); pw.println(lastTask.taskId); 9468 if (dumpAll) { 9469 lastTask.dump(pw, " "); 9470 } 9471 } 9472 } 9473 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9474 } 9475 return true; 9476 } 9477 9478 /** 9479 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9480 * there is a thread associated with the activity. 9481 */ 9482 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9483 final ActivityRecord r, String[] args, boolean dumpAll) { 9484 String innerPrefix = prefix + " "; 9485 synchronized (this) { 9486 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9487 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9488 pw.print(" pid="); 9489 if (r.app != null) pw.println(r.app.pid); 9490 else pw.println("(not running)"); 9491 if (dumpAll) { 9492 r.dump(pw, innerPrefix); 9493 } 9494 } 9495 if (r.app != null && r.app.thread != null) { 9496 // flush anything that is already in the PrintWriter since the thread is going 9497 // to write to the file descriptor directly 9498 pw.flush(); 9499 try { 9500 TransferPipe tp = new TransferPipe(); 9501 try { 9502 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9503 r.appToken, innerPrefix, args); 9504 tp.go(fd); 9505 } finally { 9506 tp.kill(); 9507 } 9508 } catch (IOException e) { 9509 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9510 } catch (RemoteException e) { 9511 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9512 } 9513 } 9514 } 9515 9516 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9517 int opti, boolean dumpAll, String dumpPackage) { 9518 boolean needSep = false; 9519 9520 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9521 if (dumpAll) { 9522 if (mRegisteredReceivers.size() > 0) { 9523 boolean printed = false; 9524 Iterator it = mRegisteredReceivers.values().iterator(); 9525 while (it.hasNext()) { 9526 ReceiverList r = (ReceiverList)it.next(); 9527 if (dumpPackage != null && (r.app == null || 9528 !dumpPackage.equals(r.app.info.packageName))) { 9529 continue; 9530 } 9531 if (!printed) { 9532 pw.println(" Registered Receivers:"); 9533 needSep = true; 9534 printed = true; 9535 } 9536 pw.print(" * "); pw.println(r); 9537 r.dump(pw, " "); 9538 } 9539 } 9540 9541 if (mReceiverResolver.dump(pw, needSep ? 9542 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9543 " ", dumpPackage, false)) { 9544 needSep = true; 9545 } 9546 } 9547 9548 for (BroadcastQueue q : mBroadcastQueues) { 9549 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9550 } 9551 9552 needSep = true; 9553 9554 if (mStickyBroadcasts != null && dumpPackage == null) { 9555 if (needSep) { 9556 pw.println(); 9557 } 9558 needSep = true; 9559 pw.println(" Sticky broadcasts:"); 9560 StringBuilder sb = new StringBuilder(128); 9561 for (Map.Entry<String, ArrayList<Intent>> ent 9562 : mStickyBroadcasts.entrySet()) { 9563 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9564 if (dumpAll) { 9565 pw.println(":"); 9566 ArrayList<Intent> intents = ent.getValue(); 9567 final int N = intents.size(); 9568 for (int i=0; i<N; i++) { 9569 sb.setLength(0); 9570 sb.append(" Intent: "); 9571 intents.get(i).toShortString(sb, false, true, false, false); 9572 pw.println(sb.toString()); 9573 Bundle bundle = intents.get(i).getExtras(); 9574 if (bundle != null) { 9575 pw.print(" "); 9576 pw.println(bundle.toString()); 9577 } 9578 } 9579 } else { 9580 pw.println(""); 9581 } 9582 } 9583 needSep = true; 9584 } 9585 9586 if (dumpAll) { 9587 pw.println(); 9588 for (BroadcastQueue queue : mBroadcastQueues) { 9589 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9590 + queue.mBroadcastsScheduled); 9591 } 9592 pw.println(" mHandler:"); 9593 mHandler.dump(new PrintWriterPrinter(pw), " "); 9594 needSep = true; 9595 } 9596 9597 return needSep; 9598 } 9599 9600 /** 9601 * Prints a list of ServiceRecords (dumpsys activity services) 9602 */ 9603 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9604 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9605 boolean needSep = false; 9606 9607 ItemMatcher matcher = new ItemMatcher(); 9608 matcher.build(args, opti); 9609 9610 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 9611 try { 9612 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9613 for (UserInfo user : users) { 9614 if (mServiceMap.getAllServices(user.id).size() > 0) { 9615 boolean printed = false; 9616 long nowReal = SystemClock.elapsedRealtime(); 9617 Iterator<ServiceRecord> it = mServiceMap.getAllServices( 9618 user.id).iterator(); 9619 needSep = false; 9620 while (it.hasNext()) { 9621 ServiceRecord r = it.next(); 9622 if (!matcher.match(r, r.name)) { 9623 continue; 9624 } 9625 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9626 continue; 9627 } 9628 if (!printed) { 9629 pw.println(" Active services:"); 9630 printed = true; 9631 } 9632 if (needSep) { 9633 pw.println(); 9634 } 9635 pw.print(" * "); 9636 pw.println(r); 9637 if (dumpAll) { 9638 r.dump(pw, " "); 9639 needSep = true; 9640 } else { 9641 pw.print(" app="); 9642 pw.println(r.app); 9643 pw.print(" created="); 9644 TimeUtils.formatDuration(r.createTime, nowReal, pw); 9645 pw.print(" started="); 9646 pw.print(r.startRequested); 9647 pw.print(" connections="); 9648 pw.println(r.connections.size()); 9649 if (r.connections.size() > 0) { 9650 pw.println(" Connections:"); 9651 for (ArrayList<ConnectionRecord> clist : r.connections.values()) { 9652 for (int i = 0; i < clist.size(); i++) { 9653 ConnectionRecord conn = clist.get(i); 9654 pw.print(" "); 9655 pw.print(conn.binding.intent.intent.getIntent() 9656 .toShortString(false, false, false, false)); 9657 pw.print(" -> "); 9658 ProcessRecord proc = conn.binding.client; 9659 pw.println(proc != null ? proc.toShortString() : "null"); 9660 } 9661 } 9662 } 9663 } 9664 if (dumpClient && r.app != null && r.app.thread != null) { 9665 pw.println(" Client:"); 9666 pw.flush(); 9667 try { 9668 TransferPipe tp = new TransferPipe(); 9669 try { 9670 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), 9671 r, args); 9672 tp.setBufferPrefix(" "); 9673 // Short timeout, since blocking here can 9674 // deadlock with the application. 9675 tp.go(fd, 2000); 9676 } finally { 9677 tp.kill(); 9678 } 9679 } catch (IOException e) { 9680 pw.println(" Failure while dumping the service: " + e); 9681 } catch (RemoteException e) { 9682 pw.println(" Got a RemoteException while dumping the service"); 9683 } 9684 needSep = true; 9685 } 9686 } 9687 needSep = printed; 9688 } 9689 } 9690 } catch (RemoteException re) { 9691 9692 } 9693 9694 if (mPendingServices.size() > 0) { 9695 boolean printed = false; 9696 for (int i=0; i<mPendingServices.size(); i++) { 9697 ServiceRecord r = mPendingServices.get(i); 9698 if (!matcher.match(r, r.name)) { 9699 continue; 9700 } 9701 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9702 continue; 9703 } 9704 if (!printed) { 9705 if (needSep) pw.println(" "); 9706 needSep = true; 9707 pw.println(" Pending services:"); 9708 printed = true; 9709 } 9710 pw.print(" * Pending "); pw.println(r); 9711 r.dump(pw, " "); 9712 } 9713 needSep = true; 9714 } 9715 9716 if (mRestartingServices.size() > 0) { 9717 boolean printed = false; 9718 for (int i=0; i<mRestartingServices.size(); i++) { 9719 ServiceRecord r = mRestartingServices.get(i); 9720 if (!matcher.match(r, r.name)) { 9721 continue; 9722 } 9723 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9724 continue; 9725 } 9726 if (!printed) { 9727 if (needSep) pw.println(" "); 9728 needSep = true; 9729 pw.println(" Restarting services:"); 9730 printed = true; 9731 } 9732 pw.print(" * Restarting "); pw.println(r); 9733 r.dump(pw, " "); 9734 } 9735 needSep = true; 9736 } 9737 9738 if (mStoppingServices.size() > 0) { 9739 boolean printed = false; 9740 for (int i=0; i<mStoppingServices.size(); i++) { 9741 ServiceRecord r = mStoppingServices.get(i); 9742 if (!matcher.match(r, r.name)) { 9743 continue; 9744 } 9745 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9746 continue; 9747 } 9748 if (!printed) { 9749 if (needSep) pw.println(" "); 9750 needSep = true; 9751 pw.println(" Stopping services:"); 9752 printed = true; 9753 } 9754 pw.print(" * Stopping "); pw.println(r); 9755 r.dump(pw, " "); 9756 } 9757 needSep = true; 9758 } 9759 9760 if (dumpAll) { 9761 if (mServiceConnections.size() > 0) { 9762 boolean printed = false; 9763 Iterator<ArrayList<ConnectionRecord>> it 9764 = mServiceConnections.values().iterator(); 9765 while (it.hasNext()) { 9766 ArrayList<ConnectionRecord> r = it.next(); 9767 for (int i=0; i<r.size(); i++) { 9768 ConnectionRecord cr = r.get(i); 9769 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 9770 continue; 9771 } 9772 if (dumpPackage != null && (cr.binding.client == null 9773 || !dumpPackage.equals(cr.binding.client.info.packageName))) { 9774 continue; 9775 } 9776 if (!printed) { 9777 if (needSep) pw.println(" "); 9778 needSep = true; 9779 pw.println(" Connection bindings to services:"); 9780 printed = true; 9781 } 9782 pw.print(" * "); pw.println(cr); 9783 cr.dump(pw, " "); 9784 } 9785 } 9786 needSep = true; 9787 } 9788 } 9789 9790 return needSep; 9791 } 9792 9793 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9794 int opti, boolean dumpAll, String dumpPackage) { 9795 boolean needSep = true; 9796 9797 ItemMatcher matcher = new ItemMatcher(); 9798 matcher.build(args, opti); 9799 9800 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9801 9802 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9803 9804 if (mLaunchingProviders.size() > 0) { 9805 boolean printed = false; 9806 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9807 ContentProviderRecord r = mLaunchingProviders.get(i); 9808 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9809 continue; 9810 } 9811 if (!printed) { 9812 if (needSep) pw.println(" "); 9813 needSep = true; 9814 pw.println(" Launching content providers:"); 9815 printed = true; 9816 } 9817 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9818 pw.println(r); 9819 } 9820 } 9821 9822 if (mGrantedUriPermissions.size() > 0) { 9823 if (needSep) pw.println(); 9824 needSep = true; 9825 pw.println("Granted Uri Permissions:"); 9826 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9827 int uid = mGrantedUriPermissions.keyAt(i); 9828 HashMap<Uri, UriPermission> perms 9829 = mGrantedUriPermissions.valueAt(i); 9830 pw.print(" * UID "); pw.print(uid); 9831 pw.println(" holds:"); 9832 for (UriPermission perm : perms.values()) { 9833 pw.print(" "); pw.println(perm); 9834 if (dumpAll) { 9835 perm.dump(pw, " "); 9836 } 9837 } 9838 } 9839 needSep = true; 9840 } 9841 9842 return needSep; 9843 } 9844 9845 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9846 int opti, boolean dumpAll, String dumpPackage) { 9847 boolean needSep = false; 9848 9849 if (mIntentSenderRecords.size() > 0) { 9850 boolean printed = false; 9851 Iterator<WeakReference<PendingIntentRecord>> it 9852 = mIntentSenderRecords.values().iterator(); 9853 while (it.hasNext()) { 9854 WeakReference<PendingIntentRecord> ref = it.next(); 9855 PendingIntentRecord rec = ref != null ? ref.get(): null; 9856 if (dumpPackage != null && (rec == null 9857 || !dumpPackage.equals(rec.key.packageName))) { 9858 continue; 9859 } 9860 if (!printed) { 9861 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9862 printed = true; 9863 } 9864 needSep = true; 9865 if (rec != null) { 9866 pw.print(" * "); pw.println(rec); 9867 if (dumpAll) { 9868 rec.dump(pw, " "); 9869 } 9870 } else { 9871 pw.print(" * "); pw.println(ref); 9872 } 9873 } 9874 } 9875 9876 return needSep; 9877 } 9878 9879 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9880 String prefix, String label, boolean complete, boolean brief, boolean client, 9881 String dumpPackage) { 9882 TaskRecord lastTask = null; 9883 boolean needNL = false; 9884 final String innerPrefix = prefix + " "; 9885 final String[] args = new String[0]; 9886 for (int i=list.size()-1; i>=0; i--) { 9887 final ActivityRecord r = (ActivityRecord)list.get(i); 9888 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9889 continue; 9890 } 9891 final boolean full = !brief && (complete || !r.isInHistory()); 9892 if (needNL) { 9893 pw.println(" "); 9894 needNL = false; 9895 } 9896 if (lastTask != r.task) { 9897 lastTask = r.task; 9898 pw.print(prefix); 9899 pw.print(full ? "* " : " "); 9900 pw.println(lastTask); 9901 if (full) { 9902 lastTask.dump(pw, prefix + " "); 9903 } else if (complete) { 9904 // Complete + brief == give a summary. Isn't that obvious?!? 9905 if (lastTask.intent != null) { 9906 pw.print(prefix); pw.print(" "); 9907 pw.println(lastTask.intent.toInsecureStringWithClip()); 9908 } 9909 } 9910 } 9911 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9912 pw.print(" #"); pw.print(i); pw.print(": "); 9913 pw.println(r); 9914 if (full) { 9915 r.dump(pw, innerPrefix); 9916 } else if (complete) { 9917 // Complete + brief == give a summary. Isn't that obvious?!? 9918 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9919 if (r.app != null) { 9920 pw.print(innerPrefix); pw.println(r.app); 9921 } 9922 } 9923 if (client && r.app != null && r.app.thread != null) { 9924 // flush anything that is already in the PrintWriter since the thread is going 9925 // to write to the file descriptor directly 9926 pw.flush(); 9927 try { 9928 TransferPipe tp = new TransferPipe(); 9929 try { 9930 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9931 r.appToken, innerPrefix, args); 9932 // Short timeout, since blocking here can 9933 // deadlock with the application. 9934 tp.go(fd, 2000); 9935 } finally { 9936 tp.kill(); 9937 } 9938 } catch (IOException e) { 9939 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9940 } catch (RemoteException e) { 9941 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9942 } 9943 needNL = true; 9944 } 9945 } 9946 } 9947 9948 private static String buildOomTag(String prefix, String space, int val, int base) { 9949 if (val == base) { 9950 if (space == null) return prefix; 9951 return prefix + " "; 9952 } 9953 return prefix + "+" + Integer.toString(val-base); 9954 } 9955 9956 private static final int dumpProcessList(PrintWriter pw, 9957 ActivityManagerService service, List list, 9958 String prefix, String normalLabel, String persistentLabel, 9959 String dumpPackage) { 9960 int numPers = 0; 9961 final int N = list.size()-1; 9962 for (int i=N; i>=0; i--) { 9963 ProcessRecord r = (ProcessRecord)list.get(i); 9964 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9965 continue; 9966 } 9967 pw.println(String.format("%s%s #%2d: %s", 9968 prefix, (r.persistent ? persistentLabel : normalLabel), 9969 i, r.toString())); 9970 if (r.persistent) { 9971 numPers++; 9972 } 9973 } 9974 return numPers; 9975 } 9976 9977 private static final boolean dumpProcessOomList(PrintWriter pw, 9978 ActivityManagerService service, List<ProcessRecord> origList, 9979 String prefix, String normalLabel, String persistentLabel, 9980 boolean inclDetails, String dumpPackage) { 9981 9982 ArrayList<Pair<ProcessRecord, Integer>> list 9983 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9984 for (int i=0; i<origList.size(); i++) { 9985 ProcessRecord r = origList.get(i); 9986 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9987 continue; 9988 } 9989 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9990 } 9991 9992 if (list.size() <= 0) { 9993 return false; 9994 } 9995 9996 Comparator<Pair<ProcessRecord, Integer>> comparator 9997 = new Comparator<Pair<ProcessRecord, Integer>>() { 9998 @Override 9999 public int compare(Pair<ProcessRecord, Integer> object1, 10000 Pair<ProcessRecord, Integer> object2) { 10001 if (object1.first.setAdj != object2.first.setAdj) { 10002 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10003 } 10004 if (object1.second.intValue() != object2.second.intValue()) { 10005 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10006 } 10007 return 0; 10008 } 10009 }; 10010 10011 Collections.sort(list, comparator); 10012 10013 final long curRealtime = SystemClock.elapsedRealtime(); 10014 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10015 final long curUptime = SystemClock.uptimeMillis(); 10016 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10017 10018 for (int i=list.size()-1; i>=0; i--) { 10019 ProcessRecord r = list.get(i).first; 10020 String oomAdj; 10021 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10022 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10023 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10024 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10025 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10026 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10027 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10028 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10029 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10030 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10031 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10032 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10033 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10034 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10035 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10036 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10037 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10038 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10039 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10040 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10041 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10042 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10043 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10044 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10045 } else { 10046 oomAdj = Integer.toString(r.setAdj); 10047 } 10048 String schedGroup; 10049 switch (r.setSchedGroup) { 10050 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10051 schedGroup = "B"; 10052 break; 10053 case Process.THREAD_GROUP_DEFAULT: 10054 schedGroup = "F"; 10055 break; 10056 default: 10057 schedGroup = Integer.toString(r.setSchedGroup); 10058 break; 10059 } 10060 String foreground; 10061 if (r.foregroundActivities) { 10062 foreground = "A"; 10063 } else if (r.foregroundServices) { 10064 foreground = "S"; 10065 } else { 10066 foreground = " "; 10067 } 10068 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10069 prefix, (r.persistent ? persistentLabel : normalLabel), 10070 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10071 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10072 if (r.adjSource != null || r.adjTarget != null) { 10073 pw.print(prefix); 10074 pw.print(" "); 10075 if (r.adjTarget instanceof ComponentName) { 10076 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10077 } else if (r.adjTarget != null) { 10078 pw.print(r.adjTarget.toString()); 10079 } else { 10080 pw.print("{null}"); 10081 } 10082 pw.print("<="); 10083 if (r.adjSource instanceof ProcessRecord) { 10084 pw.print("Proc{"); 10085 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10086 pw.println("}"); 10087 } else if (r.adjSource != null) { 10088 pw.println(r.adjSource.toString()); 10089 } else { 10090 pw.println("{null}"); 10091 } 10092 } 10093 if (inclDetails) { 10094 pw.print(prefix); 10095 pw.print(" "); 10096 pw.print("oom: max="); pw.print(r.maxAdj); 10097 pw.print(" hidden="); pw.print(r.hiddenAdj); 10098 pw.print(" curRaw="); pw.print(r.curRawAdj); 10099 pw.print(" setRaw="); pw.print(r.setRawAdj); 10100 pw.print(" cur="); pw.print(r.curAdj); 10101 pw.print(" set="); pw.println(r.setAdj); 10102 pw.print(prefix); 10103 pw.print(" "); 10104 pw.print("keeping="); pw.print(r.keeping); 10105 pw.print(" hidden="); pw.print(r.hidden); 10106 pw.print(" empty="); pw.print(r.empty); 10107 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10108 10109 if (!r.keeping) { 10110 if (r.lastWakeTime != 0) { 10111 long wtime; 10112 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10113 synchronized (stats) { 10114 wtime = stats.getProcessWakeTime(r.info.uid, 10115 r.pid, curRealtime); 10116 } 10117 long timeUsed = wtime - r.lastWakeTime; 10118 pw.print(prefix); 10119 pw.print(" "); 10120 pw.print("keep awake over "); 10121 TimeUtils.formatDuration(realtimeSince, pw); 10122 pw.print(" used "); 10123 TimeUtils.formatDuration(timeUsed, pw); 10124 pw.print(" ("); 10125 pw.print((timeUsed*100)/realtimeSince); 10126 pw.println("%)"); 10127 } 10128 if (r.lastCpuTime != 0) { 10129 long timeUsed = r.curCpuTime - r.lastCpuTime; 10130 pw.print(prefix); 10131 pw.print(" "); 10132 pw.print("run cpu over "); 10133 TimeUtils.formatDuration(uptimeSince, pw); 10134 pw.print(" used "); 10135 TimeUtils.formatDuration(timeUsed, pw); 10136 pw.print(" ("); 10137 pw.print((timeUsed*100)/uptimeSince); 10138 pw.println("%)"); 10139 } 10140 } 10141 } 10142 } 10143 return true; 10144 } 10145 10146 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10147 ArrayList<ProcessRecord> procs; 10148 synchronized (this) { 10149 if (args != null && args.length > start 10150 && args[start].charAt(0) != '-') { 10151 procs = new ArrayList<ProcessRecord>(); 10152 int pid = -1; 10153 try { 10154 pid = Integer.parseInt(args[start]); 10155 } catch (NumberFormatException e) { 10156 10157 } 10158 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10159 ProcessRecord proc = mLruProcesses.get(i); 10160 if (proc.pid == pid) { 10161 procs.add(proc); 10162 } else if (proc.processName.equals(args[start])) { 10163 procs.add(proc); 10164 } 10165 } 10166 if (procs.size() <= 0) { 10167 pw.println("No process found for: " + args[start]); 10168 return null; 10169 } 10170 } else { 10171 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10172 } 10173 } 10174 return procs; 10175 } 10176 10177 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10178 PrintWriter pw, String[] args) { 10179 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10180 if (procs == null) { 10181 return; 10182 } 10183 10184 long uptime = SystemClock.uptimeMillis(); 10185 long realtime = SystemClock.elapsedRealtime(); 10186 pw.println("Applications Graphics Acceleration Info:"); 10187 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10188 10189 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10190 ProcessRecord r = procs.get(i); 10191 if (r.thread != null) { 10192 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10193 pw.flush(); 10194 try { 10195 TransferPipe tp = new TransferPipe(); 10196 try { 10197 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10198 tp.go(fd); 10199 } finally { 10200 tp.kill(); 10201 } 10202 } catch (IOException e) { 10203 pw.println("Failure while dumping the app: " + r); 10204 pw.flush(); 10205 } catch (RemoteException e) { 10206 pw.println("Got a RemoteException while dumping the app " + r); 10207 pw.flush(); 10208 } 10209 } 10210 } 10211 } 10212 10213 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10214 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10215 if (procs == null) { 10216 return; 10217 } 10218 10219 pw.println("Applications Database Info:"); 10220 10221 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10222 ProcessRecord r = procs.get(i); 10223 if (r.thread != null) { 10224 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10225 pw.flush(); 10226 try { 10227 TransferPipe tp = new TransferPipe(); 10228 try { 10229 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10230 tp.go(fd); 10231 } finally { 10232 tp.kill(); 10233 } 10234 } catch (IOException e) { 10235 pw.println("Failure while dumping the app: " + r); 10236 pw.flush(); 10237 } catch (RemoteException e) { 10238 pw.println("Got a RemoteException while dumping the app " + r); 10239 pw.flush(); 10240 } 10241 } 10242 } 10243 } 10244 10245 final static class MemItem { 10246 final String label; 10247 final String shortLabel; 10248 final long pss; 10249 final int id; 10250 ArrayList<MemItem> subitems; 10251 10252 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10253 label = _label; 10254 shortLabel = _shortLabel; 10255 pss = _pss; 10256 id = _id; 10257 } 10258 } 10259 10260 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10261 boolean sort) { 10262 if (sort) { 10263 Collections.sort(items, new Comparator<MemItem>() { 10264 @Override 10265 public int compare(MemItem lhs, MemItem rhs) { 10266 if (lhs.pss < rhs.pss) { 10267 return 1; 10268 } else if (lhs.pss > rhs.pss) { 10269 return -1; 10270 } 10271 return 0; 10272 } 10273 }); 10274 } 10275 10276 for (int i=0; i<items.size(); i++) { 10277 MemItem mi = items.get(i); 10278 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10279 if (mi.subitems != null) { 10280 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10281 } 10282 } 10283 } 10284 10285 // These are in KB. 10286 static final long[] DUMP_MEM_BUCKETS = new long[] { 10287 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10288 120*1024, 160*1024, 200*1024, 10289 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10290 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10291 }; 10292 10293 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10294 boolean stackLike) { 10295 int start = label.lastIndexOf('.'); 10296 if (start >= 0) start++; 10297 else start = 0; 10298 int end = label.length(); 10299 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10300 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10301 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10302 out.append(bucket); 10303 out.append(stackLike ? "MB." : "MB "); 10304 out.append(label, start, end); 10305 return; 10306 } 10307 } 10308 out.append(memKB/1024); 10309 out.append(stackLike ? "MB." : "MB "); 10310 out.append(label, start, end); 10311 } 10312 10313 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10314 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10315 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10316 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10317 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10318 }; 10319 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10320 "System", "Persistent", "Foreground", 10321 "Visible", "Perceptible", "Heavy Weight", 10322 "Backup", "A Services", "Home", "Previous", 10323 "B Services", "Background" 10324 }; 10325 10326 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10327 PrintWriter pw, String prefix, String[] args, boolean brief, 10328 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10329 boolean dumpAll = false; 10330 boolean oomOnly = false; 10331 10332 int opti = 0; 10333 while (opti < args.length) { 10334 String opt = args[opti]; 10335 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10336 break; 10337 } 10338 opti++; 10339 if ("-a".equals(opt)) { 10340 dumpAll = true; 10341 } else if ("--oom".equals(opt)) { 10342 oomOnly = true; 10343 } else if ("-h".equals(opt)) { 10344 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10345 pw.println(" -a: include all available information for each process."); 10346 pw.println(" --oom: only show processes organized by oom adj."); 10347 pw.println("If [process] is specified it can be the name or "); 10348 pw.println("pid of a specific process to dump."); 10349 return; 10350 } else { 10351 pw.println("Unknown argument: " + opt + "; use -h for help"); 10352 } 10353 } 10354 10355 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10356 if (procs == null) { 10357 return; 10358 } 10359 10360 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10361 long uptime = SystemClock.uptimeMillis(); 10362 long realtime = SystemClock.elapsedRealtime(); 10363 10364 if (procs.size() == 1 || isCheckinRequest) { 10365 dumpAll = true; 10366 } 10367 10368 if (isCheckinRequest) { 10369 // short checkin version 10370 pw.println(uptime + "," + realtime); 10371 pw.flush(); 10372 } else { 10373 pw.println("Applications Memory Usage (kB):"); 10374 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10375 } 10376 10377 String[] innerArgs = new String[args.length-opti]; 10378 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10379 10380 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10381 long nativePss=0, dalvikPss=0, otherPss=0; 10382 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10383 10384 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10385 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10386 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10387 10388 long totalPss = 0; 10389 10390 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10391 ProcessRecord r = procs.get(i); 10392 if (r.thread != null) { 10393 if (!isCheckinRequest && dumpAll) { 10394 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10395 pw.flush(); 10396 } 10397 Debug.MemoryInfo mi = null; 10398 if (dumpAll) { 10399 try { 10400 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10401 } catch (RemoteException e) { 10402 if (!isCheckinRequest) { 10403 pw.println("Got RemoteException!"); 10404 pw.flush(); 10405 } 10406 } 10407 } else { 10408 mi = new Debug.MemoryInfo(); 10409 Debug.getMemoryInfo(r.pid, mi); 10410 } 10411 10412 if (!isCheckinRequest && mi != null) { 10413 long myTotalPss = mi.getTotalPss(); 10414 totalPss += myTotalPss; 10415 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10416 r.processName, myTotalPss, 0); 10417 procMems.add(pssItem); 10418 10419 nativePss += mi.nativePss; 10420 dalvikPss += mi.dalvikPss; 10421 otherPss += mi.otherPss; 10422 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10423 long mem = mi.getOtherPss(j); 10424 miscPss[j] += mem; 10425 otherPss -= mem; 10426 } 10427 10428 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10429 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10430 || oomIndex == (oomPss.length-1)) { 10431 oomPss[oomIndex] += myTotalPss; 10432 if (oomProcs[oomIndex] == null) { 10433 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10434 } 10435 oomProcs[oomIndex].add(pssItem); 10436 break; 10437 } 10438 } 10439 } 10440 } 10441 } 10442 10443 if (!isCheckinRequest && procs.size() > 1) { 10444 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10445 10446 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10447 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10448 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10449 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10450 String label = Debug.MemoryInfo.getOtherLabel(j); 10451 catMems.add(new MemItem(label, label, miscPss[j], j)); 10452 } 10453 10454 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10455 for (int j=0; j<oomPss.length; j++) { 10456 if (oomPss[j] != 0) { 10457 String label = DUMP_MEM_OOM_LABEL[j]; 10458 MemItem item = new MemItem(label, label, oomPss[j], 10459 DUMP_MEM_OOM_ADJ[j]); 10460 item.subitems = oomProcs[j]; 10461 oomMems.add(item); 10462 } 10463 } 10464 10465 if (outTag != null || outStack != null) { 10466 if (outTag != null) { 10467 appendMemBucket(outTag, totalPss, "total", false); 10468 } 10469 if (outStack != null) { 10470 appendMemBucket(outStack, totalPss, "total", true); 10471 } 10472 boolean firstLine = true; 10473 for (int i=0; i<oomMems.size(); i++) { 10474 MemItem miCat = oomMems.get(i); 10475 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10476 continue; 10477 } 10478 if (miCat.id < ProcessList.SERVICE_ADJ 10479 || miCat.id == ProcessList.HOME_APP_ADJ 10480 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10481 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10482 outTag.append(" / "); 10483 } 10484 if (outStack != null) { 10485 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10486 if (firstLine) { 10487 outStack.append(":"); 10488 firstLine = false; 10489 } 10490 outStack.append("\n\t at "); 10491 } else { 10492 outStack.append("$"); 10493 } 10494 } 10495 for (int j=0; j<miCat.subitems.size(); j++) { 10496 MemItem mi = miCat.subitems.get(j); 10497 if (j > 0) { 10498 if (outTag != null) { 10499 outTag.append(" "); 10500 } 10501 if (outStack != null) { 10502 outStack.append("$"); 10503 } 10504 } 10505 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10506 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10507 } 10508 if (outStack != null) { 10509 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10510 } 10511 } 10512 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10513 outStack.append("("); 10514 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10515 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10516 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10517 outStack.append(":"); 10518 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10519 } 10520 } 10521 outStack.append(")"); 10522 } 10523 } 10524 } 10525 } 10526 10527 if (!brief && !oomOnly) { 10528 pw.println(); 10529 pw.println("Total PSS by process:"); 10530 dumpMemItems(pw, " ", procMems, true); 10531 pw.println(); 10532 } 10533 pw.println("Total PSS by OOM adjustment:"); 10534 dumpMemItems(pw, " ", oomMems, false); 10535 if (!oomOnly) { 10536 PrintWriter out = categoryPw != null ? categoryPw : pw; 10537 out.println(); 10538 out.println("Total PSS by category:"); 10539 dumpMemItems(out, " ", catMems, true); 10540 } 10541 pw.println(); 10542 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10543 final int[] SINGLE_LONG_FORMAT = new int[] { 10544 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10545 }; 10546 long[] longOut = new long[1]; 10547 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10548 SINGLE_LONG_FORMAT, null, longOut, null); 10549 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10550 longOut[0] = 0; 10551 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10552 SINGLE_LONG_FORMAT, null, longOut, null); 10553 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10554 longOut[0] = 0; 10555 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10556 SINGLE_LONG_FORMAT, null, longOut, null); 10557 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10558 longOut[0] = 0; 10559 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10560 SINGLE_LONG_FORMAT, null, longOut, null); 10561 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10562 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10563 pw.print(shared); pw.println(" kB"); 10564 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10565 pw.print(voltile); pw.println(" kB volatile"); 10566 } 10567 } 10568 10569 /** 10570 * Searches array of arguments for the specified string 10571 * @param args array of argument strings 10572 * @param value value to search for 10573 * @return true if the value is contained in the array 10574 */ 10575 private static boolean scanArgs(String[] args, String value) { 10576 if (args != null) { 10577 for (String arg : args) { 10578 if (value.equals(arg)) { 10579 return true; 10580 } 10581 } 10582 } 10583 return false; 10584 } 10585 10586 private final void killServicesLocked(ProcessRecord app, 10587 boolean allowRestart) { 10588 // Report disconnected services. 10589 if (false) { 10590 // XXX we are letting the client link to the service for 10591 // death notifications. 10592 if (app.services.size() > 0) { 10593 Iterator<ServiceRecord> it = app.services.iterator(); 10594 while (it.hasNext()) { 10595 ServiceRecord r = it.next(); 10596 if (r.connections.size() > 0) { 10597 Iterator<ArrayList<ConnectionRecord>> jt 10598 = r.connections.values().iterator(); 10599 while (jt.hasNext()) { 10600 ArrayList<ConnectionRecord> cl = jt.next(); 10601 for (int i=0; i<cl.size(); i++) { 10602 ConnectionRecord c = cl.get(i); 10603 if (c.binding.client != app) { 10604 try { 10605 //c.conn.connected(r.className, null); 10606 } catch (Exception e) { 10607 // todo: this should be asynchronous! 10608 Slog.w(TAG, "Exception thrown disconnected servce " 10609 + r.shortName 10610 + " from app " + app.processName, e); 10611 } 10612 } 10613 } 10614 } 10615 } 10616 } 10617 } 10618 } 10619 10620 // Clean up any connections this application has to other services. 10621 if (app.connections.size() > 0) { 10622 Iterator<ConnectionRecord> it = app.connections.iterator(); 10623 while (it.hasNext()) { 10624 ConnectionRecord r = it.next(); 10625 removeConnectionLocked(r, app, null); 10626 } 10627 } 10628 app.connections.clear(); 10629 10630 if (app.services.size() != 0) { 10631 // Any services running in the application need to be placed 10632 // back in the pending list. 10633 Iterator<ServiceRecord> it = app.services.iterator(); 10634 while (it.hasNext()) { 10635 ServiceRecord sr = it.next(); 10636 synchronized (sr.stats.getBatteryStats()) { 10637 sr.stats.stopLaunchedLocked(); 10638 } 10639 sr.app = null; 10640 sr.isolatedProc = null; 10641 sr.executeNesting = 0; 10642 if (mStoppingServices.remove(sr)) { 10643 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10644 } 10645 10646 boolean hasClients = sr.bindings.size() > 0; 10647 if (hasClients) { 10648 Iterator<IntentBindRecord> bindings 10649 = sr.bindings.values().iterator(); 10650 while (bindings.hasNext()) { 10651 IntentBindRecord b = bindings.next(); 10652 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10653 + ": shouldUnbind=" + b.hasBound); 10654 b.binder = null; 10655 b.requested = b.received = b.hasBound = false; 10656 } 10657 } 10658 10659 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 10660 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 10661 Slog.w(TAG, "Service crashed " + sr.crashCount 10662 + " times, stopping: " + sr); 10663 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10664 sr.crashCount, sr.shortName, app.pid); 10665 bringDownServiceLocked(sr, true); 10666 } else if (!allowRestart) { 10667 bringDownServiceLocked(sr, true); 10668 } else { 10669 boolean canceled = scheduleServiceRestartLocked(sr, true); 10670 10671 // Should the service remain running? Note that in the 10672 // extreme case of so many attempts to deliver a command 10673 // that it failed we also will stop it here. 10674 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10675 if (sr.pendingStarts.size() == 0) { 10676 sr.startRequested = false; 10677 if (!hasClients) { 10678 // Whoops, no reason to restart! 10679 bringDownServiceLocked(sr, true); 10680 } 10681 } 10682 } 10683 } 10684 } 10685 10686 if (!allowRestart) { 10687 app.services.clear(); 10688 } 10689 } 10690 10691 // Make sure we have no more records on the stopping list. 10692 int i = mStoppingServices.size(); 10693 while (i > 0) { 10694 i--; 10695 ServiceRecord sr = mStoppingServices.get(i); 10696 if (sr.app == app) { 10697 mStoppingServices.remove(i); 10698 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10699 } 10700 } 10701 10702 app.executingServices.clear(); 10703 } 10704 10705 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10706 ContentProviderRecord cpr, boolean always) { 10707 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10708 10709 if (!inLaunching || always) { 10710 synchronized (cpr) { 10711 cpr.launchingApp = null; 10712 cpr.notifyAll(); 10713 } 10714 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10715 String names[] = cpr.info.authority.split(";"); 10716 for (int j = 0; j < names.length; j++) { 10717 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10718 } 10719 } 10720 10721 for (int i=0; i<cpr.connections.size(); i++) { 10722 ContentProviderConnection conn = cpr.connections.get(i); 10723 if (conn.waiting) { 10724 // If this connection is waiting for the provider, then we don't 10725 // need to mess with its process unless we are always removing 10726 // or for some reason the provider is not currently launching. 10727 if (inLaunching && !always) { 10728 continue; 10729 } 10730 } 10731 ProcessRecord capp = conn.client; 10732 conn.dead = true; 10733 if (conn.stableCount > 0) { 10734 if (!capp.persistent && capp.thread != null 10735 && capp.pid != 0 10736 && capp.pid != MY_PID) { 10737 Slog.i(TAG, "Kill " + capp.processName 10738 + " (pid " + capp.pid + "): provider " + cpr.info.name 10739 + " in dying process " + (proc != null ? proc.processName : "??")); 10740 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10741 capp.processName, capp.setAdj, "dying provider " 10742 + cpr.name.toShortString()); 10743 Process.killProcessQuiet(capp.pid); 10744 } 10745 } else if (capp.thread != null && conn.provider.provider != null) { 10746 try { 10747 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10748 } catch (RemoteException e) { 10749 } 10750 // In the protocol here, we don't expect the client to correctly 10751 // clean up this connection, we'll just remove it. 10752 cpr.connections.remove(i); 10753 conn.client.conProviders.remove(conn); 10754 } 10755 } 10756 10757 if (inLaunching && always) { 10758 mLaunchingProviders.remove(cpr); 10759 } 10760 return inLaunching; 10761 } 10762 10763 /** 10764 * Main code for cleaning up a process when it has gone away. This is 10765 * called both as a result of the process dying, or directly when stopping 10766 * a process when running in single process mode. 10767 */ 10768 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10769 boolean restarting, boolean allowRestart, int index) { 10770 if (index >= 0) { 10771 mLruProcesses.remove(index); 10772 } 10773 10774 mProcessesToGc.remove(app); 10775 10776 // Dismiss any open dialogs. 10777 if (app.crashDialog != null) { 10778 app.crashDialog.dismiss(); 10779 app.crashDialog = null; 10780 } 10781 if (app.anrDialog != null) { 10782 app.anrDialog.dismiss(); 10783 app.anrDialog = null; 10784 } 10785 if (app.waitDialog != null) { 10786 app.waitDialog.dismiss(); 10787 app.waitDialog = null; 10788 } 10789 10790 app.crashing = false; 10791 app.notResponding = false; 10792 10793 app.resetPackageList(); 10794 app.unlinkDeathRecipient(); 10795 app.thread = null; 10796 app.forcingToForeground = null; 10797 app.foregroundServices = false; 10798 app.foregroundActivities = false; 10799 app.hasShownUi = false; 10800 app.hasAboveClient = false; 10801 10802 killServicesLocked(app, allowRestart); 10803 10804 boolean restart = false; 10805 10806 // Remove published content providers. 10807 if (!app.pubProviders.isEmpty()) { 10808 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10809 while (it.hasNext()) { 10810 ContentProviderRecord cpr = it.next(); 10811 10812 final boolean always = app.bad || !allowRestart; 10813 if (removeDyingProviderLocked(app, cpr, always) || always) { 10814 // We left the provider in the launching list, need to 10815 // restart it. 10816 restart = true; 10817 } 10818 10819 cpr.provider = null; 10820 cpr.proc = null; 10821 } 10822 app.pubProviders.clear(); 10823 } 10824 10825 // Take care of any launching providers waiting for this process. 10826 if (checkAppInLaunchingProvidersLocked(app, false)) { 10827 restart = true; 10828 } 10829 10830 // Unregister from connected content providers. 10831 if (!app.conProviders.isEmpty()) { 10832 for (int i=0; i<app.conProviders.size(); i++) { 10833 ContentProviderConnection conn = app.conProviders.get(i); 10834 conn.provider.connections.remove(conn); 10835 } 10836 app.conProviders.clear(); 10837 } 10838 10839 // At this point there may be remaining entries in mLaunchingProviders 10840 // where we were the only one waiting, so they are no longer of use. 10841 // Look for these and clean up if found. 10842 // XXX Commented out for now. Trying to figure out a way to reproduce 10843 // the actual situation to identify what is actually going on. 10844 if (false) { 10845 for (int i=0; i<mLaunchingProviders.size(); i++) { 10846 ContentProviderRecord cpr = (ContentProviderRecord) 10847 mLaunchingProviders.get(i); 10848 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10849 synchronized (cpr) { 10850 cpr.launchingApp = null; 10851 cpr.notifyAll(); 10852 } 10853 } 10854 } 10855 } 10856 10857 skipCurrentReceiverLocked(app); 10858 10859 // Unregister any receivers. 10860 if (app.receivers.size() > 0) { 10861 Iterator<ReceiverList> it = app.receivers.iterator(); 10862 while (it.hasNext()) { 10863 removeReceiverLocked(it.next()); 10864 } 10865 app.receivers.clear(); 10866 } 10867 10868 // If the app is undergoing backup, tell the backup manager about it 10869 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10870 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10871 try { 10872 IBackupManager bm = IBackupManager.Stub.asInterface( 10873 ServiceManager.getService(Context.BACKUP_SERVICE)); 10874 bm.agentDisconnected(app.info.packageName); 10875 } catch (RemoteException e) { 10876 // can't happen; backup manager is local 10877 } 10878 } 10879 10880 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10881 ProcessChangeItem item = mPendingProcessChanges.get(i); 10882 if (item.pid == app.pid) { 10883 mPendingProcessChanges.remove(i); 10884 mAvailProcessChanges.add(item); 10885 } 10886 } 10887 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10888 10889 // If the caller is restarting this app, then leave it in its 10890 // current lists and let the caller take care of it. 10891 if (restarting) { 10892 return; 10893 } 10894 10895 if (!app.persistent || app.isolated) { 10896 if (DEBUG_PROCESSES) Slog.v(TAG, 10897 "Removing non-persistent process during cleanup: " + app); 10898 mProcessNames.remove(app.processName, app.uid); 10899 mIsolatedProcesses.remove(app.uid); 10900 if (mHeavyWeightProcess == app) { 10901 mHeavyWeightProcess = null; 10902 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10903 } 10904 } else if (!app.removed) { 10905 // This app is persistent, so we need to keep its record around. 10906 // If it is not already on the pending app list, add it there 10907 // and start a new process for it. 10908 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10909 mPersistentStartingProcesses.add(app); 10910 restart = true; 10911 } 10912 } 10913 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10914 "Clean-up removing on hold: " + app); 10915 mProcessesOnHold.remove(app); 10916 10917 if (app == mHomeProcess) { 10918 mHomeProcess = null; 10919 } 10920 if (app == mPreviousProcess) { 10921 mPreviousProcess = null; 10922 } 10923 10924 if (restart && !app.isolated) { 10925 // We have components that still need to be running in the 10926 // process, so re-launch it. 10927 mProcessNames.put(app.processName, app.uid, app); 10928 startProcessLocked(app, "restart", app.processName); 10929 } else if (app.pid > 0 && app.pid != MY_PID) { 10930 // Goodbye! 10931 synchronized (mPidsSelfLocked) { 10932 mPidsSelfLocked.remove(app.pid); 10933 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10934 } 10935 app.setPid(0); 10936 } 10937 } 10938 10939 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10940 // Look through the content providers we are waiting to have launched, 10941 // and if any run in this process then either schedule a restart of 10942 // the process or kill the client waiting for it if this process has 10943 // gone bad. 10944 int NL = mLaunchingProviders.size(); 10945 boolean restart = false; 10946 for (int i=0; i<NL; i++) { 10947 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10948 if (cpr.launchingApp == app) { 10949 if (!alwaysBad && !app.bad) { 10950 restart = true; 10951 } else { 10952 removeDyingProviderLocked(app, cpr, true); 10953 NL = mLaunchingProviders.size(); 10954 } 10955 } 10956 } 10957 return restart; 10958 } 10959 10960 // ========================================================= 10961 // SERVICES 10962 // ========================================================= 10963 10964 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10965 ActivityManager.RunningServiceInfo info = 10966 new ActivityManager.RunningServiceInfo(); 10967 info.service = r.name; 10968 if (r.app != null) { 10969 info.pid = r.app.pid; 10970 } 10971 info.uid = r.appInfo.uid; 10972 info.process = r.processName; 10973 info.foreground = r.isForeground; 10974 info.activeSince = r.createTime; 10975 info.started = r.startRequested; 10976 info.clientCount = r.connections.size(); 10977 info.crashCount = r.crashCount; 10978 info.lastActivityTime = r.lastActivity; 10979 if (r.isForeground) { 10980 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10981 } 10982 if (r.startRequested) { 10983 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10984 } 10985 if (r.app != null && r.app.pid == MY_PID) { 10986 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10987 } 10988 if (r.app != null && r.app.persistent) { 10989 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10990 } 10991 10992 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 10993 for (int i=0; i<connl.size(); i++) { 10994 ConnectionRecord conn = connl.get(i); 10995 if (conn.clientLabel != 0) { 10996 info.clientPackage = conn.binding.client.info.packageName; 10997 info.clientLabel = conn.clientLabel; 10998 return info; 10999 } 11000 } 11001 } 11002 return info; 11003 } 11004 11005 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 11006 int flags) { 11007 enforceNotIsolatedCaller("getServices"); 11008 synchronized (this) { 11009 ArrayList<ActivityManager.RunningServiceInfo> res 11010 = new ArrayList<ActivityManager.RunningServiceInfo>(); 11011 11012 int userId = UserId.getUserId(Binder.getCallingUid()); 11013 if (mServiceMap.getAllServices(userId).size() > 0) { 11014 Iterator<ServiceRecord> it 11015 = mServiceMap.getAllServices(userId).iterator(); 11016 while (it.hasNext() && res.size() < maxNum) { 11017 res.add(makeRunningServiceInfoLocked(it.next())); 11018 } 11019 } 11020 11021 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 11022 ServiceRecord r = mRestartingServices.get(i); 11023 ActivityManager.RunningServiceInfo info = 11024 makeRunningServiceInfoLocked(r); 11025 info.restarting = r.nextRestartTime; 11026 res.add(info); 11027 } 11028 11029 return res; 11030 } 11031 } 11032 11033 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 11034 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 11035 synchronized (this) { 11036 int userId = UserId.getUserId(Binder.getCallingUid()); 11037 ServiceRecord r = mServiceMap.getServiceByName(name, userId); 11038 if (r != null) { 11039 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 11040 for (int i=0; i<conn.size(); i++) { 11041 if (conn.get(i).clientIntent != null) { 11042 return conn.get(i).clientIntent; 11043 } 11044 } 11045 } 11046 } 11047 } 11048 return null; 11049 } 11050 11051 private final ServiceRecord findServiceLocked(ComponentName name, 11052 IBinder token) { 11053 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 11054 return r == token ? r : null; 11055 } 11056 11057 private final class ServiceLookupResult { 11058 final ServiceRecord record; 11059 final String permission; 11060 11061 ServiceLookupResult(ServiceRecord _record, String _permission) { 11062 record = _record; 11063 permission = _permission; 11064 } 11065 }; 11066 11067 private ServiceLookupResult findServiceLocked(Intent service, 11068 String resolvedType, int userId) { 11069 ServiceRecord r = null; 11070 if (service.getComponent() != null) { 11071 r = mServiceMap.getServiceByName(service.getComponent(), userId); 11072 } 11073 if (r == null) { 11074 Intent.FilterComparison filter = new Intent.FilterComparison(service); 11075 r = mServiceMap.getServiceByIntent(filter, userId); 11076 } 11077 11078 if (r == null) { 11079 try { 11080 ResolveInfo rInfo = 11081 AppGlobals.getPackageManager().resolveService( 11082 service, resolvedType, 0, userId); 11083 ServiceInfo sInfo = 11084 rInfo != null ? rInfo.serviceInfo : null; 11085 if (sInfo == null) { 11086 return null; 11087 } 11088 11089 ComponentName name = new ComponentName( 11090 sInfo.applicationInfo.packageName, sInfo.name); 11091 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 11092 } catch (RemoteException ex) { 11093 // pm is in same process, this will never happen. 11094 } 11095 } 11096 if (r != null) { 11097 int callingPid = Binder.getCallingPid(); 11098 int callingUid = Binder.getCallingUid(); 11099 if (checkComponentPermission(r.permission, 11100 callingPid, callingUid, r.appInfo.uid, r.exported) 11101 != PackageManager.PERMISSION_GRANTED) { 11102 if (!r.exported) { 11103 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11104 + " from pid=" + callingPid 11105 + ", uid=" + callingUid 11106 + " that is not exported from uid " + r.appInfo.uid); 11107 return new ServiceLookupResult(null, "not exported from uid " 11108 + r.appInfo.uid); 11109 } 11110 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11111 + " from pid=" + callingPid 11112 + ", uid=" + callingUid 11113 + " requires " + r.permission); 11114 return new ServiceLookupResult(null, r.permission); 11115 } 11116 return new ServiceLookupResult(r, null); 11117 } 11118 return null; 11119 } 11120 11121 private class ServiceRestarter implements Runnable { 11122 private ServiceRecord mService; 11123 11124 void setService(ServiceRecord service) { 11125 mService = service; 11126 } 11127 11128 public void run() { 11129 synchronized(ActivityManagerService.this) { 11130 performServiceRestartLocked(mService); 11131 } 11132 } 11133 } 11134 11135 private ServiceLookupResult retrieveServiceLocked(Intent service, 11136 String resolvedType, int callingPid, int callingUid, int userId) { 11137 ServiceRecord r = null; 11138 if (DEBUG_SERVICE) 11139 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType 11140 + " callingUid=" + callingUid); 11141 11142 if (service.getComponent() != null) { 11143 r = mServiceMap.getServiceByName(service.getComponent(), userId); 11144 } 11145 if (r == null) { 11146 Intent.FilterComparison filter = new Intent.FilterComparison(service); 11147 r = mServiceMap.getServiceByIntent(filter, userId); 11148 } 11149 if (r == null) { 11150 try { 11151 ResolveInfo rInfo = 11152 AppGlobals.getPackageManager().resolveService( 11153 service, resolvedType, STOCK_PM_FLAGS, userId); 11154 ServiceInfo sInfo = 11155 rInfo != null ? rInfo.serviceInfo : null; 11156 if (sInfo == null) { 11157 Slog.w(TAG, "Unable to start service " + service + 11158 ": not found"); 11159 return null; 11160 } 11161 if (userId > 0) { 11162 if (isSingleton(sInfo.processName, sInfo.applicationInfo)) { 11163 userId = 0; 11164 } 11165 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId); 11166 } 11167 ComponentName name = new ComponentName( 11168 sInfo.applicationInfo.packageName, sInfo.name); 11169 r = mServiceMap.getServiceByName(name, userId); 11170 if (r == null) { 11171 Intent.FilterComparison filter = new Intent.FilterComparison( 11172 service.cloneFilter()); 11173 ServiceRestarter res = new ServiceRestarter(); 11174 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11175 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11176 synchronized (stats) { 11177 ss = stats.getServiceStatsLocked( 11178 sInfo.applicationInfo.uid, sInfo.packageName, 11179 sInfo.name); 11180 } 11181 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 11182 res.setService(r); 11183 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r); 11184 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r); 11185 11186 // Make sure this component isn't in the pending list. 11187 int N = mPendingServices.size(); 11188 for (int i=0; i<N; i++) { 11189 ServiceRecord pr = mPendingServices.get(i); 11190 if (pr.name.equals(name)) { 11191 mPendingServices.remove(i); 11192 i--; 11193 N--; 11194 } 11195 } 11196 } 11197 } catch (RemoteException ex) { 11198 // pm is in same process, this will never happen. 11199 } 11200 } 11201 if (r != null) { 11202 if (checkComponentPermission(r.permission, 11203 callingPid, callingUid, r.appInfo.uid, r.exported) 11204 != PackageManager.PERMISSION_GRANTED) { 11205 if (!r.exported) { 11206 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11207 + " from pid=" + callingPid 11208 + ", uid=" + callingUid 11209 + " that is not exported from uid " + r.appInfo.uid); 11210 return new ServiceLookupResult(null, "not exported from uid " 11211 + r.appInfo.uid); 11212 } 11213 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11214 + " from pid=" + callingPid 11215 + ", uid=" + callingUid 11216 + " requires " + r.permission); 11217 return new ServiceLookupResult(null, r.permission); 11218 } 11219 return new ServiceLookupResult(r, null); 11220 } 11221 return null; 11222 } 11223 11224 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 11225 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 11226 + why + " of " + r + " in app " + r.app); 11227 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 11228 + why + " of " + r.shortName); 11229 long now = SystemClock.uptimeMillis(); 11230 if (r.executeNesting == 0 && r.app != null) { 11231 if (r.app.executingServices.size() == 0) { 11232 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11233 msg.obj = r.app; 11234 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 11235 } 11236 r.app.executingServices.add(r); 11237 } 11238 r.executeNesting++; 11239 r.executingStart = now; 11240 } 11241 11242 private final void sendServiceArgsLocked(ServiceRecord r, 11243 boolean oomAdjusted) { 11244 final int N = r.pendingStarts.size(); 11245 if (N == 0) { 11246 return; 11247 } 11248 11249 while (r.pendingStarts.size() > 0) { 11250 try { 11251 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 11252 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 11253 + r + " " + r.intent + " args=" + si.intent); 11254 if (si.intent == null && N > 1) { 11255 // If somehow we got a dummy null intent in the middle, 11256 // then skip it. DO NOT skip a null intent when it is 11257 // the only one in the list -- this is to support the 11258 // onStartCommand(null) case. 11259 continue; 11260 } 11261 si.deliveredTime = SystemClock.uptimeMillis(); 11262 r.deliveredStarts.add(si); 11263 si.deliveryCount++; 11264 if (si.neededGrants != null) { 11265 grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, 11266 si.getUriPermissionsLocked()); 11267 } 11268 bumpServiceExecutingLocked(r, "start"); 11269 if (!oomAdjusted) { 11270 oomAdjusted = true; 11271 updateOomAdjLocked(r.app); 11272 } 11273 int flags = 0; 11274 if (si.deliveryCount > 1) { 11275 flags |= Service.START_FLAG_RETRY; 11276 } 11277 if (si.doneExecutingCount > 0) { 11278 flags |= Service.START_FLAG_REDELIVERY; 11279 } 11280 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 11281 } catch (RemoteException e) { 11282 // Remote process gone... we'll let the normal cleanup take 11283 // care of this. 11284 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 11285 break; 11286 } catch (Exception e) { 11287 Slog.w(TAG, "Unexpected exception", e); 11288 break; 11289 } 11290 } 11291 } 11292 11293 private final boolean requestServiceBindingLocked(ServiceRecord r, 11294 IntentBindRecord i, boolean rebind) { 11295 if (r.app == null || r.app.thread == null) { 11296 // If service is not currently running, can't yet bind. 11297 return false; 11298 } 11299 if ((!i.requested || rebind) && i.apps.size() > 0) { 11300 try { 11301 bumpServiceExecutingLocked(r, "bind"); 11302 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 11303 if (!rebind) { 11304 i.requested = true; 11305 } 11306 i.hasBound = true; 11307 i.doRebind = false; 11308 } catch (RemoteException e) { 11309 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 11310 return false; 11311 } 11312 } 11313 return true; 11314 } 11315 11316 private final void requestServiceBindingsLocked(ServiceRecord r) { 11317 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 11318 while (bindings.hasNext()) { 11319 IntentBindRecord i = bindings.next(); 11320 if (!requestServiceBindingLocked(r, i, false)) { 11321 break; 11322 } 11323 } 11324 } 11325 11326 private final void realStartServiceLocked(ServiceRecord r, 11327 ProcessRecord app) throws RemoteException { 11328 if (app.thread == null) { 11329 throw new RemoteException(); 11330 } 11331 if (DEBUG_MU) 11332 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid 11333 + ", ProcessRecord.uid = " + app.uid); 11334 r.app = app; 11335 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 11336 11337 app.services.add(r); 11338 bumpServiceExecutingLocked(r, "create"); 11339 updateLruProcessLocked(app, true, true); 11340 11341 boolean created = false; 11342 try { 11343 mStringBuilder.setLength(0); 11344 r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false); 11345 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 11346 System.identityHashCode(r), r.shortName, 11347 mStringBuilder.toString(), r.app.pid); 11348 synchronized (r.stats.getBatteryStats()) { 11349 r.stats.startLaunchedLocked(); 11350 } 11351 ensurePackageDexOpt(r.serviceInfo.packageName); 11352 app.thread.scheduleCreateService(r, r.serviceInfo, 11353 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 11354 r.postNotification(); 11355 created = true; 11356 } finally { 11357 if (!created) { 11358 app.services.remove(r); 11359 scheduleServiceRestartLocked(r, false); 11360 } 11361 } 11362 11363 requestServiceBindingsLocked(r); 11364 11365 // If the service is in the started state, and there are no 11366 // pending arguments, then fake up one so its onStartCommand() will 11367 // be called. 11368 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 11369 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11370 null, null)); 11371 } 11372 11373 sendServiceArgsLocked(r, true); 11374 } 11375 11376 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 11377 boolean allowCancel) { 11378 boolean canceled = false; 11379 11380 final long now = SystemClock.uptimeMillis(); 11381 long minDuration = SERVICE_RESTART_DURATION; 11382 long resetTime = SERVICE_RESET_RUN_DURATION; 11383 11384 if ((r.serviceInfo.applicationInfo.flags 11385 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11386 minDuration /= 4; 11387 } 11388 11389 // Any delivered but not yet finished starts should be put back 11390 // on the pending list. 11391 final int N = r.deliveredStarts.size(); 11392 if (N > 0) { 11393 for (int i=N-1; i>=0; i--) { 11394 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 11395 si.removeUriPermissionsLocked(); 11396 if (si.intent == null) { 11397 // We'll generate this again if needed. 11398 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 11399 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 11400 r.pendingStarts.add(0, si); 11401 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 11402 dur *= 2; 11403 if (minDuration < dur) minDuration = dur; 11404 if (resetTime < dur) resetTime = dur; 11405 } else { 11406 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 11407 + r.name); 11408 canceled = true; 11409 } 11410 } 11411 r.deliveredStarts.clear(); 11412 } 11413 11414 r.totalRestartCount++; 11415 if (r.restartDelay == 0) { 11416 r.restartCount++; 11417 r.restartDelay = minDuration; 11418 } else { 11419 // If it has been a "reasonably long time" since the service 11420 // was started, then reset our restart duration back to 11421 // the beginning, so we don't infinitely increase the duration 11422 // on a service that just occasionally gets killed (which is 11423 // a normal case, due to process being killed to reclaim memory). 11424 if (now > (r.restartTime+resetTime)) { 11425 r.restartCount = 1; 11426 r.restartDelay = minDuration; 11427 } else { 11428 if ((r.serviceInfo.applicationInfo.flags 11429 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11430 // Services in peristent processes will restart much more 11431 // quickly, since they are pretty important. (Think SystemUI). 11432 r.restartDelay += minDuration/2; 11433 } else { 11434 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 11435 if (r.restartDelay < minDuration) { 11436 r.restartDelay = minDuration; 11437 } 11438 } 11439 } 11440 } 11441 11442 r.nextRestartTime = now + r.restartDelay; 11443 11444 // Make sure that we don't end up restarting a bunch of services 11445 // all at the same time. 11446 boolean repeat; 11447 do { 11448 repeat = false; 11449 for (int i=mRestartingServices.size()-1; i>=0; i--) { 11450 ServiceRecord r2 = mRestartingServices.get(i); 11451 if (r2 != r && r.nextRestartTime 11452 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 11453 && r.nextRestartTime 11454 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 11455 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 11456 r.restartDelay = r.nextRestartTime - now; 11457 repeat = true; 11458 break; 11459 } 11460 } 11461 } while (repeat); 11462 11463 if (!mRestartingServices.contains(r)) { 11464 mRestartingServices.add(r); 11465 } 11466 11467 r.cancelNotification(); 11468 11469 mHandler.removeCallbacks(r.restarter); 11470 mHandler.postAtTime(r.restarter, r.nextRestartTime); 11471 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 11472 Slog.w(TAG, "Scheduling restart of crashed service " 11473 + r.shortName + " in " + r.restartDelay + "ms"); 11474 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 11475 r.shortName, r.restartDelay); 11476 11477 return canceled; 11478 } 11479 11480 final void performServiceRestartLocked(ServiceRecord r) { 11481 if (!mRestartingServices.contains(r)) { 11482 return; 11483 } 11484 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 11485 } 11486 11487 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 11488 if (r.restartDelay == 0) { 11489 return false; 11490 } 11491 r.resetRestartCounter(); 11492 mRestartingServices.remove(r); 11493 mHandler.removeCallbacks(r.restarter); 11494 return true; 11495 } 11496 11497 private final boolean bringUpServiceLocked(ServiceRecord r, 11498 int intentFlags, boolean whileRestarting) { 11499 //Slog.i(TAG, "Bring up service:"); 11500 //r.dump(" "); 11501 11502 if (r.app != null && r.app.thread != null) { 11503 sendServiceArgsLocked(r, false); 11504 return true; 11505 } 11506 11507 if (!whileRestarting && r.restartDelay > 0) { 11508 // If waiting for a restart, then do nothing. 11509 return true; 11510 } 11511 11512 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 11513 11514 // We are now bringing the service up, so no longer in the 11515 // restarting state. 11516 mRestartingServices.remove(r); 11517 11518 // Service is now being launched, its package can't be stopped. 11519 try { 11520 AppGlobals.getPackageManager().setPackageStoppedState( 11521 r.packageName, false, r.userId); 11522 } catch (RemoteException e) { 11523 } catch (IllegalArgumentException e) { 11524 Slog.w(TAG, "Failed trying to unstop package " 11525 + r.packageName + ": " + e); 11526 } 11527 11528 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; 11529 final String appName = r.processName; 11530 ProcessRecord app; 11531 11532 if (!isolated) { 11533 app = getProcessRecordLocked(appName, r.appInfo.uid); 11534 if (DEBUG_MU) 11535 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); 11536 if (app != null && app.thread != null) { 11537 try { 11538 app.addPackage(r.appInfo.packageName); 11539 realStartServiceLocked(r, app); 11540 return true; 11541 } catch (RemoteException e) { 11542 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 11543 } 11544 11545 // If a dead object exception was thrown -- fall through to 11546 // restart the application. 11547 } 11548 } else { 11549 // If this service runs in an isolated process, then each time 11550 // we call startProcessLocked() we will get a new isolated 11551 // process, starting another process if we are currently waiting 11552 // for a previous process to come up. To deal with this, we store 11553 // in the service any current isolated process it is running in or 11554 // waiting to have come up. 11555 app = r.isolatedProc; 11556 } 11557 11558 // Not running -- get it started, and enqueue this service record 11559 // to be executed when the app comes up. 11560 if (app == null) { 11561 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags, 11562 "service", r.name, false, isolated)) == null) { 11563 Slog.w(TAG, "Unable to launch app " 11564 + r.appInfo.packageName + "/" 11565 + r.appInfo.uid + " for service " 11566 + r.intent.getIntent() + ": process is bad"); 11567 bringDownServiceLocked(r, true); 11568 return false; 11569 } 11570 if (isolated) { 11571 r.isolatedProc = app; 11572 } 11573 } 11574 11575 if (!mPendingServices.contains(r)) { 11576 mPendingServices.add(r); 11577 } 11578 11579 return true; 11580 } 11581 11582 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 11583 //Slog.i(TAG, "Bring down service:"); 11584 //r.dump(" "); 11585 11586 // Does it still need to run? 11587 if (!force && r.startRequested) { 11588 return; 11589 } 11590 if (r.connections.size() > 0) { 11591 if (!force) { 11592 // XXX should probably keep a count of the number of auto-create 11593 // connections directly in the service. 11594 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11595 while (it.hasNext()) { 11596 ArrayList<ConnectionRecord> cr = it.next(); 11597 for (int i=0; i<cr.size(); i++) { 11598 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 11599 return; 11600 } 11601 } 11602 } 11603 } 11604 11605 // Report to all of the connections that the service is no longer 11606 // available. 11607 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11608 while (it.hasNext()) { 11609 ArrayList<ConnectionRecord> c = it.next(); 11610 for (int i=0; i<c.size(); i++) { 11611 ConnectionRecord cr = c.get(i); 11612 // There is still a connection to the service that is 11613 // being brought down. Mark it as dead. 11614 cr.serviceDead = true; 11615 try { 11616 cr.conn.connected(r.name, null); 11617 } catch (Exception e) { 11618 Slog.w(TAG, "Failure disconnecting service " + r.name + 11619 " to connection " + c.get(i).conn.asBinder() + 11620 " (in " + c.get(i).binding.client.processName + ")", e); 11621 } 11622 } 11623 } 11624 } 11625 11626 // Tell the service that it has been unbound. 11627 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 11628 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 11629 while (it.hasNext()) { 11630 IntentBindRecord ibr = it.next(); 11631 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 11632 + ": hasBound=" + ibr.hasBound); 11633 if (r.app != null && r.app.thread != null && ibr.hasBound) { 11634 try { 11635 bumpServiceExecutingLocked(r, "bring down unbind"); 11636 updateOomAdjLocked(r.app); 11637 ibr.hasBound = false; 11638 r.app.thread.scheduleUnbindService(r, 11639 ibr.intent.getIntent()); 11640 } catch (Exception e) { 11641 Slog.w(TAG, "Exception when unbinding service " 11642 + r.shortName, e); 11643 serviceDoneExecutingLocked(r, true); 11644 } 11645 } 11646 } 11647 } 11648 11649 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 11650 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 11651 System.identityHashCode(r), r.shortName, 11652 (r.app != null) ? r.app.pid : -1); 11653 11654 mServiceMap.removeServiceByName(r.name, r.userId); 11655 mServiceMap.removeServiceByIntent(r.intent, r.userId); 11656 r.totalRestartCount = 0; 11657 unscheduleServiceRestartLocked(r); 11658 11659 // Also make sure it is not on the pending list. 11660 int N = mPendingServices.size(); 11661 for (int i=0; i<N; i++) { 11662 if (mPendingServices.get(i) == r) { 11663 mPendingServices.remove(i); 11664 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 11665 i--; 11666 N--; 11667 } 11668 } 11669 11670 r.cancelNotification(); 11671 r.isForeground = false; 11672 r.foregroundId = 0; 11673 r.foregroundNoti = null; 11674 11675 // Clear start entries. 11676 r.clearDeliveredStartsLocked(); 11677 r.pendingStarts.clear(); 11678 11679 if (r.app != null) { 11680 synchronized (r.stats.getBatteryStats()) { 11681 r.stats.stopLaunchedLocked(); 11682 } 11683 r.app.services.remove(r); 11684 if (r.app.thread != null) { 11685 try { 11686 bumpServiceExecutingLocked(r, "stop"); 11687 mStoppingServices.add(r); 11688 updateOomAdjLocked(r.app); 11689 r.app.thread.scheduleStopService(r); 11690 } catch (Exception e) { 11691 Slog.w(TAG, "Exception when stopping service " 11692 + r.shortName, e); 11693 serviceDoneExecutingLocked(r, true); 11694 } 11695 updateServiceForegroundLocked(r.app, false); 11696 } else { 11697 if (DEBUG_SERVICE) Slog.v( 11698 TAG, "Removed service that has no process: " + r); 11699 } 11700 } else { 11701 if (DEBUG_SERVICE) Slog.v( 11702 TAG, "Removed service that is not running: " + r); 11703 } 11704 11705 if (r.bindings.size() > 0) { 11706 r.bindings.clear(); 11707 } 11708 11709 if (r.restarter instanceof ServiceRestarter) { 11710 ((ServiceRestarter)r.restarter).setService(null); 11711 } 11712 } 11713 11714 ComponentName startServiceLocked(IApplicationThread caller, 11715 Intent service, String resolvedType, 11716 int callingPid, int callingUid) { 11717 synchronized(this) { 11718 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11719 + " type=" + resolvedType + " args=" + service.getExtras()); 11720 11721 if (caller != null) { 11722 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11723 if (callerApp == null) { 11724 throw new SecurityException( 11725 "Unable to find app for caller " + caller 11726 + " (pid=" + Binder.getCallingPid() 11727 + ") when starting service " + service); 11728 } 11729 } 11730 11731 ServiceLookupResult res = 11732 retrieveServiceLocked(service, resolvedType, 11733 callingPid, callingUid, UserId.getUserId(callingUid)); 11734 if (res == null) { 11735 return null; 11736 } 11737 if (res.record == null) { 11738 return new ComponentName("!", res.permission != null 11739 ? res.permission : "private to package"); 11740 } 11741 ServiceRecord r = res.record; 11742 NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked( 11743 callingUid, r.packageName, service, service.getFlags(), null); 11744 if (unscheduleServiceRestartLocked(r)) { 11745 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 11746 } 11747 r.startRequested = true; 11748 r.callStart = false; 11749 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11750 service, neededGrants)); 11751 r.lastActivity = SystemClock.uptimeMillis(); 11752 synchronized (r.stats.getBatteryStats()) { 11753 r.stats.startRunningLocked(); 11754 } 11755 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11756 return new ComponentName("!", "Service process is bad"); 11757 } 11758 return r.name; 11759 } 11760 } 11761 11762 public ComponentName startService(IApplicationThread caller, Intent service, 11763 String resolvedType) { 11764 enforceNotIsolatedCaller("startService"); 11765 // Refuse possible leaked file descriptors 11766 if (service != null && service.hasFileDescriptors() == true) { 11767 throw new IllegalArgumentException("File descriptors passed in Intent"); 11768 } 11769 11770 if (DEBUG_SERVICE) 11771 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 11772 synchronized(this) { 11773 final int callingPid = Binder.getCallingPid(); 11774 final int callingUid = Binder.getCallingUid(); 11775 final long origId = Binder.clearCallingIdentity(); 11776 ComponentName res = startServiceLocked(caller, service, 11777 resolvedType, callingPid, callingUid); 11778 Binder.restoreCallingIdentity(origId); 11779 return res; 11780 } 11781 } 11782 11783 ComponentName startServiceInPackage(int uid, 11784 Intent service, String resolvedType) { 11785 synchronized(this) { 11786 if (DEBUG_SERVICE) 11787 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 11788 final long origId = Binder.clearCallingIdentity(); 11789 ComponentName res = startServiceLocked(null, service, 11790 resolvedType, -1, uid); 11791 Binder.restoreCallingIdentity(origId); 11792 return res; 11793 } 11794 } 11795 11796 private void stopServiceLocked(ServiceRecord service) { 11797 synchronized (service.stats.getBatteryStats()) { 11798 service.stats.stopRunningLocked(); 11799 } 11800 service.startRequested = false; 11801 service.callStart = false; 11802 bringDownServiceLocked(service, false); 11803 } 11804 11805 public int stopService(IApplicationThread caller, Intent service, 11806 String resolvedType) { 11807 enforceNotIsolatedCaller("stopService"); 11808 // Refuse possible leaked file descriptors 11809 if (service != null && service.hasFileDescriptors() == true) { 11810 throw new IllegalArgumentException("File descriptors passed in Intent"); 11811 } 11812 11813 synchronized(this) { 11814 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11815 + " type=" + resolvedType); 11816 11817 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11818 if (caller != null && callerApp == null) { 11819 throw new SecurityException( 11820 "Unable to find app for caller " + caller 11821 + " (pid=" + Binder.getCallingPid() 11822 + ") when stopping service " + service); 11823 } 11824 11825 // If this service is active, make sure it is stopped. 11826 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11827 callerApp == null ? UserId.getCallingUserId() : callerApp.userId); 11828 if (r != null) { 11829 if (r.record != null) { 11830 final long origId = Binder.clearCallingIdentity(); 11831 try { 11832 stopServiceLocked(r.record); 11833 } finally { 11834 Binder.restoreCallingIdentity(origId); 11835 } 11836 return 1; 11837 } 11838 return -1; 11839 } 11840 } 11841 11842 return 0; 11843 } 11844 11845 public IBinder peekService(Intent service, String resolvedType) { 11846 enforceNotIsolatedCaller("peekService"); 11847 // Refuse possible leaked file descriptors 11848 if (service != null && service.hasFileDescriptors() == true) { 11849 throw new IllegalArgumentException("File descriptors passed in Intent"); 11850 } 11851 11852 IBinder ret = null; 11853 11854 synchronized(this) { 11855 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11856 UserId.getCallingUserId()); 11857 11858 if (r != null) { 11859 // r.record is null if findServiceLocked() failed the caller permission check 11860 if (r.record == null) { 11861 throw new SecurityException( 11862 "Permission Denial: Accessing service " + r.record.name 11863 + " from pid=" + Binder.getCallingPid() 11864 + ", uid=" + Binder.getCallingUid() 11865 + " requires " + r.permission); 11866 } 11867 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11868 if (ib != null) { 11869 ret = ib.binder; 11870 } 11871 } 11872 } 11873 11874 return ret; 11875 } 11876 11877 public boolean stopServiceToken(ComponentName className, IBinder token, 11878 int startId) { 11879 synchronized(this) { 11880 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11881 + " " + token + " startId=" + startId); 11882 ServiceRecord r = findServiceLocked(className, token); 11883 if (r != null) { 11884 if (startId >= 0) { 11885 // Asked to only stop if done with all work. Note that 11886 // to avoid leaks, we will take this as dropping all 11887 // start items up to and including this one. 11888 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11889 if (si != null) { 11890 while (r.deliveredStarts.size() > 0) { 11891 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 11892 cur.removeUriPermissionsLocked(); 11893 if (cur == si) { 11894 break; 11895 } 11896 } 11897 } 11898 11899 if (r.getLastStartId() != startId) { 11900 return false; 11901 } 11902 11903 if (r.deliveredStarts.size() > 0) { 11904 Slog.w(TAG, "stopServiceToken startId " + startId 11905 + " is last, but have " + r.deliveredStarts.size() 11906 + " remaining args"); 11907 } 11908 } 11909 11910 synchronized (r.stats.getBatteryStats()) { 11911 r.stats.stopRunningLocked(); 11912 r.startRequested = false; 11913 r.callStart = false; 11914 } 11915 final long origId = Binder.clearCallingIdentity(); 11916 bringDownServiceLocked(r, false); 11917 Binder.restoreCallingIdentity(origId); 11918 return true; 11919 } 11920 } 11921 return false; 11922 } 11923 11924 public void setServiceForeground(ComponentName className, IBinder token, 11925 int id, Notification notification, boolean removeNotification) { 11926 final long origId = Binder.clearCallingIdentity(); 11927 try { 11928 synchronized(this) { 11929 ServiceRecord r = findServiceLocked(className, token); 11930 if (r != null) { 11931 if (id != 0) { 11932 if (notification == null) { 11933 throw new IllegalArgumentException("null notification"); 11934 } 11935 if (r.foregroundId != id) { 11936 r.cancelNotification(); 11937 r.foregroundId = id; 11938 } 11939 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11940 r.foregroundNoti = notification; 11941 r.isForeground = true; 11942 r.postNotification(); 11943 if (r.app != null) { 11944 updateServiceForegroundLocked(r.app, true); 11945 } 11946 } else { 11947 if (r.isForeground) { 11948 r.isForeground = false; 11949 if (r.app != null) { 11950 updateLruProcessLocked(r.app, false, true); 11951 updateServiceForegroundLocked(r.app, true); 11952 } 11953 } 11954 if (removeNotification) { 11955 r.cancelNotification(); 11956 r.foregroundId = 0; 11957 r.foregroundNoti = null; 11958 } 11959 } 11960 } 11961 } 11962 } finally { 11963 Binder.restoreCallingIdentity(origId); 11964 } 11965 } 11966 11967 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11968 boolean anyForeground = false; 11969 for (ServiceRecord sr : proc.services) { 11970 if (sr.isForeground) { 11971 anyForeground = true; 11972 break; 11973 } 11974 } 11975 if (anyForeground != proc.foregroundServices) { 11976 proc.foregroundServices = anyForeground; 11977 if (oomAdj) { 11978 updateOomAdjLocked(); 11979 } 11980 } 11981 } 11982 11983 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) { 11984 boolean result = false; 11985 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11986 result = false; 11987 } else if (componentProcessName == aInfo.packageName) { 11988 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11989 } else if ("system".equals(componentProcessName)) { 11990 result = true; 11991 } 11992 if (DEBUG_MU) { 11993 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result); 11994 } 11995 return result; 11996 } 11997 11998 public int bindService(IApplicationThread caller, IBinder token, 11999 Intent service, String resolvedType, 12000 IServiceConnection connection, int flags, int userId) { 12001 enforceNotIsolatedCaller("bindService"); 12002 // Refuse possible leaked file descriptors 12003 if (service != null && service.hasFileDescriptors() == true) { 12004 throw new IllegalArgumentException("File descriptors passed in Intent"); 12005 } 12006 12007 checkValidCaller(Binder.getCallingUid(), userId); 12008 12009 synchronized(this) { 12010 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 12011 + " type=" + resolvedType + " conn=" + connection.asBinder() 12012 + " flags=0x" + Integer.toHexString(flags)); 12013 if (DEBUG_MU) 12014 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid=" 12015 + Binder.getOrigCallingUid()); 12016 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12017 if (callerApp == null) { 12018 throw new SecurityException( 12019 "Unable to find app for caller " + caller 12020 + " (pid=" + Binder.getCallingPid() 12021 + ") when binding service " + service); 12022 } 12023 12024 ActivityRecord activity = null; 12025 if (token != null) { 12026 activity = mMainStack.isInStackLocked(token); 12027 if (activity == null) { 12028 Slog.w(TAG, "Binding with unknown activity: " + token); 12029 return 0; 12030 } 12031 } 12032 12033 int clientLabel = 0; 12034 PendingIntent clientIntent = null; 12035 12036 if (callerApp.info.uid == Process.SYSTEM_UID) { 12037 // Hacky kind of thing -- allow system stuff to tell us 12038 // what they are, so we can report this elsewhere for 12039 // others to know why certain services are running. 12040 try { 12041 clientIntent = (PendingIntent)service.getParcelableExtra( 12042 Intent.EXTRA_CLIENT_INTENT); 12043 } catch (RuntimeException e) { 12044 } 12045 if (clientIntent != null) { 12046 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 12047 if (clientLabel != 0) { 12048 // There are no useful extras in the intent, trash them. 12049 // System code calling with this stuff just needs to know 12050 // this will happen. 12051 service = service.cloneFilter(); 12052 } 12053 } 12054 } 12055 12056 ServiceLookupResult res = 12057 retrieveServiceLocked(service, resolvedType, 12058 Binder.getCallingPid(), Binder.getCallingUid(), userId); 12059 if (res == null) { 12060 return 0; 12061 } 12062 if (res.record == null) { 12063 return -1; 12064 } 12065 if (isSingleton(res.record.processName, res.record.appInfo)) { 12066 userId = 0; 12067 res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(), 12068 Binder.getCallingUid(), 0); 12069 } 12070 ServiceRecord s = res.record; 12071 12072 final long origId = Binder.clearCallingIdentity(); 12073 12074 if (unscheduleServiceRestartLocked(s)) { 12075 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 12076 + s); 12077 } 12078 12079 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 12080 ConnectionRecord c = new ConnectionRecord(b, activity, 12081 connection, flags, clientLabel, clientIntent); 12082 12083 IBinder binder = connection.asBinder(); 12084 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 12085 if (clist == null) { 12086 clist = new ArrayList<ConnectionRecord>(); 12087 s.connections.put(binder, clist); 12088 } 12089 clist.add(c); 12090 b.connections.add(c); 12091 if (activity != null) { 12092 if (activity.connections == null) { 12093 activity.connections = new HashSet<ConnectionRecord>(); 12094 } 12095 activity.connections.add(c); 12096 } 12097 b.client.connections.add(c); 12098 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 12099 b.client.hasAboveClient = true; 12100 } 12101 clist = mServiceConnections.get(binder); 12102 if (clist == null) { 12103 clist = new ArrayList<ConnectionRecord>(); 12104 mServiceConnections.put(binder, clist); 12105 } 12106 clist.add(c); 12107 12108 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 12109 s.lastActivity = SystemClock.uptimeMillis(); 12110 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 12111 return 0; 12112 } 12113 } 12114 12115 if (s.app != null) { 12116 // This could have made the service more important. 12117 updateOomAdjLocked(s.app); 12118 } 12119 12120 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 12121 + ": received=" + b.intent.received 12122 + " apps=" + b.intent.apps.size() 12123 + " doRebind=" + b.intent.doRebind); 12124 12125 if (s.app != null && b.intent.received) { 12126 // Service is already running, so we can immediately 12127 // publish the connection. 12128 try { 12129 c.conn.connected(s.name, b.intent.binder); 12130 } catch (Exception e) { 12131 Slog.w(TAG, "Failure sending service " + s.shortName 12132 + " to connection " + c.conn.asBinder() 12133 + " (in " + c.binding.client.processName + ")", e); 12134 } 12135 12136 // If this is the first app connected back to this binding, 12137 // and the service had previously asked to be told when 12138 // rebound, then do so. 12139 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 12140 requestServiceBindingLocked(s, b.intent, true); 12141 } 12142 } else if (!b.intent.requested) { 12143 requestServiceBindingLocked(s, b.intent, false); 12144 } 12145 12146 Binder.restoreCallingIdentity(origId); 12147 } 12148 12149 return 1; 12150 } 12151 12152 void removeConnectionLocked( 12153 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 12154 IBinder binder = c.conn.asBinder(); 12155 AppBindRecord b = c.binding; 12156 ServiceRecord s = b.service; 12157 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 12158 if (clist != null) { 12159 clist.remove(c); 12160 if (clist.size() == 0) { 12161 s.connections.remove(binder); 12162 } 12163 } 12164 b.connections.remove(c); 12165 if (c.activity != null && c.activity != skipAct) { 12166 if (c.activity.connections != null) { 12167 c.activity.connections.remove(c); 12168 } 12169 } 12170 if (b.client != skipApp) { 12171 b.client.connections.remove(c); 12172 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 12173 b.client.updateHasAboveClientLocked(); 12174 } 12175 } 12176 clist = mServiceConnections.get(binder); 12177 if (clist != null) { 12178 clist.remove(c); 12179 if (clist.size() == 0) { 12180 mServiceConnections.remove(binder); 12181 } 12182 } 12183 12184 if (b.connections.size() == 0) { 12185 b.intent.apps.remove(b.client); 12186 } 12187 12188 if (!c.serviceDead) { 12189 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 12190 + ": shouldUnbind=" + b.intent.hasBound); 12191 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 12192 && b.intent.hasBound) { 12193 try { 12194 bumpServiceExecutingLocked(s, "unbind"); 12195 updateOomAdjLocked(s.app); 12196 b.intent.hasBound = false; 12197 // Assume the client doesn't want to know about a rebind; 12198 // we will deal with that later if it asks for one. 12199 b.intent.doRebind = false; 12200 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 12201 } catch (Exception e) { 12202 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 12203 serviceDoneExecutingLocked(s, true); 12204 } 12205 } 12206 12207 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 12208 bringDownServiceLocked(s, false); 12209 } 12210 } 12211 } 12212 12213 public boolean unbindService(IServiceConnection connection) { 12214 synchronized (this) { 12215 IBinder binder = connection.asBinder(); 12216 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 12217 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 12218 if (clist == null) { 12219 Slog.w(TAG, "Unbind failed: could not find connection for " 12220 + connection.asBinder()); 12221 return false; 12222 } 12223 12224 final long origId = Binder.clearCallingIdentity(); 12225 12226 while (clist.size() > 0) { 12227 ConnectionRecord r = clist.get(0); 12228 removeConnectionLocked(r, null, null); 12229 12230 if (r.binding.service.app != null) { 12231 // This could have made the service less important. 12232 updateOomAdjLocked(r.binding.service.app); 12233 } 12234 } 12235 12236 Binder.restoreCallingIdentity(origId); 12237 } 12238 12239 return true; 12240 } 12241 12242 public void publishService(IBinder token, Intent intent, IBinder service) { 12243 // Refuse possible leaked file descriptors 12244 if (intent != null && intent.hasFileDescriptors() == true) { 12245 throw new IllegalArgumentException("File descriptors passed in Intent"); 12246 } 12247 12248 synchronized(this) { 12249 if (!(token instanceof ServiceRecord)) { 12250 throw new IllegalArgumentException("Invalid service token"); 12251 } 12252 ServiceRecord r = (ServiceRecord)token; 12253 12254 final long origId = Binder.clearCallingIdentity(); 12255 12256 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 12257 + " " + intent + ": " + service); 12258 if (r != null) { 12259 Intent.FilterComparison filter 12260 = new Intent.FilterComparison(intent); 12261 IntentBindRecord b = r.bindings.get(filter); 12262 if (b != null && !b.received) { 12263 b.binder = service; 12264 b.requested = true; 12265 b.received = true; 12266 if (r.connections.size() > 0) { 12267 Iterator<ArrayList<ConnectionRecord>> it 12268 = r.connections.values().iterator(); 12269 while (it.hasNext()) { 12270 ArrayList<ConnectionRecord> clist = it.next(); 12271 for (int i=0; i<clist.size(); i++) { 12272 ConnectionRecord c = clist.get(i); 12273 if (!filter.equals(c.binding.intent.intent)) { 12274 if (DEBUG_SERVICE) Slog.v( 12275 TAG, "Not publishing to: " + c); 12276 if (DEBUG_SERVICE) Slog.v( 12277 TAG, "Bound intent: " + c.binding.intent.intent); 12278 if (DEBUG_SERVICE) Slog.v( 12279 TAG, "Published intent: " + intent); 12280 continue; 12281 } 12282 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 12283 try { 12284 c.conn.connected(r.name, service); 12285 } catch (Exception e) { 12286 Slog.w(TAG, "Failure sending service " + r.name + 12287 " to connection " + c.conn.asBinder() + 12288 " (in " + c.binding.client.processName + ")", e); 12289 } 12290 } 12291 } 12292 } 12293 } 12294 12295 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 12296 12297 Binder.restoreCallingIdentity(origId); 12298 } 12299 } 12300 } 12301 12302 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12303 // Refuse possible leaked file descriptors 12304 if (intent != null && intent.hasFileDescriptors() == true) { 12305 throw new IllegalArgumentException("File descriptors passed in Intent"); 12306 } 12307 12308 synchronized(this) { 12309 if (!(token instanceof ServiceRecord)) { 12310 throw new IllegalArgumentException("Invalid service token"); 12311 } 12312 ServiceRecord r = (ServiceRecord)token; 12313 12314 final long origId = Binder.clearCallingIdentity(); 12315 12316 if (r != null) { 12317 Intent.FilterComparison filter 12318 = new Intent.FilterComparison(intent); 12319 IntentBindRecord b = r.bindings.get(filter); 12320 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 12321 + " at " + b + ": apps=" 12322 + (b != null ? b.apps.size() : 0)); 12323 12324 boolean inStopping = mStoppingServices.contains(r); 12325 if (b != null) { 12326 if (b.apps.size() > 0 && !inStopping) { 12327 // Applications have already bound since the last 12328 // unbind, so just rebind right here. 12329 requestServiceBindingLocked(r, b, true); 12330 } else { 12331 // Note to tell the service the next time there is 12332 // a new client. 12333 b.doRebind = true; 12334 } 12335 } 12336 12337 serviceDoneExecutingLocked(r, inStopping); 12338 12339 Binder.restoreCallingIdentity(origId); 12340 } 12341 } 12342 } 12343 12344 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12345 synchronized(this) { 12346 if (!(token instanceof ServiceRecord)) { 12347 throw new IllegalArgumentException("Invalid service token"); 12348 } 12349 ServiceRecord r = (ServiceRecord)token; 12350 boolean inStopping = mStoppingServices.contains(token); 12351 if (r != null) { 12352 if (r != token) { 12353 Slog.w(TAG, "Done executing service " + r.name 12354 + " with incorrect token: given " + token 12355 + ", expected " + r); 12356 return; 12357 } 12358 12359 if (type == 1) { 12360 // This is a call from a service start... take care of 12361 // book-keeping. 12362 r.callStart = true; 12363 switch (res) { 12364 case Service.START_STICKY_COMPATIBILITY: 12365 case Service.START_STICKY: { 12366 // We are done with the associated start arguments. 12367 r.findDeliveredStart(startId, true); 12368 // Don't stop if killed. 12369 r.stopIfKilled = false; 12370 break; 12371 } 12372 case Service.START_NOT_STICKY: { 12373 // We are done with the associated start arguments. 12374 r.findDeliveredStart(startId, true); 12375 if (r.getLastStartId() == startId) { 12376 // There is no more work, and this service 12377 // doesn't want to hang around if killed. 12378 r.stopIfKilled = true; 12379 } 12380 break; 12381 } 12382 case Service.START_REDELIVER_INTENT: { 12383 // We'll keep this item until they explicitly 12384 // call stop for it, but keep track of the fact 12385 // that it was delivered. 12386 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 12387 if (si != null) { 12388 si.deliveryCount = 0; 12389 si.doneExecutingCount++; 12390 // Don't stop if killed. 12391 r.stopIfKilled = true; 12392 } 12393 break; 12394 } 12395 case Service.START_TASK_REMOVED_COMPLETE: { 12396 // Special processing for onTaskRemoved(). Don't 12397 // impact normal onStartCommand() processing. 12398 r.findDeliveredStart(startId, true); 12399 break; 12400 } 12401 default: 12402 throw new IllegalArgumentException( 12403 "Unknown service start result: " + res); 12404 } 12405 if (res == Service.START_STICKY_COMPATIBILITY) { 12406 r.callStart = false; 12407 } 12408 } 12409 if (DEBUG_MU) 12410 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid=" 12411 + Binder.getOrigCallingUid()); 12412 final long origId = Binder.clearCallingIdentity(); 12413 serviceDoneExecutingLocked(r, inStopping); 12414 Binder.restoreCallingIdentity(origId); 12415 } else { 12416 Slog.w(TAG, "Done executing unknown service from pid " 12417 + Binder.getCallingPid()); 12418 } 12419 } 12420 } 12421 12422 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 12423 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 12424 + ": nesting=" + r.executeNesting 12425 + ", inStopping=" + inStopping + ", app=" + r.app); 12426 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 12427 r.executeNesting--; 12428 if (r.executeNesting <= 0 && r.app != null) { 12429 if (DEBUG_SERVICE) Slog.v(TAG, 12430 "Nesting at 0 of " + r.shortName); 12431 r.app.executingServices.remove(r); 12432 if (r.app.executingServices.size() == 0) { 12433 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 12434 "No more executingServices of " + r.shortName); 12435 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 12436 } 12437 if (inStopping) { 12438 if (DEBUG_SERVICE) Slog.v(TAG, 12439 "doneExecuting remove stopping " + r); 12440 mStoppingServices.remove(r); 12441 r.bindings.clear(); 12442 } 12443 updateOomAdjLocked(r.app); 12444 } 12445 } 12446 12447 void serviceTimeout(ProcessRecord proc) { 12448 String anrMessage = null; 12449 12450 synchronized(this) { 12451 if (proc.executingServices.size() == 0 || proc.thread == null) { 12452 return; 12453 } 12454 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 12455 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 12456 ServiceRecord timeout = null; 12457 long nextTime = 0; 12458 while (it.hasNext()) { 12459 ServiceRecord sr = it.next(); 12460 if (sr.executingStart < maxTime) { 12461 timeout = sr; 12462 break; 12463 } 12464 if (sr.executingStart > nextTime) { 12465 nextTime = sr.executingStart; 12466 } 12467 } 12468 if (timeout != null && mLruProcesses.contains(proc)) { 12469 Slog.w(TAG, "Timeout executing service: " + timeout); 12470 anrMessage = "Executing service " + timeout.shortName; 12471 } else { 12472 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 12473 msg.obj = proc; 12474 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 12475 } 12476 } 12477 12478 if (anrMessage != null) { 12479 appNotResponding(proc, null, null, anrMessage); 12480 } 12481 } 12482 12483 // ========================================================= 12484 // BACKUP AND RESTORE 12485 // ========================================================= 12486 12487 // Cause the target app to be launched if necessary and its backup agent 12488 // instantiated. The backup agent will invoke backupAgentCreated() on the 12489 // activity manager to announce its creation. 12490 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12491 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 12492 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 12493 12494 synchronized(this) { 12495 // !!! TODO: currently no check here that we're already bound 12496 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12497 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12498 synchronized (stats) { 12499 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12500 } 12501 12502 // Backup agent is now in use, its package can't be stopped. 12503 try { 12504 AppGlobals.getPackageManager().setPackageStoppedState( 12505 app.packageName, false, UserId.getUserId(app.uid)); 12506 } catch (RemoteException e) { 12507 } catch (IllegalArgumentException e) { 12508 Slog.w(TAG, "Failed trying to unstop package " 12509 + app.packageName + ": " + e); 12510 } 12511 12512 BackupRecord r = new BackupRecord(ss, app, backupMode); 12513 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12514 ? new ComponentName(app.packageName, app.backupAgentName) 12515 : new ComponentName("android", "FullBackupAgent"); 12516 // startProcessLocked() returns existing proc's record if it's already running 12517 ProcessRecord proc = startProcessLocked(app.processName, app, 12518 false, 0, "backup", hostingName, false, false); 12519 if (proc == null) { 12520 Slog.e(TAG, "Unable to start backup agent process " + r); 12521 return false; 12522 } 12523 12524 r.app = proc; 12525 mBackupTarget = r; 12526 mBackupAppName = app.packageName; 12527 12528 // Try not to kill the process during backup 12529 updateOomAdjLocked(proc); 12530 12531 // If the process is already attached, schedule the creation of the backup agent now. 12532 // If it is not yet live, this will be done when it attaches to the framework. 12533 if (proc.thread != null) { 12534 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12535 try { 12536 proc.thread.scheduleCreateBackupAgent(app, 12537 compatibilityInfoForPackageLocked(app), backupMode); 12538 } catch (RemoteException e) { 12539 // Will time out on the backup manager side 12540 } 12541 } else { 12542 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12543 } 12544 // Invariants: at this point, the target app process exists and the application 12545 // is either already running or in the process of coming up. mBackupTarget and 12546 // mBackupAppName describe the app, so that when it binds back to the AM we 12547 // know that it's scheduled for a backup-agent operation. 12548 } 12549 12550 return true; 12551 } 12552 12553 // A backup agent has just come up 12554 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12555 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12556 + " = " + agent); 12557 12558 synchronized(this) { 12559 if (!agentPackageName.equals(mBackupAppName)) { 12560 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12561 return; 12562 } 12563 } 12564 12565 long oldIdent = Binder.clearCallingIdentity(); 12566 try { 12567 IBackupManager bm = IBackupManager.Stub.asInterface( 12568 ServiceManager.getService(Context.BACKUP_SERVICE)); 12569 bm.agentConnected(agentPackageName, agent); 12570 } catch (RemoteException e) { 12571 // can't happen; the backup manager service is local 12572 } catch (Exception e) { 12573 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12574 e.printStackTrace(); 12575 } finally { 12576 Binder.restoreCallingIdentity(oldIdent); 12577 } 12578 } 12579 12580 // done with this agent 12581 public void unbindBackupAgent(ApplicationInfo appInfo) { 12582 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12583 if (appInfo == null) { 12584 Slog.w(TAG, "unbind backup agent for null app"); 12585 return; 12586 } 12587 12588 synchronized(this) { 12589 if (mBackupAppName == null) { 12590 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12591 return; 12592 } 12593 12594 if (!mBackupAppName.equals(appInfo.packageName)) { 12595 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12596 return; 12597 } 12598 12599 ProcessRecord proc = mBackupTarget.app; 12600 mBackupTarget = null; 12601 mBackupAppName = null; 12602 12603 // Not backing this app up any more; reset its OOM adjustment 12604 updateOomAdjLocked(proc); 12605 12606 // If the app crashed during backup, 'thread' will be null here 12607 if (proc.thread != null) { 12608 try { 12609 proc.thread.scheduleDestroyBackupAgent(appInfo, 12610 compatibilityInfoForPackageLocked(appInfo)); 12611 } catch (Exception e) { 12612 Slog.e(TAG, "Exception when unbinding backup agent:"); 12613 e.printStackTrace(); 12614 } 12615 } 12616 } 12617 } 12618 // ========================================================= 12619 // BROADCASTS 12620 // ========================================================= 12621 12622 private final List getStickiesLocked(String action, IntentFilter filter, 12623 List cur) { 12624 final ContentResolver resolver = mContext.getContentResolver(); 12625 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 12626 if (list == null) { 12627 return cur; 12628 } 12629 int N = list.size(); 12630 for (int i=0; i<N; i++) { 12631 Intent intent = list.get(i); 12632 if (filter.match(resolver, intent, true, TAG) >= 0) { 12633 if (cur == null) { 12634 cur = new ArrayList<Intent>(); 12635 } 12636 cur.add(intent); 12637 } 12638 } 12639 return cur; 12640 } 12641 12642 boolean isPendingBroadcastProcessLocked(int pid) { 12643 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12644 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12645 } 12646 12647 void skipPendingBroadcastLocked(int pid) { 12648 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12649 for (BroadcastQueue queue : mBroadcastQueues) { 12650 queue.skipPendingBroadcastLocked(pid); 12651 } 12652 } 12653 12654 // The app just attached; send any pending broadcasts that it should receive 12655 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12656 boolean didSomething = false; 12657 for (BroadcastQueue queue : mBroadcastQueues) { 12658 didSomething |= queue.sendPendingBroadcastsLocked(app); 12659 } 12660 return didSomething; 12661 } 12662 12663 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12664 IIntentReceiver receiver, IntentFilter filter, String permission) { 12665 enforceNotIsolatedCaller("registerReceiver"); 12666 synchronized(this) { 12667 ProcessRecord callerApp = null; 12668 if (caller != null) { 12669 callerApp = getRecordForAppLocked(caller); 12670 if (callerApp == null) { 12671 throw new SecurityException( 12672 "Unable to find app for caller " + caller 12673 + " (pid=" + Binder.getCallingPid() 12674 + ") when registering receiver " + receiver); 12675 } 12676 if (callerApp.info.uid != Process.SYSTEM_UID && 12677 !callerApp.pkgList.contains(callerPackage)) { 12678 throw new SecurityException("Given caller package " + callerPackage 12679 + " is not running in process " + callerApp); 12680 } 12681 } else { 12682 callerPackage = null; 12683 } 12684 12685 List allSticky = null; 12686 12687 // Look for any matching sticky broadcasts... 12688 Iterator actions = filter.actionsIterator(); 12689 if (actions != null) { 12690 while (actions.hasNext()) { 12691 String action = (String)actions.next(); 12692 allSticky = getStickiesLocked(action, filter, allSticky); 12693 } 12694 } else { 12695 allSticky = getStickiesLocked(null, filter, allSticky); 12696 } 12697 12698 // The first sticky in the list is returned directly back to 12699 // the client. 12700 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12701 12702 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12703 + ": " + sticky); 12704 12705 if (receiver == null) { 12706 return sticky; 12707 } 12708 12709 ReceiverList rl 12710 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12711 if (rl == null) { 12712 rl = new ReceiverList(this, callerApp, 12713 Binder.getCallingPid(), 12714 Binder.getCallingUid(), receiver); 12715 if (rl.app != null) { 12716 rl.app.receivers.add(rl); 12717 } else { 12718 try { 12719 receiver.asBinder().linkToDeath(rl, 0); 12720 } catch (RemoteException e) { 12721 return sticky; 12722 } 12723 rl.linkedToDeath = true; 12724 } 12725 mRegisteredReceivers.put(receiver.asBinder(), rl); 12726 } 12727 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 12728 rl.add(bf); 12729 if (!bf.debugCheck()) { 12730 Slog.w(TAG, "==> For Dynamic broadast"); 12731 } 12732 mReceiverResolver.addFilter(bf); 12733 12734 // Enqueue broadcasts for all existing stickies that match 12735 // this filter. 12736 if (allSticky != null) { 12737 ArrayList receivers = new ArrayList(); 12738 receivers.add(bf); 12739 12740 int N = allSticky.size(); 12741 for (int i=0; i<N; i++) { 12742 Intent intent = (Intent)allSticky.get(i); 12743 BroadcastQueue queue = broadcastQueueForIntent(intent); 12744 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12745 null, -1, -1, null, receivers, null, 0, null, null, 12746 false, true, true); 12747 queue.enqueueParallelBroadcastLocked(r); 12748 queue.scheduleBroadcastsLocked(); 12749 } 12750 } 12751 12752 return sticky; 12753 } 12754 } 12755 12756 public void unregisterReceiver(IIntentReceiver receiver) { 12757 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12758 12759 final long origId = Binder.clearCallingIdentity(); 12760 try { 12761 boolean doTrim = false; 12762 12763 synchronized(this) { 12764 ReceiverList rl 12765 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12766 if (rl != null) { 12767 if (rl.curBroadcast != null) { 12768 BroadcastRecord r = rl.curBroadcast; 12769 final boolean doNext = finishReceiverLocked( 12770 receiver.asBinder(), r.resultCode, r.resultData, 12771 r.resultExtras, r.resultAbort, true); 12772 if (doNext) { 12773 doTrim = true; 12774 r.queue.processNextBroadcast(false); 12775 } 12776 } 12777 12778 if (rl.app != null) { 12779 rl.app.receivers.remove(rl); 12780 } 12781 removeReceiverLocked(rl); 12782 if (rl.linkedToDeath) { 12783 rl.linkedToDeath = false; 12784 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12785 } 12786 } 12787 } 12788 12789 // If we actually concluded any broadcasts, we might now be able 12790 // to trim the recipients' apps from our working set 12791 if (doTrim) { 12792 trimApplications(); 12793 return; 12794 } 12795 12796 } finally { 12797 Binder.restoreCallingIdentity(origId); 12798 } 12799 } 12800 12801 void removeReceiverLocked(ReceiverList rl) { 12802 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12803 int N = rl.size(); 12804 for (int i=0; i<N; i++) { 12805 mReceiverResolver.removeFilter(rl.get(i)); 12806 } 12807 } 12808 12809 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12810 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12811 ProcessRecord r = mLruProcesses.get(i); 12812 if (r.thread != null) { 12813 try { 12814 r.thread.dispatchPackageBroadcast(cmd, packages); 12815 } catch (RemoteException ex) { 12816 } 12817 } 12818 } 12819 } 12820 12821 private final int broadcastIntentLocked(ProcessRecord callerApp, 12822 String callerPackage, Intent intent, String resolvedType, 12823 IIntentReceiver resultTo, int resultCode, String resultData, 12824 Bundle map, String requiredPermission, 12825 boolean ordered, boolean sticky, int callingPid, int callingUid, 12826 int userId) { 12827 intent = new Intent(intent); 12828 12829 // By default broadcasts do not go to stopped apps. 12830 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 12831 12832 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12833 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12834 + " ordered=" + ordered + " userid=" + userId); 12835 if ((resultTo != null) && !ordered) { 12836 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12837 } 12838 12839 // Handle special intents: if this broadcast is from the package 12840 // manager about a package being removed, we need to remove all of 12841 // its activities from the history stack. 12842 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 12843 intent.getAction()); 12844 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12845 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12846 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12847 || uidRemoved) { 12848 if (checkComponentPermission( 12849 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12850 callingPid, callingUid, -1, true) 12851 == PackageManager.PERMISSION_GRANTED) { 12852 if (uidRemoved) { 12853 final Bundle intentExtras = intent.getExtras(); 12854 final int uid = intentExtras != null 12855 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12856 if (uid >= 0) { 12857 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12858 synchronized (bs) { 12859 bs.removeUidStatsLocked(uid); 12860 } 12861 } 12862 } else { 12863 // If resources are unvailble just force stop all 12864 // those packages and flush the attribute cache as well. 12865 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12866 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12867 if (list != null && (list.length > 0)) { 12868 for (String pkg : list) { 12869 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 12870 } 12871 sendPackageBroadcastLocked( 12872 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12873 } 12874 } else { 12875 Uri data = intent.getData(); 12876 String ssp; 12877 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12878 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12879 forceStopPackageLocked(ssp, 12880 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 12881 false, userId); 12882 } 12883 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12884 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12885 new String[] {ssp}); 12886 } 12887 } 12888 } 12889 } 12890 } else { 12891 String msg = "Permission Denial: " + intent.getAction() 12892 + " broadcast from " + callerPackage + " (pid=" + callingPid 12893 + ", uid=" + callingUid + ")" 12894 + " requires " 12895 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12896 Slog.w(TAG, msg); 12897 throw new SecurityException(msg); 12898 } 12899 12900 // Special case for adding a package: by default turn on compatibility 12901 // mode. 12902 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12903 Uri data = intent.getData(); 12904 String ssp; 12905 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12906 mCompatModePackages.handlePackageAddedLocked(ssp, 12907 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12908 } 12909 } 12910 12911 /* 12912 * If this is the time zone changed action, queue up a message that will reset the timezone 12913 * of all currently running processes. This message will get queued up before the broadcast 12914 * happens. 12915 */ 12916 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12917 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12918 } 12919 12920 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12921 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12922 } 12923 12924 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12925 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12926 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12927 } 12928 12929 /* 12930 * Prevent non-system code (defined here to be non-persistent 12931 * processes) from sending protected broadcasts. 12932 */ 12933 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12934 || callingUid == Process.SHELL_UID || callingUid == 0) { 12935 // Always okay. 12936 } else if (callerApp == null || !callerApp.persistent) { 12937 try { 12938 if (AppGlobals.getPackageManager().isProtectedBroadcast( 12939 intent.getAction())) { 12940 String msg = "Permission Denial: not allowed to send broadcast " 12941 + intent.getAction() + " from pid=" 12942 + callingPid + ", uid=" + callingUid; 12943 Slog.w(TAG, msg); 12944 throw new SecurityException(msg); 12945 } 12946 } catch (RemoteException e) { 12947 Slog.w(TAG, "Remote exception", e); 12948 return ActivityManager.BROADCAST_SUCCESS; 12949 } 12950 } 12951 12952 // Add to the sticky list if requested. 12953 if (sticky) { 12954 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12955 callingPid, callingUid) 12956 != PackageManager.PERMISSION_GRANTED) { 12957 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12958 + callingPid + ", uid=" + callingUid 12959 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12960 Slog.w(TAG, msg); 12961 throw new SecurityException(msg); 12962 } 12963 if (requiredPermission != null) { 12964 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12965 + " and enforce permission " + requiredPermission); 12966 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12967 } 12968 if (intent.getComponent() != null) { 12969 throw new SecurityException( 12970 "Sticky broadcasts can't target a specific component"); 12971 } 12972 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12973 if (list == null) { 12974 list = new ArrayList<Intent>(); 12975 mStickyBroadcasts.put(intent.getAction(), list); 12976 } 12977 int N = list.size(); 12978 int i; 12979 for (i=0; i<N; i++) { 12980 if (intent.filterEquals(list.get(i))) { 12981 // This sticky already exists, replace it. 12982 list.set(i, new Intent(intent)); 12983 break; 12984 } 12985 } 12986 if (i >= N) { 12987 list.add(new Intent(intent)); 12988 } 12989 } 12990 12991 // Figure out who all will receive this broadcast. 12992 List receivers = null; 12993 List<BroadcastFilter> registeredReceivers = null; 12994 try { 12995 if (intent.getComponent() != null) { 12996 // Broadcast is going to one specific receiver class... 12997 ActivityInfo ai = AppGlobals.getPackageManager(). 12998 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId); 12999 if (ai != null) { 13000 receivers = new ArrayList(); 13001 ResolveInfo ri = new ResolveInfo(); 13002 if (isSingleton(ai.processName, ai.applicationInfo)) { 13003 ri.activityInfo = getActivityInfoForUser(ai, 0); 13004 } else { 13005 ri.activityInfo = getActivityInfoForUser(ai, userId); 13006 } 13007 receivers.add(ri); 13008 } 13009 } else { 13010 // Need to resolve the intent to interested receivers... 13011 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13012 == 0) { 13013 receivers = 13014 AppGlobals.getPackageManager().queryIntentReceivers( 13015 intent, resolvedType, STOCK_PM_FLAGS, userId); 13016 } 13017 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, 13018 userId); 13019 } 13020 } catch (RemoteException ex) { 13021 // pm is in same process, this will never happen. 13022 } 13023 13024 final boolean replacePending = 13025 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13026 13027 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13028 + " replacePending=" + replacePending); 13029 13030 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13031 if (!ordered && NR > 0) { 13032 // If we are not serializing this broadcast, then send the 13033 // registered receivers separately so they don't wait for the 13034 // components to be launched. 13035 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13036 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13037 callerPackage, callingPid, callingUid, requiredPermission, 13038 registeredReceivers, resultTo, resultCode, resultData, map, 13039 ordered, sticky, false); 13040 if (DEBUG_BROADCAST) Slog.v( 13041 TAG, "Enqueueing parallel broadcast " + r); 13042 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13043 if (!replaced) { 13044 queue.enqueueParallelBroadcastLocked(r); 13045 queue.scheduleBroadcastsLocked(); 13046 } 13047 registeredReceivers = null; 13048 NR = 0; 13049 } 13050 13051 // Merge into one list. 13052 int ir = 0; 13053 if (receivers != null) { 13054 // A special case for PACKAGE_ADDED: do not allow the package 13055 // being added to see this broadcast. This prevents them from 13056 // using this as a back door to get run as soon as they are 13057 // installed. Maybe in the future we want to have a special install 13058 // broadcast or such for apps, but we'd like to deliberately make 13059 // this decision. 13060 String skipPackages[] = null; 13061 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13062 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13063 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13064 Uri data = intent.getData(); 13065 if (data != null) { 13066 String pkgName = data.getSchemeSpecificPart(); 13067 if (pkgName != null) { 13068 skipPackages = new String[] { pkgName }; 13069 } 13070 } 13071 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13072 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13073 } 13074 if (skipPackages != null && (skipPackages.length > 0)) { 13075 for (String skipPackage : skipPackages) { 13076 if (skipPackage != null) { 13077 int NT = receivers.size(); 13078 for (int it=0; it<NT; it++) { 13079 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13080 if (curt.activityInfo.packageName.equals(skipPackage)) { 13081 receivers.remove(it); 13082 it--; 13083 NT--; 13084 } 13085 } 13086 } 13087 } 13088 } 13089 13090 int NT = receivers != null ? receivers.size() : 0; 13091 int it = 0; 13092 ResolveInfo curt = null; 13093 BroadcastFilter curr = null; 13094 while (it < NT && ir < NR) { 13095 if (curt == null) { 13096 curt = (ResolveInfo)receivers.get(it); 13097 } 13098 if (curr == null) { 13099 curr = registeredReceivers.get(ir); 13100 } 13101 if (curr.getPriority() >= curt.priority) { 13102 // Insert this broadcast record into the final list. 13103 receivers.add(it, curr); 13104 ir++; 13105 curr = null; 13106 it++; 13107 NT++; 13108 } else { 13109 // Skip to the next ResolveInfo in the final list. 13110 it++; 13111 curt = null; 13112 } 13113 } 13114 } 13115 while (ir < NR) { 13116 if (receivers == null) { 13117 receivers = new ArrayList(); 13118 } 13119 receivers.add(registeredReceivers.get(ir)); 13120 ir++; 13121 } 13122 13123 if ((receivers != null && receivers.size() > 0) 13124 || resultTo != null) { 13125 BroadcastQueue queue = broadcastQueueForIntent(intent); 13126 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13127 callerPackage, callingPid, callingUid, requiredPermission, 13128 receivers, resultTo, resultCode, resultData, map, ordered, 13129 sticky, false); 13130 if (DEBUG_BROADCAST) Slog.v( 13131 TAG, "Enqueueing ordered broadcast " + r 13132 + ": prev had " + queue.mOrderedBroadcasts.size()); 13133 if (DEBUG_BROADCAST) { 13134 int seq = r.intent.getIntExtra("seq", -1); 13135 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13136 } 13137 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13138 if (!replaced) { 13139 queue.enqueueOrderedBroadcastLocked(r); 13140 queue.scheduleBroadcastsLocked(); 13141 } 13142 } 13143 13144 return ActivityManager.BROADCAST_SUCCESS; 13145 } 13146 13147 final Intent verifyBroadcastLocked(Intent intent) { 13148 // Refuse possible leaked file descriptors 13149 if (intent != null && intent.hasFileDescriptors() == true) { 13150 throw new IllegalArgumentException("File descriptors passed in Intent"); 13151 } 13152 13153 int flags = intent.getFlags(); 13154 13155 if (!mProcessesReady) { 13156 // if the caller really truly claims to know what they're doing, go 13157 // ahead and allow the broadcast without launching any receivers 13158 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13159 intent = new Intent(intent); 13160 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13161 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13162 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13163 + " before boot completion"); 13164 throw new IllegalStateException("Cannot broadcast before boot completed"); 13165 } 13166 } 13167 13168 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13169 throw new IllegalArgumentException( 13170 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13171 } 13172 13173 return intent; 13174 } 13175 13176 public final int broadcastIntent(IApplicationThread caller, 13177 Intent intent, String resolvedType, IIntentReceiver resultTo, 13178 int resultCode, String resultData, Bundle map, 13179 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13180 enforceNotIsolatedCaller("broadcastIntent"); 13181 synchronized(this) { 13182 intent = verifyBroadcastLocked(intent); 13183 13184 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13185 final int callingPid = Binder.getCallingPid(); 13186 final int callingUid = Binder.getCallingUid(); 13187 final long origId = Binder.clearCallingIdentity(); 13188 int res = broadcastIntentLocked(callerApp, 13189 callerApp != null ? callerApp.info.packageName : null, 13190 intent, resolvedType, resultTo, 13191 resultCode, resultData, map, requiredPermission, serialized, sticky, 13192 callingPid, callingUid, userId); 13193 Binder.restoreCallingIdentity(origId); 13194 return res; 13195 } 13196 } 13197 13198 int broadcastIntentInPackage(String packageName, int uid, 13199 Intent intent, String resolvedType, IIntentReceiver resultTo, 13200 int resultCode, String resultData, Bundle map, 13201 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13202 synchronized(this) { 13203 intent = verifyBroadcastLocked(intent); 13204 13205 final long origId = Binder.clearCallingIdentity(); 13206 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13207 resultTo, resultCode, resultData, map, requiredPermission, 13208 serialized, sticky, -1, uid, userId); 13209 Binder.restoreCallingIdentity(origId); 13210 return res; 13211 } 13212 } 13213 13214 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 13215 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13216 // Refuse possible leaked file descriptors 13217 if (intent != null && intent.hasFileDescriptors() == true) { 13218 throw new IllegalArgumentException("File descriptors passed in Intent"); 13219 } 13220 13221 synchronized(this) { 13222 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13223 != PackageManager.PERMISSION_GRANTED) { 13224 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13225 + Binder.getCallingPid() 13226 + ", uid=" + Binder.getCallingUid() 13227 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13228 Slog.w(TAG, msg); 13229 throw new SecurityException(msg); 13230 } 13231 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 13232 if (list != null) { 13233 int N = list.size(); 13234 int i; 13235 for (i=0; i<N; i++) { 13236 if (intent.filterEquals(list.get(i))) { 13237 list.remove(i); 13238 break; 13239 } 13240 } 13241 } 13242 } 13243 } 13244 13245 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13246 String resultData, Bundle resultExtras, boolean resultAbort, 13247 boolean explicit) { 13248 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13249 if (r == null) { 13250 Slog.w(TAG, "finishReceiver called but not found on queue"); 13251 return false; 13252 } 13253 13254 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 13255 explicit); 13256 } 13257 13258 public void finishReceiver(IBinder who, int resultCode, String resultData, 13259 Bundle resultExtras, boolean resultAbort) { 13260 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13261 13262 // Refuse possible leaked file descriptors 13263 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13264 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13265 } 13266 13267 final long origId = Binder.clearCallingIdentity(); 13268 try { 13269 boolean doNext = false; 13270 BroadcastRecord r = null; 13271 13272 synchronized(this) { 13273 r = broadcastRecordForReceiverLocked(who); 13274 if (r != null) { 13275 doNext = r.queue.finishReceiverLocked(r, resultCode, 13276 resultData, resultExtras, resultAbort, true); 13277 } 13278 } 13279 13280 if (doNext) { 13281 r.queue.processNextBroadcast(false); 13282 } 13283 trimApplications(); 13284 } finally { 13285 Binder.restoreCallingIdentity(origId); 13286 } 13287 } 13288 13289 // ========================================================= 13290 // INSTRUMENTATION 13291 // ========================================================= 13292 13293 public boolean startInstrumentation(ComponentName className, 13294 String profileFile, int flags, Bundle arguments, 13295 IInstrumentationWatcher watcher) { 13296 enforceNotIsolatedCaller("startInstrumentation"); 13297 // Refuse possible leaked file descriptors 13298 if (arguments != null && arguments.hasFileDescriptors()) { 13299 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13300 } 13301 13302 synchronized(this) { 13303 InstrumentationInfo ii = null; 13304 ApplicationInfo ai = null; 13305 try { 13306 ii = mContext.getPackageManager().getInstrumentationInfo( 13307 className, STOCK_PM_FLAGS); 13308 ai = mContext.getPackageManager().getApplicationInfo( 13309 ii.targetPackage, STOCK_PM_FLAGS); 13310 } catch (PackageManager.NameNotFoundException e) { 13311 } 13312 if (ii == null) { 13313 reportStartInstrumentationFailure(watcher, className, 13314 "Unable to find instrumentation info for: " + className); 13315 return false; 13316 } 13317 if (ai == null) { 13318 reportStartInstrumentationFailure(watcher, className, 13319 "Unable to find instrumentation target package: " + ii.targetPackage); 13320 return false; 13321 } 13322 13323 int match = mContext.getPackageManager().checkSignatures( 13324 ii.targetPackage, ii.packageName); 13325 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13326 String msg = "Permission Denial: starting instrumentation " 13327 + className + " from pid=" 13328 + Binder.getCallingPid() 13329 + ", uid=" + Binder.getCallingPid() 13330 + " not allowed because package " + ii.packageName 13331 + " does not have a signature matching the target " 13332 + ii.targetPackage; 13333 reportStartInstrumentationFailure(watcher, className, msg); 13334 throw new SecurityException(msg); 13335 } 13336 13337 int userId = UserId.getCallingUserId(); 13338 final long origId = Binder.clearCallingIdentity(); 13339 // Instrumentation can kill and relaunch even persistent processes 13340 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 13341 ProcessRecord app = addAppLocked(ai, false); 13342 app.instrumentationClass = className; 13343 app.instrumentationInfo = ai; 13344 app.instrumentationProfileFile = profileFile; 13345 app.instrumentationArguments = arguments; 13346 app.instrumentationWatcher = watcher; 13347 app.instrumentationResultClass = className; 13348 Binder.restoreCallingIdentity(origId); 13349 } 13350 13351 return true; 13352 } 13353 13354 /** 13355 * Report errors that occur while attempting to start Instrumentation. Always writes the 13356 * error to the logs, but if somebody is watching, send the report there too. This enables 13357 * the "am" command to report errors with more information. 13358 * 13359 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13360 * @param cn The component name of the instrumentation. 13361 * @param report The error report. 13362 */ 13363 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13364 ComponentName cn, String report) { 13365 Slog.w(TAG, report); 13366 try { 13367 if (watcher != null) { 13368 Bundle results = new Bundle(); 13369 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13370 results.putString("Error", report); 13371 watcher.instrumentationStatus(cn, -1, results); 13372 } 13373 } catch (RemoteException e) { 13374 Slog.w(TAG, e); 13375 } 13376 } 13377 13378 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13379 if (app.instrumentationWatcher != null) { 13380 try { 13381 // NOTE: IInstrumentationWatcher *must* be oneway here 13382 app.instrumentationWatcher.instrumentationFinished( 13383 app.instrumentationClass, 13384 resultCode, 13385 results); 13386 } catch (RemoteException e) { 13387 } 13388 } 13389 app.instrumentationWatcher = null; 13390 app.instrumentationClass = null; 13391 app.instrumentationInfo = null; 13392 app.instrumentationProfileFile = null; 13393 app.instrumentationArguments = null; 13394 13395 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 13396 } 13397 13398 public void finishInstrumentation(IApplicationThread target, 13399 int resultCode, Bundle results) { 13400 int userId = UserId.getCallingUserId(); 13401 // Refuse possible leaked file descriptors 13402 if (results != null && results.hasFileDescriptors()) { 13403 throw new IllegalArgumentException("File descriptors passed in Intent"); 13404 } 13405 13406 synchronized(this) { 13407 ProcessRecord app = getRecordForAppLocked(target); 13408 if (app == null) { 13409 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13410 return; 13411 } 13412 final long origId = Binder.clearCallingIdentity(); 13413 finishInstrumentationLocked(app, resultCode, results); 13414 Binder.restoreCallingIdentity(origId); 13415 } 13416 } 13417 13418 // ========================================================= 13419 // CONFIGURATION 13420 // ========================================================= 13421 13422 public ConfigurationInfo getDeviceConfigurationInfo() { 13423 ConfigurationInfo config = new ConfigurationInfo(); 13424 synchronized (this) { 13425 config.reqTouchScreen = mConfiguration.touchscreen; 13426 config.reqKeyboardType = mConfiguration.keyboard; 13427 config.reqNavigation = mConfiguration.navigation; 13428 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13429 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13430 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13431 } 13432 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13433 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13434 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13435 } 13436 config.reqGlEsVersion = GL_ES_VERSION; 13437 } 13438 return config; 13439 } 13440 13441 public Configuration getConfiguration() { 13442 Configuration ci; 13443 synchronized(this) { 13444 ci = new Configuration(mConfiguration); 13445 } 13446 return ci; 13447 } 13448 13449 public void updatePersistentConfiguration(Configuration values) { 13450 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13451 "updateConfiguration()"); 13452 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13453 "updateConfiguration()"); 13454 if (values == null) { 13455 throw new NullPointerException("Configuration must not be null"); 13456 } 13457 13458 synchronized(this) { 13459 final long origId = Binder.clearCallingIdentity(); 13460 updateConfigurationLocked(values, null, true, false); 13461 Binder.restoreCallingIdentity(origId); 13462 } 13463 } 13464 13465 public void updateConfiguration(Configuration values) { 13466 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13467 "updateConfiguration()"); 13468 13469 synchronized(this) { 13470 if (values == null && mWindowManager != null) { 13471 // sentinel: fetch the current configuration from the window manager 13472 values = mWindowManager.computeNewConfiguration(); 13473 } 13474 13475 if (mWindowManager != null) { 13476 mProcessList.applyDisplaySize(mWindowManager); 13477 } 13478 13479 final long origId = Binder.clearCallingIdentity(); 13480 if (values != null) { 13481 Settings.System.clearConfiguration(values); 13482 } 13483 updateConfigurationLocked(values, null, false, false); 13484 Binder.restoreCallingIdentity(origId); 13485 } 13486 } 13487 13488 /** 13489 * Do either or both things: (1) change the current configuration, and (2) 13490 * make sure the given activity is running with the (now) current 13491 * configuration. Returns true if the activity has been left running, or 13492 * false if <var>starting</var> is being destroyed to match the new 13493 * configuration. 13494 * @param persistent TODO 13495 */ 13496 boolean updateConfigurationLocked(Configuration values, 13497 ActivityRecord starting, boolean persistent, boolean initLocale) { 13498 // do nothing if we are headless 13499 if (mHeadless) return true; 13500 13501 int changes = 0; 13502 13503 boolean kept = true; 13504 13505 if (values != null) { 13506 Configuration newConfig = new Configuration(mConfiguration); 13507 changes = newConfig.updateFrom(values); 13508 if (changes != 0) { 13509 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13510 Slog.i(TAG, "Updating configuration to: " + values); 13511 } 13512 13513 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13514 13515 if (values.locale != null && !initLocale) { 13516 saveLocaleLocked(values.locale, 13517 !values.locale.equals(mConfiguration.locale), 13518 values.userSetLocale); 13519 } 13520 13521 mConfigurationSeq++; 13522 if (mConfigurationSeq <= 0) { 13523 mConfigurationSeq = 1; 13524 } 13525 newConfig.seq = mConfigurationSeq; 13526 mConfiguration = newConfig; 13527 Slog.i(TAG, "Config changed: " + newConfig); 13528 13529 final Configuration configCopy = new Configuration(mConfiguration); 13530 13531 // TODO: If our config changes, should we auto dismiss any currently 13532 // showing dialogs? 13533 mShowDialogs = shouldShowDialogs(newConfig); 13534 13535 AttributeCache ac = AttributeCache.instance(); 13536 if (ac != null) { 13537 ac.updateConfiguration(configCopy); 13538 } 13539 13540 // Make sure all resources in our process are updated 13541 // right now, so that anyone who is going to retrieve 13542 // resource values after we return will be sure to get 13543 // the new ones. This is especially important during 13544 // boot, where the first config change needs to guarantee 13545 // all resources have that config before following boot 13546 // code is executed. 13547 mSystemThread.applyConfigurationToResources(configCopy); 13548 13549 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13550 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13551 msg.obj = new Configuration(configCopy); 13552 mHandler.sendMessage(msg); 13553 } 13554 13555 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13556 ProcessRecord app = mLruProcesses.get(i); 13557 try { 13558 if (app.thread != null) { 13559 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13560 + app.processName + " new config " + mConfiguration); 13561 app.thread.scheduleConfigurationChanged(configCopy); 13562 } 13563 } catch (Exception e) { 13564 } 13565 } 13566 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13567 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13568 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13569 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13570 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13571 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13572 broadcastIntentLocked(null, null, 13573 new Intent(Intent.ACTION_LOCALE_CHANGED), 13574 null, null, 0, null, null, 13575 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13576 } 13577 } 13578 } 13579 13580 if (changes != 0 && starting == null) { 13581 // If the configuration changed, and the caller is not already 13582 // in the process of starting an activity, then find the top 13583 // activity to check if its configuration needs to change. 13584 starting = mMainStack.topRunningActivityLocked(null); 13585 } 13586 13587 if (starting != null) { 13588 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 13589 // And we need to make sure at this point that all other activities 13590 // are made visible with the correct configuration. 13591 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 13592 } 13593 13594 if (values != null && mWindowManager != null) { 13595 mWindowManager.setNewConfiguration(mConfiguration); 13596 } 13597 13598 return kept; 13599 } 13600 13601 /** 13602 * Decide based on the configuration whether we should shouw the ANR, 13603 * crash, etc dialogs. The idea is that if there is no affordnace to 13604 * press the on-screen buttons, we shouldn't show the dialog. 13605 * 13606 * A thought: SystemUI might also want to get told about this, the Power 13607 * dialog / global actions also might want different behaviors. 13608 */ 13609 private static final boolean shouldShowDialogs(Configuration config) { 13610 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 13611 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 13612 } 13613 13614 /** 13615 * Save the locale. You must be inside a synchronized (this) block. 13616 */ 13617 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13618 if(isDiff) { 13619 SystemProperties.set("user.language", l.getLanguage()); 13620 SystemProperties.set("user.region", l.getCountry()); 13621 } 13622 13623 if(isPersist) { 13624 SystemProperties.set("persist.sys.language", l.getLanguage()); 13625 SystemProperties.set("persist.sys.country", l.getCountry()); 13626 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13627 } 13628 } 13629 13630 @Override 13631 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 13632 ActivityRecord srec = ActivityRecord.forToken(token); 13633 return srec != null && srec.task.affinity != null && 13634 srec.task.affinity.equals(destAffinity); 13635 } 13636 13637 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 13638 Intent resultData) { 13639 ComponentName dest = destIntent.getComponent(); 13640 13641 synchronized (this) { 13642 ActivityRecord srec = ActivityRecord.forToken(token); 13643 if (srec == null) { 13644 return false; 13645 } 13646 ArrayList<ActivityRecord> history = srec.stack.mHistory; 13647 final int start = history.indexOf(srec); 13648 if (start < 0) { 13649 // Current activity is not in history stack; do nothing. 13650 return false; 13651 } 13652 int finishTo = start - 1; 13653 ActivityRecord parent = null; 13654 boolean foundParentInTask = false; 13655 if (dest != null) { 13656 TaskRecord tr = srec.task; 13657 for (int i = start - 1; i >= 0; i--) { 13658 ActivityRecord r = history.get(i); 13659 if (tr != r.task) { 13660 // Couldn't find parent in the same task; stop at the one above this. 13661 // (Root of current task; in-app "home" behavior) 13662 // Always at least finish the current activity. 13663 finishTo = Math.min(start - 1, i + 1); 13664 parent = history.get(finishTo); 13665 break; 13666 } else if (r.info.packageName.equals(dest.getPackageName()) && 13667 r.info.name.equals(dest.getClassName())) { 13668 finishTo = i; 13669 parent = r; 13670 foundParentInTask = true; 13671 break; 13672 } 13673 } 13674 } 13675 13676 if (mController != null) { 13677 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 13678 if (next != null) { 13679 // ask watcher if this is allowed 13680 boolean resumeOK = true; 13681 try { 13682 resumeOK = mController.activityResuming(next.packageName); 13683 } catch (RemoteException e) { 13684 mController = null; 13685 } 13686 13687 if (!resumeOK) { 13688 return false; 13689 } 13690 } 13691 } 13692 final long origId = Binder.clearCallingIdentity(); 13693 for (int i = start; i > finishTo; i--) { 13694 ActivityRecord r = history.get(i); 13695 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 13696 "navigate-up"); 13697 // Only return the supplied result for the first activity finished 13698 resultCode = Activity.RESULT_CANCELED; 13699 resultData = null; 13700 } 13701 13702 if (parent != null && foundParentInTask) { 13703 final int parentLaunchMode = parent.info.launchMode; 13704 final int destIntentFlags = destIntent.getFlags(); 13705 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 13706 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 13707 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 13708 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 13709 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 13710 } else { 13711 try { 13712 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 13713 destIntent.getComponent(), 0, UserId.getCallingUserId()); 13714 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 13715 null, aInfo, parent.appToken, null, 13716 0, -1, parent.launchedFromUid, 0, null, true, null); 13717 foundParentInTask = res == ActivityManager.START_SUCCESS; 13718 } catch (RemoteException e) { 13719 foundParentInTask = false; 13720 } 13721 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 13722 resultData, "navigate-up"); 13723 } 13724 } 13725 Binder.restoreCallingIdentity(origId); 13726 return foundParentInTask; 13727 } 13728 } 13729 13730 public int getLaunchedFromUid(IBinder activityToken) { 13731 ActivityRecord srec = ActivityRecord.forToken(activityToken); 13732 if (srec == null) { 13733 return -1; 13734 } 13735 return srec.launchedFromUid; 13736 } 13737 13738 // ========================================================= 13739 // LIFETIME MANAGEMENT 13740 // ========================================================= 13741 13742 // Returns which broadcast queue the app is the current [or imminent] receiver 13743 // on, or 'null' if the app is not an active broadcast recipient. 13744 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 13745 BroadcastRecord r = app.curReceiver; 13746 if (r != null) { 13747 return r.queue; 13748 } 13749 13750 // It's not the current receiver, but it might be starting up to become one 13751 synchronized (this) { 13752 for (BroadcastQueue queue : mBroadcastQueues) { 13753 r = queue.mPendingBroadcast; 13754 if (r != null && r.curApp == app) { 13755 // found it; report which queue it's in 13756 return queue; 13757 } 13758 } 13759 } 13760 13761 return null; 13762 } 13763 13764 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13765 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 13766 if (mAdjSeq == app.adjSeq) { 13767 // This adjustment has already been computed. If we are calling 13768 // from the top, we may have already computed our adjustment with 13769 // an earlier hidden adjustment that isn't really for us... if 13770 // so, use the new hidden adjustment. 13771 if (!recursed && app.hidden) { 13772 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 13773 } 13774 return app.curRawAdj; 13775 } 13776 13777 if (app.thread == null) { 13778 app.adjSeq = mAdjSeq; 13779 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13780 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 13781 } 13782 13783 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13784 app.adjSource = null; 13785 app.adjTarget = null; 13786 app.empty = false; 13787 app.hidden = false; 13788 13789 final int activitiesSize = app.activities.size(); 13790 13791 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13792 // The max adjustment doesn't allow this app to be anything 13793 // below foreground, so it is not worth doing work for it. 13794 app.adjType = "fixed"; 13795 app.adjSeq = mAdjSeq; 13796 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 13797 app.foregroundActivities = false; 13798 app.keeping = true; 13799 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13800 // System process can do UI, and when they do we want to have 13801 // them trim their memory after the user leaves the UI. To 13802 // facilitate this, here we need to determine whether or not it 13803 // is currently showing UI. 13804 app.systemNoUi = true; 13805 if (app == TOP_APP) { 13806 app.systemNoUi = false; 13807 } else if (activitiesSize > 0) { 13808 for (int j = 0; j < activitiesSize; j++) { 13809 final ActivityRecord r = app.activities.get(j); 13810 if (r.visible) { 13811 app.systemNoUi = false; 13812 break; 13813 } 13814 } 13815 } 13816 return (app.curAdj=app.maxAdj); 13817 } 13818 13819 app.keeping = false; 13820 app.systemNoUi = false; 13821 13822 // Determine the importance of the process, starting with most 13823 // important to least, and assign an appropriate OOM adjustment. 13824 int adj; 13825 int schedGroup; 13826 boolean foregroundActivities = false; 13827 boolean interesting = false; 13828 BroadcastQueue queue; 13829 if (app == TOP_APP) { 13830 // The last app on the list is the foreground app. 13831 adj = ProcessList.FOREGROUND_APP_ADJ; 13832 schedGroup = Process.THREAD_GROUP_DEFAULT; 13833 app.adjType = "top-activity"; 13834 foregroundActivities = true; 13835 interesting = true; 13836 } else if (app.instrumentationClass != null) { 13837 // Don't want to kill running instrumentation. 13838 adj = ProcessList.FOREGROUND_APP_ADJ; 13839 schedGroup = Process.THREAD_GROUP_DEFAULT; 13840 app.adjType = "instrumentation"; 13841 interesting = true; 13842 } else if ((queue = isReceivingBroadcast(app)) != null) { 13843 // An app that is currently receiving a broadcast also 13844 // counts as being in the foreground for OOM killer purposes. 13845 // It's placed in a sched group based on the nature of the 13846 // broadcast as reflected by which queue it's active in. 13847 adj = ProcessList.FOREGROUND_APP_ADJ; 13848 schedGroup = (queue == mFgBroadcastQueue) 13849 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 13850 app.adjType = "broadcast"; 13851 } else if (app.executingServices.size() > 0) { 13852 // An app that is currently executing a service callback also 13853 // counts as being in the foreground. 13854 adj = ProcessList.FOREGROUND_APP_ADJ; 13855 schedGroup = Process.THREAD_GROUP_DEFAULT; 13856 app.adjType = "exec-service"; 13857 } else if (activitiesSize > 0) { 13858 // This app is in the background with paused activities. 13859 // We inspect activities to potentially upgrade adjustment further below. 13860 adj = hiddenAdj; 13861 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13862 app.hidden = true; 13863 app.adjType = "bg-activities"; 13864 } else { 13865 // A very not-needed process. If this is lower in the lru list, 13866 // we will push it in to the empty bucket. 13867 adj = hiddenAdj; 13868 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13869 app.hidden = true; 13870 app.empty = true; 13871 app.adjType = "bg-empty"; 13872 } 13873 13874 boolean hasStoppingActivities = false; 13875 13876 // Examine all activities if not already foreground. 13877 if (!foregroundActivities && activitiesSize > 0) { 13878 for (int j = 0; j < activitiesSize; j++) { 13879 final ActivityRecord r = app.activities.get(j); 13880 if (r.visible) { 13881 // App has a visible activity; only upgrade adjustment. 13882 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13883 adj = ProcessList.VISIBLE_APP_ADJ; 13884 app.adjType = "visible"; 13885 } 13886 schedGroup = Process.THREAD_GROUP_DEFAULT; 13887 app.hidden = false; 13888 foregroundActivities = true; 13889 break; 13890 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 13891 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13892 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13893 app.adjType = "pausing"; 13894 } 13895 app.hidden = false; 13896 foregroundActivities = true; 13897 } else if (r.state == ActivityState.STOPPING) { 13898 // We will apply the actual adjustment later, because 13899 // we want to allow this process to immediately go through 13900 // any memory trimming that is in effect. 13901 app.hidden = false; 13902 foregroundActivities = true; 13903 hasStoppingActivities = true; 13904 } 13905 } 13906 } 13907 13908 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13909 if (app.foregroundServices) { 13910 // The user is aware of this app, so make it visible. 13911 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13912 app.hidden = false; 13913 app.adjType = "foreground-service"; 13914 schedGroup = Process.THREAD_GROUP_DEFAULT; 13915 } else if (app.forcingToForeground != null) { 13916 // The user is aware of this app, so make it visible. 13917 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13918 app.hidden = false; 13919 app.adjType = "force-foreground"; 13920 app.adjSource = app.forcingToForeground; 13921 schedGroup = Process.THREAD_GROUP_DEFAULT; 13922 } 13923 } 13924 13925 if (app.foregroundServices) { 13926 interesting = true; 13927 } 13928 13929 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13930 // We don't want to kill the current heavy-weight process. 13931 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13932 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13933 app.hidden = false; 13934 app.adjType = "heavy"; 13935 } 13936 13937 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13938 // This process is hosting what we currently consider to be the 13939 // home app, so we don't want to let it go into the background. 13940 adj = ProcessList.HOME_APP_ADJ; 13941 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13942 app.hidden = false; 13943 app.adjType = "home"; 13944 } 13945 13946 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13947 && app.activities.size() > 0) { 13948 // This was the previous process that showed UI to the user. 13949 // We want to try to keep it around more aggressively, to give 13950 // a good experience around switching between two apps. 13951 adj = ProcessList.PREVIOUS_APP_ADJ; 13952 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13953 app.hidden = false; 13954 app.adjType = "previous"; 13955 } 13956 13957 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13958 + " reason=" + app.adjType); 13959 13960 // By default, we use the computed adjustment. It may be changed if 13961 // there are applications dependent on our services or providers, but 13962 // this gives us a baseline and makes sure we don't get into an 13963 // infinite recursion. 13964 app.adjSeq = mAdjSeq; 13965 app.curRawAdj = app.nonStoppingAdj = adj; 13966 13967 if (mBackupTarget != null && app == mBackupTarget.app) { 13968 // If possible we want to avoid killing apps while they're being backed up 13969 if (adj > ProcessList.BACKUP_APP_ADJ) { 13970 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13971 adj = ProcessList.BACKUP_APP_ADJ; 13972 app.adjType = "backup"; 13973 app.hidden = false; 13974 } 13975 } 13976 13977 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13978 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13979 final long now = SystemClock.uptimeMillis(); 13980 // This process is more important if the top activity is 13981 // bound to the service. 13982 Iterator<ServiceRecord> jt = app.services.iterator(); 13983 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13984 ServiceRecord s = jt.next(); 13985 if (s.startRequested) { 13986 if (app.hasShownUi && app != mHomeProcess) { 13987 // If this process has shown some UI, let it immediately 13988 // go to the LRU list because it may be pretty heavy with 13989 // UI stuff. We'll tag it with a label just to help 13990 // debug and understand what is going on. 13991 if (adj > ProcessList.SERVICE_ADJ) { 13992 app.adjType = "started-bg-ui-services"; 13993 } 13994 } else { 13995 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13996 // This service has seen some activity within 13997 // recent memory, so we will keep its process ahead 13998 // of the background processes. 13999 if (adj > ProcessList.SERVICE_ADJ) { 14000 adj = ProcessList.SERVICE_ADJ; 14001 app.adjType = "started-services"; 14002 app.hidden = false; 14003 } 14004 } 14005 // If we have let the service slide into the background 14006 // state, still have some text describing what it is doing 14007 // even though the service no longer has an impact. 14008 if (adj > ProcessList.SERVICE_ADJ) { 14009 app.adjType = "started-bg-services"; 14010 } 14011 } 14012 // Don't kill this process because it is doing work; it 14013 // has said it is doing work. 14014 app.keeping = true; 14015 } 14016 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14017 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14018 Iterator<ArrayList<ConnectionRecord>> kt 14019 = s.connections.values().iterator(); 14020 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 14021 ArrayList<ConnectionRecord> clist = kt.next(); 14022 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 14023 // XXX should compute this based on the max of 14024 // all connected clients. 14025 ConnectionRecord cr = clist.get(i); 14026 if (cr.binding.client == app) { 14027 // Binding to ourself is not interesting. 14028 continue; 14029 } 14030 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14031 ProcessRecord client = cr.binding.client; 14032 int clientAdj = adj; 14033 int myHiddenAdj = hiddenAdj; 14034 if (myHiddenAdj > client.hiddenAdj) { 14035 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 14036 myHiddenAdj = client.hiddenAdj; 14037 } else { 14038 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 14039 } 14040 } 14041 clientAdj = computeOomAdjLocked( 14042 client, myHiddenAdj, TOP_APP, true, doingAll); 14043 String adjType = null; 14044 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14045 // Not doing bind OOM management, so treat 14046 // this guy more like a started service. 14047 if (app.hasShownUi && app != mHomeProcess) { 14048 // If this process has shown some UI, let it immediately 14049 // go to the LRU list because it may be pretty heavy with 14050 // UI stuff. We'll tag it with a label just to help 14051 // debug and understand what is going on. 14052 if (adj > clientAdj) { 14053 adjType = "bound-bg-ui-services"; 14054 } 14055 app.hidden = false; 14056 clientAdj = adj; 14057 } else { 14058 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 14059 // This service has not seen activity within 14060 // recent memory, so allow it to drop to the 14061 // LRU list if there is no other reason to keep 14062 // it around. We'll also tag it with a label just 14063 // to help debug and undertand what is going on. 14064 if (adj > clientAdj) { 14065 adjType = "bound-bg-services"; 14066 } 14067 clientAdj = adj; 14068 } 14069 } 14070 } 14071 if (adj > clientAdj) { 14072 // If this process has recently shown UI, and 14073 // the process that is binding to it is less 14074 // important than being visible, then we don't 14075 // care about the binding as much as we care 14076 // about letting this process get into the LRU 14077 // list to be killed and restarted if needed for 14078 // memory. 14079 if (app.hasShownUi && app != mHomeProcess 14080 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14081 adjType = "bound-bg-ui-services"; 14082 } else { 14083 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14084 |Context.BIND_IMPORTANT)) != 0) { 14085 adj = clientAdj; 14086 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14087 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14088 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14089 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14090 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14091 adj = clientAdj; 14092 } else { 14093 app.pendingUiClean = true; 14094 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14095 adj = ProcessList.VISIBLE_APP_ADJ; 14096 } 14097 } 14098 if (!client.hidden) { 14099 app.hidden = false; 14100 } 14101 if (client.keeping) { 14102 app.keeping = true; 14103 } 14104 adjType = "service"; 14105 } 14106 } 14107 if (adjType != null) { 14108 app.adjType = adjType; 14109 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14110 .REASON_SERVICE_IN_USE; 14111 app.adjSource = cr.binding.client; 14112 app.adjSourceOom = clientAdj; 14113 app.adjTarget = s.name; 14114 } 14115 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14116 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14117 schedGroup = Process.THREAD_GROUP_DEFAULT; 14118 } 14119 } 14120 } 14121 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14122 ActivityRecord a = cr.activity; 14123 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14124 (a.visible || a.state == ActivityState.RESUMED 14125 || a.state == ActivityState.PAUSING)) { 14126 adj = ProcessList.FOREGROUND_APP_ADJ; 14127 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14128 schedGroup = Process.THREAD_GROUP_DEFAULT; 14129 } 14130 app.hidden = false; 14131 app.adjType = "service"; 14132 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14133 .REASON_SERVICE_IN_USE; 14134 app.adjSource = a; 14135 app.adjSourceOom = adj; 14136 app.adjTarget = s.name; 14137 } 14138 } 14139 } 14140 } 14141 } 14142 } 14143 14144 // Finally, if this process has active services running in it, we 14145 // would like to avoid killing it unless it would prevent the current 14146 // application from running. By default we put the process in 14147 // with the rest of the background processes; as we scan through 14148 // its services we may bump it up from there. 14149 if (adj > hiddenAdj) { 14150 adj = hiddenAdj; 14151 app.hidden = false; 14152 app.adjType = "bg-services"; 14153 } 14154 } 14155 14156 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14157 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14158 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 14159 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 14160 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14161 ContentProviderRecord cpr = jt.next(); 14162 for (int i = cpr.connections.size()-1; 14163 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14164 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 14165 i--) { 14166 ContentProviderConnection conn = cpr.connections.get(i); 14167 ProcessRecord client = conn.client; 14168 if (client == app) { 14169 // Being our own client is not interesting. 14170 continue; 14171 } 14172 int myHiddenAdj = hiddenAdj; 14173 if (myHiddenAdj > client.hiddenAdj) { 14174 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 14175 myHiddenAdj = client.hiddenAdj; 14176 } else { 14177 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 14178 } 14179 } 14180 int clientAdj = computeOomAdjLocked( 14181 client, myHiddenAdj, TOP_APP, true, doingAll); 14182 if (adj > clientAdj) { 14183 if (app.hasShownUi && app != mHomeProcess 14184 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14185 app.adjType = "bg-ui-provider"; 14186 } else { 14187 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14188 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14189 app.adjType = "provider"; 14190 } 14191 if (!client.hidden) { 14192 app.hidden = false; 14193 } 14194 if (client.keeping) { 14195 app.keeping = true; 14196 } 14197 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14198 .REASON_PROVIDER_IN_USE; 14199 app.adjSource = client; 14200 app.adjSourceOom = clientAdj; 14201 app.adjTarget = cpr.name; 14202 } 14203 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14204 schedGroup = Process.THREAD_GROUP_DEFAULT; 14205 } 14206 } 14207 // If the provider has external (non-framework) process 14208 // dependencies, ensure that its adjustment is at least 14209 // FOREGROUND_APP_ADJ. 14210 if (cpr.hasExternalProcessHandles()) { 14211 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14212 adj = ProcessList.FOREGROUND_APP_ADJ; 14213 schedGroup = Process.THREAD_GROUP_DEFAULT; 14214 app.hidden = false; 14215 app.keeping = true; 14216 app.adjType = "provider"; 14217 app.adjTarget = cpr.name; 14218 } 14219 } 14220 } 14221 } 14222 14223 if (adj == ProcessList.SERVICE_ADJ) { 14224 if (doingAll) { 14225 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 14226 mNewNumServiceProcs++; 14227 } 14228 if (app.serviceb) { 14229 adj = ProcessList.SERVICE_B_ADJ; 14230 } 14231 } else { 14232 app.serviceb = false; 14233 } 14234 14235 app.nonStoppingAdj = adj; 14236 14237 if (hasStoppingActivities) { 14238 // Only upgrade adjustment. 14239 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14240 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14241 app.adjType = "stopping"; 14242 } 14243 } 14244 14245 app.curRawAdj = adj; 14246 14247 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14248 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14249 if (adj > app.maxAdj) { 14250 adj = app.maxAdj; 14251 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14252 schedGroup = Process.THREAD_GROUP_DEFAULT; 14253 } 14254 } 14255 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14256 app.keeping = true; 14257 } 14258 14259 if (app.hasAboveClient) { 14260 // If this process has bound to any services with BIND_ABOVE_CLIENT, 14261 // then we need to drop its adjustment to be lower than the service's 14262 // in order to honor the request. We want to drop it by one adjustment 14263 // level... but there is special meaning applied to various levels so 14264 // we will skip some of them. 14265 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 14266 // System process will not get dropped, ever 14267 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 14268 adj = ProcessList.VISIBLE_APP_ADJ; 14269 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 14270 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14271 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14272 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 14273 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 14274 adj++; 14275 } 14276 } 14277 14278 int importance = app.memImportance; 14279 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14280 app.curAdj = adj; 14281 app.curSchedGroup = schedGroup; 14282 if (!interesting) { 14283 // For this reporting, if there is not something explicitly 14284 // interesting in this process then we will push it to the 14285 // background importance. 14286 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14287 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14288 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14289 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14290 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14291 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14292 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14293 } else if (adj >= ProcessList.SERVICE_ADJ) { 14294 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14295 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14296 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14297 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14298 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14299 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14300 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14301 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14302 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14303 } else { 14304 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14305 } 14306 } 14307 14308 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14309 if (foregroundActivities != app.foregroundActivities) { 14310 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14311 } 14312 if (changes != 0) { 14313 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14314 app.memImportance = importance; 14315 app.foregroundActivities = foregroundActivities; 14316 int i = mPendingProcessChanges.size()-1; 14317 ProcessChangeItem item = null; 14318 while (i >= 0) { 14319 item = mPendingProcessChanges.get(i); 14320 if (item.pid == app.pid) { 14321 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14322 break; 14323 } 14324 i--; 14325 } 14326 if (i < 0) { 14327 // No existing item in pending changes; need a new one. 14328 final int NA = mAvailProcessChanges.size(); 14329 if (NA > 0) { 14330 item = mAvailProcessChanges.remove(NA-1); 14331 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14332 } else { 14333 item = new ProcessChangeItem(); 14334 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14335 } 14336 item.changes = 0; 14337 item.pid = app.pid; 14338 item.uid = app.info.uid; 14339 if (mPendingProcessChanges.size() == 0) { 14340 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14341 "*** Enqueueing dispatch processes changed!"); 14342 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14343 } 14344 mPendingProcessChanges.add(item); 14345 } 14346 item.changes |= changes; 14347 item.importance = importance; 14348 item.foregroundActivities = foregroundActivities; 14349 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14350 + Integer.toHexString(System.identityHashCode(item)) 14351 + " " + app.toShortString() + ": changes=" + item.changes 14352 + " importance=" + item.importance 14353 + " foreground=" + item.foregroundActivities 14354 + " type=" + app.adjType + " source=" + app.adjSource 14355 + " target=" + app.adjTarget); 14356 } 14357 14358 return app.curRawAdj; 14359 } 14360 14361 /** 14362 * Ask a given process to GC right now. 14363 */ 14364 final void performAppGcLocked(ProcessRecord app) { 14365 try { 14366 app.lastRequestedGc = SystemClock.uptimeMillis(); 14367 if (app.thread != null) { 14368 if (app.reportLowMemory) { 14369 app.reportLowMemory = false; 14370 app.thread.scheduleLowMemory(); 14371 } else { 14372 app.thread.processInBackground(); 14373 } 14374 } 14375 } catch (Exception e) { 14376 // whatever. 14377 } 14378 } 14379 14380 /** 14381 * Returns true if things are idle enough to perform GCs. 14382 */ 14383 private final boolean canGcNowLocked() { 14384 boolean processingBroadcasts = false; 14385 for (BroadcastQueue q : mBroadcastQueues) { 14386 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14387 processingBroadcasts = true; 14388 } 14389 } 14390 return !processingBroadcasts 14391 && (mSleeping || (mMainStack.mResumedActivity != null && 14392 mMainStack.mResumedActivity.idle)); 14393 } 14394 14395 /** 14396 * Perform GCs on all processes that are waiting for it, but only 14397 * if things are idle. 14398 */ 14399 final void performAppGcsLocked() { 14400 final int N = mProcessesToGc.size(); 14401 if (N <= 0) { 14402 return; 14403 } 14404 if (canGcNowLocked()) { 14405 while (mProcessesToGc.size() > 0) { 14406 ProcessRecord proc = mProcessesToGc.remove(0); 14407 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14408 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14409 <= SystemClock.uptimeMillis()) { 14410 // To avoid spamming the system, we will GC processes one 14411 // at a time, waiting a few seconds between each. 14412 performAppGcLocked(proc); 14413 scheduleAppGcsLocked(); 14414 return; 14415 } else { 14416 // It hasn't been long enough since we last GCed this 14417 // process... put it in the list to wait for its time. 14418 addProcessToGcListLocked(proc); 14419 break; 14420 } 14421 } 14422 } 14423 14424 scheduleAppGcsLocked(); 14425 } 14426 } 14427 14428 /** 14429 * If all looks good, perform GCs on all processes waiting for them. 14430 */ 14431 final void performAppGcsIfAppropriateLocked() { 14432 if (canGcNowLocked()) { 14433 performAppGcsLocked(); 14434 return; 14435 } 14436 // Still not idle, wait some more. 14437 scheduleAppGcsLocked(); 14438 } 14439 14440 /** 14441 * Schedule the execution of all pending app GCs. 14442 */ 14443 final void scheduleAppGcsLocked() { 14444 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14445 14446 if (mProcessesToGc.size() > 0) { 14447 // Schedule a GC for the time to the next process. 14448 ProcessRecord proc = mProcessesToGc.get(0); 14449 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14450 14451 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14452 long now = SystemClock.uptimeMillis(); 14453 if (when < (now+GC_TIMEOUT)) { 14454 when = now + GC_TIMEOUT; 14455 } 14456 mHandler.sendMessageAtTime(msg, when); 14457 } 14458 } 14459 14460 /** 14461 * Add a process to the array of processes waiting to be GCed. Keeps the 14462 * list in sorted order by the last GC time. The process can't already be 14463 * on the list. 14464 */ 14465 final void addProcessToGcListLocked(ProcessRecord proc) { 14466 boolean added = false; 14467 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14468 if (mProcessesToGc.get(i).lastRequestedGc < 14469 proc.lastRequestedGc) { 14470 added = true; 14471 mProcessesToGc.add(i+1, proc); 14472 break; 14473 } 14474 } 14475 if (!added) { 14476 mProcessesToGc.add(0, proc); 14477 } 14478 } 14479 14480 /** 14481 * Set up to ask a process to GC itself. This will either do it 14482 * immediately, or put it on the list of processes to gc the next 14483 * time things are idle. 14484 */ 14485 final void scheduleAppGcLocked(ProcessRecord app) { 14486 long now = SystemClock.uptimeMillis(); 14487 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14488 return; 14489 } 14490 if (!mProcessesToGc.contains(app)) { 14491 addProcessToGcListLocked(app); 14492 scheduleAppGcsLocked(); 14493 } 14494 } 14495 14496 final void checkExcessivePowerUsageLocked(boolean doKills) { 14497 updateCpuStatsNow(); 14498 14499 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14500 boolean doWakeKills = doKills; 14501 boolean doCpuKills = doKills; 14502 if (mLastPowerCheckRealtime == 0) { 14503 doWakeKills = false; 14504 } 14505 if (mLastPowerCheckUptime == 0) { 14506 doCpuKills = false; 14507 } 14508 if (stats.isScreenOn()) { 14509 doWakeKills = false; 14510 } 14511 final long curRealtime = SystemClock.elapsedRealtime(); 14512 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14513 final long curUptime = SystemClock.uptimeMillis(); 14514 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14515 mLastPowerCheckRealtime = curRealtime; 14516 mLastPowerCheckUptime = curUptime; 14517 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14518 doWakeKills = false; 14519 } 14520 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14521 doCpuKills = false; 14522 } 14523 int i = mLruProcesses.size(); 14524 while (i > 0) { 14525 i--; 14526 ProcessRecord app = mLruProcesses.get(i); 14527 if (!app.keeping) { 14528 long wtime; 14529 synchronized (stats) { 14530 wtime = stats.getProcessWakeTime(app.info.uid, 14531 app.pid, curRealtime); 14532 } 14533 long wtimeUsed = wtime - app.lastWakeTime; 14534 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14535 if (DEBUG_POWER) { 14536 StringBuilder sb = new StringBuilder(128); 14537 sb.append("Wake for "); 14538 app.toShortString(sb); 14539 sb.append(": over "); 14540 TimeUtils.formatDuration(realtimeSince, sb); 14541 sb.append(" used "); 14542 TimeUtils.formatDuration(wtimeUsed, sb); 14543 sb.append(" ("); 14544 sb.append((wtimeUsed*100)/realtimeSince); 14545 sb.append("%)"); 14546 Slog.i(TAG, sb.toString()); 14547 sb.setLength(0); 14548 sb.append("CPU for "); 14549 app.toShortString(sb); 14550 sb.append(": over "); 14551 TimeUtils.formatDuration(uptimeSince, sb); 14552 sb.append(" used "); 14553 TimeUtils.formatDuration(cputimeUsed, sb); 14554 sb.append(" ("); 14555 sb.append((cputimeUsed*100)/uptimeSince); 14556 sb.append("%)"); 14557 Slog.i(TAG, sb.toString()); 14558 } 14559 // If a process has held a wake lock for more 14560 // than 50% of the time during this period, 14561 // that sounds bad. Kill! 14562 if (doWakeKills && realtimeSince > 0 14563 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14564 synchronized (stats) { 14565 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14566 realtimeSince, wtimeUsed); 14567 } 14568 Slog.w(TAG, "Excessive wake lock in " + app.processName 14569 + " (pid " + app.pid + "): held " + wtimeUsed 14570 + " during " + realtimeSince); 14571 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14572 app.processName, app.setAdj, "excessive wake lock"); 14573 Process.killProcessQuiet(app.pid); 14574 } else if (doCpuKills && uptimeSince > 0 14575 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14576 synchronized (stats) { 14577 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 14578 uptimeSince, cputimeUsed); 14579 } 14580 Slog.w(TAG, "Excessive CPU in " + app.processName 14581 + " (pid " + app.pid + "): used " + cputimeUsed 14582 + " during " + uptimeSince); 14583 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14584 app.processName, app.setAdj, "excessive cpu"); 14585 Process.killProcessQuiet(app.pid); 14586 } else { 14587 app.lastWakeTime = wtime; 14588 app.lastCpuTime = app.curCpuTime; 14589 } 14590 } 14591 } 14592 } 14593 14594 private final boolean updateOomAdjLocked( 14595 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 14596 app.hiddenAdj = hiddenAdj; 14597 14598 if (app.thread == null) { 14599 return false; 14600 } 14601 14602 final boolean wasKeeping = app.keeping; 14603 14604 boolean success = true; 14605 14606 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 14607 14608 if (app.curRawAdj != app.setRawAdj) { 14609 if (wasKeeping && !app.keeping) { 14610 // This app is no longer something we want to keep. Note 14611 // its current wake lock time to later know to kill it if 14612 // it is not behaving well. 14613 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14614 synchronized (stats) { 14615 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 14616 app.pid, SystemClock.elapsedRealtime()); 14617 } 14618 app.lastCpuTime = app.curCpuTime; 14619 } 14620 14621 app.setRawAdj = app.curRawAdj; 14622 } 14623 14624 if (app.curAdj != app.setAdj) { 14625 if (Process.setOomAdj(app.pid, app.curAdj)) { 14626 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 14627 TAG, "Set " + app.pid + " " + app.processName + 14628 " adj " + app.curAdj + ": " + app.adjType); 14629 app.setAdj = app.curAdj; 14630 } else { 14631 success = false; 14632 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 14633 } 14634 } 14635 if (app.setSchedGroup != app.curSchedGroup) { 14636 app.setSchedGroup = app.curSchedGroup; 14637 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 14638 "Setting process group of " + app.processName 14639 + " to " + app.curSchedGroup); 14640 if (app.waitingToKill != null && 14641 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 14642 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 14643 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14644 app.processName, app.setAdj, app.waitingToKill); 14645 app.killedBackground = true; 14646 Process.killProcessQuiet(app.pid); 14647 success = false; 14648 } else { 14649 if (true) { 14650 long oldId = Binder.clearCallingIdentity(); 14651 try { 14652 Process.setProcessGroup(app.pid, app.curSchedGroup); 14653 } catch (Exception e) { 14654 Slog.w(TAG, "Failed setting process group of " + app.pid 14655 + " to " + app.curSchedGroup); 14656 e.printStackTrace(); 14657 } finally { 14658 Binder.restoreCallingIdentity(oldId); 14659 } 14660 } else { 14661 if (app.thread != null) { 14662 try { 14663 app.thread.setSchedulingGroup(app.curSchedGroup); 14664 } catch (RemoteException e) { 14665 } 14666 } 14667 } 14668 } 14669 } 14670 return success; 14671 } 14672 14673 private final ActivityRecord resumedAppLocked() { 14674 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 14675 if (resumedActivity == null || resumedActivity.app == null) { 14676 resumedActivity = mMainStack.mPausingActivity; 14677 if (resumedActivity == null || resumedActivity.app == null) { 14678 resumedActivity = mMainStack.topRunningActivityLocked(null); 14679 } 14680 } 14681 return resumedActivity; 14682 } 14683 14684 private final boolean updateOomAdjLocked(ProcessRecord app) { 14685 final ActivityRecord TOP_ACT = resumedAppLocked(); 14686 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14687 int curAdj = app.curAdj; 14688 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14689 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14690 14691 mAdjSeq++; 14692 14693 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 14694 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14695 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14696 if (nowHidden != wasHidden) { 14697 // Changed to/from hidden state, so apps after it in the LRU 14698 // list may also be changed. 14699 updateOomAdjLocked(); 14700 } 14701 return success; 14702 } 14703 14704 final void updateOomAdjLocked() { 14705 final ActivityRecord TOP_ACT = resumedAppLocked(); 14706 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14707 14708 if (false) { 14709 RuntimeException e = new RuntimeException(); 14710 e.fillInStackTrace(); 14711 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 14712 } 14713 14714 mAdjSeq++; 14715 mNewNumServiceProcs = 0; 14716 14717 // Let's determine how many processes we have running vs. 14718 // how many slots we have for background processes; we may want 14719 // to put multiple processes in a slot of there are enough of 14720 // them. 14721 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 14722 int factor = (mLruProcesses.size()-4)/numSlots; 14723 if (factor < 1) factor = 1; 14724 int step = 0; 14725 int numHidden = 0; 14726 int numTrimming = 0; 14727 14728 // First update the OOM adjustment for each of the 14729 // application processes based on their current state. 14730 int i = mLruProcesses.size(); 14731 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 14732 while (i > 0) { 14733 i--; 14734 ProcessRecord app = mLruProcesses.get(i); 14735 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 14736 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 14737 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 14738 && app.curAdj == curHiddenAdj) { 14739 step++; 14740 if (step >= factor) { 14741 step = 0; 14742 curHiddenAdj++; 14743 } 14744 } 14745 if (!app.killedBackground) { 14746 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14747 numHidden++; 14748 if (numHidden > mProcessLimit) { 14749 Slog.i(TAG, "No longer want " + app.processName 14750 + " (pid " + app.pid + "): hidden #" + numHidden); 14751 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14752 app.processName, app.setAdj, "too many background"); 14753 app.killedBackground = true; 14754 Process.killProcessQuiet(app.pid); 14755 } 14756 } 14757 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 14758 // If this is an isolated process, and there are no 14759 // services running in it, then the process is no longer 14760 // needed. We agressively kill these because we can by 14761 // definition not re-use the same process again, and it is 14762 // good to avoid having whatever code was running in them 14763 // left sitting around after no longer needed. 14764 Slog.i(TAG, "Isolated process " + app.processName 14765 + " (pid " + app.pid + ") no longer needed"); 14766 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14767 app.processName, app.setAdj, "isolated not needed"); 14768 app.killedBackground = true; 14769 Process.killProcessQuiet(app.pid); 14770 } 14771 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14772 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14773 && !app.killedBackground) { 14774 numTrimming++; 14775 } 14776 } 14777 } 14778 14779 mNumServiceProcs = mNewNumServiceProcs; 14780 14781 // Now determine the memory trimming level of background processes. 14782 // Unfortunately we need to start at the back of the list to do this 14783 // properly. We only do this if the number of background apps we 14784 // are managing to keep around is less than half the maximum we desire; 14785 // if we are keeping a good number around, we'll let them use whatever 14786 // memory they want. 14787 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 14788 final int N = mLruProcesses.size(); 14789 factor = numTrimming/3; 14790 int minFactor = 2; 14791 if (mHomeProcess != null) minFactor++; 14792 if (mPreviousProcess != null) minFactor++; 14793 if (factor < minFactor) factor = minFactor; 14794 step = 0; 14795 int fgTrimLevel; 14796 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 14797 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 14798 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 14799 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 14800 } else { 14801 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 14802 } 14803 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14804 for (i=0; i<N; i++) { 14805 ProcessRecord app = mLruProcesses.get(i); 14806 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14807 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14808 && !app.killedBackground) { 14809 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14810 try { 14811 app.thread.scheduleTrimMemory(curLevel); 14812 } catch (RemoteException e) { 14813 } 14814 if (false) { 14815 // For now we won't do this; our memory trimming seems 14816 // to be good enough at this point that destroying 14817 // activities causes more harm than good. 14818 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14819 && app != mHomeProcess && app != mPreviousProcess) { 14820 // Need to do this on its own message because the stack may not 14821 // be in a consistent state at this point. 14822 // For these apps we will also finish their activities 14823 // to help them free memory. 14824 mMainStack.scheduleDestroyActivities(app, false, "trim"); 14825 } 14826 } 14827 } 14828 app.trimMemoryLevel = curLevel; 14829 step++; 14830 if (step >= factor) { 14831 step = 0; 14832 switch (curLevel) { 14833 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14834 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14835 break; 14836 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14837 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14838 break; 14839 } 14840 } 14841 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14842 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14843 && app.thread != null) { 14844 try { 14845 app.thread.scheduleTrimMemory( 14846 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14847 } catch (RemoteException e) { 14848 } 14849 } 14850 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14851 } else { 14852 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14853 && app.pendingUiClean) { 14854 // If this application is now in the background and it 14855 // had done UI, then give it the special trim level to 14856 // have it free UI resources. 14857 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14858 if (app.trimMemoryLevel < level && app.thread != null) { 14859 try { 14860 app.thread.scheduleTrimMemory(level); 14861 } catch (RemoteException e) { 14862 } 14863 } 14864 app.pendingUiClean = false; 14865 } 14866 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 14867 try { 14868 app.thread.scheduleTrimMemory(fgTrimLevel); 14869 } catch (RemoteException e) { 14870 } 14871 } 14872 app.trimMemoryLevel = fgTrimLevel; 14873 } 14874 } 14875 } else { 14876 final int N = mLruProcesses.size(); 14877 for (i=0; i<N; i++) { 14878 ProcessRecord app = mLruProcesses.get(i); 14879 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14880 && app.pendingUiClean) { 14881 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14882 && app.thread != null) { 14883 try { 14884 app.thread.scheduleTrimMemory( 14885 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14886 } catch (RemoteException e) { 14887 } 14888 } 14889 app.pendingUiClean = false; 14890 } 14891 app.trimMemoryLevel = 0; 14892 } 14893 } 14894 14895 if (mAlwaysFinishActivities) { 14896 // Need to do this on its own message because the stack may not 14897 // be in a consistent state at this point. 14898 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 14899 } 14900 } 14901 14902 final void trimApplications() { 14903 synchronized (this) { 14904 int i; 14905 14906 // First remove any unused application processes whose package 14907 // has been removed. 14908 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14909 final ProcessRecord app = mRemovedProcesses.get(i); 14910 if (app.activities.size() == 0 14911 && app.curReceiver == null && app.services.size() == 0) { 14912 Slog.i( 14913 TAG, "Exiting empty application process " 14914 + app.processName + " (" 14915 + (app.thread != null ? app.thread.asBinder() : null) 14916 + ")\n"); 14917 if (app.pid > 0 && app.pid != MY_PID) { 14918 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14919 app.processName, app.setAdj, "empty"); 14920 Process.killProcessQuiet(app.pid); 14921 } else { 14922 try { 14923 app.thread.scheduleExit(); 14924 } catch (Exception e) { 14925 // Ignore exceptions. 14926 } 14927 } 14928 cleanUpApplicationRecordLocked(app, false, true, -1); 14929 mRemovedProcesses.remove(i); 14930 14931 if (app.persistent) { 14932 if (app.persistent) { 14933 addAppLocked(app.info, false); 14934 } 14935 } 14936 } 14937 } 14938 14939 // Now update the oom adj for all processes. 14940 updateOomAdjLocked(); 14941 } 14942 } 14943 14944 /** This method sends the specified signal to each of the persistent apps */ 14945 public void signalPersistentProcesses(int sig) throws RemoteException { 14946 if (sig != Process.SIGNAL_USR1) { 14947 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14948 } 14949 14950 synchronized (this) { 14951 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14952 != PackageManager.PERMISSION_GRANTED) { 14953 throw new SecurityException("Requires permission " 14954 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14955 } 14956 14957 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14958 ProcessRecord r = mLruProcesses.get(i); 14959 if (r.thread != null && r.persistent) { 14960 Process.sendSignal(r.pid, sig); 14961 } 14962 } 14963 } 14964 } 14965 14966 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14967 if (proc == null || proc == mProfileProc) { 14968 proc = mProfileProc; 14969 path = mProfileFile; 14970 profileType = mProfileType; 14971 clearProfilerLocked(); 14972 } 14973 if (proc == null) { 14974 return; 14975 } 14976 try { 14977 proc.thread.profilerControl(false, path, null, profileType); 14978 } catch (RemoteException e) { 14979 throw new IllegalStateException("Process disappeared"); 14980 } 14981 } 14982 14983 private void clearProfilerLocked() { 14984 if (mProfileFd != null) { 14985 try { 14986 mProfileFd.close(); 14987 } catch (IOException e) { 14988 } 14989 } 14990 mProfileApp = null; 14991 mProfileProc = null; 14992 mProfileFile = null; 14993 mProfileType = 0; 14994 mAutoStopProfiler = false; 14995 } 14996 14997 public boolean profileControl(String process, boolean start, 14998 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14999 15000 try { 15001 synchronized (this) { 15002 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15003 // its own permission. 15004 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15005 != PackageManager.PERMISSION_GRANTED) { 15006 throw new SecurityException("Requires permission " 15007 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15008 } 15009 15010 if (start && fd == null) { 15011 throw new IllegalArgumentException("null fd"); 15012 } 15013 15014 ProcessRecord proc = null; 15015 if (process != null) { 15016 try { 15017 int pid = Integer.parseInt(process); 15018 synchronized (mPidsSelfLocked) { 15019 proc = mPidsSelfLocked.get(pid); 15020 } 15021 } catch (NumberFormatException e) { 15022 } 15023 15024 if (proc == null) { 15025 HashMap<String, SparseArray<ProcessRecord>> all 15026 = mProcessNames.getMap(); 15027 SparseArray<ProcessRecord> procs = all.get(process); 15028 if (procs != null && procs.size() > 0) { 15029 proc = procs.valueAt(0); 15030 } 15031 } 15032 } 15033 15034 if (start && (proc == null || proc.thread == null)) { 15035 throw new IllegalArgumentException("Unknown process: " + process); 15036 } 15037 15038 if (start) { 15039 stopProfilerLocked(null, null, 0); 15040 setProfileApp(proc.info, proc.processName, path, fd, false); 15041 mProfileProc = proc; 15042 mProfileType = profileType; 15043 try { 15044 fd = fd.dup(); 15045 } catch (IOException e) { 15046 fd = null; 15047 } 15048 proc.thread.profilerControl(start, path, fd, profileType); 15049 fd = null; 15050 mProfileFd = null; 15051 } else { 15052 stopProfilerLocked(proc, path, profileType); 15053 if (fd != null) { 15054 try { 15055 fd.close(); 15056 } catch (IOException e) { 15057 } 15058 } 15059 } 15060 15061 return true; 15062 } 15063 } catch (RemoteException e) { 15064 throw new IllegalStateException("Process disappeared"); 15065 } finally { 15066 if (fd != null) { 15067 try { 15068 fd.close(); 15069 } catch (IOException e) { 15070 } 15071 } 15072 } 15073 } 15074 15075 public boolean dumpHeap(String process, boolean managed, 15076 String path, ParcelFileDescriptor fd) throws RemoteException { 15077 15078 try { 15079 synchronized (this) { 15080 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15081 // its own permission (same as profileControl). 15082 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15083 != PackageManager.PERMISSION_GRANTED) { 15084 throw new SecurityException("Requires permission " 15085 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15086 } 15087 15088 if (fd == null) { 15089 throw new IllegalArgumentException("null fd"); 15090 } 15091 15092 ProcessRecord proc = null; 15093 try { 15094 int pid = Integer.parseInt(process); 15095 synchronized (mPidsSelfLocked) { 15096 proc = mPidsSelfLocked.get(pid); 15097 } 15098 } catch (NumberFormatException e) { 15099 } 15100 15101 if (proc == null) { 15102 HashMap<String, SparseArray<ProcessRecord>> all 15103 = mProcessNames.getMap(); 15104 SparseArray<ProcessRecord> procs = all.get(process); 15105 if (procs != null && procs.size() > 0) { 15106 proc = procs.valueAt(0); 15107 } 15108 } 15109 15110 if (proc == null || proc.thread == null) { 15111 throw new IllegalArgumentException("Unknown process: " + process); 15112 } 15113 15114 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15115 if (!isDebuggable) { 15116 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15117 throw new SecurityException("Process not debuggable: " + proc); 15118 } 15119 } 15120 15121 proc.thread.dumpHeap(managed, path, fd); 15122 fd = null; 15123 return true; 15124 } 15125 } catch (RemoteException e) { 15126 throw new IllegalStateException("Process disappeared"); 15127 } finally { 15128 if (fd != null) { 15129 try { 15130 fd.close(); 15131 } catch (IOException e) { 15132 } 15133 } 15134 } 15135 } 15136 15137 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15138 public void monitor() { 15139 synchronized (this) { } 15140 } 15141 15142 void onCoreSettingsChange(Bundle settings) { 15143 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15144 ProcessRecord processRecord = mLruProcesses.get(i); 15145 try { 15146 if (processRecord.thread != null) { 15147 processRecord.thread.setCoreSettings(settings); 15148 } 15149 } catch (RemoteException re) { 15150 /* ignore */ 15151 } 15152 } 15153 } 15154 15155 // Multi-user methods 15156 15157 private int mCurrentUserId; 15158 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 15159 15160 public boolean switchUser(int userId) { 15161 final int callingUid = Binder.getCallingUid(); 15162 if (callingUid != 0 && callingUid != Process.myUid()) { 15163 Slog.e(TAG, "Trying to switch user from unauthorized app"); 15164 return false; 15165 } 15166 if (mCurrentUserId == userId) 15167 return true; 15168 15169 synchronized (this) { 15170 // Check if user is already logged in, otherwise check if user exists first before 15171 // adding to the list of logged in users. 15172 if (mLoggedInUsers.indexOfKey(userId) < 0) { 15173 if (!userExists(userId)) { 15174 return false; 15175 } 15176 mLoggedInUsers.append(userId, userId); 15177 } 15178 15179 mCurrentUserId = userId; 15180 boolean haveActivities = mMainStack.switchUser(userId); 15181 if (!haveActivities) { 15182 startHomeActivityLocked(userId); 15183 } 15184 15185 } 15186 15187 // Inform of user switch 15188 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 15189 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 15190 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 15191 15192 return true; 15193 } 15194 15195 @Override 15196 public UserInfo getCurrentUser() throws RemoteException { 15197 final int callingUid = Binder.getCallingUid(); 15198 if (callingUid != 0 && callingUid != Process.myUid()) { 15199 Slog.e(TAG, "Trying to get user from unauthorized app"); 15200 return null; 15201 } 15202 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 15203 } 15204 15205 private void onUserRemoved(Intent intent) { 15206 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 15207 if (extraUserId < 1) return; 15208 15209 // Kill all the processes for the user 15210 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 15211 synchronized (this) { 15212 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 15213 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 15214 SparseArray<ProcessRecord> uids = uidMap.getValue(); 15215 for (int i = 0; i < uids.size(); i++) { 15216 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 15217 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 15218 } 15219 } 15220 } 15221 15222 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 15223 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 15224 false, false, true, true, extraUserId); 15225 } 15226 } 15227 } 15228 15229 private boolean userExists(int userId) { 15230 try { 15231 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 15232 return user != null; 15233 } catch (RemoteException re) { 15234 // Won't happen, in same process 15235 } 15236 15237 return false; 15238 } 15239 15240 private void checkValidCaller(int uid, int userId) { 15241 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 15242 15243 throw new SecurityException("Caller uid=" + uid 15244 + " is not privileged to communicate with user=" + userId); 15245 } 15246 15247 private int applyUserId(int uid, int userId) { 15248 return UserId.getUid(userId, uid); 15249 } 15250 15251 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 15252 if (info == null) return null; 15253 ApplicationInfo newInfo = new ApplicationInfo(info); 15254 newInfo.uid = applyUserId(info.uid, userId); 15255 newInfo.dataDir = USER_DATA_DIR + userId + "/" 15256 + info.packageName; 15257 return newInfo; 15258 } 15259 15260 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 15261 if (aInfo == null 15262 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 15263 return aInfo; 15264 } 15265 15266 ActivityInfo info = new ActivityInfo(aInfo); 15267 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 15268 return info; 15269 } 15270 15271 static class ServiceMap { 15272 15273 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser 15274 = new SparseArray<HashMap<ComponentName, ServiceRecord>>(); 15275 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>> 15276 mServicesByIntentPerUser = new SparseArray< 15277 HashMap<Intent.FilterComparison, ServiceRecord>>(); 15278 15279 ServiceRecord getServiceByName(ComponentName name, int callingUser) { 15280 // TODO: Deal with global services 15281 if (DEBUG_MU) 15282 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser); 15283 return getServices(callingUser).get(name); 15284 } 15285 15286 ServiceRecord getServiceByName(ComponentName name) { 15287 return getServiceByName(name, -1); 15288 } 15289 15290 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15291 // TODO: Deal with global services 15292 if (DEBUG_MU) 15293 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser); 15294 return getServicesByIntent(callingUser).get(filter); 15295 } 15296 15297 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) { 15298 return getServiceByIntent(filter, -1); 15299 } 15300 15301 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) { 15302 // TODO: Deal with global services 15303 getServices(callingUser).put(name, value); 15304 } 15305 15306 void putServiceByIntent(Intent.FilterComparison filter, int callingUser, 15307 ServiceRecord value) { 15308 // TODO: Deal with global services 15309 getServicesByIntent(callingUser).put(filter, value); 15310 } 15311 15312 void removeServiceByName(ComponentName name, int callingUser) { 15313 // TODO: Deal with global services 15314 ServiceRecord removed = getServices(callingUser).remove(name); 15315 if (DEBUG_MU) 15316 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name 15317 + " removed=" + removed); 15318 } 15319 15320 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15321 // TODO: Deal with global services 15322 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter); 15323 if (DEBUG_MU) 15324 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter 15325 + " removed=" + removed); 15326 } 15327 15328 Collection<ServiceRecord> getAllServices(int callingUser) { 15329 // TODO: Deal with global services 15330 return getServices(callingUser).values(); 15331 } 15332 15333 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) { 15334 HashMap map = mServicesByNamePerUser.get(callingUser); 15335 if (map == null) { 15336 map = new HashMap<ComponentName, ServiceRecord>(); 15337 mServicesByNamePerUser.put(callingUser, map); 15338 } 15339 return map; 15340 } 15341 15342 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent( 15343 int callingUser) { 15344 HashMap map = mServicesByIntentPerUser.get(callingUser); 15345 if (map == null) { 15346 map = new HashMap<Intent.FilterComparison, ServiceRecord>(); 15347 mServicesByIntentPerUser.put(callingUser, map); 15348 } 15349 return map; 15350 } 15351 } 15352 } 15353