ActivityManagerService.java revision 59325eb31f25704bb88c348160bb69e7c1aa3b48
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 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IThumbnailReceiver; 50import android.app.Instrumentation; 51import android.app.Notification; 52import android.app.NotificationManager; 53import android.app.PendingIntent; 54import android.app.Service; 55import android.app.backup.IBackupManager; 56import android.content.ActivityNotFoundException; 57import android.content.BroadcastReceiver; 58import android.content.ClipData; 59import android.content.ComponentCallbacks2; 60import android.content.ComponentName; 61import android.content.ContentProvider; 62import android.content.ContentResolver; 63import android.content.Context; 64import android.content.DialogInterface; 65import android.content.IIntentReceiver; 66import android.content.IIntentSender; 67import android.content.Intent; 68import android.content.IntentFilter; 69import android.content.IntentSender; 70import android.content.pm.ActivityInfo; 71import android.content.pm.ApplicationInfo; 72import android.content.pm.ConfigurationInfo; 73import android.content.pm.IPackageDataObserver; 74import android.content.pm.IPackageManager; 75import android.content.pm.InstrumentationInfo; 76import android.content.pm.PackageInfo; 77import android.content.pm.PackageManager; 78import android.content.pm.PackageManager.NameNotFoundException; 79import android.content.pm.PathPermission; 80import android.content.pm.ProviderInfo; 81import android.content.pm.ResolveInfo; 82import android.content.pm.ServiceInfo; 83import android.content.pm.UserInfo; 84import android.content.res.CompatibilityInfo; 85import android.content.res.Configuration; 86import android.graphics.Bitmap; 87import android.net.Proxy; 88import android.net.ProxyProperties; 89import android.net.Uri; 90import android.os.Binder; 91import android.os.Build; 92import android.os.Bundle; 93import android.os.Debug; 94import android.os.DropBoxManager; 95import android.os.Environment; 96import android.os.FileObserver; 97import android.os.FileUtils; 98import android.os.Handler; 99import android.os.IBinder; 100import android.os.IPermissionController; 101import android.os.Looper; 102import android.os.Message; 103import android.os.Parcel; 104import android.os.ParcelFileDescriptor; 105import android.os.Process; 106import android.os.RemoteCallbackList; 107import android.os.RemoteException; 108import android.os.ServiceManager; 109import android.os.StrictMode; 110import android.os.SystemClock; 111import android.os.SystemProperties; 112import android.os.UserId; 113import android.provider.Settings; 114import android.text.format.Time; 115import android.util.EventLog; 116import android.util.Log; 117import android.util.Pair; 118import android.util.PrintWriterPrinter; 119import android.util.Slog; 120import android.util.SparseArray; 121import android.util.SparseIntArray; 122import android.util.TimeUtils; 123import android.view.Gravity; 124import android.view.LayoutInflater; 125import android.view.View; 126import android.view.WindowManager; 127import android.view.WindowManagerPolicy; 128 129import java.io.BufferedInputStream; 130import java.io.BufferedOutputStream; 131import java.io.BufferedReader; 132import java.io.DataInputStream; 133import java.io.DataOutputStream; 134import java.io.File; 135import java.io.FileDescriptor; 136import java.io.FileInputStream; 137import java.io.FileNotFoundException; 138import java.io.FileOutputStream; 139import java.io.IOException; 140import java.io.InputStreamReader; 141import java.io.PrintWriter; 142import java.io.StringWriter; 143import java.lang.ref.WeakReference; 144import java.util.ArrayList; 145import java.util.Collection; 146import java.util.Collections; 147import java.util.Comparator; 148import java.util.HashMap; 149import java.util.HashSet; 150import java.util.Iterator; 151import java.util.List; 152import java.util.Locale; 153import java.util.Map; 154import java.util.Map.Entry; 155import java.util.Set; 156import java.util.concurrent.atomic.AtomicBoolean; 157import java.util.concurrent.atomic.AtomicLong; 158 159public final class ActivityManagerService extends ActivityManagerNative 160 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 161 private static final String USER_DATA_DIR = "/data/user/"; 162 static final String TAG = "ActivityManager"; 163 static final String TAG_MU = "ActivityManagerServiceMU"; 164 static final boolean DEBUG = false; 165 static final boolean localLOGV = DEBUG; 166 static final boolean DEBUG_SWITCH = localLOGV || false; 167 static final boolean DEBUG_TASKS = localLOGV || false; 168 static final boolean DEBUG_PAUSE = localLOGV || false; 169 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 170 static final boolean DEBUG_TRANSITION = localLOGV || false; 171 static final boolean DEBUG_BROADCAST = localLOGV || false; 172 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 173 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_SERVICE = localLOGV || false; 175 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 176 static final boolean DEBUG_VISBILITY = localLOGV || false; 177 static final boolean DEBUG_PROCESSES = localLOGV || false; 178 static final boolean DEBUG_PROVIDER = localLOGV || false; 179 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 180 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 181 static final boolean DEBUG_RESULTS = localLOGV || false; 182 static final boolean DEBUG_BACKUP = localLOGV || false; 183 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 184 static final boolean DEBUG_POWER = localLOGV || false; 185 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 186 static final boolean DEBUG_MU = localLOGV || false; 187 static final boolean VALIDATE_TOKENS = false; 188 static final boolean SHOW_ACTIVITY_START_TIME = true; 189 190 // Control over CPU and battery monitoring. 191 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 192 static final boolean MONITOR_CPU_USAGE = true; 193 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 194 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 195 static final boolean MONITOR_THREAD_CPU_USAGE = false; 196 197 // The flags that are set for all calls we make to the package manager. 198 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 199 200 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 201 202 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 203 204 // Maximum number of recent tasks that we can remember. 205 static final int MAX_RECENT_TASKS = 20; 206 207 // Amount of time after a call to stopAppSwitches() during which we will 208 // prevent further untrusted switches from happening. 209 static final long APP_SWITCH_DELAY_TIME = 5*1000; 210 211 // How long we wait for a launched process to attach to the activity manager 212 // before we decide it's never going to come up for real. 213 static final int PROC_START_TIMEOUT = 10*1000; 214 215 // How long we wait for a launched process to attach to the activity manager 216 // before we decide it's never going to come up for real, when the process was 217 // started with a wrapper for instrumentation (such as Valgrind) because it 218 // could take much longer than usual. 219 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 220 221 // How long to wait after going idle before forcing apps to GC. 222 static final int GC_TIMEOUT = 5*1000; 223 224 // The minimum amount of time between successive GC requests for a process. 225 static final int GC_MIN_INTERVAL = 60*1000; 226 227 // The rate at which we check for apps using excessive power -- 15 mins. 228 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 229 230 // The minimum sample duration we will allow before deciding we have 231 // enough data on wake locks to start killing things. 232 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 233 234 // The minimum sample duration we will allow before deciding we have 235 // enough data on CPU usage to start killing things. 236 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 237 238 // How long we allow a receiver to run before giving up on it. 239 static final int BROADCAST_FG_TIMEOUT = 10*1000; 240 static final int BROADCAST_BG_TIMEOUT = 60*1000; 241 242 // How long we wait for a service to finish executing. 243 static final int SERVICE_TIMEOUT = 20*1000; 244 245 // How long a service needs to be running until restarting its process 246 // is no longer considered to be a relaunch of the service. 247 static final int SERVICE_RESTART_DURATION = 5*1000; 248 249 // How long a service needs to be running until it will start back at 250 // SERVICE_RESTART_DURATION after being killed. 251 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 252 253 // Multiplying factor to increase restart duration time by, for each time 254 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 255 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 256 257 // The minimum amount of time between restarting services that we allow. 258 // That is, when multiple services are restarting, we won't allow each 259 // to restart less than this amount of time from the last one. 260 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 261 262 // Maximum amount of time for there to be no activity on a service before 263 // we consider it non-essential and allow its process to go on the 264 // LRU background list. 265 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 266 267 // How long we wait until we timeout on key dispatching. 268 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 269 270 // How long we wait until we timeout on key dispatching during instrumentation. 271 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 272 273 static final int MY_PID = Process.myPid(); 274 275 static final String[] EMPTY_STRING_ARRAY = new String[0]; 276 277 public ActivityStack mMainStack; 278 279 private final boolean mHeadless; 280 281 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 282 // default actuion automatically. Important for devices without direct input 283 // devices. 284 private boolean mShowDialogs = true; 285 286 /** 287 * Description of a request to start a new activity, which has been held 288 * due to app switches being disabled. 289 */ 290 static class PendingActivityLaunch { 291 ActivityRecord r; 292 ActivityRecord sourceRecord; 293 int startFlags; 294 } 295 296 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 297 = new ArrayList<PendingActivityLaunch>(); 298 299 300 BroadcastQueue mFgBroadcastQueue; 301 BroadcastQueue mBgBroadcastQueue; 302 // Convenient for easy iteration over the queues. Foreground is first 303 // so that dispatch of foreground broadcasts gets precedence. 304 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 305 306 BroadcastQueue broadcastQueueForIntent(Intent intent) { 307 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 308 if (DEBUG_BACKGROUND_BROADCAST) { 309 Slog.i(TAG, "Broadcast intent " + intent + " on " 310 + (isFg ? "foreground" : "background") 311 + " queue"); 312 } 313 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 314 } 315 316 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 317 for (BroadcastQueue queue : mBroadcastQueues) { 318 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 319 if (r != null) { 320 return r; 321 } 322 } 323 return null; 324 } 325 326 /** 327 * Activity we have told the window manager to have key focus. 328 */ 329 ActivityRecord mFocusedActivity = null; 330 /** 331 * List of intents that were used to start the most recent tasks. 332 */ 333 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 334 335 /** 336 * Process management. 337 */ 338 final ProcessList mProcessList = new ProcessList(); 339 340 /** 341 * All of the applications we currently have running organized by name. 342 * The keys are strings of the application package name (as 343 * returned by the package manager), and the keys are ApplicationRecord 344 * objects. 345 */ 346 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 347 348 /** 349 * The currently running isolated processes. 350 */ 351 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 352 353 /** 354 * Counter for assigning isolated process uids, to avoid frequently reusing the 355 * same ones. 356 */ 357 int mNextIsolatedProcessUid = 0; 358 359 /** 360 * The currently running heavy-weight process, if any. 361 */ 362 ProcessRecord mHeavyWeightProcess = null; 363 364 /** 365 * The last time that various processes have crashed. 366 */ 367 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 368 369 /** 370 * Set of applications that we consider to be bad, and will reject 371 * incoming broadcasts from (which the user has no control over). 372 * Processes are added to this set when they have crashed twice within 373 * a minimum amount of time; they are removed from it when they are 374 * later restarted (hopefully due to some user action). The value is the 375 * time it was added to the list. 376 */ 377 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 378 379 /** 380 * All of the processes we currently have running organized by pid. 381 * The keys are the pid running the application. 382 * 383 * <p>NOTE: This object is protected by its own lock, NOT the global 384 * activity manager lock! 385 */ 386 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 387 388 /** 389 * All of the processes that have been forced to be foreground. The key 390 * is the pid of the caller who requested it (we hold a death 391 * link on it). 392 */ 393 abstract class ForegroundToken implements IBinder.DeathRecipient { 394 int pid; 395 IBinder token; 396 } 397 final SparseArray<ForegroundToken> mForegroundProcesses 398 = new SparseArray<ForegroundToken>(); 399 400 /** 401 * List of records for processes that someone had tried to start before the 402 * system was ready. We don't start them at that point, but ensure they 403 * are started by the time booting is complete. 404 */ 405 final ArrayList<ProcessRecord> mProcessesOnHold 406 = new ArrayList<ProcessRecord>(); 407 408 /** 409 * List of persistent applications that are in the process 410 * of being started. 411 */ 412 final ArrayList<ProcessRecord> mPersistentStartingProcesses 413 = new ArrayList<ProcessRecord>(); 414 415 /** 416 * Processes that are being forcibly torn down. 417 */ 418 final ArrayList<ProcessRecord> mRemovedProcesses 419 = new ArrayList<ProcessRecord>(); 420 421 /** 422 * List of running applications, sorted by recent usage. 423 * The first entry in the list is the least recently used. 424 * It contains ApplicationRecord objects. This list does NOT include 425 * any persistent application records (since we never want to exit them). 426 */ 427 final ArrayList<ProcessRecord> mLruProcesses 428 = new ArrayList<ProcessRecord>(); 429 430 /** 431 * List of processes that should gc as soon as things are idle. 432 */ 433 final ArrayList<ProcessRecord> mProcessesToGc 434 = new ArrayList<ProcessRecord>(); 435 436 /** 437 * This is the process holding what we currently consider to be 438 * the "home" activity. 439 */ 440 ProcessRecord mHomeProcess; 441 442 /** 443 * This is the process holding the activity the user last visited that 444 * is in a different process from the one they are currently in. 445 */ 446 ProcessRecord mPreviousProcess; 447 448 /** 449 * The time at which the previous process was last visible. 450 */ 451 long mPreviousProcessVisibleTime; 452 453 /** 454 * Packages that the user has asked to have run in screen size 455 * compatibility mode instead of filling the screen. 456 */ 457 final CompatModePackages mCompatModePackages; 458 459 /** 460 * Set of PendingResultRecord objects that are currently active. 461 */ 462 final HashSet mPendingResultRecords = new HashSet(); 463 464 /** 465 * Set of IntentSenderRecord objects that are currently active. 466 */ 467 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 468 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 469 470 /** 471 * Fingerprints (hashCode()) of stack traces that we've 472 * already logged DropBox entries for. Guarded by itself. If 473 * something (rogue user app) forces this over 474 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 475 */ 476 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 477 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 478 479 /** 480 * Strict Mode background batched logging state. 481 * 482 * The string buffer is guarded by itself, and its lock is also 483 * used to determine if another batched write is already 484 * in-flight. 485 */ 486 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 487 488 /** 489 * Keeps track of all IIntentReceivers that have been registered for 490 * broadcasts. Hash keys are the receiver IBinder, hash value is 491 * a ReceiverList. 492 */ 493 final HashMap mRegisteredReceivers = new HashMap(); 494 495 /** 496 * Resolver for broadcast intents to registered receivers. 497 * Holds BroadcastFilter (subclass of IntentFilter). 498 */ 499 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 500 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 501 @Override 502 protected boolean allowFilterResult( 503 BroadcastFilter filter, List<BroadcastFilter> dest) { 504 IBinder target = filter.receiverList.receiver.asBinder(); 505 for (int i=dest.size()-1; i>=0; i--) { 506 if (dest.get(i).receiverList.receiver.asBinder() == target) { 507 return false; 508 } 509 } 510 return true; 511 } 512 513 @Override 514 protected String packageForFilter(BroadcastFilter filter) { 515 return filter.packageName; 516 } 517 }; 518 519 /** 520 * State of all active sticky broadcasts. Keys are the action of the 521 * sticky Intent, values are an ArrayList of all broadcasted intents with 522 * that action (which should usually be one). 523 */ 524 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 525 new HashMap<String, ArrayList<Intent>>(); 526 527 final ServiceMap mServiceMap = new ServiceMap(); 528 529 /** 530 * All currently bound service connections. Keys are the IBinder of 531 * the client's IServiceConnection. 532 */ 533 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections 534 = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); 535 536 /** 537 * List of services that we have been asked to start, 538 * but haven't yet been able to. It is used to hold start requests 539 * while waiting for their corresponding application thread to get 540 * going. 541 */ 542 final ArrayList<ServiceRecord> mPendingServices 543 = new ArrayList<ServiceRecord>(); 544 545 /** 546 * List of services that are scheduled to restart following a crash. 547 */ 548 final ArrayList<ServiceRecord> mRestartingServices 549 = new ArrayList<ServiceRecord>(); 550 551 /** 552 * List of services that are in the process of being stopped. 553 */ 554 final ArrayList<ServiceRecord> mStoppingServices 555 = new ArrayList<ServiceRecord>(); 556 557 /** 558 * Backup/restore process management 559 */ 560 String mBackupAppName = null; 561 BackupRecord mBackupTarget = null; 562 563 /** 564 * List of PendingThumbnailsRecord objects of clients who are still 565 * waiting to receive all of the thumbnails for a task. 566 */ 567 final ArrayList mPendingThumbnails = new ArrayList(); 568 569 /** 570 * List of HistoryRecord objects that have been finished and must 571 * still report back to a pending thumbnail receiver. 572 */ 573 final ArrayList mCancelledThumbnails = new ArrayList(); 574 575 final ProviderMap mProviderMap = new ProviderMap(); 576 577 /** 578 * List of content providers who have clients waiting for them. The 579 * application is currently being launched and the provider will be 580 * removed from this list once it is published. 581 */ 582 final ArrayList<ContentProviderRecord> mLaunchingProviders 583 = new ArrayList<ContentProviderRecord>(); 584 585 /** 586 * Global set of specific Uri permissions that have been granted. 587 */ 588 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 589 = new SparseArray<HashMap<Uri, UriPermission>>(); 590 591 CoreSettingsObserver mCoreSettingsObserver; 592 593 /** 594 * Thread-local storage used to carry caller permissions over through 595 * indirect content-provider access. 596 * @see #ActivityManagerService.openContentUri() 597 */ 598 private class Identity { 599 public int pid; 600 public int uid; 601 602 Identity(int _pid, int _uid) { 603 pid = _pid; 604 uid = _uid; 605 } 606 } 607 608 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 609 610 /** 611 * All information we have collected about the runtime performance of 612 * any user id that can impact battery performance. 613 */ 614 final BatteryStatsService mBatteryStatsService; 615 616 /** 617 * information about component usage 618 */ 619 final UsageStatsService mUsageStatsService; 620 621 /** 622 * Current configuration information. HistoryRecord objects are given 623 * a reference to this object to indicate which configuration they are 624 * currently running in, so this object must be kept immutable. 625 */ 626 Configuration mConfiguration = new Configuration(); 627 628 /** 629 * Current sequencing integer of the configuration, for skipping old 630 * configurations. 631 */ 632 int mConfigurationSeq = 0; 633 634 /** 635 * Hardware-reported OpenGLES version. 636 */ 637 final int GL_ES_VERSION; 638 639 /** 640 * List of initialization arguments to pass to all processes when binding applications to them. 641 * For example, references to the commonly used services. 642 */ 643 HashMap<String, IBinder> mAppBindArgs; 644 645 /** 646 * Temporary to avoid allocations. Protected by main lock. 647 */ 648 final StringBuilder mStringBuilder = new StringBuilder(256); 649 650 /** 651 * Used to control how we initialize the service. 652 */ 653 boolean mStartRunning = false; 654 ComponentName mTopComponent; 655 String mTopAction; 656 String mTopData; 657 boolean mProcessesReady = false; 658 boolean mSystemReady = false; 659 boolean mBooting = false; 660 boolean mWaitingUpdate = false; 661 boolean mDidUpdate = false; 662 boolean mOnBattery = false; 663 boolean mLaunchWarningShown = false; 664 665 Context mContext; 666 667 int mFactoryTest; 668 669 boolean mCheckedForSetup; 670 671 /** 672 * The time at which we will allow normal application switches again, 673 * after a call to {@link #stopAppSwitches()}. 674 */ 675 long mAppSwitchesAllowedTime; 676 677 /** 678 * This is set to true after the first switch after mAppSwitchesAllowedTime 679 * is set; any switches after that will clear the time. 680 */ 681 boolean mDidAppSwitch; 682 683 /** 684 * Last time (in realtime) at which we checked for power usage. 685 */ 686 long mLastPowerCheckRealtime; 687 688 /** 689 * Last time (in uptime) at which we checked for power usage. 690 */ 691 long mLastPowerCheckUptime; 692 693 /** 694 * Set while we are wanting to sleep, to prevent any 695 * activities from being started/resumed. 696 */ 697 boolean mSleeping = false; 698 699 /** 700 * State of external calls telling us if the device is asleep. 701 */ 702 boolean mWentToSleep = false; 703 704 /** 705 * State of external call telling us if the lock screen is shown. 706 */ 707 boolean mLockScreenShown = false; 708 709 /** 710 * Set if we are shutting down the system, similar to sleeping. 711 */ 712 boolean mShuttingDown = false; 713 714 /** 715 * Task identifier that activities are currently being started 716 * in. Incremented each time a new task is created. 717 * todo: Replace this with a TokenSpace class that generates non-repeating 718 * integers that won't wrap. 719 */ 720 int mCurTask = 1; 721 722 /** 723 * Current sequence id for oom_adj computation traversal. 724 */ 725 int mAdjSeq = 0; 726 727 /** 728 * Current sequence id for process LRU updating. 729 */ 730 int mLruSeq = 0; 731 732 /** 733 * Keep track of the number of service processes we last found, to 734 * determine on the next iteration which should be B services. 735 */ 736 int mNumServiceProcs = 0; 737 int mNewNumServiceProcs = 0; 738 739 /** 740 * System monitoring: number of processes that died since the last 741 * N procs were started. 742 */ 743 int[] mProcDeaths = new int[20]; 744 745 /** 746 * This is set if we had to do a delayed dexopt of an app before launching 747 * it, to increasing the ANR timeouts in that case. 748 */ 749 boolean mDidDexOpt; 750 751 String mDebugApp = null; 752 boolean mWaitForDebugger = false; 753 boolean mDebugTransient = false; 754 String mOrigDebugApp = null; 755 boolean mOrigWaitForDebugger = false; 756 boolean mAlwaysFinishActivities = false; 757 IActivityController mController = null; 758 String mProfileApp = null; 759 ProcessRecord mProfileProc = null; 760 String mProfileFile; 761 ParcelFileDescriptor mProfileFd; 762 int mProfileType = 0; 763 boolean mAutoStopProfiler = false; 764 String mOpenGlTraceApp = null; 765 766 final RemoteCallbackList<IProcessObserver> mProcessObservers 767 = new RemoteCallbackList<IProcessObserver>(); 768 769 /** 770 * Callback of last caller to {@link #requestPss}. 771 */ 772 Runnable mRequestPssCallback; 773 774 /** 775 * Remaining processes for which we are waiting results from the last 776 * call to {@link #requestPss}. 777 */ 778 final ArrayList<ProcessRecord> mRequestPssList 779 = new ArrayList<ProcessRecord>(); 780 781 /** 782 * Runtime statistics collection thread. This object's lock is used to 783 * protect all related state. 784 */ 785 final Thread mProcessStatsThread; 786 787 /** 788 * Used to collect process stats when showing not responding dialog. 789 * Protected by mProcessStatsThread. 790 */ 791 final ProcessStats mProcessStats = new ProcessStats( 792 MONITOR_THREAD_CPU_USAGE); 793 final AtomicLong mLastCpuTime = new AtomicLong(0); 794 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 795 796 long mLastWriteTime = 0; 797 798 /** 799 * Set to true after the system has finished booting. 800 */ 801 boolean mBooted = false; 802 803 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 804 int mProcessLimitOverride = -1; 805 806 WindowManagerService mWindowManager; 807 808 static ActivityManagerService mSelf; 809 static ActivityThread mSystemThread; 810 811 private final class AppDeathRecipient implements IBinder.DeathRecipient { 812 final ProcessRecord mApp; 813 final int mPid; 814 final IApplicationThread mAppThread; 815 816 AppDeathRecipient(ProcessRecord app, int pid, 817 IApplicationThread thread) { 818 if (localLOGV) Slog.v( 819 TAG, "New death recipient " + this 820 + " for thread " + thread.asBinder()); 821 mApp = app; 822 mPid = pid; 823 mAppThread = thread; 824 } 825 826 public void binderDied() { 827 if (localLOGV) Slog.v( 828 TAG, "Death received in " + this 829 + " for thread " + mAppThread.asBinder()); 830 synchronized(ActivityManagerService.this) { 831 appDiedLocked(mApp, mPid, mAppThread); 832 } 833 } 834 } 835 836 static final int SHOW_ERROR_MSG = 1; 837 static final int SHOW_NOT_RESPONDING_MSG = 2; 838 static final int SHOW_FACTORY_ERROR_MSG = 3; 839 static final int UPDATE_CONFIGURATION_MSG = 4; 840 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 841 static final int WAIT_FOR_DEBUGGER_MSG = 6; 842 static final int SERVICE_TIMEOUT_MSG = 12; 843 static final int UPDATE_TIME_ZONE = 13; 844 static final int SHOW_UID_ERROR_MSG = 14; 845 static final int IM_FEELING_LUCKY_MSG = 15; 846 static final int PROC_START_TIMEOUT_MSG = 20; 847 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 848 static final int KILL_APPLICATION_MSG = 22; 849 static final int FINALIZE_PENDING_INTENT_MSG = 23; 850 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 851 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 852 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 853 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 854 static final int CLEAR_DNS_CACHE = 28; 855 static final int UPDATE_HTTP_PROXY = 29; 856 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 857 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31; 858 static final int DISPATCH_PROCESS_DIED = 32; 859 static final int REPORT_MEM_USAGE = 33; 860 861 static final int FIRST_ACTIVITY_STACK_MSG = 100; 862 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 863 static final int FIRST_COMPAT_MODE_MSG = 300; 864 865 AlertDialog mUidAlert; 866 CompatModeDialog mCompatModeDialog; 867 long mLastMemUsageReportTime = 0; 868 869 final Handler mHandler = new Handler() { 870 //public Handler() { 871 // if (localLOGV) Slog.v(TAG, "Handler started!"); 872 //} 873 874 public void handleMessage(Message msg) { 875 switch (msg.what) { 876 case SHOW_ERROR_MSG: { 877 HashMap data = (HashMap) msg.obj; 878 synchronized (ActivityManagerService.this) { 879 ProcessRecord proc = (ProcessRecord)data.get("app"); 880 if (proc != null && proc.crashDialog != null) { 881 Slog.e(TAG, "App already has crash dialog: " + proc); 882 return; 883 } 884 AppErrorResult res = (AppErrorResult) data.get("result"); 885 if (mShowDialogs && !mSleeping && !mShuttingDown) { 886 Dialog d = new AppErrorDialog(mContext, res, proc); 887 d.show(); 888 proc.crashDialog = d; 889 } else { 890 // The device is asleep, so just pretend that the user 891 // saw a crash dialog and hit "force quit". 892 res.set(0); 893 } 894 } 895 896 ensureBootCompleted(); 897 } break; 898 case SHOW_NOT_RESPONDING_MSG: { 899 synchronized (ActivityManagerService.this) { 900 HashMap data = (HashMap) msg.obj; 901 ProcessRecord proc = (ProcessRecord)data.get("app"); 902 if (proc != null && proc.anrDialog != null) { 903 Slog.e(TAG, "App already has anr dialog: " + proc); 904 return; 905 } 906 907 Intent intent = new Intent("android.intent.action.ANR"); 908 if (!mProcessesReady) { 909 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 910 | Intent.FLAG_RECEIVER_FOREGROUND); 911 } 912 broadcastIntentLocked(null, null, intent, 913 null, null, 0, null, null, null, 914 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 915 916 if (mShowDialogs) { 917 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 918 mContext, proc, (ActivityRecord)data.get("activity")); 919 d.show(); 920 proc.anrDialog = d; 921 } else { 922 // Just kill the app if there is no dialog to be shown. 923 killAppAtUsersRequest(proc, null); 924 } 925 } 926 927 ensureBootCompleted(); 928 } break; 929 case SHOW_STRICT_MODE_VIOLATION_MSG: { 930 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 931 synchronized (ActivityManagerService.this) { 932 ProcessRecord proc = (ProcessRecord) data.get("app"); 933 if (proc == null) { 934 Slog.e(TAG, "App not found when showing strict mode dialog."); 935 break; 936 } 937 if (proc.crashDialog != null) { 938 Slog.e(TAG, "App already has strict mode dialog: " + proc); 939 return; 940 } 941 AppErrorResult res = (AppErrorResult) data.get("result"); 942 if (mShowDialogs && !mSleeping && !mShuttingDown) { 943 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 944 d.show(); 945 proc.crashDialog = d; 946 } else { 947 // The device is asleep, so just pretend that the user 948 // saw a crash dialog and hit "force quit". 949 res.set(0); 950 } 951 } 952 ensureBootCompleted(); 953 } break; 954 case SHOW_FACTORY_ERROR_MSG: { 955 Dialog d = new FactoryErrorDialog( 956 mContext, msg.getData().getCharSequence("msg")); 957 d.show(); 958 ensureBootCompleted(); 959 } break; 960 case UPDATE_CONFIGURATION_MSG: { 961 final ContentResolver resolver = mContext.getContentResolver(); 962 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 963 } break; 964 case GC_BACKGROUND_PROCESSES_MSG: { 965 synchronized (ActivityManagerService.this) { 966 performAppGcsIfAppropriateLocked(); 967 } 968 } break; 969 case WAIT_FOR_DEBUGGER_MSG: { 970 synchronized (ActivityManagerService.this) { 971 ProcessRecord app = (ProcessRecord)msg.obj; 972 if (msg.arg1 != 0) { 973 if (!app.waitedForDebugger) { 974 Dialog d = new AppWaitingForDebuggerDialog( 975 ActivityManagerService.this, 976 mContext, app); 977 app.waitDialog = d; 978 app.waitedForDebugger = true; 979 d.show(); 980 } 981 } else { 982 if (app.waitDialog != null) { 983 app.waitDialog.dismiss(); 984 app.waitDialog = null; 985 } 986 } 987 } 988 } break; 989 case SERVICE_TIMEOUT_MSG: { 990 if (mDidDexOpt) { 991 mDidDexOpt = false; 992 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 993 nmsg.obj = msg.obj; 994 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 995 return; 996 } 997 serviceTimeout((ProcessRecord)msg.obj); 998 } break; 999 case UPDATE_TIME_ZONE: { 1000 synchronized (ActivityManagerService.this) { 1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1002 ProcessRecord r = mLruProcesses.get(i); 1003 if (r.thread != null) { 1004 try { 1005 r.thread.updateTimeZone(); 1006 } catch (RemoteException ex) { 1007 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1008 } 1009 } 1010 } 1011 } 1012 } break; 1013 case CLEAR_DNS_CACHE: { 1014 synchronized (ActivityManagerService.this) { 1015 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1016 ProcessRecord r = mLruProcesses.get(i); 1017 if (r.thread != null) { 1018 try { 1019 r.thread.clearDnsCache(); 1020 } catch (RemoteException ex) { 1021 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1022 } 1023 } 1024 } 1025 } 1026 } break; 1027 case UPDATE_HTTP_PROXY: { 1028 ProxyProperties proxy = (ProxyProperties)msg.obj; 1029 String host = ""; 1030 String port = ""; 1031 String exclList = ""; 1032 if (proxy != null) { 1033 host = proxy.getHost(); 1034 port = Integer.toString(proxy.getPort()); 1035 exclList = proxy.getExclusionList(); 1036 } 1037 synchronized (ActivityManagerService.this) { 1038 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1039 ProcessRecord r = mLruProcesses.get(i); 1040 if (r.thread != null) { 1041 try { 1042 r.thread.setHttpProxy(host, port, exclList); 1043 } catch (RemoteException ex) { 1044 Slog.w(TAG, "Failed to update http proxy for: " + 1045 r.info.processName); 1046 } 1047 } 1048 } 1049 } 1050 } break; 1051 case SHOW_UID_ERROR_MSG: { 1052 String title = "System UIDs Inconsistent"; 1053 String text = "UIDs on the system are inconsistent, you need to wipe your" 1054 + " data partition or your device will be unstable."; 1055 Log.e(TAG, title + ": " + text); 1056 if (mShowDialogs) { 1057 // XXX This is a temporary dialog, no need to localize. 1058 AlertDialog d = new BaseErrorDialog(mContext); 1059 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1060 d.setCancelable(false); 1061 d.setTitle(title); 1062 d.setMessage(text); 1063 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1064 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1065 mUidAlert = d; 1066 d.show(); 1067 } 1068 } break; 1069 case IM_FEELING_LUCKY_MSG: { 1070 if (mUidAlert != null) { 1071 mUidAlert.dismiss(); 1072 mUidAlert = null; 1073 } 1074 } break; 1075 case PROC_START_TIMEOUT_MSG: { 1076 if (mDidDexOpt) { 1077 mDidDexOpt = false; 1078 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1079 nmsg.obj = msg.obj; 1080 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1081 return; 1082 } 1083 ProcessRecord app = (ProcessRecord)msg.obj; 1084 synchronized (ActivityManagerService.this) { 1085 processStartTimedOutLocked(app); 1086 } 1087 } break; 1088 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1089 synchronized (ActivityManagerService.this) { 1090 doPendingActivityLaunchesLocked(true); 1091 } 1092 } break; 1093 case KILL_APPLICATION_MSG: { 1094 synchronized (ActivityManagerService.this) { 1095 int uid = msg.arg1; 1096 boolean restart = (msg.arg2 == 1); 1097 String pkg = (String) msg.obj; 1098 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1099 UserId.getUserId(uid)); 1100 } 1101 } break; 1102 case FINALIZE_PENDING_INTENT_MSG: { 1103 ((PendingIntentRecord)msg.obj).completeFinalize(); 1104 } break; 1105 case POST_HEAVY_NOTIFICATION_MSG: { 1106 INotificationManager inm = NotificationManager.getService(); 1107 if (inm == null) { 1108 return; 1109 } 1110 1111 ActivityRecord root = (ActivityRecord)msg.obj; 1112 ProcessRecord process = root.app; 1113 if (process == null) { 1114 return; 1115 } 1116 1117 try { 1118 Context context = mContext.createPackageContext(process.info.packageName, 0); 1119 String text = mContext.getString(R.string.heavy_weight_notification, 1120 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1121 Notification notification = new Notification(); 1122 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1123 notification.when = 0; 1124 notification.flags = Notification.FLAG_ONGOING_EVENT; 1125 notification.tickerText = text; 1126 notification.defaults = 0; // please be quiet 1127 notification.sound = null; 1128 notification.vibrate = null; 1129 notification.setLatestEventInfo(context, text, 1130 mContext.getText(R.string.heavy_weight_notification_detail), 1131 PendingIntent.getActivity(mContext, 0, root.intent, 1132 PendingIntent.FLAG_CANCEL_CURRENT)); 1133 1134 try { 1135 int[] outId = new int[1]; 1136 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1137 notification, outId); 1138 } catch (RuntimeException e) { 1139 Slog.w(ActivityManagerService.TAG, 1140 "Error showing notification for heavy-weight app", e); 1141 } catch (RemoteException e) { 1142 } 1143 } catch (NameNotFoundException e) { 1144 Slog.w(TAG, "Unable to create context for heavy notification", e); 1145 } 1146 } break; 1147 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1148 INotificationManager inm = NotificationManager.getService(); 1149 if (inm == null) { 1150 return; 1151 } 1152 try { 1153 inm.cancelNotification("android", 1154 R.string.heavy_weight_notification); 1155 } catch (RuntimeException e) { 1156 Slog.w(ActivityManagerService.TAG, 1157 "Error canceling notification for service", e); 1158 } catch (RemoteException e) { 1159 } 1160 } break; 1161 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1162 synchronized (ActivityManagerService.this) { 1163 checkExcessivePowerUsageLocked(true); 1164 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1165 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1166 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1167 } 1168 } break; 1169 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1170 synchronized (ActivityManagerService.this) { 1171 ActivityRecord ar = (ActivityRecord)msg.obj; 1172 if (mCompatModeDialog != null) { 1173 if (mCompatModeDialog.mAppInfo.packageName.equals( 1174 ar.info.applicationInfo.packageName)) { 1175 return; 1176 } 1177 mCompatModeDialog.dismiss(); 1178 mCompatModeDialog = null; 1179 } 1180 if (ar != null && false) { 1181 if (mCompatModePackages.getPackageAskCompatModeLocked( 1182 ar.packageName)) { 1183 int mode = mCompatModePackages.computeCompatModeLocked( 1184 ar.info.applicationInfo); 1185 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1186 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1187 mCompatModeDialog = new CompatModeDialog( 1188 ActivityManagerService.this, mContext, 1189 ar.info.applicationInfo); 1190 mCompatModeDialog.show(); 1191 } 1192 } 1193 } 1194 } 1195 break; 1196 } 1197 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: { 1198 final int pid = msg.arg1; 1199 final int uid = msg.arg2; 1200 final boolean foregroundActivities = (Boolean) msg.obj; 1201 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities); 1202 break; 1203 } 1204 case DISPATCH_PROCESS_DIED: { 1205 final int pid = msg.arg1; 1206 final int uid = msg.arg2; 1207 dispatchProcessDied(pid, uid); 1208 break; 1209 } 1210 case REPORT_MEM_USAGE: { 1211 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1212 if (!isDebuggable) { 1213 return; 1214 } 1215 synchronized (ActivityManagerService.this) { 1216 long now = SystemClock.uptimeMillis(); 1217 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1218 // Don't report more than every 5 minutes to somewhat 1219 // avoid spamming. 1220 return; 1221 } 1222 mLastMemUsageReportTime = now; 1223 } 1224 Thread thread = new Thread() { 1225 @Override public void run() { 1226 StringBuilder dropBuilder = new StringBuilder(1024); 1227 StringBuilder logBuilder = new StringBuilder(1024); 1228 StringWriter oomSw = new StringWriter(); 1229 PrintWriter oomPw = new PrintWriter(oomSw); 1230 StringWriter catSw = new StringWriter(); 1231 PrintWriter catPw = new PrintWriter(catSw); 1232 String[] emptyArgs = new String[] { }; 1233 StringBuilder tag = new StringBuilder(128); 1234 StringBuilder stack = new StringBuilder(128); 1235 tag.append("Low on memory -- "); 1236 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1237 tag, stack); 1238 dropBuilder.append(stack); 1239 dropBuilder.append('\n'); 1240 dropBuilder.append('\n'); 1241 String oomString = oomSw.toString(); 1242 dropBuilder.append(oomString); 1243 dropBuilder.append('\n'); 1244 logBuilder.append(oomString); 1245 try { 1246 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1247 "procrank", }); 1248 final InputStreamReader converter = new InputStreamReader( 1249 proc.getInputStream()); 1250 BufferedReader in = new BufferedReader(converter); 1251 String line; 1252 while (true) { 1253 line = in.readLine(); 1254 if (line == null) { 1255 break; 1256 } 1257 if (line.length() > 0) { 1258 logBuilder.append(line); 1259 logBuilder.append('\n'); 1260 } 1261 dropBuilder.append(line); 1262 dropBuilder.append('\n'); 1263 } 1264 converter.close(); 1265 } catch (IOException e) { 1266 } 1267 synchronized (ActivityManagerService.this) { 1268 catPw.println(); 1269 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1270 catPw.println(); 1271 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null); 1272 catPw.println(); 1273 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1274 } 1275 dropBuilder.append(catSw.toString()); 1276 addErrorToDropBox("lowmem", null, "system_server", null, 1277 null, tag.toString(), dropBuilder.toString(), null, null); 1278 Slog.i(TAG, logBuilder.toString()); 1279 synchronized (ActivityManagerService.this) { 1280 long now = SystemClock.uptimeMillis(); 1281 if (mLastMemUsageReportTime < now) { 1282 mLastMemUsageReportTime = now; 1283 } 1284 } 1285 } 1286 }; 1287 thread.start(); 1288 break; 1289 } 1290 } 1291 } 1292 }; 1293 1294 public static void setSystemProcess() { 1295 try { 1296 ActivityManagerService m = mSelf; 1297 1298 ServiceManager.addService("activity", m, true); 1299 ServiceManager.addService("meminfo", new MemBinder(m)); 1300 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1301 ServiceManager.addService("dbinfo", new DbBinder(m)); 1302 if (MONITOR_CPU_USAGE) { 1303 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1304 } 1305 ServiceManager.addService("permission", new PermissionController(m)); 1306 1307 ApplicationInfo info = 1308 mSelf.mContext.getPackageManager().getApplicationInfo( 1309 "android", STOCK_PM_FLAGS); 1310 mSystemThread.installSystemApplicationInfo(info); 1311 1312 synchronized (mSelf) { 1313 ProcessRecord app = mSelf.newProcessRecordLocked( 1314 mSystemThread.getApplicationThread(), info, 1315 info.processName, false); 1316 app.persistent = true; 1317 app.pid = MY_PID; 1318 app.maxAdj = ProcessList.SYSTEM_ADJ; 1319 mSelf.mProcessNames.put(app.processName, app.uid, app); 1320 synchronized (mSelf.mPidsSelfLocked) { 1321 mSelf.mPidsSelfLocked.put(app.pid, app); 1322 } 1323 mSelf.updateLruProcessLocked(app, true, true); 1324 } 1325 } catch (PackageManager.NameNotFoundException e) { 1326 throw new RuntimeException( 1327 "Unable to find android system package", e); 1328 } 1329 } 1330 1331 public void setWindowManager(WindowManagerService wm) { 1332 mWindowManager = wm; 1333 } 1334 1335 public static final Context main(int factoryTest) { 1336 AThread thr = new AThread(); 1337 thr.start(); 1338 1339 synchronized (thr) { 1340 while (thr.mService == null) { 1341 try { 1342 thr.wait(); 1343 } catch (InterruptedException e) { 1344 } 1345 } 1346 } 1347 1348 ActivityManagerService m = thr.mService; 1349 mSelf = m; 1350 ActivityThread at = ActivityThread.systemMain(); 1351 mSystemThread = at; 1352 Context context = at.getSystemContext(); 1353 context.setTheme(android.R.style.Theme_Holo); 1354 m.mContext = context; 1355 m.mFactoryTest = factoryTest; 1356 m.mMainStack = new ActivityStack(m, context, true); 1357 1358 m.mBatteryStatsService.publish(context); 1359 m.mUsageStatsService.publish(context); 1360 1361 synchronized (thr) { 1362 thr.mReady = true; 1363 thr.notifyAll(); 1364 } 1365 1366 m.startRunning(null, null, null, null); 1367 1368 return context; 1369 } 1370 1371 public static ActivityManagerService self() { 1372 return mSelf; 1373 } 1374 1375 static class AThread extends Thread { 1376 ActivityManagerService mService; 1377 boolean mReady = false; 1378 1379 public AThread() { 1380 super("ActivityManager"); 1381 } 1382 1383 public void run() { 1384 Looper.prepare(); 1385 1386 android.os.Process.setThreadPriority( 1387 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1388 android.os.Process.setCanSelfBackground(false); 1389 1390 ActivityManagerService m = new ActivityManagerService(); 1391 1392 synchronized (this) { 1393 mService = m; 1394 notifyAll(); 1395 } 1396 1397 synchronized (this) { 1398 while (!mReady) { 1399 try { 1400 wait(); 1401 } catch (InterruptedException e) { 1402 } 1403 } 1404 } 1405 1406 // For debug builds, log event loop stalls to dropbox for analysis. 1407 if (StrictMode.conditionallyEnableDebugLogging()) { 1408 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1409 } 1410 1411 Looper.loop(); 1412 } 1413 } 1414 1415 static class MemBinder extends Binder { 1416 ActivityManagerService mActivityManagerService; 1417 MemBinder(ActivityManagerService activityManagerService) { 1418 mActivityManagerService = activityManagerService; 1419 } 1420 1421 @Override 1422 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1423 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1424 != PackageManager.PERMISSION_GRANTED) { 1425 pw.println("Permission Denial: can't dump meminfo from from pid=" 1426 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1427 + " without permission " + android.Manifest.permission.DUMP); 1428 return; 1429 } 1430 1431 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1432 false, null, null, null); 1433 } 1434 } 1435 1436 static class GraphicsBinder extends Binder { 1437 ActivityManagerService mActivityManagerService; 1438 GraphicsBinder(ActivityManagerService activityManagerService) { 1439 mActivityManagerService = activityManagerService; 1440 } 1441 1442 @Override 1443 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1444 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1445 != PackageManager.PERMISSION_GRANTED) { 1446 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1447 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1448 + " without permission " + android.Manifest.permission.DUMP); 1449 return; 1450 } 1451 1452 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1453 } 1454 } 1455 1456 static class DbBinder extends Binder { 1457 ActivityManagerService mActivityManagerService; 1458 DbBinder(ActivityManagerService activityManagerService) { 1459 mActivityManagerService = activityManagerService; 1460 } 1461 1462 @Override 1463 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1464 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1465 != PackageManager.PERMISSION_GRANTED) { 1466 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1467 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1468 + " without permission " + android.Manifest.permission.DUMP); 1469 return; 1470 } 1471 1472 mActivityManagerService.dumpDbInfo(fd, pw, args); 1473 } 1474 } 1475 1476 static class CpuBinder extends Binder { 1477 ActivityManagerService mActivityManagerService; 1478 CpuBinder(ActivityManagerService activityManagerService) { 1479 mActivityManagerService = activityManagerService; 1480 } 1481 1482 @Override 1483 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1484 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1485 != PackageManager.PERMISSION_GRANTED) { 1486 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1487 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1488 + " without permission " + android.Manifest.permission.DUMP); 1489 return; 1490 } 1491 1492 synchronized (mActivityManagerService.mProcessStatsThread) { 1493 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1494 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1495 SystemClock.uptimeMillis())); 1496 } 1497 } 1498 } 1499 1500 private ActivityManagerService() { 1501 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1502 1503 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1504 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1505 mBroadcastQueues[0] = mFgBroadcastQueue; 1506 mBroadcastQueues[1] = mBgBroadcastQueue; 1507 1508 File dataDir = Environment.getDataDirectory(); 1509 File systemDir = new File(dataDir, "system"); 1510 systemDir.mkdirs(); 1511 mBatteryStatsService = new BatteryStatsService(new File( 1512 systemDir, "batterystats.bin").toString()); 1513 mBatteryStatsService.getActiveStatistics().readLocked(); 1514 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1515 mOnBattery = DEBUG_POWER ? true 1516 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1517 mBatteryStatsService.getActiveStatistics().setCallback(this); 1518 1519 mUsageStatsService = new UsageStatsService(new File( 1520 systemDir, "usagestats").toString()); 1521 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1522 1523 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1524 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1525 1526 mConfiguration.setToDefaults(); 1527 mConfiguration.locale = Locale.getDefault(); 1528 mConfigurationSeq = mConfiguration.seq = 1; 1529 mProcessStats.init(); 1530 1531 mCompatModePackages = new CompatModePackages(this, systemDir); 1532 1533 // Add ourself to the Watchdog monitors. 1534 Watchdog.getInstance().addMonitor(this); 1535 1536 mProcessStatsThread = new Thread("ProcessStats") { 1537 public void run() { 1538 while (true) { 1539 try { 1540 try { 1541 synchronized(this) { 1542 final long now = SystemClock.uptimeMillis(); 1543 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1544 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1545 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1546 // + ", write delay=" + nextWriteDelay); 1547 if (nextWriteDelay < nextCpuDelay) { 1548 nextCpuDelay = nextWriteDelay; 1549 } 1550 if (nextCpuDelay > 0) { 1551 mProcessStatsMutexFree.set(true); 1552 this.wait(nextCpuDelay); 1553 } 1554 } 1555 } catch (InterruptedException e) { 1556 } 1557 updateCpuStatsNow(); 1558 } catch (Exception e) { 1559 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1560 } 1561 } 1562 } 1563 }; 1564 mProcessStatsThread.start(); 1565 } 1566 1567 @Override 1568 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1569 throws RemoteException { 1570 if (code == SYSPROPS_TRANSACTION) { 1571 // We need to tell all apps about the system property change. 1572 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1573 synchronized(this) { 1574 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1575 final int NA = apps.size(); 1576 for (int ia=0; ia<NA; ia++) { 1577 ProcessRecord app = apps.valueAt(ia); 1578 if (app.thread != null) { 1579 procs.add(app.thread.asBinder()); 1580 } 1581 } 1582 } 1583 } 1584 1585 int N = procs.size(); 1586 for (int i=0; i<N; i++) { 1587 Parcel data2 = Parcel.obtain(); 1588 try { 1589 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1590 } catch (RemoteException e) { 1591 } 1592 data2.recycle(); 1593 } 1594 } 1595 try { 1596 return super.onTransact(code, data, reply, flags); 1597 } catch (RuntimeException e) { 1598 // The activity manager only throws security exceptions, so let's 1599 // log all others. 1600 if (!(e instanceof SecurityException)) { 1601 Slog.e(TAG, "Activity Manager Crash", e); 1602 } 1603 throw e; 1604 } 1605 } 1606 1607 void updateCpuStats() { 1608 final long now = SystemClock.uptimeMillis(); 1609 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1610 return; 1611 } 1612 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1613 synchronized (mProcessStatsThread) { 1614 mProcessStatsThread.notify(); 1615 } 1616 } 1617 } 1618 1619 void updateCpuStatsNow() { 1620 synchronized (mProcessStatsThread) { 1621 mProcessStatsMutexFree.set(false); 1622 final long now = SystemClock.uptimeMillis(); 1623 boolean haveNewCpuStats = false; 1624 1625 if (MONITOR_CPU_USAGE && 1626 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1627 mLastCpuTime.set(now); 1628 haveNewCpuStats = true; 1629 mProcessStats.update(); 1630 //Slog.i(TAG, mProcessStats.printCurrentState()); 1631 //Slog.i(TAG, "Total CPU usage: " 1632 // + mProcessStats.getTotalCpuPercent() + "%"); 1633 1634 // Slog the cpu usage if the property is set. 1635 if ("true".equals(SystemProperties.get("events.cpu"))) { 1636 int user = mProcessStats.getLastUserTime(); 1637 int system = mProcessStats.getLastSystemTime(); 1638 int iowait = mProcessStats.getLastIoWaitTime(); 1639 int irq = mProcessStats.getLastIrqTime(); 1640 int softIrq = mProcessStats.getLastSoftIrqTime(); 1641 int idle = mProcessStats.getLastIdleTime(); 1642 1643 int total = user + system + iowait + irq + softIrq + idle; 1644 if (total == 0) total = 1; 1645 1646 EventLog.writeEvent(EventLogTags.CPU, 1647 ((user+system+iowait+irq+softIrq) * 100) / total, 1648 (user * 100) / total, 1649 (system * 100) / total, 1650 (iowait * 100) / total, 1651 (irq * 100) / total, 1652 (softIrq * 100) / total); 1653 } 1654 } 1655 1656 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1657 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1658 synchronized(bstats) { 1659 synchronized(mPidsSelfLocked) { 1660 if (haveNewCpuStats) { 1661 if (mOnBattery) { 1662 int perc = bstats.startAddingCpuLocked(); 1663 int totalUTime = 0; 1664 int totalSTime = 0; 1665 final int N = mProcessStats.countStats(); 1666 for (int i=0; i<N; i++) { 1667 ProcessStats.Stats st = mProcessStats.getStats(i); 1668 if (!st.working) { 1669 continue; 1670 } 1671 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1672 int otherUTime = (st.rel_utime*perc)/100; 1673 int otherSTime = (st.rel_stime*perc)/100; 1674 totalUTime += otherUTime; 1675 totalSTime += otherSTime; 1676 if (pr != null) { 1677 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1678 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1679 st.rel_stime-otherSTime); 1680 ps.addSpeedStepTimes(cpuSpeedTimes); 1681 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1682 } else { 1683 BatteryStatsImpl.Uid.Proc ps = 1684 bstats.getProcessStatsLocked(st.name, st.pid); 1685 if (ps != null) { 1686 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1687 st.rel_stime-otherSTime); 1688 ps.addSpeedStepTimes(cpuSpeedTimes); 1689 } 1690 } 1691 } 1692 bstats.finishAddingCpuLocked(perc, totalUTime, 1693 totalSTime, cpuSpeedTimes); 1694 } 1695 } 1696 } 1697 1698 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1699 mLastWriteTime = now; 1700 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1701 } 1702 } 1703 } 1704 } 1705 1706 @Override 1707 public void batteryNeedsCpuUpdate() { 1708 updateCpuStatsNow(); 1709 } 1710 1711 @Override 1712 public void batteryPowerChanged(boolean onBattery) { 1713 // When plugging in, update the CPU stats first before changing 1714 // the plug state. 1715 updateCpuStatsNow(); 1716 synchronized (this) { 1717 synchronized(mPidsSelfLocked) { 1718 mOnBattery = DEBUG_POWER ? true : onBattery; 1719 } 1720 } 1721 } 1722 1723 /** 1724 * Initialize the application bind args. These are passed to each 1725 * process when the bindApplication() IPC is sent to the process. They're 1726 * lazily setup to make sure the services are running when they're asked for. 1727 */ 1728 private HashMap<String, IBinder> getCommonServicesLocked() { 1729 if (mAppBindArgs == null) { 1730 mAppBindArgs = new HashMap<String, IBinder>(); 1731 1732 // Setup the application init args 1733 mAppBindArgs.put("package", ServiceManager.getService("package")); 1734 mAppBindArgs.put("window", ServiceManager.getService("window")); 1735 mAppBindArgs.put(Context.ALARM_SERVICE, 1736 ServiceManager.getService(Context.ALARM_SERVICE)); 1737 } 1738 return mAppBindArgs; 1739 } 1740 1741 final void setFocusedActivityLocked(ActivityRecord r) { 1742 if (mFocusedActivity != r) { 1743 mFocusedActivity = r; 1744 if (r != null) { 1745 mWindowManager.setFocusedApp(r.appToken, true); 1746 } 1747 } 1748 } 1749 1750 private final void updateLruProcessInternalLocked(ProcessRecord app, 1751 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1752 // put it on the LRU to keep track of when it should be exited. 1753 int lrui = mLruProcesses.indexOf(app); 1754 if (lrui >= 0) mLruProcesses.remove(lrui); 1755 1756 int i = mLruProcesses.size()-1; 1757 int skipTop = 0; 1758 1759 app.lruSeq = mLruSeq; 1760 1761 // compute the new weight for this process. 1762 if (updateActivityTime) { 1763 app.lastActivityTime = SystemClock.uptimeMillis(); 1764 } 1765 if (app.activities.size() > 0) { 1766 // If this process has activities, we more strongly want to keep 1767 // it around. 1768 app.lruWeight = app.lastActivityTime; 1769 } else if (app.pubProviders.size() > 0) { 1770 // If this process contains content providers, we want to keep 1771 // it a little more strongly. 1772 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1773 // Also don't let it kick out the first few "real" hidden processes. 1774 skipTop = ProcessList.MIN_HIDDEN_APPS; 1775 } else { 1776 // If this process doesn't have activities, we less strongly 1777 // want to keep it around, and generally want to avoid getting 1778 // in front of any very recently used activities. 1779 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1780 // Also don't let it kick out the first few "real" hidden processes. 1781 skipTop = ProcessList.MIN_HIDDEN_APPS; 1782 } 1783 1784 while (i >= 0) { 1785 ProcessRecord p = mLruProcesses.get(i); 1786 // If this app shouldn't be in front of the first N background 1787 // apps, then skip over that many that are currently hidden. 1788 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1789 skipTop--; 1790 } 1791 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1792 mLruProcesses.add(i+1, app); 1793 break; 1794 } 1795 i--; 1796 } 1797 if (i < 0) { 1798 mLruProcesses.add(0, app); 1799 } 1800 1801 // If the app is currently using a content provider or service, 1802 // bump those processes as well. 1803 if (app.connections.size() > 0) { 1804 for (ConnectionRecord cr : app.connections) { 1805 if (cr.binding != null && cr.binding.service != null 1806 && cr.binding.service.app != null 1807 && cr.binding.service.app.lruSeq != mLruSeq) { 1808 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, 1809 updateActivityTime, i+1); 1810 } 1811 } 1812 } 1813 if (app.conProviders.size() > 0) { 1814 for (ContentProviderRecord cpr : app.conProviders.keySet()) { 1815 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1816 updateLruProcessInternalLocked(cpr.proc, oomAdj, 1817 updateActivityTime, i+1); 1818 } 1819 } 1820 } 1821 1822 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1823 if (oomAdj) { 1824 updateOomAdjLocked(); 1825 } 1826 } 1827 1828 final void updateLruProcessLocked(ProcessRecord app, 1829 boolean oomAdj, boolean updateActivityTime) { 1830 mLruSeq++; 1831 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1832 } 1833 1834 final ProcessRecord getProcessRecordLocked( 1835 String processName, int uid) { 1836 if (uid == Process.SYSTEM_UID) { 1837 // The system gets to run in any process. If there are multiple 1838 // processes with the same uid, just pick the first (this 1839 // should never happen). 1840 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1841 processName); 1842 if (procs == null) return null; 1843 final int N = procs.size(); 1844 for (int i = 0; i < N; i++) { 1845 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1846 } 1847 } 1848 ProcessRecord proc = mProcessNames.get(processName, uid); 1849 return proc; 1850 } 1851 1852 void ensurePackageDexOpt(String packageName) { 1853 IPackageManager pm = AppGlobals.getPackageManager(); 1854 try { 1855 if (pm.performDexOpt(packageName)) { 1856 mDidDexOpt = true; 1857 } 1858 } catch (RemoteException e) { 1859 } 1860 } 1861 1862 boolean isNextTransitionForward() { 1863 int transit = mWindowManager.getPendingAppTransition(); 1864 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1865 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1866 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1867 } 1868 1869 final ProcessRecord startProcessLocked(String processName, 1870 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1871 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1872 boolean isolated) { 1873 ProcessRecord app; 1874 if (!isolated) { 1875 app = getProcessRecordLocked(processName, info.uid); 1876 } else { 1877 // If this is an isolated process, it can't re-use an existing process. 1878 app = null; 1879 } 1880 // We don't have to do anything more if: 1881 // (1) There is an existing application record; and 1882 // (2) The caller doesn't think it is dead, OR there is no thread 1883 // object attached to it so we know it couldn't have crashed; and 1884 // (3) There is a pid assigned to it, so it is either starting or 1885 // already running. 1886 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1887 + " app=" + app + " knownToBeDead=" + knownToBeDead 1888 + " thread=" + (app != null ? app.thread : null) 1889 + " pid=" + (app != null ? app.pid : -1)); 1890 if (app != null && app.pid > 0) { 1891 if (!knownToBeDead || app.thread == null) { 1892 // We already have the app running, or are waiting for it to 1893 // come up (we have a pid but not yet its thread), so keep it. 1894 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1895 // If this is a new package in the process, add the package to the list 1896 app.addPackage(info.packageName); 1897 return app; 1898 } else { 1899 // An application record is attached to a previous process, 1900 // clean it up now. 1901 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1902 handleAppDiedLocked(app, true, true); 1903 } 1904 } 1905 1906 String hostingNameStr = hostingName != null 1907 ? hostingName.flattenToShortString() : null; 1908 1909 if (!isolated) { 1910 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1911 // If we are in the background, then check to see if this process 1912 // is bad. If so, we will just silently fail. 1913 if (mBadProcesses.get(info.processName, info.uid) != null) { 1914 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1915 + "/" + info.processName); 1916 return null; 1917 } 1918 } else { 1919 // When the user is explicitly starting a process, then clear its 1920 // crash count so that we won't make it bad until they see at 1921 // least one crash dialog again, and make the process good again 1922 // if it had been bad. 1923 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1924 + "/" + info.processName); 1925 mProcessCrashTimes.remove(info.processName, info.uid); 1926 if (mBadProcesses.get(info.processName, info.uid) != null) { 1927 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1928 info.processName); 1929 mBadProcesses.remove(info.processName, info.uid); 1930 if (app != null) { 1931 app.bad = false; 1932 } 1933 } 1934 } 1935 } 1936 1937 if (app == null) { 1938 app = newProcessRecordLocked(null, info, processName, isolated); 1939 if (app == null) { 1940 Slog.w(TAG, "Failed making new process record for " 1941 + processName + "/" + info.uid + " isolated=" + isolated); 1942 return null; 1943 } 1944 mProcessNames.put(processName, app.uid, app); 1945 if (isolated) { 1946 mIsolatedProcesses.put(app.uid, app); 1947 } 1948 } else { 1949 // If this is a new package in the process, add the package to the list 1950 app.addPackage(info.packageName); 1951 } 1952 1953 // If the system is not ready yet, then hold off on starting this 1954 // process until it is. 1955 if (!mProcessesReady 1956 && !isAllowedWhileBooting(info) 1957 && !allowWhileBooting) { 1958 if (!mProcessesOnHold.contains(app)) { 1959 mProcessesOnHold.add(app); 1960 } 1961 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1962 return app; 1963 } 1964 1965 startProcessLocked(app, hostingType, hostingNameStr); 1966 return (app.pid != 0) ? app : null; 1967 } 1968 1969 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1970 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1971 } 1972 1973 private final void startProcessLocked(ProcessRecord app, 1974 String hostingType, String hostingNameStr) { 1975 if (app.pid > 0 && app.pid != MY_PID) { 1976 synchronized (mPidsSelfLocked) { 1977 mPidsSelfLocked.remove(app.pid); 1978 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1979 } 1980 app.pid = 0; 1981 } 1982 1983 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1984 "startProcessLocked removing on hold: " + app); 1985 mProcessesOnHold.remove(app); 1986 1987 updateCpuStats(); 1988 1989 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1990 mProcDeaths[0] = 0; 1991 1992 try { 1993 int uid = app.uid; 1994 1995 int[] gids = null; 1996 if (!app.isolated) { 1997 try { 1998 gids = mContext.getPackageManager().getPackageGids( 1999 app.info.packageName); 2000 } catch (PackageManager.NameNotFoundException e) { 2001 Slog.w(TAG, "Unable to retrieve gids", e); 2002 } 2003 } 2004 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2005 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2006 && mTopComponent != null 2007 && app.processName.equals(mTopComponent.getPackageName())) { 2008 uid = 0; 2009 } 2010 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2011 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2012 uid = 0; 2013 } 2014 } 2015 int debugFlags = 0; 2016 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2017 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2018 // Also turn on CheckJNI for debuggable apps. It's quite 2019 // awkward to turn on otherwise. 2020 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2021 } 2022 // Run the app in safe mode if its manifest requests so or the 2023 // system is booted in safe mode. 2024 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2025 Zygote.systemInSafeMode == true) { 2026 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2027 } 2028 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2029 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2030 } 2031 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2032 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2033 } 2034 if ("1".equals(SystemProperties.get("debug.assert"))) { 2035 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2036 } 2037 2038 // Start the process. It will either succeed and return a result containing 2039 // the PID of the new process, or else throw a RuntimeException. 2040 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2041 app.processName, uid, uid, gids, debugFlags, 2042 app.info.targetSdkVersion, null); 2043 2044 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2045 synchronized (bs) { 2046 if (bs.isOnBattery()) { 2047 app.batteryStats.incStartsLocked(); 2048 } 2049 } 2050 2051 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2052 app.processName, hostingType, 2053 hostingNameStr != null ? hostingNameStr : ""); 2054 2055 if (app.persistent) { 2056 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2057 } 2058 2059 StringBuilder buf = mStringBuilder; 2060 buf.setLength(0); 2061 buf.append("Start proc "); 2062 buf.append(app.processName); 2063 buf.append(" for "); 2064 buf.append(hostingType); 2065 if (hostingNameStr != null) { 2066 buf.append(" "); 2067 buf.append(hostingNameStr); 2068 } 2069 buf.append(": pid="); 2070 buf.append(startResult.pid); 2071 buf.append(" uid="); 2072 buf.append(uid); 2073 buf.append(" gids={"); 2074 if (gids != null) { 2075 for (int gi=0; gi<gids.length; gi++) { 2076 if (gi != 0) buf.append(", "); 2077 buf.append(gids[gi]); 2078 2079 } 2080 } 2081 buf.append("}"); 2082 Slog.i(TAG, buf.toString()); 2083 app.pid = startResult.pid; 2084 app.usingWrapper = startResult.usingWrapper; 2085 app.removed = false; 2086 synchronized (mPidsSelfLocked) { 2087 this.mPidsSelfLocked.put(startResult.pid, app); 2088 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2089 msg.obj = app; 2090 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2091 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2092 } 2093 } catch (RuntimeException e) { 2094 // XXX do better error recovery. 2095 app.pid = 0; 2096 Slog.e(TAG, "Failure starting process " + app.processName, e); 2097 } 2098 } 2099 2100 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2101 if (resumed) { 2102 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2103 } else { 2104 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2105 } 2106 } 2107 2108 boolean startHomeActivityLocked(int userId) { 2109 if (mHeadless) { 2110 // Added because none of the other calls to ensureBootCompleted seem to fire 2111 // when running headless. 2112 ensureBootCompleted(); 2113 return false; 2114 } 2115 2116 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2117 && mTopAction == null) { 2118 // We are running in factory test mode, but unable to find 2119 // the factory test app, so just sit around displaying the 2120 // error message and don't try to start anything. 2121 return false; 2122 } 2123 Intent intent = new Intent( 2124 mTopAction, 2125 mTopData != null ? Uri.parse(mTopData) : null); 2126 intent.setComponent(mTopComponent); 2127 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2128 intent.addCategory(Intent.CATEGORY_HOME); 2129 } 2130 ActivityInfo aInfo = 2131 intent.resolveActivityInfo(mContext.getPackageManager(), 2132 STOCK_PM_FLAGS); 2133 if (aInfo != null) { 2134 intent.setComponent(new ComponentName( 2135 aInfo.applicationInfo.packageName, aInfo.name)); 2136 // Don't do this if the home app is currently being 2137 // instrumented. 2138 aInfo = new ActivityInfo(aInfo); 2139 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2140 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2141 aInfo.applicationInfo.uid); 2142 if (app == null || app.instrumentationClass == null) { 2143 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2144 mMainStack.startActivityLocked(null, intent, null, aInfo, 2145 null, null, 0, 0, 0, 0, null, false, null); 2146 } 2147 } 2148 2149 return true; 2150 } 2151 2152 /** 2153 * Starts the "new version setup screen" if appropriate. 2154 */ 2155 void startSetupActivityLocked() { 2156 // Only do this once per boot. 2157 if (mCheckedForSetup) { 2158 return; 2159 } 2160 2161 // We will show this screen if the current one is a different 2162 // version than the last one shown, and we are not running in 2163 // low-level factory test mode. 2164 final ContentResolver resolver = mContext.getContentResolver(); 2165 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2166 Settings.Secure.getInt(resolver, 2167 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2168 mCheckedForSetup = true; 2169 2170 // See if we should be showing the platform update setup UI. 2171 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2172 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2173 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2174 2175 // We don't allow third party apps to replace this. 2176 ResolveInfo ri = null; 2177 for (int i=0; ris != null && i<ris.size(); i++) { 2178 if ((ris.get(i).activityInfo.applicationInfo.flags 2179 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2180 ri = ris.get(i); 2181 break; 2182 } 2183 } 2184 2185 if (ri != null) { 2186 String vers = ri.activityInfo.metaData != null 2187 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2188 : null; 2189 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2190 vers = ri.activityInfo.applicationInfo.metaData.getString( 2191 Intent.METADATA_SETUP_VERSION); 2192 } 2193 String lastVers = Settings.Secure.getString( 2194 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2195 if (vers != null && !vers.equals(lastVers)) { 2196 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2197 intent.setComponent(new ComponentName( 2198 ri.activityInfo.packageName, ri.activityInfo.name)); 2199 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2200 null, null, 0, 0, 0, 0, null, false, null); 2201 } 2202 } 2203 } 2204 } 2205 2206 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2207 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2208 } 2209 2210 void enforceNotIsolatedCaller(String caller) { 2211 if (UserId.isIsolated(Binder.getCallingUid())) { 2212 throw new SecurityException("Isolated process not allowed to call " + caller); 2213 } 2214 } 2215 2216 public int getFrontActivityScreenCompatMode() { 2217 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2218 synchronized (this) { 2219 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2220 } 2221 } 2222 2223 public void setFrontActivityScreenCompatMode(int mode) { 2224 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2225 "setFrontActivityScreenCompatMode"); 2226 synchronized (this) { 2227 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2228 } 2229 } 2230 2231 public int getPackageScreenCompatMode(String packageName) { 2232 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2233 synchronized (this) { 2234 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2235 } 2236 } 2237 2238 public void setPackageScreenCompatMode(String packageName, int mode) { 2239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2240 "setPackageScreenCompatMode"); 2241 synchronized (this) { 2242 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2243 } 2244 } 2245 2246 public boolean getPackageAskScreenCompat(String packageName) { 2247 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2248 synchronized (this) { 2249 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2250 } 2251 } 2252 2253 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2254 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2255 "setPackageAskScreenCompat"); 2256 synchronized (this) { 2257 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2258 } 2259 } 2260 2261 void reportResumedActivityLocked(ActivityRecord r) { 2262 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2263 2264 final int identHash = System.identityHashCode(r); 2265 updateUsageStats(r, true); 2266 } 2267 2268 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 2269 int i = mProcessObservers.beginBroadcast(); 2270 while (i > 0) { 2271 i--; 2272 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2273 if (observer != null) { 2274 try { 2275 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities); 2276 } catch (RemoteException e) { 2277 } 2278 } 2279 } 2280 mProcessObservers.finishBroadcast(); 2281 } 2282 2283 private void dispatchProcessDied(int pid, int uid) { 2284 int i = mProcessObservers.beginBroadcast(); 2285 while (i > 0) { 2286 i--; 2287 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2288 if (observer != null) { 2289 try { 2290 observer.onProcessDied(pid, uid); 2291 } catch (RemoteException e) { 2292 } 2293 } 2294 } 2295 mProcessObservers.finishBroadcast(); 2296 } 2297 2298 final void doPendingActivityLaunchesLocked(boolean doResume) { 2299 final int N = mPendingActivityLaunches.size(); 2300 if (N <= 0) { 2301 return; 2302 } 2303 for (int i=0; i<N; i++) { 2304 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2305 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2306 pal.startFlags, doResume && i == (N-1), null); 2307 } 2308 mPendingActivityLaunches.clear(); 2309 } 2310 2311 public final int startActivity(IApplicationThread caller, 2312 Intent intent, String resolvedType, IBinder resultTo, 2313 String resultWho, int requestCode, int startFlags, 2314 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2315 enforceNotIsolatedCaller("startActivity"); 2316 int userId = 0; 2317 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2318 // Requesting home, set the identity to the current user 2319 // HACK! 2320 userId = mCurrentUserId; 2321 } else { 2322 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2323 // the current user's userId 2324 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2325 userId = 0; 2326 } else { 2327 userId = Binder.getOrigCallingUser(); 2328 } 2329 } 2330 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2331 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2332 null, null, options, userId); 2333 } 2334 2335 public final WaitResult startActivityAndWait(IApplicationThread caller, 2336 Intent intent, String resolvedType, IBinder resultTo, 2337 String resultWho, int requestCode, int startFlags, String profileFile, 2338 ParcelFileDescriptor profileFd, Bundle options) { 2339 enforceNotIsolatedCaller("startActivityAndWait"); 2340 WaitResult res = new WaitResult(); 2341 int userId = Binder.getOrigCallingUser(); 2342 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2343 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2344 res, null, options, userId); 2345 return res; 2346 } 2347 2348 public final int startActivityWithConfig(IApplicationThread caller, 2349 Intent intent, String resolvedType, IBinder resultTo, 2350 String resultWho, int requestCode, int startFlags, Configuration config, 2351 Bundle options) { 2352 enforceNotIsolatedCaller("startActivityWithConfig"); 2353 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2354 resultTo, resultWho, requestCode, startFlags, 2355 null, null, null, config, options, Binder.getOrigCallingUser()); 2356 return ret; 2357 } 2358 2359 public int startActivityIntentSender(IApplicationThread caller, 2360 IntentSender intent, Intent fillInIntent, String resolvedType, 2361 IBinder resultTo, String resultWho, int requestCode, 2362 int flagsMask, int flagsValues, Bundle options) { 2363 enforceNotIsolatedCaller("startActivityIntentSender"); 2364 // Refuse possible leaked file descriptors 2365 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2366 throw new IllegalArgumentException("File descriptors passed in Intent"); 2367 } 2368 2369 IIntentSender sender = intent.getTarget(); 2370 if (!(sender instanceof PendingIntentRecord)) { 2371 throw new IllegalArgumentException("Bad PendingIntent object"); 2372 } 2373 2374 PendingIntentRecord pir = (PendingIntentRecord)sender; 2375 2376 synchronized (this) { 2377 // If this is coming from the currently resumed activity, it is 2378 // effectively saying that app switches are allowed at this point. 2379 if (mMainStack.mResumedActivity != null 2380 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2381 Binder.getCallingUid()) { 2382 mAppSwitchesAllowedTime = 0; 2383 } 2384 } 2385 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2386 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2387 return ret; 2388 } 2389 2390 public boolean startNextMatchingActivity(IBinder callingActivity, 2391 Intent intent, Bundle options) { 2392 // Refuse possible leaked file descriptors 2393 if (intent != null && intent.hasFileDescriptors() == true) { 2394 throw new IllegalArgumentException("File descriptors passed in Intent"); 2395 } 2396 2397 synchronized (this) { 2398 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2399 if (r == null) { 2400 ActivityOptions.abort(options); 2401 return false; 2402 } 2403 if (r.app == null || r.app.thread == null) { 2404 // The caller is not running... d'oh! 2405 ActivityOptions.abort(options); 2406 return false; 2407 } 2408 intent = new Intent(intent); 2409 // The caller is not allowed to change the data. 2410 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2411 // And we are resetting to find the next component... 2412 intent.setComponent(null); 2413 2414 ActivityInfo aInfo = null; 2415 try { 2416 List<ResolveInfo> resolves = 2417 AppGlobals.getPackageManager().queryIntentActivities( 2418 intent, r.resolvedType, 2419 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2420 UserId.getCallingUserId()); 2421 2422 // Look for the original activity in the list... 2423 final int N = resolves != null ? resolves.size() : 0; 2424 for (int i=0; i<N; i++) { 2425 ResolveInfo rInfo = resolves.get(i); 2426 if (rInfo.activityInfo.packageName.equals(r.packageName) 2427 && rInfo.activityInfo.name.equals(r.info.name)) { 2428 // We found the current one... the next matching is 2429 // after it. 2430 i++; 2431 if (i<N) { 2432 aInfo = resolves.get(i).activityInfo; 2433 } 2434 break; 2435 } 2436 } 2437 } catch (RemoteException e) { 2438 } 2439 2440 if (aInfo == null) { 2441 // Nobody who is next! 2442 ActivityOptions.abort(options); 2443 return false; 2444 } 2445 2446 intent.setComponent(new ComponentName( 2447 aInfo.applicationInfo.packageName, aInfo.name)); 2448 intent.setFlags(intent.getFlags()&~( 2449 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2450 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2451 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2452 Intent.FLAG_ACTIVITY_NEW_TASK)); 2453 2454 // Okay now we need to start the new activity, replacing the 2455 // currently running activity. This is a little tricky because 2456 // we want to start the new one as if the current one is finished, 2457 // but not finish the current one first so that there is no flicker. 2458 // And thus... 2459 final boolean wasFinishing = r.finishing; 2460 r.finishing = true; 2461 2462 // Propagate reply information over to the new activity. 2463 final ActivityRecord resultTo = r.resultTo; 2464 final String resultWho = r.resultWho; 2465 final int requestCode = r.requestCode; 2466 r.resultTo = null; 2467 if (resultTo != null) { 2468 resultTo.removeResultsLocked(r, resultWho, requestCode); 2469 } 2470 2471 final long origId = Binder.clearCallingIdentity(); 2472 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2473 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2474 resultWho, requestCode, -1, r.launchedFromUid, 0, 2475 options, false, null); 2476 Binder.restoreCallingIdentity(origId); 2477 2478 r.finishing = wasFinishing; 2479 if (res != ActivityManager.START_SUCCESS) { 2480 return false; 2481 } 2482 return true; 2483 } 2484 } 2485 2486 public final int startActivityInPackage(int uid, 2487 Intent intent, String resolvedType, IBinder resultTo, 2488 String resultWho, int requestCode, int startFlags, Bundle options) { 2489 2490 // This is so super not safe, that only the system (or okay root) 2491 // can do it. 2492 int userId = Binder.getOrigCallingUser(); 2493 final int callingUid = Binder.getCallingUid(); 2494 if (callingUid != 0 && callingUid != Process.myUid()) { 2495 throw new SecurityException( 2496 "startActivityInPackage only available to the system"); 2497 } 2498 2499 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2500 resultTo, resultWho, requestCode, startFlags, 2501 null, null, null, null, options, userId); 2502 return ret; 2503 } 2504 2505 public final int startActivities(IApplicationThread caller, 2506 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2507 enforceNotIsolatedCaller("startActivities"); 2508 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2509 options, Binder.getOrigCallingUser()); 2510 return ret; 2511 } 2512 2513 public final int startActivitiesInPackage(int uid, 2514 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2515 Bundle options) { 2516 2517 // This is so super not safe, that only the system (or okay root) 2518 // can do it. 2519 final int callingUid = Binder.getCallingUid(); 2520 if (callingUid != 0 && callingUid != Process.myUid()) { 2521 throw new SecurityException( 2522 "startActivityInPackage only available to the system"); 2523 } 2524 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2525 options, UserId.getUserId(uid)); 2526 return ret; 2527 } 2528 2529 final void addRecentTaskLocked(TaskRecord task) { 2530 int N = mRecentTasks.size(); 2531 // Quick case: check if the top-most recent task is the same. 2532 if (N > 0 && mRecentTasks.get(0) == task) { 2533 return; 2534 } 2535 // Remove any existing entries that are the same kind of task. 2536 for (int i=0; i<N; i++) { 2537 TaskRecord tr = mRecentTasks.get(i); 2538 if (task.userId == tr.userId 2539 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2540 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2541 mRecentTasks.remove(i); 2542 i--; 2543 N--; 2544 if (task.intent == null) { 2545 // If the new recent task we are adding is not fully 2546 // specified, then replace it with the existing recent task. 2547 task = tr; 2548 } 2549 } 2550 } 2551 if (N >= MAX_RECENT_TASKS) { 2552 mRecentTasks.remove(N-1); 2553 } 2554 mRecentTasks.add(0, task); 2555 } 2556 2557 public void setRequestedOrientation(IBinder token, 2558 int requestedOrientation) { 2559 synchronized (this) { 2560 ActivityRecord r = mMainStack.isInStackLocked(token); 2561 if (r == null) { 2562 return; 2563 } 2564 final long origId = Binder.clearCallingIdentity(); 2565 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2566 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2567 mConfiguration, 2568 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2569 if (config != null) { 2570 r.frozenBeforeDestroy = true; 2571 if (!updateConfigurationLocked(config, r, false, false)) { 2572 mMainStack.resumeTopActivityLocked(null); 2573 } 2574 } 2575 Binder.restoreCallingIdentity(origId); 2576 } 2577 } 2578 2579 public int getRequestedOrientation(IBinder token) { 2580 synchronized (this) { 2581 ActivityRecord r = mMainStack.isInStackLocked(token); 2582 if (r == null) { 2583 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2584 } 2585 return mWindowManager.getAppOrientation(r.appToken); 2586 } 2587 } 2588 2589 /** 2590 * This is the internal entry point for handling Activity.finish(). 2591 * 2592 * @param token The Binder token referencing the Activity we want to finish. 2593 * @param resultCode Result code, if any, from this Activity. 2594 * @param resultData Result data (Intent), if any, from this Activity. 2595 * 2596 * @return Returns true if the activity successfully finished, or false if it is still running. 2597 */ 2598 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2599 // Refuse possible leaked file descriptors 2600 if (resultData != null && resultData.hasFileDescriptors() == true) { 2601 throw new IllegalArgumentException("File descriptors passed in Intent"); 2602 } 2603 2604 synchronized(this) { 2605 if (mController != null) { 2606 // Find the first activity that is not finishing. 2607 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2608 if (next != null) { 2609 // ask watcher if this is allowed 2610 boolean resumeOK = true; 2611 try { 2612 resumeOK = mController.activityResuming(next.packageName); 2613 } catch (RemoteException e) { 2614 mController = null; 2615 } 2616 2617 if (!resumeOK) { 2618 return false; 2619 } 2620 } 2621 } 2622 final long origId = Binder.clearCallingIdentity(); 2623 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2624 resultData, "app-request"); 2625 Binder.restoreCallingIdentity(origId); 2626 return res; 2627 } 2628 } 2629 2630 public final void finishHeavyWeightApp() { 2631 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2632 != PackageManager.PERMISSION_GRANTED) { 2633 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2634 + Binder.getCallingPid() 2635 + ", uid=" + Binder.getCallingUid() 2636 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2637 Slog.w(TAG, msg); 2638 throw new SecurityException(msg); 2639 } 2640 2641 synchronized(this) { 2642 if (mHeavyWeightProcess == null) { 2643 return; 2644 } 2645 2646 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2647 mHeavyWeightProcess.activities); 2648 for (int i=0; i<activities.size(); i++) { 2649 ActivityRecord r = activities.get(i); 2650 if (!r.finishing) { 2651 int index = mMainStack.indexOfTokenLocked(r.appToken); 2652 if (index >= 0) { 2653 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2654 null, "finish-heavy"); 2655 } 2656 } 2657 } 2658 2659 mHeavyWeightProcess = null; 2660 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2661 } 2662 } 2663 2664 public void crashApplication(int uid, int initialPid, String packageName, 2665 String message) { 2666 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2667 != PackageManager.PERMISSION_GRANTED) { 2668 String msg = "Permission Denial: crashApplication() from pid=" 2669 + Binder.getCallingPid() 2670 + ", uid=" + Binder.getCallingUid() 2671 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2672 Slog.w(TAG, msg); 2673 throw new SecurityException(msg); 2674 } 2675 2676 synchronized(this) { 2677 ProcessRecord proc = null; 2678 2679 // Figure out which process to kill. We don't trust that initialPid 2680 // still has any relation to current pids, so must scan through the 2681 // list. 2682 synchronized (mPidsSelfLocked) { 2683 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2684 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2685 if (p.uid != uid) { 2686 continue; 2687 } 2688 if (p.pid == initialPid) { 2689 proc = p; 2690 break; 2691 } 2692 for (String str : p.pkgList) { 2693 if (str.equals(packageName)) { 2694 proc = p; 2695 } 2696 } 2697 } 2698 } 2699 2700 if (proc == null) { 2701 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2702 + " initialPid=" + initialPid 2703 + " packageName=" + packageName); 2704 return; 2705 } 2706 2707 if (proc.thread != null) { 2708 if (proc.pid == Process.myPid()) { 2709 Log.w(TAG, "crashApplication: trying to crash self!"); 2710 return; 2711 } 2712 long ident = Binder.clearCallingIdentity(); 2713 try { 2714 proc.thread.scheduleCrash(message); 2715 } catch (RemoteException e) { 2716 } 2717 Binder.restoreCallingIdentity(ident); 2718 } 2719 } 2720 } 2721 2722 public final void finishSubActivity(IBinder token, String resultWho, 2723 int requestCode) { 2724 synchronized(this) { 2725 final long origId = Binder.clearCallingIdentity(); 2726 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2727 Binder.restoreCallingIdentity(origId); 2728 } 2729 } 2730 2731 public boolean finishActivityAffinity(IBinder token) { 2732 synchronized(this) { 2733 final long origId = Binder.clearCallingIdentity(); 2734 boolean res = mMainStack.finishActivityAffinityLocked(token); 2735 Binder.restoreCallingIdentity(origId); 2736 return res; 2737 } 2738 } 2739 2740 public boolean willActivityBeVisible(IBinder token) { 2741 synchronized(this) { 2742 int i; 2743 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2744 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2745 if (r.appToken == token) { 2746 return true; 2747 } 2748 if (r.fullscreen && !r.finishing) { 2749 return false; 2750 } 2751 } 2752 return true; 2753 } 2754 } 2755 2756 public void overridePendingTransition(IBinder token, String packageName, 2757 int enterAnim, int exitAnim) { 2758 synchronized(this) { 2759 ActivityRecord self = mMainStack.isInStackLocked(token); 2760 if (self == null) { 2761 return; 2762 } 2763 2764 final long origId = Binder.clearCallingIdentity(); 2765 2766 if (self.state == ActivityState.RESUMED 2767 || self.state == ActivityState.PAUSING) { 2768 mWindowManager.overridePendingAppTransition(packageName, 2769 enterAnim, exitAnim); 2770 } 2771 2772 Binder.restoreCallingIdentity(origId); 2773 } 2774 } 2775 2776 /** 2777 * Main function for removing an existing process from the activity manager 2778 * as a result of that process going away. Clears out all connections 2779 * to the process. 2780 */ 2781 private final void handleAppDiedLocked(ProcessRecord app, 2782 boolean restarting, boolean allowRestart) { 2783 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2784 if (!restarting) { 2785 mLruProcesses.remove(app); 2786 } 2787 2788 if (mProfileProc == app) { 2789 clearProfilerLocked(); 2790 } 2791 2792 // Just in case... 2793 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2794 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2795 mMainStack.mPausingActivity = null; 2796 } 2797 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2798 mMainStack.mLastPausedActivity = null; 2799 } 2800 2801 // Remove this application's activities from active lists. 2802 mMainStack.removeHistoryRecordsForAppLocked(app); 2803 2804 boolean atTop = true; 2805 boolean hasVisibleActivities = false; 2806 2807 // Clean out the history list. 2808 int i = mMainStack.mHistory.size(); 2809 if (localLOGV) Slog.v( 2810 TAG, "Removing app " + app + " from history with " + i + " entries"); 2811 while (i > 0) { 2812 i--; 2813 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2814 if (localLOGV) Slog.v( 2815 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2816 if (r.app == app) { 2817 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2818 if (ActivityStack.DEBUG_ADD_REMOVE) { 2819 RuntimeException here = new RuntimeException("here"); 2820 here.fillInStackTrace(); 2821 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2822 + ": haveState=" + r.haveState 2823 + " stateNotNeeded=" + r.stateNotNeeded 2824 + " finishing=" + r.finishing 2825 + " state=" + r.state, here); 2826 } 2827 if (!r.finishing) { 2828 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2829 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2830 System.identityHashCode(r), 2831 r.task.taskId, r.shortComponentName, 2832 "proc died without state saved"); 2833 } 2834 mMainStack.removeActivityFromHistoryLocked(r); 2835 2836 } else { 2837 // We have the current state for this activity, so 2838 // it can be restarted later when needed. 2839 if (localLOGV) Slog.v( 2840 TAG, "Keeping entry, setting app to null"); 2841 if (r.visible) { 2842 hasVisibleActivities = true; 2843 } 2844 r.app = null; 2845 r.nowVisible = false; 2846 if (!r.haveState) { 2847 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2848 "App died, clearing saved state of " + r); 2849 r.icicle = null; 2850 } 2851 } 2852 2853 r.stack.cleanUpActivityLocked(r, true, true); 2854 } 2855 atTop = false; 2856 } 2857 2858 app.activities.clear(); 2859 2860 if (app.instrumentationClass != null) { 2861 Slog.w(TAG, "Crash of app " + app.processName 2862 + " running instrumentation " + app.instrumentationClass); 2863 Bundle info = new Bundle(); 2864 info.putString("shortMsg", "Process crashed."); 2865 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2866 } 2867 2868 if (!restarting) { 2869 if (!mMainStack.resumeTopActivityLocked(null)) { 2870 // If there was nothing to resume, and we are not already 2871 // restarting this process, but there is a visible activity that 2872 // is hosted by the process... then make sure all visible 2873 // activities are running, taking care of restarting this 2874 // process. 2875 if (hasVisibleActivities) { 2876 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2877 } 2878 } 2879 } 2880 } 2881 2882 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2883 IBinder threadBinder = thread.asBinder(); 2884 // Find the application record. 2885 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2886 ProcessRecord rec = mLruProcesses.get(i); 2887 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2888 return i; 2889 } 2890 } 2891 return -1; 2892 } 2893 2894 final ProcessRecord getRecordForAppLocked( 2895 IApplicationThread thread) { 2896 if (thread == null) { 2897 return null; 2898 } 2899 2900 int appIndex = getLRURecordIndexForAppLocked(thread); 2901 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2902 } 2903 2904 final void appDiedLocked(ProcessRecord app, int pid, 2905 IApplicationThread thread) { 2906 2907 mProcDeaths[0]++; 2908 2909 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2910 synchronized (stats) { 2911 stats.noteProcessDiedLocked(app.info.uid, pid); 2912 } 2913 2914 // Clean up already done if the process has been re-started. 2915 if (app.pid == pid && app.thread != null && 2916 app.thread.asBinder() == thread.asBinder()) { 2917 if (!app.killedBackground) { 2918 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2919 + ") has died."); 2920 } 2921 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2922 if (localLOGV) Slog.v( 2923 TAG, "Dying app: " + app + ", pid: " + pid 2924 + ", thread: " + thread.asBinder()); 2925 boolean doLowMem = app.instrumentationClass == null; 2926 handleAppDiedLocked(app, false, true); 2927 2928 if (doLowMem) { 2929 // If there are no longer any background processes running, 2930 // and the app that died was not running instrumentation, 2931 // then tell everyone we are now low on memory. 2932 boolean haveBg = false; 2933 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2934 ProcessRecord rec = mLruProcesses.get(i); 2935 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2936 haveBg = true; 2937 break; 2938 } 2939 } 2940 2941 if (!haveBg) { 2942 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2943 long now = SystemClock.uptimeMillis(); 2944 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2945 ProcessRecord rec = mLruProcesses.get(i); 2946 if (rec != app && rec.thread != null && 2947 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2948 // The low memory report is overriding any current 2949 // state for a GC request. Make sure to do 2950 // heavy/important/visible/foreground processes first. 2951 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2952 rec.lastRequestedGc = 0; 2953 } else { 2954 rec.lastRequestedGc = rec.lastLowMemory; 2955 } 2956 rec.reportLowMemory = true; 2957 rec.lastLowMemory = now; 2958 mProcessesToGc.remove(rec); 2959 addProcessToGcListLocked(rec); 2960 } 2961 } 2962 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 2963 scheduleAppGcsLocked(); 2964 } 2965 } 2966 } else if (app.pid != pid) { 2967 // A new process has already been started. 2968 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2969 + ") has died and restarted (pid " + app.pid + ")."); 2970 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2971 } else if (DEBUG_PROCESSES) { 2972 Slog.d(TAG, "Received spurious death notification for thread " 2973 + thread.asBinder()); 2974 } 2975 } 2976 2977 /** 2978 * If a stack trace dump file is configured, dump process stack traces. 2979 * @param clearTraces causes the dump file to be erased prior to the new 2980 * traces being written, if true; when false, the new traces will be 2981 * appended to any existing file content. 2982 * @param firstPids of dalvik VM processes to dump stack traces for first 2983 * @param lastPids of dalvik VM processes to dump stack traces for last 2984 * @return file containing stack traces, or null if no dump file is configured 2985 */ 2986 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 2987 ProcessStats processStats, SparseArray<Boolean> lastPids) { 2988 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 2989 if (tracesPath == null || tracesPath.length() == 0) { 2990 return null; 2991 } 2992 2993 File tracesFile = new File(tracesPath); 2994 try { 2995 File tracesDir = tracesFile.getParentFile(); 2996 if (!tracesDir.exists()) tracesFile.mkdirs(); 2997 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 2998 2999 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3000 tracesFile.createNewFile(); 3001 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3002 } catch (IOException e) { 3003 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3004 return null; 3005 } 3006 3007 dumpStackTraces(tracesPath, firstPids, processStats, lastPids); 3008 return tracesFile; 3009 } 3010 3011 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3012 ProcessStats processStats, SparseArray<Boolean> lastPids) { 3013 // Use a FileObserver to detect when traces finish writing. 3014 // The order of traces is considered important to maintain for legibility. 3015 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3016 public synchronized void onEvent(int event, String path) { notify(); } 3017 }; 3018 3019 try { 3020 observer.startWatching(); 3021 3022 // First collect all of the stacks of the most important pids. 3023 if (firstPids != null) { 3024 try { 3025 int num = firstPids.size(); 3026 for (int i = 0; i < num; i++) { 3027 synchronized (observer) { 3028 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3029 observer.wait(200); // Wait for write-close, give up after 200msec 3030 } 3031 } 3032 } catch (InterruptedException e) { 3033 Log.wtf(TAG, e); 3034 } 3035 } 3036 3037 // Next measure CPU usage. 3038 if (processStats != null) { 3039 processStats.init(); 3040 System.gc(); 3041 processStats.update(); 3042 try { 3043 synchronized (processStats) { 3044 processStats.wait(500); // measure over 1/2 second. 3045 } 3046 } catch (InterruptedException e) { 3047 } 3048 processStats.update(); 3049 3050 // We'll take the stack crawls of just the top apps using CPU. 3051 final int N = processStats.countWorkingStats(); 3052 int numProcs = 0; 3053 for (int i=0; i<N && numProcs<5; i++) { 3054 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3055 if (lastPids.indexOfKey(stats.pid) >= 0) { 3056 numProcs++; 3057 try { 3058 synchronized (observer) { 3059 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3060 observer.wait(200); // Wait for write-close, give up after 200msec 3061 } 3062 } catch (InterruptedException e) { 3063 Log.wtf(TAG, e); 3064 } 3065 3066 } 3067 } 3068 } 3069 3070 } finally { 3071 observer.stopWatching(); 3072 } 3073 } 3074 3075 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3076 if (true || IS_USER_BUILD) { 3077 return; 3078 } 3079 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3080 if (tracesPath == null || tracesPath.length() == 0) { 3081 return; 3082 } 3083 3084 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3085 StrictMode.allowThreadDiskWrites(); 3086 try { 3087 final File tracesFile = new File(tracesPath); 3088 final File tracesDir = tracesFile.getParentFile(); 3089 final File tracesTmp = new File(tracesDir, "__tmp__"); 3090 try { 3091 if (!tracesDir.exists()) tracesFile.mkdirs(); 3092 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3093 3094 if (tracesFile.exists()) { 3095 tracesTmp.delete(); 3096 tracesFile.renameTo(tracesTmp); 3097 } 3098 StringBuilder sb = new StringBuilder(); 3099 Time tobj = new Time(); 3100 tobj.set(System.currentTimeMillis()); 3101 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3102 sb.append(": "); 3103 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3104 sb.append(" since "); 3105 sb.append(msg); 3106 FileOutputStream fos = new FileOutputStream(tracesFile); 3107 fos.write(sb.toString().getBytes()); 3108 if (app == null) { 3109 fos.write("\n*** No application process!".getBytes()); 3110 } 3111 fos.close(); 3112 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3113 } catch (IOException e) { 3114 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3115 return; 3116 } 3117 3118 if (app != null) { 3119 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3120 firstPids.add(app.pid); 3121 dumpStackTraces(tracesPath, firstPids, null, null); 3122 } 3123 3124 File lastTracesFile = null; 3125 File curTracesFile = null; 3126 for (int i=9; i>=0; i--) { 3127 String name = String.format("slow%02d.txt", i); 3128 curTracesFile = new File(tracesDir, name); 3129 if (curTracesFile.exists()) { 3130 if (lastTracesFile != null) { 3131 curTracesFile.renameTo(lastTracesFile); 3132 } else { 3133 curTracesFile.delete(); 3134 } 3135 } 3136 lastTracesFile = curTracesFile; 3137 } 3138 tracesFile.renameTo(curTracesFile); 3139 if (tracesTmp.exists()) { 3140 tracesTmp.renameTo(tracesFile); 3141 } 3142 } finally { 3143 StrictMode.setThreadPolicy(oldPolicy); 3144 } 3145 } 3146 3147 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3148 ActivityRecord parent, final String annotation) { 3149 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3150 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3151 3152 if (mController != null) { 3153 try { 3154 // 0 == continue, -1 = kill process immediately 3155 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3156 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3157 } catch (RemoteException e) { 3158 mController = null; 3159 } 3160 } 3161 3162 long anrTime = SystemClock.uptimeMillis(); 3163 if (MONITOR_CPU_USAGE) { 3164 updateCpuStatsNow(); 3165 } 3166 3167 synchronized (this) { 3168 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3169 if (mShuttingDown) { 3170 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3171 return; 3172 } else if (app.notResponding) { 3173 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3174 return; 3175 } else if (app.crashing) { 3176 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3177 return; 3178 } 3179 3180 // In case we come through here for the same app before completing 3181 // this one, mark as anring now so we will bail out. 3182 app.notResponding = true; 3183 3184 // Log the ANR to the event log. 3185 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3186 annotation); 3187 3188 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3189 firstPids.add(app.pid); 3190 3191 int parentPid = app.pid; 3192 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3193 if (parentPid != app.pid) firstPids.add(parentPid); 3194 3195 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3196 3197 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3198 ProcessRecord r = mLruProcesses.get(i); 3199 if (r != null && r.thread != null) { 3200 int pid = r.pid; 3201 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3202 if (r.persistent) { 3203 firstPids.add(pid); 3204 } else { 3205 lastPids.put(pid, Boolean.TRUE); 3206 } 3207 } 3208 } 3209 } 3210 } 3211 3212 // Log the ANR to the main log. 3213 StringBuilder info = new StringBuilder(); 3214 info.setLength(0); 3215 info.append("ANR in ").append(app.processName); 3216 if (activity != null && activity.shortComponentName != null) { 3217 info.append(" (").append(activity.shortComponentName).append(")"); 3218 } 3219 info.append("\n"); 3220 if (annotation != null) { 3221 info.append("Reason: ").append(annotation).append("\n"); 3222 } 3223 if (parent != null && parent != activity) { 3224 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3225 } 3226 3227 final ProcessStats processStats = new ProcessStats(true); 3228 3229 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids); 3230 3231 String cpuInfo = null; 3232 if (MONITOR_CPU_USAGE) { 3233 updateCpuStatsNow(); 3234 synchronized (mProcessStatsThread) { 3235 cpuInfo = mProcessStats.printCurrentState(anrTime); 3236 } 3237 info.append(processStats.printCurrentLoad()); 3238 info.append(cpuInfo); 3239 } 3240 3241 info.append(processStats.printCurrentState(anrTime)); 3242 3243 Slog.e(TAG, info.toString()); 3244 if (tracesFile == null) { 3245 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3246 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3247 } 3248 3249 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3250 cpuInfo, tracesFile, null); 3251 3252 if (mController != null) { 3253 try { 3254 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3255 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3256 if (res != 0) { 3257 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3258 return; 3259 } 3260 } catch (RemoteException e) { 3261 mController = null; 3262 } 3263 } 3264 3265 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3266 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3267 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3268 3269 synchronized (this) { 3270 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3271 Slog.w(TAG, "Killing " + app + ": background ANR"); 3272 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3273 app.processName, app.setAdj, "background ANR"); 3274 Process.killProcessQuiet(app.pid); 3275 return; 3276 } 3277 3278 // Set the app's notResponding state, and look up the errorReportReceiver 3279 makeAppNotRespondingLocked(app, 3280 activity != null ? activity.shortComponentName : null, 3281 annotation != null ? "ANR " + annotation : "ANR", 3282 info.toString()); 3283 3284 // Bring up the infamous App Not Responding dialog 3285 Message msg = Message.obtain(); 3286 HashMap map = new HashMap(); 3287 msg.what = SHOW_NOT_RESPONDING_MSG; 3288 msg.obj = map; 3289 map.put("app", app); 3290 if (activity != null) { 3291 map.put("activity", activity); 3292 } 3293 3294 mHandler.sendMessage(msg); 3295 } 3296 } 3297 3298 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3299 if (!mLaunchWarningShown) { 3300 mLaunchWarningShown = true; 3301 mHandler.post(new Runnable() { 3302 @Override 3303 public void run() { 3304 synchronized (ActivityManagerService.this) { 3305 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3306 d.show(); 3307 mHandler.postDelayed(new Runnable() { 3308 @Override 3309 public void run() { 3310 synchronized (ActivityManagerService.this) { 3311 d.dismiss(); 3312 mLaunchWarningShown = false; 3313 } 3314 } 3315 }, 4000); 3316 } 3317 } 3318 }); 3319 } 3320 } 3321 3322 public boolean clearApplicationUserData(final String packageName, 3323 final IPackageDataObserver observer, final int userId) { 3324 enforceNotIsolatedCaller("clearApplicationUserData"); 3325 int uid = Binder.getCallingUid(); 3326 int pid = Binder.getCallingPid(); 3327 long callingId = Binder.clearCallingIdentity(); 3328 try { 3329 IPackageManager pm = AppGlobals.getPackageManager(); 3330 int pkgUid = -1; 3331 synchronized(this) { 3332 try { 3333 pkgUid = pm.getPackageUid(packageName, userId); 3334 } catch (RemoteException e) { 3335 } 3336 if (pkgUid == -1) { 3337 Slog.w(TAG, "Invalid packageName:" + packageName); 3338 return false; 3339 } 3340 if (uid == pkgUid || checkComponentPermission( 3341 android.Manifest.permission.CLEAR_APP_USER_DATA, 3342 pid, uid, -1, true) 3343 == PackageManager.PERMISSION_GRANTED) { 3344 forceStopPackageLocked(packageName, pkgUid); 3345 } else { 3346 throw new SecurityException(pid+" does not have permission:"+ 3347 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3348 "for process:"+packageName); 3349 } 3350 } 3351 3352 try { 3353 //clear application user data 3354 pm.clearApplicationUserData(packageName, observer, userId); 3355 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3356 Uri.fromParts("package", packageName, null)); 3357 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3358 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3359 null, null, 0, null, null, null, false, false, userId); 3360 } catch (RemoteException e) { 3361 } 3362 } finally { 3363 Binder.restoreCallingIdentity(callingId); 3364 } 3365 return true; 3366 } 3367 3368 public void killBackgroundProcesses(final String packageName) { 3369 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3370 != PackageManager.PERMISSION_GRANTED && 3371 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3372 != PackageManager.PERMISSION_GRANTED) { 3373 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3374 + Binder.getCallingPid() 3375 + ", uid=" + Binder.getCallingUid() 3376 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3377 Slog.w(TAG, msg); 3378 throw new SecurityException(msg); 3379 } 3380 3381 int userId = UserId.getCallingUserId(); 3382 long callingId = Binder.clearCallingIdentity(); 3383 try { 3384 IPackageManager pm = AppGlobals.getPackageManager(); 3385 int pkgUid = -1; 3386 synchronized(this) { 3387 try { 3388 pkgUid = pm.getPackageUid(packageName, userId); 3389 } catch (RemoteException e) { 3390 } 3391 if (pkgUid == -1) { 3392 Slog.w(TAG, "Invalid packageName: " + packageName); 3393 return; 3394 } 3395 killPackageProcessesLocked(packageName, pkgUid, 3396 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3397 } 3398 } finally { 3399 Binder.restoreCallingIdentity(callingId); 3400 } 3401 } 3402 3403 public void killAllBackgroundProcesses() { 3404 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3405 != PackageManager.PERMISSION_GRANTED) { 3406 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3407 + Binder.getCallingPid() 3408 + ", uid=" + Binder.getCallingUid() 3409 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3410 Slog.w(TAG, msg); 3411 throw new SecurityException(msg); 3412 } 3413 3414 long callingId = Binder.clearCallingIdentity(); 3415 try { 3416 synchronized(this) { 3417 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3418 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3419 final int NA = apps.size(); 3420 for (int ia=0; ia<NA; ia++) { 3421 ProcessRecord app = apps.valueAt(ia); 3422 if (app.persistent) { 3423 // we don't kill persistent processes 3424 continue; 3425 } 3426 if (app.removed) { 3427 procs.add(app); 3428 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3429 app.removed = true; 3430 procs.add(app); 3431 } 3432 } 3433 } 3434 3435 int N = procs.size(); 3436 for (int i=0; i<N; i++) { 3437 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3438 } 3439 } 3440 } finally { 3441 Binder.restoreCallingIdentity(callingId); 3442 } 3443 } 3444 3445 public void forceStopPackage(final String packageName) { 3446 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3447 != PackageManager.PERMISSION_GRANTED) { 3448 String msg = "Permission Denial: forceStopPackage() from pid=" 3449 + Binder.getCallingPid() 3450 + ", uid=" + Binder.getCallingUid() 3451 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3452 Slog.w(TAG, msg); 3453 throw new SecurityException(msg); 3454 } 3455 final int userId = UserId.getCallingUserId(); 3456 long callingId = Binder.clearCallingIdentity(); 3457 try { 3458 IPackageManager pm = AppGlobals.getPackageManager(); 3459 int pkgUid = -1; 3460 synchronized(this) { 3461 try { 3462 pkgUid = pm.getPackageUid(packageName, userId); 3463 } catch (RemoteException e) { 3464 } 3465 if (pkgUid == -1) { 3466 Slog.w(TAG, "Invalid packageName: " + packageName); 3467 return; 3468 } 3469 forceStopPackageLocked(packageName, pkgUid); 3470 try { 3471 pm.setPackageStoppedState(packageName, true, userId); 3472 } catch (RemoteException e) { 3473 } catch (IllegalArgumentException e) { 3474 Slog.w(TAG, "Failed trying to unstop package " 3475 + packageName + ": " + e); 3476 } 3477 } 3478 } finally { 3479 Binder.restoreCallingIdentity(callingId); 3480 } 3481 } 3482 3483 /* 3484 * The pkg name and uid have to be specified. 3485 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3486 */ 3487 public void killApplicationWithUid(String pkg, int uid) { 3488 if (pkg == null) { 3489 return; 3490 } 3491 // Make sure the uid is valid. 3492 if (uid < 0) { 3493 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3494 return; 3495 } 3496 int callerUid = Binder.getCallingUid(); 3497 // Only the system server can kill an application 3498 if (callerUid == Process.SYSTEM_UID) { 3499 // Post an aysnc message to kill the application 3500 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3501 msg.arg1 = uid; 3502 msg.arg2 = 0; 3503 msg.obj = pkg; 3504 mHandler.sendMessage(msg); 3505 } else { 3506 throw new SecurityException(callerUid + " cannot kill pkg: " + 3507 pkg); 3508 } 3509 } 3510 3511 public void closeSystemDialogs(String reason) { 3512 enforceNotIsolatedCaller("closeSystemDialogs"); 3513 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3514 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3515 if (reason != null) { 3516 intent.putExtra("reason", reason); 3517 } 3518 3519 final int uid = Binder.getCallingUid(); 3520 final long origId = Binder.clearCallingIdentity(); 3521 synchronized (this) { 3522 mWindowManager.closeSystemDialogs(reason); 3523 3524 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3525 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3526 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3527 r.stack.finishActivityLocked(r, i, 3528 Activity.RESULT_CANCELED, null, "close-sys"); 3529 } 3530 } 3531 3532 broadcastIntentLocked(null, null, intent, null, 3533 null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */); 3534 } 3535 Binder.restoreCallingIdentity(origId); 3536 } 3537 3538 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3539 throws RemoteException { 3540 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3541 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3542 for (int i=pids.length-1; i>=0; i--) { 3543 infos[i] = new Debug.MemoryInfo(); 3544 Debug.getMemoryInfo(pids[i], infos[i]); 3545 } 3546 return infos; 3547 } 3548 3549 public long[] getProcessPss(int[] pids) throws RemoteException { 3550 enforceNotIsolatedCaller("getProcessPss"); 3551 long[] pss = new long[pids.length]; 3552 for (int i=pids.length-1; i>=0; i--) { 3553 pss[i] = Debug.getPss(pids[i]); 3554 } 3555 return pss; 3556 } 3557 3558 public void killApplicationProcess(String processName, int uid) { 3559 if (processName == null) { 3560 return; 3561 } 3562 3563 int callerUid = Binder.getCallingUid(); 3564 // Only the system server can kill an application 3565 if (callerUid == Process.SYSTEM_UID) { 3566 synchronized (this) { 3567 ProcessRecord app = getProcessRecordLocked(processName, uid); 3568 if (app != null && app.thread != null) { 3569 try { 3570 app.thread.scheduleSuicide(); 3571 } catch (RemoteException e) { 3572 // If the other end already died, then our work here is done. 3573 } 3574 } else { 3575 Slog.w(TAG, "Process/uid not found attempting kill of " 3576 + processName + " / " + uid); 3577 } 3578 } 3579 } else { 3580 throw new SecurityException(callerUid + " cannot kill app process: " + 3581 processName); 3582 } 3583 } 3584 3585 private void forceStopPackageLocked(final String packageName, int uid) { 3586 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3587 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3588 Uri.fromParts("package", packageName, null)); 3589 if (!mProcessesReady) { 3590 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3591 } 3592 intent.putExtra(Intent.EXTRA_UID, uid); 3593 broadcastIntentLocked(null, null, intent, 3594 null, null, 0, null, null, null, 3595 false, false, 3596 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3597 } 3598 3599 private final boolean killPackageProcessesLocked(String packageName, int uid, 3600 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3601 boolean evenPersistent, String reason) { 3602 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3603 3604 // Remove all processes this package may have touched: all with the 3605 // same UID (except for the system or root user), and all whose name 3606 // matches the package name. 3607 final String procNamePrefix = packageName + ":"; 3608 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3609 final int NA = apps.size(); 3610 for (int ia=0; ia<NA; ia++) { 3611 ProcessRecord app = apps.valueAt(ia); 3612 if (app.persistent && !evenPersistent) { 3613 // we don't kill persistent processes 3614 continue; 3615 } 3616 if (app.removed) { 3617 if (doit) { 3618 procs.add(app); 3619 } 3620 // If uid is specified and the uid and process name match 3621 // Or, the uid is not specified and the process name matches 3622 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3623 || ((app.processName.equals(packageName) 3624 || app.processName.startsWith(procNamePrefix)) 3625 && uid < 0))) { 3626 if (app.setAdj >= minOomAdj) { 3627 if (!doit) { 3628 return true; 3629 } 3630 app.removed = true; 3631 procs.add(app); 3632 } 3633 } 3634 } 3635 } 3636 3637 int N = procs.size(); 3638 for (int i=0; i<N; i++) { 3639 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3640 } 3641 return N > 0; 3642 } 3643 3644 private final boolean forceStopPackageLocked(String name, int uid, 3645 boolean callerWillRestart, boolean purgeCache, boolean doit, 3646 boolean evenPersistent, int userId) { 3647 int i; 3648 int N; 3649 3650 if (uid < 0) { 3651 try { 3652 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3653 } catch (RemoteException e) { 3654 } 3655 } 3656 3657 if (doit) { 3658 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3659 3660 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3661 while (badApps.hasNext()) { 3662 SparseArray<Long> ba = badApps.next(); 3663 if (ba.get(uid) != null) { 3664 badApps.remove(); 3665 } 3666 } 3667 } 3668 3669 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3670 callerWillRestart, false, doit, evenPersistent, "force stop"); 3671 3672 TaskRecord lastTask = null; 3673 for (i=0; i<mMainStack.mHistory.size(); i++) { 3674 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3675 final boolean samePackage = r.packageName.equals(name); 3676 if (r.userId == userId 3677 && (samePackage || r.task == lastTask) 3678 && (r.app == null || evenPersistent || !r.app.persistent)) { 3679 if (!doit) { 3680 if (r.finishing) { 3681 // If this activity is just finishing, then it is not 3682 // interesting as far as something to stop. 3683 continue; 3684 } 3685 return true; 3686 } 3687 didSomething = true; 3688 Slog.i(TAG, " Force finishing activity " + r); 3689 if (samePackage) { 3690 if (r.app != null) { 3691 r.app.removed = true; 3692 } 3693 r.app = null; 3694 } 3695 lastTask = r.task; 3696 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3697 null, "force-stop", true)) { 3698 i--; 3699 } 3700 } 3701 } 3702 3703 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 3704 for (ServiceRecord service : mServiceMap.getAllServices(userId)) { 3705 if (service.packageName.equals(name) 3706 && (service.app == null || evenPersistent || !service.app.persistent)) { 3707 if (!doit) { 3708 return true; 3709 } 3710 didSomething = true; 3711 Slog.i(TAG, " Force stopping service " + service); 3712 if (service.app != null) { 3713 service.app.removed = true; 3714 } 3715 service.app = null; 3716 service.isolatedProc = null; 3717 services.add(service); 3718 } 3719 } 3720 3721 N = services.size(); 3722 for (i=0; i<N; i++) { 3723 bringDownServiceLocked(services.get(i), true); 3724 } 3725 3726 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3727 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3728 if (provider.info.packageName.equals(name) 3729 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3730 if (!doit) { 3731 return true; 3732 } 3733 didSomething = true; 3734 providers.add(provider); 3735 } 3736 } 3737 3738 N = providers.size(); 3739 for (i=0; i<N; i++) { 3740 removeDyingProviderLocked(null, providers.get(i)); 3741 } 3742 3743 if (doit) { 3744 if (purgeCache) { 3745 AttributeCache ac = AttributeCache.instance(); 3746 if (ac != null) { 3747 ac.removePackage(name); 3748 } 3749 } 3750 if (mBooted) { 3751 mMainStack.resumeTopActivityLocked(null); 3752 mMainStack.scheduleIdleLocked(); 3753 } 3754 } 3755 3756 return didSomething; 3757 } 3758 3759 private final boolean removeProcessLocked(ProcessRecord app, 3760 boolean callerWillRestart, boolean allowRestart, String reason) { 3761 final String name = app.processName; 3762 final int uid = app.uid; 3763 if (DEBUG_PROCESSES) Slog.d( 3764 TAG, "Force removing proc " + app.toShortString() + " (" + name 3765 + "/" + uid + ")"); 3766 3767 mProcessNames.remove(name, uid); 3768 mIsolatedProcesses.remove(app.uid); 3769 if (mHeavyWeightProcess == app) { 3770 mHeavyWeightProcess = null; 3771 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3772 } 3773 boolean needRestart = false; 3774 if (app.pid > 0 && app.pid != MY_PID) { 3775 int pid = app.pid; 3776 synchronized (mPidsSelfLocked) { 3777 mPidsSelfLocked.remove(pid); 3778 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3779 } 3780 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3781 handleAppDiedLocked(app, true, allowRestart); 3782 mLruProcesses.remove(app); 3783 Process.killProcessQuiet(pid); 3784 3785 if (app.persistent && !app.isolated) { 3786 if (!callerWillRestart) { 3787 addAppLocked(app.info, false); 3788 } else { 3789 needRestart = true; 3790 } 3791 } 3792 } else { 3793 mRemovedProcesses.add(app); 3794 } 3795 3796 return needRestart; 3797 } 3798 3799 private final void processStartTimedOutLocked(ProcessRecord app) { 3800 final int pid = app.pid; 3801 boolean gone = false; 3802 synchronized (mPidsSelfLocked) { 3803 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3804 if (knownApp != null && knownApp.thread == null) { 3805 mPidsSelfLocked.remove(pid); 3806 gone = true; 3807 } 3808 } 3809 3810 if (gone) { 3811 Slog.w(TAG, "Process " + app + " failed to attach"); 3812 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3813 app.processName); 3814 mProcessNames.remove(app.processName, app.uid); 3815 mIsolatedProcesses.remove(app.uid); 3816 if (mHeavyWeightProcess == app) { 3817 mHeavyWeightProcess = null; 3818 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3819 } 3820 // Take care of any launching providers waiting for this process. 3821 checkAppInLaunchingProvidersLocked(app, true); 3822 // Take care of any services that are waiting for the process. 3823 for (int i=0; i<mPendingServices.size(); i++) { 3824 ServiceRecord sr = mPendingServices.get(i); 3825 if ((app.uid == sr.appInfo.uid 3826 && app.processName.equals(sr.processName)) 3827 || sr.isolatedProc == app) { 3828 Slog.w(TAG, "Forcing bringing down service: " + sr); 3829 sr.isolatedProc = null; 3830 mPendingServices.remove(i); 3831 i--; 3832 bringDownServiceLocked(sr, true); 3833 } 3834 } 3835 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3836 app.processName, app.setAdj, "start timeout"); 3837 Process.killProcessQuiet(pid); 3838 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3839 Slog.w(TAG, "Unattached app died before backup, skipping"); 3840 try { 3841 IBackupManager bm = IBackupManager.Stub.asInterface( 3842 ServiceManager.getService(Context.BACKUP_SERVICE)); 3843 bm.agentDisconnected(app.info.packageName); 3844 } catch (RemoteException e) { 3845 // Can't happen; the backup manager is local 3846 } 3847 } 3848 if (isPendingBroadcastProcessLocked(pid)) { 3849 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3850 skipPendingBroadcastLocked(pid); 3851 } 3852 } else { 3853 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3854 } 3855 } 3856 3857 private final boolean attachApplicationLocked(IApplicationThread thread, 3858 int pid) { 3859 3860 // Find the application record that is being attached... either via 3861 // the pid if we are running in multiple processes, or just pull the 3862 // next app record if we are emulating process with anonymous threads. 3863 ProcessRecord app; 3864 if (pid != MY_PID && pid >= 0) { 3865 synchronized (mPidsSelfLocked) { 3866 app = mPidsSelfLocked.get(pid); 3867 } 3868 } else { 3869 app = null; 3870 } 3871 3872 if (app == null) { 3873 Slog.w(TAG, "No pending application record for pid " + pid 3874 + " (IApplicationThread " + thread + "); dropping process"); 3875 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3876 if (pid > 0 && pid != MY_PID) { 3877 Process.killProcessQuiet(pid); 3878 } else { 3879 try { 3880 thread.scheduleExit(); 3881 } catch (Exception e) { 3882 // Ignore exceptions. 3883 } 3884 } 3885 return false; 3886 } 3887 3888 // If this application record is still attached to a previous 3889 // process, clean it up now. 3890 if (app.thread != null) { 3891 handleAppDiedLocked(app, true, true); 3892 } 3893 3894 // Tell the process all about itself. 3895 3896 if (localLOGV) Slog.v( 3897 TAG, "Binding process pid " + pid + " to record " + app); 3898 3899 String processName = app.processName; 3900 try { 3901 AppDeathRecipient adr = new AppDeathRecipient( 3902 app, pid, thread); 3903 thread.asBinder().linkToDeath(adr, 0); 3904 app.deathRecipient = adr; 3905 } catch (RemoteException e) { 3906 app.resetPackageList(); 3907 startProcessLocked(app, "link fail", processName); 3908 return false; 3909 } 3910 3911 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3912 3913 app.thread = thread; 3914 app.curAdj = app.setAdj = -100; 3915 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3916 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3917 app.forcingToForeground = null; 3918 app.foregroundServices = false; 3919 app.hasShownUi = false; 3920 app.debugging = false; 3921 3922 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3923 3924 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3925 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3926 3927 if (!normalMode) { 3928 Slog.i(TAG, "Launching preboot mode app: " + app); 3929 } 3930 3931 if (localLOGV) Slog.v( 3932 TAG, "New app record " + app 3933 + " thread=" + thread.asBinder() + " pid=" + pid); 3934 try { 3935 int testMode = IApplicationThread.DEBUG_OFF; 3936 if (mDebugApp != null && mDebugApp.equals(processName)) { 3937 testMode = mWaitForDebugger 3938 ? IApplicationThread.DEBUG_WAIT 3939 : IApplicationThread.DEBUG_ON; 3940 app.debugging = true; 3941 if (mDebugTransient) { 3942 mDebugApp = mOrigDebugApp; 3943 mWaitForDebugger = mOrigWaitForDebugger; 3944 } 3945 } 3946 String profileFile = app.instrumentationProfileFile; 3947 ParcelFileDescriptor profileFd = null; 3948 boolean profileAutoStop = false; 3949 if (mProfileApp != null && mProfileApp.equals(processName)) { 3950 mProfileProc = app; 3951 profileFile = mProfileFile; 3952 profileFd = mProfileFd; 3953 profileAutoStop = mAutoStopProfiler; 3954 } 3955 boolean enableOpenGlTrace = false; 3956 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3957 enableOpenGlTrace = true; 3958 mOpenGlTraceApp = null; 3959 } 3960 3961 // If the app is being launched for restore or full backup, set it up specially 3962 boolean isRestrictedBackupMode = false; 3963 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3964 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3965 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3966 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3967 } 3968 3969 ensurePackageDexOpt(app.instrumentationInfo != null 3970 ? app.instrumentationInfo.packageName 3971 : app.info.packageName); 3972 if (app.instrumentationClass != null) { 3973 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3974 } 3975 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3976 + processName + " with config " + mConfiguration); 3977 ApplicationInfo appInfo = app.instrumentationInfo != null 3978 ? app.instrumentationInfo : app.info; 3979 app.compat = compatibilityInfoForPackageLocked(appInfo); 3980 if (profileFd != null) { 3981 profileFd = profileFd.dup(); 3982 } 3983 thread.bindApplication(processName, appInfo, providers, 3984 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 3985 app.instrumentationArguments, app.instrumentationWatcher, testMode, 3986 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 3987 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 3988 mCoreSettingsObserver.getCoreSettingsLocked()); 3989 updateLruProcessLocked(app, false, true); 3990 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 3991 } catch (Exception e) { 3992 // todo: Yikes! What should we do? For now we will try to 3993 // start another process, but that could easily get us in 3994 // an infinite loop of restarting processes... 3995 Slog.w(TAG, "Exception thrown during bind!", e); 3996 3997 app.resetPackageList(); 3998 app.unlinkDeathRecipient(); 3999 startProcessLocked(app, "bind fail", processName); 4000 return false; 4001 } 4002 4003 // Remove this record from the list of starting applications. 4004 mPersistentStartingProcesses.remove(app); 4005 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4006 "Attach application locked removing on hold: " + app); 4007 mProcessesOnHold.remove(app); 4008 4009 boolean badApp = false; 4010 boolean didSomething = false; 4011 4012 // See if the top visible activity is waiting to run in this process... 4013 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4014 if (hr != null && normalMode) { 4015 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4016 && processName.equals(hr.processName)) { 4017 try { 4018 if (mHeadless) { 4019 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4020 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4021 didSomething = true; 4022 } 4023 } catch (Exception e) { 4024 Slog.w(TAG, "Exception in new application when starting activity " 4025 + hr.intent.getComponent().flattenToShortString(), e); 4026 badApp = true; 4027 } 4028 } else { 4029 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4030 } 4031 } 4032 4033 // Find any services that should be running in this process... 4034 if (!badApp && mPendingServices.size() > 0) { 4035 ServiceRecord sr = null; 4036 try { 4037 for (int i=0; i<mPendingServices.size(); i++) { 4038 sr = mPendingServices.get(i); 4039 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid 4040 || !processName.equals(sr.processName))) { 4041 continue; 4042 } 4043 4044 mPendingServices.remove(i); 4045 i--; 4046 realStartServiceLocked(sr, app); 4047 didSomething = true; 4048 } 4049 } catch (Exception e) { 4050 Slog.w(TAG, "Exception in new application when starting service " 4051 + sr.shortName, e); 4052 badApp = true; 4053 } 4054 } 4055 4056 // Check if a next-broadcast receiver is in this process... 4057 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4058 try { 4059 didSomething = sendPendingBroadcastsLocked(app); 4060 } catch (Exception e) { 4061 // If the app died trying to launch the receiver we declare it 'bad' 4062 badApp = true; 4063 } 4064 } 4065 4066 // Check whether the next backup agent is in this process... 4067 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4068 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4069 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4070 try { 4071 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4072 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4073 mBackupTarget.backupMode); 4074 } catch (Exception e) { 4075 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4076 e.printStackTrace(); 4077 } 4078 } 4079 4080 if (badApp) { 4081 // todo: Also need to kill application to deal with all 4082 // kinds of exceptions. 4083 handleAppDiedLocked(app, false, true); 4084 return false; 4085 } 4086 4087 if (!didSomething) { 4088 updateOomAdjLocked(); 4089 } 4090 4091 return true; 4092 } 4093 4094 public final void attachApplication(IApplicationThread thread) { 4095 synchronized (this) { 4096 int callingPid = Binder.getCallingPid(); 4097 final long origId = Binder.clearCallingIdentity(); 4098 attachApplicationLocked(thread, callingPid); 4099 Binder.restoreCallingIdentity(origId); 4100 } 4101 } 4102 4103 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4104 final long origId = Binder.clearCallingIdentity(); 4105 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4106 if (stopProfiling) { 4107 synchronized (this) { 4108 if (mProfileProc == r.app) { 4109 if (mProfileFd != null) { 4110 try { 4111 mProfileFd.close(); 4112 } catch (IOException e) { 4113 } 4114 clearProfilerLocked(); 4115 } 4116 } 4117 } 4118 } 4119 Binder.restoreCallingIdentity(origId); 4120 } 4121 4122 void enableScreenAfterBoot() { 4123 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4124 SystemClock.uptimeMillis()); 4125 mWindowManager.enableScreenAfterBoot(); 4126 4127 synchronized (this) { 4128 updateEventDispatchingLocked(); 4129 } 4130 } 4131 4132 public void showBootMessage(final CharSequence msg, final boolean always) { 4133 enforceNotIsolatedCaller("showBootMessage"); 4134 mWindowManager.showBootMessage(msg, always); 4135 } 4136 4137 public void dismissKeyguardOnNextActivity() { 4138 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4139 final long token = Binder.clearCallingIdentity(); 4140 try { 4141 synchronized (this) { 4142 if (mLockScreenShown) { 4143 mLockScreenShown = false; 4144 comeOutOfSleepIfNeededLocked(); 4145 } 4146 mMainStack.dismissKeyguardOnNextActivityLocked(); 4147 } 4148 } finally { 4149 Binder.restoreCallingIdentity(token); 4150 } 4151 } 4152 4153 final void finishBooting() { 4154 IntentFilter pkgFilter = new IntentFilter(); 4155 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4156 pkgFilter.addDataScheme("package"); 4157 mContext.registerReceiver(new BroadcastReceiver() { 4158 @Override 4159 public void onReceive(Context context, Intent intent) { 4160 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4161 if (pkgs != null) { 4162 for (String pkg : pkgs) { 4163 synchronized (ActivityManagerService.this) { 4164 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4165 setResultCode(Activity.RESULT_OK); 4166 return; 4167 } 4168 } 4169 } 4170 } 4171 } 4172 }, pkgFilter); 4173 4174 IntentFilter userFilter = new IntentFilter(); 4175 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4176 mContext.registerReceiver(new BroadcastReceiver() { 4177 @Override 4178 public void onReceive(Context context, Intent intent) { 4179 onUserRemoved(intent); 4180 } 4181 }, userFilter); 4182 4183 synchronized (this) { 4184 // Ensure that any processes we had put on hold are now started 4185 // up. 4186 final int NP = mProcessesOnHold.size(); 4187 if (NP > 0) { 4188 ArrayList<ProcessRecord> procs = 4189 new ArrayList<ProcessRecord>(mProcessesOnHold); 4190 for (int ip=0; ip<NP; ip++) { 4191 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4192 + procs.get(ip)); 4193 startProcessLocked(procs.get(ip), "on-hold", null); 4194 } 4195 } 4196 4197 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4198 // Start looking for apps that are abusing wake locks. 4199 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4200 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4201 // Tell anyone interested that we are done booting! 4202 SystemProperties.set("sys.boot_completed", "1"); 4203 SystemProperties.set("dev.bootcomplete", "1"); 4204 /* TODO: Send this to all users that are to be logged in on startup */ 4205 broadcastIntentLocked(null, null, 4206 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4207 null, null, 0, null, null, 4208 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4209 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser()); 4210 } 4211 } 4212 } 4213 4214 final void ensureBootCompleted() { 4215 boolean booting; 4216 boolean enableScreen; 4217 synchronized (this) { 4218 booting = mBooting; 4219 mBooting = false; 4220 enableScreen = !mBooted; 4221 mBooted = true; 4222 } 4223 4224 if (booting) { 4225 finishBooting(); 4226 } 4227 4228 if (enableScreen) { 4229 enableScreenAfterBoot(); 4230 } 4231 } 4232 4233 public final void activityPaused(IBinder token) { 4234 final long origId = Binder.clearCallingIdentity(); 4235 mMainStack.activityPaused(token, false); 4236 Binder.restoreCallingIdentity(origId); 4237 } 4238 4239 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4240 CharSequence description) { 4241 if (localLOGV) Slog.v( 4242 TAG, "Activity stopped: token=" + token); 4243 4244 // Refuse possible leaked file descriptors 4245 if (icicle != null && icicle.hasFileDescriptors()) { 4246 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4247 } 4248 4249 ActivityRecord r = null; 4250 4251 final long origId = Binder.clearCallingIdentity(); 4252 4253 synchronized (this) { 4254 r = mMainStack.isInStackLocked(token); 4255 if (r != null) { 4256 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4257 } 4258 } 4259 4260 if (r != null) { 4261 sendPendingThumbnail(r, null, null, null, false); 4262 } 4263 4264 trimApplications(); 4265 4266 Binder.restoreCallingIdentity(origId); 4267 } 4268 4269 public final void activityDestroyed(IBinder token) { 4270 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4271 mMainStack.activityDestroyed(token); 4272 } 4273 4274 public String getCallingPackage(IBinder token) { 4275 synchronized (this) { 4276 ActivityRecord r = getCallingRecordLocked(token); 4277 return r != null && r.app != null ? r.info.packageName : null; 4278 } 4279 } 4280 4281 public ComponentName getCallingActivity(IBinder token) { 4282 synchronized (this) { 4283 ActivityRecord r = getCallingRecordLocked(token); 4284 return r != null ? r.intent.getComponent() : null; 4285 } 4286 } 4287 4288 private ActivityRecord getCallingRecordLocked(IBinder token) { 4289 ActivityRecord r = mMainStack.isInStackLocked(token); 4290 if (r == null) { 4291 return null; 4292 } 4293 return r.resultTo; 4294 } 4295 4296 public ComponentName getActivityClassForToken(IBinder token) { 4297 synchronized(this) { 4298 ActivityRecord r = mMainStack.isInStackLocked(token); 4299 if (r == null) { 4300 return null; 4301 } 4302 return r.intent.getComponent(); 4303 } 4304 } 4305 4306 public String getPackageForToken(IBinder token) { 4307 synchronized(this) { 4308 ActivityRecord r = mMainStack.isInStackLocked(token); 4309 if (r == null) { 4310 return null; 4311 } 4312 return r.packageName; 4313 } 4314 } 4315 4316 public IIntentSender getIntentSender(int type, 4317 String packageName, IBinder token, String resultWho, 4318 int requestCode, Intent[] intents, String[] resolvedTypes, 4319 int flags, Bundle options) { 4320 enforceNotIsolatedCaller("getIntentSender"); 4321 // Refuse possible leaked file descriptors 4322 if (intents != null) { 4323 if (intents.length < 1) { 4324 throw new IllegalArgumentException("Intents array length must be >= 1"); 4325 } 4326 for (int i=0; i<intents.length; i++) { 4327 Intent intent = intents[i]; 4328 if (intent != null) { 4329 if (intent.hasFileDescriptors()) { 4330 throw new IllegalArgumentException("File descriptors passed in Intent"); 4331 } 4332 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4333 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4334 throw new IllegalArgumentException( 4335 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4336 } 4337 intents[i] = new Intent(intent); 4338 } 4339 } 4340 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4341 throw new IllegalArgumentException( 4342 "Intent array length does not match resolvedTypes length"); 4343 } 4344 } 4345 if (options != null) { 4346 if (options.hasFileDescriptors()) { 4347 throw new IllegalArgumentException("File descriptors passed in options"); 4348 } 4349 } 4350 4351 synchronized(this) { 4352 int callingUid = Binder.getCallingUid(); 4353 try { 4354 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4355 int uid = AppGlobals.getPackageManager() 4356 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4357 if (!UserId.isSameApp(callingUid, uid)) { 4358 String msg = "Permission Denial: getIntentSender() from pid=" 4359 + Binder.getCallingPid() 4360 + ", uid=" + Binder.getCallingUid() 4361 + ", (need uid=" + uid + ")" 4362 + " is not allowed to send as package " + packageName; 4363 Slog.w(TAG, msg); 4364 throw new SecurityException(msg); 4365 } 4366 } 4367 4368 if (DEBUG_MU) 4369 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4370 + Binder.getOrigCallingUid()); 4371 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4372 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4373 4374 } catch (RemoteException e) { 4375 throw new SecurityException(e); 4376 } 4377 } 4378 } 4379 4380 IIntentSender getIntentSenderLocked(int type, 4381 String packageName, int callingUid, IBinder token, String resultWho, 4382 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4383 Bundle options) { 4384 if (DEBUG_MU) 4385 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4386 ActivityRecord activity = null; 4387 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4388 activity = mMainStack.isInStackLocked(token); 4389 if (activity == null) { 4390 return null; 4391 } 4392 if (activity.finishing) { 4393 return null; 4394 } 4395 } 4396 4397 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4398 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4399 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4400 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4401 |PendingIntent.FLAG_UPDATE_CURRENT); 4402 4403 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4404 type, packageName, activity, resultWho, 4405 requestCode, intents, resolvedTypes, flags, options); 4406 WeakReference<PendingIntentRecord> ref; 4407 ref = mIntentSenderRecords.get(key); 4408 PendingIntentRecord rec = ref != null ? ref.get() : null; 4409 if (rec != null) { 4410 if (!cancelCurrent) { 4411 if (updateCurrent) { 4412 if (rec.key.requestIntent != null) { 4413 rec.key.requestIntent.replaceExtras(intents != null ? 4414 intents[intents.length - 1] : null); 4415 } 4416 if (intents != null) { 4417 intents[intents.length-1] = rec.key.requestIntent; 4418 rec.key.allIntents = intents; 4419 rec.key.allResolvedTypes = resolvedTypes; 4420 } else { 4421 rec.key.allIntents = null; 4422 rec.key.allResolvedTypes = null; 4423 } 4424 } 4425 return rec; 4426 } 4427 rec.canceled = true; 4428 mIntentSenderRecords.remove(key); 4429 } 4430 if (noCreate) { 4431 return rec; 4432 } 4433 rec = new PendingIntentRecord(this, key, callingUid); 4434 mIntentSenderRecords.put(key, rec.ref); 4435 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4436 if (activity.pendingResults == null) { 4437 activity.pendingResults 4438 = new HashSet<WeakReference<PendingIntentRecord>>(); 4439 } 4440 activity.pendingResults.add(rec.ref); 4441 } 4442 return rec; 4443 } 4444 4445 public void cancelIntentSender(IIntentSender sender) { 4446 if (!(sender instanceof PendingIntentRecord)) { 4447 return; 4448 } 4449 synchronized(this) { 4450 PendingIntentRecord rec = (PendingIntentRecord)sender; 4451 try { 4452 int uid = AppGlobals.getPackageManager() 4453 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4454 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4455 String msg = "Permission Denial: cancelIntentSender() from pid=" 4456 + Binder.getCallingPid() 4457 + ", uid=" + Binder.getCallingUid() 4458 + " is not allowed to cancel packges " 4459 + rec.key.packageName; 4460 Slog.w(TAG, msg); 4461 throw new SecurityException(msg); 4462 } 4463 } catch (RemoteException e) { 4464 throw new SecurityException(e); 4465 } 4466 cancelIntentSenderLocked(rec, true); 4467 } 4468 } 4469 4470 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4471 rec.canceled = true; 4472 mIntentSenderRecords.remove(rec.key); 4473 if (cleanActivity && rec.key.activity != null) { 4474 rec.key.activity.pendingResults.remove(rec.ref); 4475 } 4476 } 4477 4478 public String getPackageForIntentSender(IIntentSender pendingResult) { 4479 if (!(pendingResult instanceof PendingIntentRecord)) { 4480 return null; 4481 } 4482 try { 4483 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4484 return res.key.packageName; 4485 } catch (ClassCastException e) { 4486 } 4487 return null; 4488 } 4489 4490 public int getUidForIntentSender(IIntentSender sender) { 4491 if (sender instanceof PendingIntentRecord) { 4492 try { 4493 PendingIntentRecord res = (PendingIntentRecord)sender; 4494 return res.uid; 4495 } catch (ClassCastException e) { 4496 } 4497 } 4498 return -1; 4499 } 4500 4501 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4502 if (!(pendingResult instanceof PendingIntentRecord)) { 4503 return false; 4504 } 4505 try { 4506 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4507 if (res.key.allIntents == null) { 4508 return false; 4509 } 4510 for (int i=0; i<res.key.allIntents.length; i++) { 4511 Intent intent = res.key.allIntents[i]; 4512 if (intent.getPackage() != null && intent.getComponent() != null) { 4513 return false; 4514 } 4515 } 4516 return true; 4517 } catch (ClassCastException e) { 4518 } 4519 return false; 4520 } 4521 4522 public void setProcessLimit(int max) { 4523 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4524 "setProcessLimit()"); 4525 synchronized (this) { 4526 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4527 mProcessLimitOverride = max; 4528 } 4529 trimApplications(); 4530 } 4531 4532 public int getProcessLimit() { 4533 synchronized (this) { 4534 return mProcessLimitOverride; 4535 } 4536 } 4537 4538 void foregroundTokenDied(ForegroundToken token) { 4539 synchronized (ActivityManagerService.this) { 4540 synchronized (mPidsSelfLocked) { 4541 ForegroundToken cur 4542 = mForegroundProcesses.get(token.pid); 4543 if (cur != token) { 4544 return; 4545 } 4546 mForegroundProcesses.remove(token.pid); 4547 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4548 if (pr == null) { 4549 return; 4550 } 4551 pr.forcingToForeground = null; 4552 pr.foregroundServices = false; 4553 } 4554 updateOomAdjLocked(); 4555 } 4556 } 4557 4558 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4559 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4560 "setProcessForeground()"); 4561 synchronized(this) { 4562 boolean changed = false; 4563 4564 synchronized (mPidsSelfLocked) { 4565 ProcessRecord pr = mPidsSelfLocked.get(pid); 4566 if (pr == null && isForeground) { 4567 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4568 return; 4569 } 4570 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4571 if (oldToken != null) { 4572 oldToken.token.unlinkToDeath(oldToken, 0); 4573 mForegroundProcesses.remove(pid); 4574 if (pr != null) { 4575 pr.forcingToForeground = null; 4576 } 4577 changed = true; 4578 } 4579 if (isForeground && token != null) { 4580 ForegroundToken newToken = new ForegroundToken() { 4581 public void binderDied() { 4582 foregroundTokenDied(this); 4583 } 4584 }; 4585 newToken.pid = pid; 4586 newToken.token = token; 4587 try { 4588 token.linkToDeath(newToken, 0); 4589 mForegroundProcesses.put(pid, newToken); 4590 pr.forcingToForeground = token; 4591 changed = true; 4592 } catch (RemoteException e) { 4593 // If the process died while doing this, we will later 4594 // do the cleanup with the process death link. 4595 } 4596 } 4597 } 4598 4599 if (changed) { 4600 updateOomAdjLocked(); 4601 } 4602 } 4603 } 4604 4605 // ========================================================= 4606 // PERMISSIONS 4607 // ========================================================= 4608 4609 static class PermissionController extends IPermissionController.Stub { 4610 ActivityManagerService mActivityManagerService; 4611 PermissionController(ActivityManagerService activityManagerService) { 4612 mActivityManagerService = activityManagerService; 4613 } 4614 4615 public boolean checkPermission(String permission, int pid, int uid) { 4616 return mActivityManagerService.checkPermission(permission, pid, 4617 uid) == PackageManager.PERMISSION_GRANTED; 4618 } 4619 } 4620 4621 /** 4622 * This can be called with or without the global lock held. 4623 */ 4624 int checkComponentPermission(String permission, int pid, int uid, 4625 int owningUid, boolean exported) { 4626 // We might be performing an operation on behalf of an indirect binder 4627 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4628 // client identity accordingly before proceeding. 4629 Identity tlsIdentity = sCallerIdentity.get(); 4630 if (tlsIdentity != null) { 4631 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4632 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4633 uid = tlsIdentity.uid; 4634 pid = tlsIdentity.pid; 4635 } 4636 4637 // Root, system server and our own process get to do everything. 4638 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) { 4639 return PackageManager.PERMISSION_GRANTED; 4640 } 4641 // Isolated processes don't get any permissions. 4642 if (UserId.isIsolated(uid)) { 4643 return PackageManager.PERMISSION_DENIED; 4644 } 4645 // If there is a uid that owns whatever is being accessed, it has 4646 // blanket access to it regardless of the permissions it requires. 4647 if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) { 4648 return PackageManager.PERMISSION_GRANTED; 4649 } 4650 // If the target is not exported, then nobody else can get to it. 4651 if (!exported) { 4652 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid); 4653 return PackageManager.PERMISSION_DENIED; 4654 } 4655 if (permission == null) { 4656 return PackageManager.PERMISSION_GRANTED; 4657 } 4658 try { 4659 return AppGlobals.getPackageManager() 4660 .checkUidPermission(permission, uid); 4661 } catch (RemoteException e) { 4662 // Should never happen, but if it does... deny! 4663 Slog.e(TAG, "PackageManager is dead?!?", e); 4664 } 4665 return PackageManager.PERMISSION_DENIED; 4666 } 4667 4668 /** 4669 * As the only public entry point for permissions checking, this method 4670 * can enforce the semantic that requesting a check on a null global 4671 * permission is automatically denied. (Internally a null permission 4672 * string is used when calling {@link #checkComponentPermission} in cases 4673 * when only uid-based security is needed.) 4674 * 4675 * This can be called with or without the global lock held. 4676 */ 4677 public int checkPermission(String permission, int pid, int uid) { 4678 if (permission == null) { 4679 return PackageManager.PERMISSION_DENIED; 4680 } 4681 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4682 } 4683 4684 /** 4685 * Binder IPC calls go through the public entry point. 4686 * This can be called with or without the global lock held. 4687 */ 4688 int checkCallingPermission(String permission) { 4689 return checkPermission(permission, 4690 Binder.getCallingPid(), 4691 UserId.getAppId(Binder.getCallingUid())); 4692 } 4693 4694 /** 4695 * This can be called with or without the global lock held. 4696 */ 4697 void enforceCallingPermission(String permission, String func) { 4698 if (checkCallingPermission(permission) 4699 == PackageManager.PERMISSION_GRANTED) { 4700 return; 4701 } 4702 4703 String msg = "Permission Denial: " + func + " from pid=" 4704 + Binder.getCallingPid() 4705 + ", uid=" + Binder.getCallingUid() 4706 + " requires " + permission; 4707 Slog.w(TAG, msg); 4708 throw new SecurityException(msg); 4709 } 4710 4711 /** 4712 * Determine if UID is holding permissions required to access {@link Uri} in 4713 * the given {@link ProviderInfo}. Final permission checking is always done 4714 * in {@link ContentProvider}. 4715 */ 4716 private final boolean checkHoldingPermissionsLocked( 4717 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4718 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4719 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4720 4721 if (pi.applicationInfo.uid == uid) { 4722 return true; 4723 } else if (!pi.exported) { 4724 return false; 4725 } 4726 4727 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4728 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4729 try { 4730 // check if target holds top-level <provider> permissions 4731 if (!readMet && pi.readPermission != null 4732 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4733 readMet = true; 4734 } 4735 if (!writeMet && pi.writePermission != null 4736 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4737 writeMet = true; 4738 } 4739 4740 // track if unprotected read/write is allowed; any denied 4741 // <path-permission> below removes this ability 4742 boolean allowDefaultRead = pi.readPermission == null; 4743 boolean allowDefaultWrite = pi.writePermission == null; 4744 4745 // check if target holds any <path-permission> that match uri 4746 final PathPermission[] pps = pi.pathPermissions; 4747 if (pps != null) { 4748 final String path = uri.getPath(); 4749 int i = pps.length; 4750 while (i > 0 && (!readMet || !writeMet)) { 4751 i--; 4752 PathPermission pp = pps[i]; 4753 if (pp.match(path)) { 4754 if (!readMet) { 4755 final String pprperm = pp.getReadPermission(); 4756 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4757 + pprperm + " for " + pp.getPath() 4758 + ": match=" + pp.match(path) 4759 + " check=" + pm.checkUidPermission(pprperm, uid)); 4760 if (pprperm != null) { 4761 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4762 readMet = true; 4763 } else { 4764 allowDefaultRead = false; 4765 } 4766 } 4767 } 4768 if (!writeMet) { 4769 final String ppwperm = pp.getWritePermission(); 4770 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4771 + ppwperm + " for " + pp.getPath() 4772 + ": match=" + pp.match(path) 4773 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4774 if (ppwperm != null) { 4775 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4776 writeMet = true; 4777 } else { 4778 allowDefaultWrite = false; 4779 } 4780 } 4781 } 4782 } 4783 } 4784 } 4785 4786 // grant unprotected <provider> read/write, if not blocked by 4787 // <path-permission> above 4788 if (allowDefaultRead) readMet = true; 4789 if (allowDefaultWrite) writeMet = true; 4790 4791 } catch (RemoteException e) { 4792 return false; 4793 } 4794 4795 return readMet && writeMet; 4796 } 4797 4798 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4799 int modeFlags) { 4800 // Root gets to do everything. 4801 if (uid == 0) { 4802 return true; 4803 } 4804 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4805 if (perms == null) return false; 4806 UriPermission perm = perms.get(uri); 4807 if (perm == null) return false; 4808 return (modeFlags&perm.modeFlags) == modeFlags; 4809 } 4810 4811 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4812 enforceNotIsolatedCaller("checkUriPermission"); 4813 4814 // Another redirected-binder-call permissions check as in 4815 // {@link checkComponentPermission}. 4816 Identity tlsIdentity = sCallerIdentity.get(); 4817 if (tlsIdentity != null) { 4818 uid = tlsIdentity.uid; 4819 pid = tlsIdentity.pid; 4820 } 4821 4822 uid = UserId.getAppId(uid); 4823 // Our own process gets to do everything. 4824 if (pid == MY_PID) { 4825 return PackageManager.PERMISSION_GRANTED; 4826 } 4827 synchronized(this) { 4828 return checkUriPermissionLocked(uri, uid, modeFlags) 4829 ? PackageManager.PERMISSION_GRANTED 4830 : PackageManager.PERMISSION_DENIED; 4831 } 4832 } 4833 4834 /** 4835 * Check if the targetPkg can be granted permission to access uri by 4836 * the callingUid using the given modeFlags. Throws a security exception 4837 * if callingUid is not allowed to do this. Returns the uid of the target 4838 * if the URI permission grant should be performed; returns -1 if it is not 4839 * needed (for example targetPkg already has permission to access the URI). 4840 * If you already know the uid of the target, you can supply it in 4841 * lastTargetUid else set that to -1. 4842 */ 4843 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4844 Uri uri, int modeFlags, int lastTargetUid) { 4845 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4846 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4847 if (modeFlags == 0) { 4848 return -1; 4849 } 4850 4851 if (targetPkg != null) { 4852 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4853 "Checking grant " + targetPkg + " permission to " + uri); 4854 } 4855 4856 final IPackageManager pm = AppGlobals.getPackageManager(); 4857 4858 // If this is not a content: uri, we can't do anything with it. 4859 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4860 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4861 "Can't grant URI permission for non-content URI: " + uri); 4862 return -1; 4863 } 4864 4865 String name = uri.getAuthority(); 4866 ProviderInfo pi = null; 4867 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4868 UserId.getUserId(callingUid)); 4869 if (cpr != null) { 4870 pi = cpr.info; 4871 } else { 4872 try { 4873 pi = pm.resolveContentProvider(name, 4874 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4875 } catch (RemoteException ex) { 4876 } 4877 } 4878 if (pi == null) { 4879 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4880 return -1; 4881 } 4882 4883 int targetUid = lastTargetUid; 4884 if (targetUid < 0 && targetPkg != null) { 4885 try { 4886 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4887 if (targetUid < 0) { 4888 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4889 "Can't grant URI permission no uid for: " + targetPkg); 4890 return -1; 4891 } 4892 } catch (RemoteException ex) { 4893 return -1; 4894 } 4895 } 4896 4897 if (targetUid >= 0) { 4898 // First... does the target actually need this permission? 4899 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4900 // No need to grant the target this permission. 4901 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4902 "Target " + targetPkg + " already has full permission to " + uri); 4903 return -1; 4904 } 4905 } else { 4906 // First... there is no target package, so can anyone access it? 4907 boolean allowed = pi.exported; 4908 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4909 if (pi.readPermission != null) { 4910 allowed = false; 4911 } 4912 } 4913 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4914 if (pi.writePermission != null) { 4915 allowed = false; 4916 } 4917 } 4918 if (allowed) { 4919 return -1; 4920 } 4921 } 4922 4923 // Second... is the provider allowing granting of URI permissions? 4924 if (!pi.grantUriPermissions) { 4925 throw new SecurityException("Provider " + pi.packageName 4926 + "/" + pi.name 4927 + " does not allow granting of Uri permissions (uri " 4928 + uri + ")"); 4929 } 4930 if (pi.uriPermissionPatterns != null) { 4931 final int N = pi.uriPermissionPatterns.length; 4932 boolean allowed = false; 4933 for (int i=0; i<N; i++) { 4934 if (pi.uriPermissionPatterns[i] != null 4935 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4936 allowed = true; 4937 break; 4938 } 4939 } 4940 if (!allowed) { 4941 throw new SecurityException("Provider " + pi.packageName 4942 + "/" + pi.name 4943 + " does not allow granting of permission to path of Uri " 4944 + uri); 4945 } 4946 } 4947 4948 // Third... does the caller itself have permission to access 4949 // this uri? 4950 if (callingUid != Process.myUid()) { 4951 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4952 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4953 throw new SecurityException("Uid " + callingUid 4954 + " does not have permission to uri " + uri); 4955 } 4956 } 4957 } 4958 4959 return targetUid; 4960 } 4961 4962 public int checkGrantUriPermission(int callingUid, String targetPkg, 4963 Uri uri, int modeFlags) { 4964 enforceNotIsolatedCaller("checkGrantUriPermission"); 4965 synchronized(this) { 4966 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4967 } 4968 } 4969 4970 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4971 Uri uri, int modeFlags, UriPermissionOwner owner) { 4972 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4973 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4974 if (modeFlags == 0) { 4975 return; 4976 } 4977 4978 // So here we are: the caller has the assumed permission 4979 // to the uri, and the target doesn't. Let's now give this to 4980 // the target. 4981 4982 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4983 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4984 4985 HashMap<Uri, UriPermission> targetUris 4986 = mGrantedUriPermissions.get(targetUid); 4987 if (targetUris == null) { 4988 targetUris = new HashMap<Uri, UriPermission>(); 4989 mGrantedUriPermissions.put(targetUid, targetUris); 4990 } 4991 4992 UriPermission perm = targetUris.get(uri); 4993 if (perm == null) { 4994 perm = new UriPermission(targetUid, uri); 4995 targetUris.put(uri, perm); 4996 } 4997 4998 perm.modeFlags |= modeFlags; 4999 if (owner == null) { 5000 perm.globalModeFlags |= modeFlags; 5001 } else { 5002 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5003 perm.readOwners.add(owner); 5004 owner.addReadPermission(perm); 5005 } 5006 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5007 perm.writeOwners.add(owner); 5008 owner.addWritePermission(perm); 5009 } 5010 } 5011 } 5012 5013 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5014 int modeFlags, UriPermissionOwner owner) { 5015 if (targetPkg == null) { 5016 throw new NullPointerException("targetPkg"); 5017 } 5018 5019 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5020 if (targetUid < 0) { 5021 return; 5022 } 5023 5024 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5025 } 5026 5027 static class NeededUriGrants extends ArrayList<Uri> { 5028 final String targetPkg; 5029 final int targetUid; 5030 final int flags; 5031 5032 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5033 targetPkg = _targetPkg; 5034 targetUid = _targetUid; 5035 flags = _flags; 5036 } 5037 } 5038 5039 /** 5040 * Like checkGrantUriPermissionLocked, but takes an Intent. 5041 */ 5042 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5043 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5044 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5045 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5046 + " clip=" + (intent != null ? intent.getClipData() : null) 5047 + " from " + intent + "; flags=0x" 5048 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5049 5050 if (targetPkg == null) { 5051 throw new NullPointerException("targetPkg"); 5052 } 5053 5054 if (intent == null) { 5055 return null; 5056 } 5057 Uri data = intent.getData(); 5058 ClipData clip = intent.getClipData(); 5059 if (data == null && clip == null) { 5060 return null; 5061 } 5062 if (data != null) { 5063 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5064 mode, needed != null ? needed.targetUid : -1); 5065 if (target > 0) { 5066 if (needed == null) { 5067 needed = new NeededUriGrants(targetPkg, target, mode); 5068 } 5069 needed.add(data); 5070 } 5071 } 5072 if (clip != null) { 5073 for (int i=0; i<clip.getItemCount(); i++) { 5074 Uri uri = clip.getItemAt(i).getUri(); 5075 if (uri != null) { 5076 int target = -1; 5077 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5078 mode, needed != null ? needed.targetUid : -1); 5079 if (target > 0) { 5080 if (needed == null) { 5081 needed = new NeededUriGrants(targetPkg, target, mode); 5082 } 5083 needed.add(uri); 5084 } 5085 } else { 5086 Intent clipIntent = clip.getItemAt(i).getIntent(); 5087 if (clipIntent != null) { 5088 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5089 callingUid, targetPkg, clipIntent, mode, needed); 5090 if (newNeeded != null) { 5091 needed = newNeeded; 5092 } 5093 } 5094 } 5095 } 5096 } 5097 5098 return needed; 5099 } 5100 5101 /** 5102 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5103 */ 5104 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5105 UriPermissionOwner owner) { 5106 if (needed != null) { 5107 for (int i=0; i<needed.size(); i++) { 5108 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5109 needed.get(i), needed.flags, owner); 5110 } 5111 } 5112 } 5113 5114 void grantUriPermissionFromIntentLocked(int callingUid, 5115 String targetPkg, Intent intent, UriPermissionOwner owner) { 5116 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5117 intent, intent != null ? intent.getFlags() : 0, null); 5118 if (needed == null) { 5119 return; 5120 } 5121 5122 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5123 } 5124 5125 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5126 Uri uri, int modeFlags) { 5127 enforceNotIsolatedCaller("grantUriPermission"); 5128 synchronized(this) { 5129 final ProcessRecord r = getRecordForAppLocked(caller); 5130 if (r == null) { 5131 throw new SecurityException("Unable to find app for caller " 5132 + caller 5133 + " when granting permission to uri " + uri); 5134 } 5135 if (targetPkg == null) { 5136 throw new IllegalArgumentException("null target"); 5137 } 5138 if (uri == null) { 5139 throw new IllegalArgumentException("null uri"); 5140 } 5141 5142 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5143 null); 5144 } 5145 } 5146 5147 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5148 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5149 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5150 HashMap<Uri, UriPermission> perms 5151 = mGrantedUriPermissions.get(perm.uid); 5152 if (perms != null) { 5153 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5154 "Removing " + perm.uid + " permission to " + perm.uri); 5155 perms.remove(perm.uri); 5156 if (perms.size() == 0) { 5157 mGrantedUriPermissions.remove(perm.uid); 5158 } 5159 } 5160 } 5161 } 5162 5163 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5164 int modeFlags) { 5165 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5166 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5167 if (modeFlags == 0) { 5168 return; 5169 } 5170 5171 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5172 "Revoking all granted permissions to " + uri); 5173 5174 final IPackageManager pm = AppGlobals.getPackageManager(); 5175 5176 final String authority = uri.getAuthority(); 5177 ProviderInfo pi = null; 5178 int userId = UserId.getUserId(callingUid); 5179 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5180 if (cpr != null) { 5181 pi = cpr.info; 5182 } else { 5183 try { 5184 pi = pm.resolveContentProvider(authority, 5185 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5186 } catch (RemoteException ex) { 5187 } 5188 } 5189 if (pi == null) { 5190 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5191 return; 5192 } 5193 5194 // Does the caller have this permission on the URI? 5195 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5196 // Right now, if you are not the original owner of the permission, 5197 // you are not allowed to revoke it. 5198 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5199 throw new SecurityException("Uid " + callingUid 5200 + " does not have permission to uri " + uri); 5201 //} 5202 } 5203 5204 // Go through all of the permissions and remove any that match. 5205 final List<String> SEGMENTS = uri.getPathSegments(); 5206 if (SEGMENTS != null) { 5207 final int NS = SEGMENTS.size(); 5208 int N = mGrantedUriPermissions.size(); 5209 for (int i=0; i<N; i++) { 5210 HashMap<Uri, UriPermission> perms 5211 = mGrantedUriPermissions.valueAt(i); 5212 Iterator<UriPermission> it = perms.values().iterator(); 5213 toploop: 5214 while (it.hasNext()) { 5215 UriPermission perm = it.next(); 5216 Uri targetUri = perm.uri; 5217 if (!authority.equals(targetUri.getAuthority())) { 5218 continue; 5219 } 5220 List<String> targetSegments = targetUri.getPathSegments(); 5221 if (targetSegments == null) { 5222 continue; 5223 } 5224 if (targetSegments.size() < NS) { 5225 continue; 5226 } 5227 for (int j=0; j<NS; j++) { 5228 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5229 continue toploop; 5230 } 5231 } 5232 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5233 "Revoking " + perm.uid + " permission to " + perm.uri); 5234 perm.clearModes(modeFlags); 5235 if (perm.modeFlags == 0) { 5236 it.remove(); 5237 } 5238 } 5239 if (perms.size() == 0) { 5240 mGrantedUriPermissions.remove( 5241 mGrantedUriPermissions.keyAt(i)); 5242 N--; 5243 i--; 5244 } 5245 } 5246 } 5247 } 5248 5249 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5250 int modeFlags) { 5251 enforceNotIsolatedCaller("revokeUriPermission"); 5252 synchronized(this) { 5253 final ProcessRecord r = getRecordForAppLocked(caller); 5254 if (r == null) { 5255 throw new SecurityException("Unable to find app for caller " 5256 + caller 5257 + " when revoking permission to uri " + uri); 5258 } 5259 if (uri == null) { 5260 Slog.w(TAG, "revokeUriPermission: null uri"); 5261 return; 5262 } 5263 5264 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5265 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5266 if (modeFlags == 0) { 5267 return; 5268 } 5269 5270 final IPackageManager pm = AppGlobals.getPackageManager(); 5271 5272 final String authority = uri.getAuthority(); 5273 ProviderInfo pi = null; 5274 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5275 if (cpr != null) { 5276 pi = cpr.info; 5277 } else { 5278 try { 5279 pi = pm.resolveContentProvider(authority, 5280 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5281 } catch (RemoteException ex) { 5282 } 5283 } 5284 if (pi == null) { 5285 Slog.w(TAG, "No content provider found for permission revoke: " 5286 + uri.toSafeString()); 5287 return; 5288 } 5289 5290 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5291 } 5292 } 5293 5294 @Override 5295 public IBinder newUriPermissionOwner(String name) { 5296 enforceNotIsolatedCaller("newUriPermissionOwner"); 5297 synchronized(this) { 5298 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5299 return owner.getExternalTokenLocked(); 5300 } 5301 } 5302 5303 @Override 5304 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5305 Uri uri, int modeFlags) { 5306 synchronized(this) { 5307 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5308 if (owner == null) { 5309 throw new IllegalArgumentException("Unknown owner: " + token); 5310 } 5311 if (fromUid != Binder.getCallingUid()) { 5312 if (Binder.getCallingUid() != Process.myUid()) { 5313 // Only system code can grant URI permissions on behalf 5314 // of other users. 5315 throw new SecurityException("nice try"); 5316 } 5317 } 5318 if (targetPkg == null) { 5319 throw new IllegalArgumentException("null target"); 5320 } 5321 if (uri == null) { 5322 throw new IllegalArgumentException("null uri"); 5323 } 5324 5325 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5326 } 5327 } 5328 5329 @Override 5330 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5331 synchronized(this) { 5332 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5333 if (owner == null) { 5334 throw new IllegalArgumentException("Unknown owner: " + token); 5335 } 5336 5337 if (uri == null) { 5338 owner.removeUriPermissionsLocked(mode); 5339 } else { 5340 owner.removeUriPermissionLocked(uri, mode); 5341 } 5342 } 5343 } 5344 5345 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5346 synchronized (this) { 5347 ProcessRecord app = 5348 who != null ? getRecordForAppLocked(who) : null; 5349 if (app == null) return; 5350 5351 Message msg = Message.obtain(); 5352 msg.what = WAIT_FOR_DEBUGGER_MSG; 5353 msg.obj = app; 5354 msg.arg1 = waiting ? 1 : 0; 5355 mHandler.sendMessage(msg); 5356 } 5357 } 5358 5359 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5360 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5361 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5362 outInfo.availMem = Process.getFreeMemory(); 5363 outInfo.totalMem = Process.getTotalMemory(); 5364 outInfo.threshold = homeAppMem; 5365 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5366 outInfo.hiddenAppThreshold = hiddenAppMem; 5367 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5368 ProcessList.SERVICE_ADJ); 5369 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5370 ProcessList.VISIBLE_APP_ADJ); 5371 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5372 ProcessList.FOREGROUND_APP_ADJ); 5373 } 5374 5375 // ========================================================= 5376 // TASK MANAGEMENT 5377 // ========================================================= 5378 5379 public List getTasks(int maxNum, int flags, 5380 IThumbnailReceiver receiver) { 5381 ArrayList list = new ArrayList(); 5382 5383 PendingThumbnailsRecord pending = null; 5384 IApplicationThread topThumbnail = null; 5385 ActivityRecord topRecord = null; 5386 5387 synchronized(this) { 5388 if (localLOGV) Slog.v( 5389 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5390 + ", receiver=" + receiver); 5391 5392 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5393 != PackageManager.PERMISSION_GRANTED) { 5394 if (receiver != null) { 5395 // If the caller wants to wait for pending thumbnails, 5396 // it ain't gonna get them. 5397 try { 5398 receiver.finished(); 5399 } catch (RemoteException ex) { 5400 } 5401 } 5402 String msg = "Permission Denial: getTasks() from pid=" 5403 + Binder.getCallingPid() 5404 + ", uid=" + Binder.getCallingUid() 5405 + " requires " + android.Manifest.permission.GET_TASKS; 5406 Slog.w(TAG, msg); 5407 throw new SecurityException(msg); 5408 } 5409 5410 int pos = mMainStack.mHistory.size()-1; 5411 ActivityRecord next = 5412 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5413 ActivityRecord top = null; 5414 TaskRecord curTask = null; 5415 int numActivities = 0; 5416 int numRunning = 0; 5417 while (pos >= 0 && maxNum > 0) { 5418 final ActivityRecord r = next; 5419 pos--; 5420 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5421 5422 // Initialize state for next task if needed. 5423 if (top == null || 5424 (top.state == ActivityState.INITIALIZING 5425 && top.task == r.task)) { 5426 top = r; 5427 curTask = r.task; 5428 numActivities = numRunning = 0; 5429 } 5430 5431 // Add 'r' into the current task. 5432 numActivities++; 5433 if (r.app != null && r.app.thread != null) { 5434 numRunning++; 5435 } 5436 5437 if (localLOGV) Slog.v( 5438 TAG, r.intent.getComponent().flattenToShortString() 5439 + ": task=" + r.task); 5440 5441 // If the next one is a different task, generate a new 5442 // TaskInfo entry for what we have. 5443 if (next == null || next.task != curTask) { 5444 ActivityManager.RunningTaskInfo ci 5445 = new ActivityManager.RunningTaskInfo(); 5446 ci.id = curTask.taskId; 5447 ci.baseActivity = r.intent.getComponent(); 5448 ci.topActivity = top.intent.getComponent(); 5449 if (top.thumbHolder != null) { 5450 ci.description = top.thumbHolder.lastDescription; 5451 } 5452 ci.numActivities = numActivities; 5453 ci.numRunning = numRunning; 5454 //System.out.println( 5455 // "#" + maxNum + ": " + " descr=" + ci.description); 5456 if (ci.thumbnail == null && receiver != null) { 5457 if (localLOGV) Slog.v( 5458 TAG, "State=" + top.state + "Idle=" + top.idle 5459 + " app=" + top.app 5460 + " thr=" + (top.app != null ? top.app.thread : null)); 5461 if (top.state == ActivityState.RESUMED 5462 || top.state == ActivityState.PAUSING) { 5463 if (top.idle && top.app != null 5464 && top.app.thread != null) { 5465 topRecord = top; 5466 topThumbnail = top.app.thread; 5467 } else { 5468 top.thumbnailNeeded = true; 5469 } 5470 } 5471 if (pending == null) { 5472 pending = new PendingThumbnailsRecord(receiver); 5473 } 5474 pending.pendingRecords.add(top); 5475 } 5476 list.add(ci); 5477 maxNum--; 5478 top = null; 5479 } 5480 } 5481 5482 if (pending != null) { 5483 mPendingThumbnails.add(pending); 5484 } 5485 } 5486 5487 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5488 5489 if (topThumbnail != null) { 5490 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5491 try { 5492 topThumbnail.requestThumbnail(topRecord.appToken); 5493 } catch (Exception e) { 5494 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5495 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5496 } 5497 } 5498 5499 if (pending == null && receiver != null) { 5500 // In this case all thumbnails were available and the client 5501 // is being asked to be told when the remaining ones come in... 5502 // which is unusually, since the top-most currently running 5503 // activity should never have a canned thumbnail! Oh well. 5504 try { 5505 receiver.finished(); 5506 } catch (RemoteException ex) { 5507 } 5508 } 5509 5510 return list; 5511 } 5512 5513 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5514 int flags) { 5515 final int callingUid = Binder.getCallingUid(); 5516 // If it's the system uid asking, then use the current user id. 5517 // TODO: Make sure that there aren't any other legitimate calls from the system uid that 5518 // require the entire list. 5519 final int callingUserId = callingUid == Process.SYSTEM_UID 5520 ? mCurrentUserId : UserId.getUserId(callingUid); 5521 synchronized (this) { 5522 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5523 "getRecentTasks()"); 5524 final boolean detailed = checkCallingPermission( 5525 android.Manifest.permission.GET_DETAILED_TASKS) 5526 == PackageManager.PERMISSION_GRANTED; 5527 5528 IPackageManager pm = AppGlobals.getPackageManager(); 5529 5530 final int N = mRecentTasks.size(); 5531 ArrayList<ActivityManager.RecentTaskInfo> res 5532 = new ArrayList<ActivityManager.RecentTaskInfo>( 5533 maxNum < N ? maxNum : N); 5534 for (int i=0; i<N && maxNum > 0; i++) { 5535 TaskRecord tr = mRecentTasks.get(i); 5536 // Only add calling user's recent tasks 5537 if (tr.userId != callingUserId) continue; 5538 // Return the entry if desired by the caller. We always return 5539 // the first entry, because callers always expect this to be the 5540 // foreground app. We may filter others if the caller has 5541 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5542 // we should exclude the entry. 5543 5544 if (i == 0 5545 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5546 || (tr.intent == null) 5547 || ((tr.intent.getFlags() 5548 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5549 ActivityManager.RecentTaskInfo rti 5550 = new ActivityManager.RecentTaskInfo(); 5551 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5552 rti.persistentId = tr.taskId; 5553 rti.baseIntent = new Intent( 5554 tr.intent != null ? tr.intent : tr.affinityIntent); 5555 if (!detailed) { 5556 rti.baseIntent.replaceExtras((Bundle)null); 5557 } 5558 rti.origActivity = tr.origActivity; 5559 rti.description = tr.lastDescription; 5560 5561 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5562 // Check whether this activity is currently available. 5563 try { 5564 if (rti.origActivity != null) { 5565 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId) 5566 == null) { 5567 continue; 5568 } 5569 } else if (rti.baseIntent != null) { 5570 if (pm.queryIntentActivities(rti.baseIntent, 5571 null, 0, callingUserId) == null) { 5572 continue; 5573 } 5574 } 5575 } catch (RemoteException e) { 5576 // Will never happen. 5577 } 5578 } 5579 5580 res.add(rti); 5581 maxNum--; 5582 } 5583 } 5584 return res; 5585 } 5586 } 5587 5588 private TaskRecord taskForIdLocked(int id) { 5589 final int N = mRecentTasks.size(); 5590 for (int i=0; i<N; i++) { 5591 TaskRecord tr = mRecentTasks.get(i); 5592 if (tr.taskId == id) { 5593 return tr; 5594 } 5595 } 5596 return null; 5597 } 5598 5599 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5600 synchronized (this) { 5601 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5602 "getTaskThumbnails()"); 5603 TaskRecord tr = taskForIdLocked(id); 5604 if (tr != null) { 5605 return mMainStack.getTaskThumbnailsLocked(tr); 5606 } 5607 } 5608 return null; 5609 } 5610 5611 public boolean removeSubTask(int taskId, int subTaskIndex) { 5612 synchronized (this) { 5613 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5614 "removeSubTask()"); 5615 long ident = Binder.clearCallingIdentity(); 5616 try { 5617 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5618 true) != null; 5619 } finally { 5620 Binder.restoreCallingIdentity(ident); 5621 } 5622 } 5623 } 5624 5625 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5626 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5627 Intent baseIntent = new Intent( 5628 tr.intent != null ? tr.intent : tr.affinityIntent); 5629 ComponentName component = baseIntent.getComponent(); 5630 if (component == null) { 5631 Slog.w(TAG, "Now component for base intent of task: " + tr); 5632 return; 5633 } 5634 5635 // Find any running services associated with this app. 5636 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5637 for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) { 5638 if (sr.packageName.equals(component.getPackageName())) { 5639 services.add(sr); 5640 } 5641 } 5642 5643 // Take care of any running services associated with the app. 5644 for (int i=0; i<services.size(); i++) { 5645 ServiceRecord sr = services.get(i); 5646 if (sr.startRequested) { 5647 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { 5648 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); 5649 stopServiceLocked(sr); 5650 } else { 5651 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, 5652 sr.makeNextStartId(), baseIntent, null)); 5653 if (sr.app != null && sr.app.thread != null) { 5654 sendServiceArgsLocked(sr, false); 5655 } 5656 } 5657 } 5658 } 5659 5660 if (killProcesses) { 5661 // Find any running processes associated with this app. 5662 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5663 SparseArray<ProcessRecord> appProcs 5664 = mProcessNames.getMap().get(component.getPackageName()); 5665 if (appProcs != null) { 5666 for (int i=0; i<appProcs.size(); i++) { 5667 procs.add(appProcs.valueAt(i)); 5668 } 5669 } 5670 5671 // Kill the running processes. 5672 for (int i=0; i<procs.size(); i++) { 5673 ProcessRecord pr = procs.get(i); 5674 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5675 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5676 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5677 pr.processName, pr.setAdj, "remove task"); 5678 Process.killProcessQuiet(pr.pid); 5679 } else { 5680 pr.waitingToKill = "remove task"; 5681 } 5682 } 5683 } 5684 } 5685 5686 public boolean removeTask(int taskId, int flags) { 5687 synchronized (this) { 5688 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5689 "removeTask()"); 5690 long ident = Binder.clearCallingIdentity(); 5691 try { 5692 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5693 false); 5694 if (r != null) { 5695 mRecentTasks.remove(r.task); 5696 cleanUpRemovedTaskLocked(r.task, flags); 5697 return true; 5698 } else { 5699 TaskRecord tr = null; 5700 int i=0; 5701 while (i < mRecentTasks.size()) { 5702 TaskRecord t = mRecentTasks.get(i); 5703 if (t.taskId == taskId) { 5704 tr = t; 5705 break; 5706 } 5707 i++; 5708 } 5709 if (tr != null) { 5710 if (tr.numActivities <= 0) { 5711 // Caller is just removing a recent task that is 5712 // not actively running. That is easy! 5713 mRecentTasks.remove(i); 5714 cleanUpRemovedTaskLocked(tr, flags); 5715 return true; 5716 } else { 5717 Slog.w(TAG, "removeTask: task " + taskId 5718 + " does not have activities to remove, " 5719 + " but numActivities=" + tr.numActivities 5720 + ": " + tr); 5721 } 5722 } 5723 } 5724 } finally { 5725 Binder.restoreCallingIdentity(ident); 5726 } 5727 } 5728 return false; 5729 } 5730 5731 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5732 int j; 5733 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5734 TaskRecord jt = startTask; 5735 5736 // First look backwards 5737 for (j=startIndex-1; j>=0; j--) { 5738 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5739 if (r.task != jt) { 5740 jt = r.task; 5741 if (affinity.equals(jt.affinity)) { 5742 return j; 5743 } 5744 } 5745 } 5746 5747 // Now look forwards 5748 final int N = mMainStack.mHistory.size(); 5749 jt = startTask; 5750 for (j=startIndex+1; j<N; j++) { 5751 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5752 if (r.task != jt) { 5753 if (affinity.equals(jt.affinity)) { 5754 return j; 5755 } 5756 jt = r.task; 5757 } 5758 } 5759 5760 // Might it be at the top? 5761 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5762 return N-1; 5763 } 5764 5765 return -1; 5766 } 5767 5768 /** 5769 * TODO: Add mController hook 5770 */ 5771 public void moveTaskToFront(int task, int flags, Bundle options) { 5772 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5773 "moveTaskToFront()"); 5774 5775 synchronized(this) { 5776 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5777 Binder.getCallingUid(), "Task to front")) { 5778 ActivityOptions.abort(options); 5779 return; 5780 } 5781 final long origId = Binder.clearCallingIdentity(); 5782 try { 5783 TaskRecord tr = taskForIdLocked(task); 5784 if (tr != null) { 5785 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5786 mMainStack.mUserLeaving = true; 5787 } 5788 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5789 // Caller wants the home activity moved with it. To accomplish this, 5790 // we'll just move the home task to the top first. 5791 mMainStack.moveHomeToFrontLocked(); 5792 } 5793 mMainStack.moveTaskToFrontLocked(tr, null, options); 5794 return; 5795 } 5796 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5797 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5798 if (hr.task.taskId == task) { 5799 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5800 mMainStack.mUserLeaving = true; 5801 } 5802 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5803 // Caller wants the home activity moved with it. To accomplish this, 5804 // we'll just move the home task to the top first. 5805 mMainStack.moveHomeToFrontLocked(); 5806 } 5807 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5808 return; 5809 } 5810 } 5811 } finally { 5812 Binder.restoreCallingIdentity(origId); 5813 } 5814 ActivityOptions.abort(options); 5815 } 5816 } 5817 5818 public void moveTaskToBack(int task) { 5819 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5820 "moveTaskToBack()"); 5821 5822 synchronized(this) { 5823 if (mMainStack.mResumedActivity != null 5824 && mMainStack.mResumedActivity.task.taskId == task) { 5825 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5826 Binder.getCallingUid(), "Task to back")) { 5827 return; 5828 } 5829 } 5830 final long origId = Binder.clearCallingIdentity(); 5831 mMainStack.moveTaskToBackLocked(task, null); 5832 Binder.restoreCallingIdentity(origId); 5833 } 5834 } 5835 5836 /** 5837 * Moves an activity, and all of the other activities within the same task, to the bottom 5838 * of the history stack. The activity's order within the task is unchanged. 5839 * 5840 * @param token A reference to the activity we wish to move 5841 * @param nonRoot If false then this only works if the activity is the root 5842 * of a task; if true it will work for any activity in a task. 5843 * @return Returns true if the move completed, false if not. 5844 */ 5845 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5846 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5847 synchronized(this) { 5848 final long origId = Binder.clearCallingIdentity(); 5849 int taskId = getTaskForActivityLocked(token, !nonRoot); 5850 if (taskId >= 0) { 5851 return mMainStack.moveTaskToBackLocked(taskId, null); 5852 } 5853 Binder.restoreCallingIdentity(origId); 5854 } 5855 return false; 5856 } 5857 5858 public void moveTaskBackwards(int task) { 5859 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5860 "moveTaskBackwards()"); 5861 5862 synchronized(this) { 5863 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5864 Binder.getCallingUid(), "Task backwards")) { 5865 return; 5866 } 5867 final long origId = Binder.clearCallingIdentity(); 5868 moveTaskBackwardsLocked(task); 5869 Binder.restoreCallingIdentity(origId); 5870 } 5871 } 5872 5873 private final void moveTaskBackwardsLocked(int task) { 5874 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5875 } 5876 5877 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5878 synchronized(this) { 5879 return getTaskForActivityLocked(token, onlyRoot); 5880 } 5881 } 5882 5883 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5884 final int N = mMainStack.mHistory.size(); 5885 TaskRecord lastTask = null; 5886 for (int i=0; i<N; i++) { 5887 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5888 if (r.appToken == token) { 5889 if (!onlyRoot || lastTask != r.task) { 5890 return r.task.taskId; 5891 } 5892 return -1; 5893 } 5894 lastTask = r.task; 5895 } 5896 5897 return -1; 5898 } 5899 5900 // ========================================================= 5901 // THUMBNAILS 5902 // ========================================================= 5903 5904 public void reportThumbnail(IBinder token, 5905 Bitmap thumbnail, CharSequence description) { 5906 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5907 final long origId = Binder.clearCallingIdentity(); 5908 sendPendingThumbnail(null, token, thumbnail, description, true); 5909 Binder.restoreCallingIdentity(origId); 5910 } 5911 5912 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5913 Bitmap thumbnail, CharSequence description, boolean always) { 5914 TaskRecord task = null; 5915 ArrayList receivers = null; 5916 5917 //System.out.println("Send pending thumbnail: " + r); 5918 5919 synchronized(this) { 5920 if (r == null) { 5921 r = mMainStack.isInStackLocked(token); 5922 if (r == null) { 5923 return; 5924 } 5925 } 5926 if (thumbnail == null && r.thumbHolder != null) { 5927 thumbnail = r.thumbHolder.lastThumbnail; 5928 description = r.thumbHolder.lastDescription; 5929 } 5930 if (thumbnail == null && !always) { 5931 // If there is no thumbnail, and this entry is not actually 5932 // going away, then abort for now and pick up the next 5933 // thumbnail we get. 5934 return; 5935 } 5936 task = r.task; 5937 5938 int N = mPendingThumbnails.size(); 5939 int i=0; 5940 while (i<N) { 5941 PendingThumbnailsRecord pr = 5942 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5943 //System.out.println("Looking in " + pr.pendingRecords); 5944 if (pr.pendingRecords.remove(r)) { 5945 if (receivers == null) { 5946 receivers = new ArrayList(); 5947 } 5948 receivers.add(pr); 5949 if (pr.pendingRecords.size() == 0) { 5950 pr.finished = true; 5951 mPendingThumbnails.remove(i); 5952 N--; 5953 continue; 5954 } 5955 } 5956 i++; 5957 } 5958 } 5959 5960 if (receivers != null) { 5961 final int N = receivers.size(); 5962 for (int i=0; i<N; i++) { 5963 try { 5964 PendingThumbnailsRecord pr = 5965 (PendingThumbnailsRecord)receivers.get(i); 5966 pr.receiver.newThumbnail( 5967 task != null ? task.taskId : -1, thumbnail, description); 5968 if (pr.finished) { 5969 pr.receiver.finished(); 5970 } 5971 } catch (Exception e) { 5972 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5973 } 5974 } 5975 } 5976 } 5977 5978 // ========================================================= 5979 // CONTENT PROVIDERS 5980 // ========================================================= 5981 5982 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5983 List<ProviderInfo> providers = null; 5984 try { 5985 providers = AppGlobals.getPackageManager(). 5986 queryContentProviders(app.processName, app.uid, 5987 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5988 } catch (RemoteException ex) { 5989 } 5990 if (DEBUG_MU) 5991 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 5992 int userId = app.userId; 5993 if (providers != null) { 5994 final int N = providers.size(); 5995 for (int i=0; i<N; i++) { 5996 ProviderInfo cpi = 5997 (ProviderInfo)providers.get(i); 5998 5999 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6000 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6001 if (cpr == null) { 6002 cpr = new ContentProviderRecord(this, cpi, app.info, comp); 6003 mProviderMap.putProviderByClass(comp, cpr); 6004 } 6005 if (DEBUG_MU) 6006 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6007 app.pubProviders.put(cpi.name, cpr); 6008 app.addPackage(cpi.applicationInfo.packageName); 6009 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6010 } 6011 } 6012 return providers; 6013 } 6014 6015 /** 6016 * Check if {@link ProcessRecord} has a possible chance at accessing the 6017 * given {@link ProviderInfo}. Final permission checking is always done 6018 * in {@link ContentProvider}. 6019 */ 6020 private final String checkContentProviderPermissionLocked( 6021 ProviderInfo cpi, ProcessRecord r) { 6022 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6023 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6024 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6025 cpi.applicationInfo.uid, cpi.exported) 6026 == PackageManager.PERMISSION_GRANTED) { 6027 return null; 6028 } 6029 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6030 cpi.applicationInfo.uid, cpi.exported) 6031 == PackageManager.PERMISSION_GRANTED) { 6032 return null; 6033 } 6034 6035 PathPermission[] pps = cpi.pathPermissions; 6036 if (pps != null) { 6037 int i = pps.length; 6038 while (i > 0) { 6039 i--; 6040 PathPermission pp = pps[i]; 6041 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6042 cpi.applicationInfo.uid, cpi.exported) 6043 == PackageManager.PERMISSION_GRANTED) { 6044 return null; 6045 } 6046 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6047 cpi.applicationInfo.uid, cpi.exported) 6048 == PackageManager.PERMISSION_GRANTED) { 6049 return null; 6050 } 6051 } 6052 } 6053 6054 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6055 if (perms != null) { 6056 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6057 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6058 return null; 6059 } 6060 } 6061 } 6062 6063 String msg; 6064 if (!cpi.exported) { 6065 msg = "Permission Denial: opening provider " + cpi.name 6066 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6067 + ", uid=" + callingUid + ") that is not exported from uid " 6068 + cpi.applicationInfo.uid; 6069 } else { 6070 msg = "Permission Denial: opening provider " + cpi.name 6071 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6072 + ", uid=" + callingUid + ") requires " 6073 + cpi.readPermission + " or " + cpi.writePermission; 6074 } 6075 Slog.w(TAG, msg); 6076 return msg; 6077 } 6078 6079 boolean incProviderCount(ProcessRecord r, final ContentProviderRecord cpr, 6080 IBinder externalProcessToken) { 6081 if (r != null) { 6082 Integer cnt = r.conProviders.get(cpr); 6083 if (DEBUG_PROVIDER) Slog.v(TAG, 6084 "Adding provider requested by " 6085 + r.processName + " from process " 6086 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6087 + " cnt=" + (cnt == null ? 1 : cnt)); 6088 if (cnt == null) { 6089 cpr.clients.add(r); 6090 r.conProviders.put(cpr, new Integer(1)); 6091 return true; 6092 } else { 6093 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 6094 } 6095 } else { 6096 cpr.addExternalProcessHandleLocked(externalProcessToken); 6097 } 6098 return false; 6099 } 6100 6101 boolean decProviderCount(ProcessRecord r, final ContentProviderRecord cpr, 6102 IBinder externalProcessToken) { 6103 if (r != null) { 6104 Integer cnt = r.conProviders.get(cpr); 6105 if (DEBUG_PROVIDER) Slog.v(TAG, 6106 "Removing provider requested by " 6107 + r.processName + " from process " 6108 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6109 + " cnt=" + cnt); 6110 if (cnt == null || cnt.intValue() <= 1) { 6111 cpr.clients.remove(r); 6112 r.conProviders.remove(cpr); 6113 return true; 6114 } else { 6115 r.conProviders.put(cpr, new Integer(cnt.intValue()-1)); 6116 } 6117 } else { 6118 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6119 } 6120 return false; 6121 } 6122 6123 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6124 String name, IBinder token) { 6125 ContentProviderRecord cpr; 6126 ProviderInfo cpi = null; 6127 6128 synchronized(this) { 6129 ProcessRecord r = null; 6130 if (caller != null) { 6131 r = getRecordForAppLocked(caller); 6132 if (r == null) { 6133 throw new SecurityException( 6134 "Unable to find app for caller " + caller 6135 + " (pid=" + Binder.getCallingPid() 6136 + ") when getting content provider " + name); 6137 } 6138 } 6139 6140 // First check if this content provider has been published... 6141 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6142 cpr = mProviderMap.getProviderByName(name, userId); 6143 boolean providerRunning = cpr != null; 6144 if (providerRunning) { 6145 cpi = cpr.info; 6146 String msg; 6147 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6148 throw new SecurityException(msg); 6149 } 6150 6151 if (r != null && cpr.canRunHere(r)) { 6152 // This provider has been published or is in the process 6153 // of being published... but it is also allowed to run 6154 // in the caller's process, so don't make a connection 6155 // and just let the caller instantiate its own instance. 6156 if (cpr.provider != null) { 6157 // don't give caller the provider object, it needs 6158 // to make its own. 6159 cpr = new ContentProviderRecord(cpr); 6160 } 6161 return cpr; 6162 } 6163 6164 final long origId = Binder.clearCallingIdentity(); 6165 6166 // In this case the provider instance already exists, so we can 6167 // return it right away. 6168 final boolean countChanged = incProviderCount(r, cpr, token); 6169 if (countChanged) { 6170 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6171 // If this is a perceptible app accessing the provider, 6172 // make sure to count it as being accessed and thus 6173 // back up on the LRU list. This is good because 6174 // content providers are often expensive to start. 6175 updateLruProcessLocked(cpr.proc, false, true); 6176 } 6177 } 6178 6179 if (cpr.proc != null) { 6180 if (false) { 6181 if (cpr.name.flattenToShortString().equals( 6182 "com.android.providers.calendar/.CalendarProvider2")) { 6183 Slog.v(TAG, "****************** KILLING " 6184 + cpr.name.flattenToShortString()); 6185 Process.killProcess(cpr.proc.pid); 6186 } 6187 } 6188 boolean success = updateOomAdjLocked(cpr.proc); 6189 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6190 // NOTE: there is still a race here where a signal could be 6191 // pending on the process even though we managed to update its 6192 // adj level. Not sure what to do about this, but at least 6193 // the race is now smaller. 6194 if (!success) { 6195 // Uh oh... it looks like the provider's process 6196 // has been killed on us. We need to wait for a new 6197 // process to be started, and make sure its death 6198 // doesn't kill our process. 6199 Slog.i(TAG, 6200 "Existing provider " + cpr.name.flattenToShortString() 6201 + " is crashing; detaching " + r); 6202 boolean lastRef = decProviderCount(r, cpr, token); 6203 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6204 if (!lastRef) { 6205 // This wasn't the last ref our process had on 6206 // the provider... we have now been killed, bail. 6207 return null; 6208 } 6209 providerRunning = false; 6210 } 6211 } 6212 6213 Binder.restoreCallingIdentity(origId); 6214 } 6215 6216 if (!providerRunning) { 6217 try { 6218 cpi = AppGlobals.getPackageManager(). 6219 resolveContentProvider(name, 6220 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6221 } catch (RemoteException ex) { 6222 } 6223 if (cpi == null) { 6224 return null; 6225 } 6226 if (isSingleton(cpi.processName, cpi.applicationInfo)) { 6227 userId = 0; 6228 } 6229 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6230 6231 String msg; 6232 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6233 throw new SecurityException(msg); 6234 } 6235 6236 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6237 && !cpi.processName.equals("system")) { 6238 // If this content provider does not run in the system 6239 // process, and the system is not yet ready to run other 6240 // processes, then fail fast instead of hanging. 6241 throw new IllegalArgumentException( 6242 "Attempt to launch content provider before system ready"); 6243 } 6244 6245 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6246 cpr = mProviderMap.getProviderByClass(comp, userId); 6247 final boolean firstClass = cpr == null; 6248 if (firstClass) { 6249 try { 6250 ApplicationInfo ai = 6251 AppGlobals.getPackageManager(). 6252 getApplicationInfo( 6253 cpi.applicationInfo.packageName, 6254 STOCK_PM_FLAGS, userId); 6255 if (ai == null) { 6256 Slog.w(TAG, "No package info for content provider " 6257 + cpi.name); 6258 return null; 6259 } 6260 ai = getAppInfoForUser(ai, userId); 6261 cpr = new ContentProviderRecord(this, cpi, ai, comp); 6262 } catch (RemoteException ex) { 6263 // pm is in same process, this will never happen. 6264 } 6265 } 6266 6267 if (r != null && cpr.canRunHere(r)) { 6268 // If this is a multiprocess provider, then just return its 6269 // info and allow the caller to instantiate it. Only do 6270 // this if the provider is the same user as the caller's 6271 // process, or can run as root (so can be in any process). 6272 return cpr; 6273 } 6274 6275 if (DEBUG_PROVIDER) { 6276 RuntimeException e = new RuntimeException("here"); 6277 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6278 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6279 } 6280 6281 // This is single process, and our app is now connecting to it. 6282 // See if we are already in the process of launching this 6283 // provider. 6284 final int N = mLaunchingProviders.size(); 6285 int i; 6286 for (i=0; i<N; i++) { 6287 if (mLaunchingProviders.get(i) == cpr) { 6288 break; 6289 } 6290 } 6291 6292 // If the provider is not already being launched, then get it 6293 // started. 6294 if (i >= N) { 6295 final long origId = Binder.clearCallingIdentity(); 6296 6297 try { 6298 // Content provider is now in use, its package can't be stopped. 6299 try { 6300 AppGlobals.getPackageManager().setPackageStoppedState( 6301 cpr.appInfo.packageName, false, userId); 6302 } catch (RemoteException e) { 6303 } catch (IllegalArgumentException e) { 6304 Slog.w(TAG, "Failed trying to unstop package " 6305 + cpr.appInfo.packageName + ": " + e); 6306 } 6307 6308 ProcessRecord proc = startProcessLocked(cpi.processName, 6309 cpr.appInfo, false, 0, "content provider", 6310 new ComponentName(cpi.applicationInfo.packageName, 6311 cpi.name), false, false); 6312 if (proc == null) { 6313 Slog.w(TAG, "Unable to launch app " 6314 + cpi.applicationInfo.packageName + "/" 6315 + cpi.applicationInfo.uid + " for provider " 6316 + name + ": process is bad"); 6317 return null; 6318 } 6319 cpr.launchingApp = proc; 6320 mLaunchingProviders.add(cpr); 6321 } finally { 6322 Binder.restoreCallingIdentity(origId); 6323 } 6324 } 6325 6326 // Make sure the provider is published (the same provider class 6327 // may be published under multiple names). 6328 if (firstClass) { 6329 mProviderMap.putProviderByClass(comp, cpr); 6330 } 6331 6332 mProviderMap.putProviderByName(name, cpr); 6333 incProviderCount(r, cpr, token); 6334 } 6335 } 6336 6337 // Wait for the provider to be published... 6338 synchronized (cpr) { 6339 while (cpr.provider == null) { 6340 if (cpr.launchingApp == null) { 6341 Slog.w(TAG, "Unable to launch app " 6342 + cpi.applicationInfo.packageName + "/" 6343 + cpi.applicationInfo.uid + " for provider " 6344 + name + ": launching app became null"); 6345 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6346 cpi.applicationInfo.packageName, 6347 cpi.applicationInfo.uid, name); 6348 return null; 6349 } 6350 try { 6351 if (DEBUG_MU) { 6352 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6353 + cpr.launchingApp); 6354 } 6355 cpr.wait(); 6356 } catch (InterruptedException ex) { 6357 } 6358 } 6359 } 6360 return cpr; 6361 } 6362 6363 public final ContentProviderHolder getContentProvider( 6364 IApplicationThread caller, String name) { 6365 enforceNotIsolatedCaller("getContentProvider"); 6366 if (caller == null) { 6367 String msg = "null IApplicationThread when getting content provider " 6368 + name; 6369 Slog.w(TAG, msg); 6370 throw new SecurityException(msg); 6371 } 6372 6373 return getContentProviderImpl(caller, name, null); 6374 } 6375 6376 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6377 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6378 "Do not have permission in call getContentProviderExternal()"); 6379 return getContentProviderExternalUnchecked(name, token); 6380 } 6381 6382 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6383 return getContentProviderImpl(null, name, token); 6384 } 6385 6386 /** 6387 * Drop a content provider from a ProcessRecord's bookkeeping 6388 * @param cpr 6389 */ 6390 public void removeContentProvider(IApplicationThread caller, String name) { 6391 enforceNotIsolatedCaller("removeContentProvider"); 6392 synchronized (this) { 6393 int userId = UserId.getUserId(Binder.getCallingUid()); 6394 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6395 if(cpr == null) { 6396 // remove from mProvidersByClass 6397 if (DEBUG_PROVIDER) Slog.v(TAG, name + 6398 " provider not found in providers list"); 6399 return; 6400 } 6401 final ProcessRecord r = getRecordForAppLocked(caller); 6402 if (r == null) { 6403 throw new SecurityException( 6404 "Unable to find app for caller " + caller + 6405 " when removing content provider " + name); 6406 } 6407 //update content provider record entry info 6408 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6409 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6410 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by " 6411 + r.info.processName + " from process " 6412 + localCpr.appInfo.processName); 6413 if (localCpr.launchingApp == r) { 6414 //should not happen. taken care of as a local provider 6415 Slog.w(TAG, "removeContentProvider called on local provider: " 6416 + cpr.info.name + " in process " + r.processName); 6417 return; 6418 } else { 6419 if (decProviderCount(r, localCpr, null)) { 6420 updateOomAdjLocked(); 6421 } 6422 } 6423 } 6424 } 6425 6426 public void removeContentProviderExternal(String name, IBinder token) { 6427 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6428 "Do not have permission in call removeContentProviderExternal()"); 6429 removeContentProviderExternalUnchecked(name, token); 6430 } 6431 6432 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6433 synchronized (this) { 6434 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6435 Binder.getOrigCallingUser()); 6436 if(cpr == null) { 6437 //remove from mProvidersByClass 6438 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6439 return; 6440 } 6441 6442 //update content provider record entry info 6443 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6444 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6445 Binder.getOrigCallingUser()); 6446 if (localCpr.hasExternalProcessHandles()) { 6447 if (localCpr.removeExternalProcessHandleLocked(token)) { 6448 updateOomAdjLocked(); 6449 } else { 6450 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6451 + " with no external reference for token: " 6452 + token + "."); 6453 } 6454 } else { 6455 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6456 + " with no external references."); 6457 } 6458 } 6459 } 6460 6461 public final void publishContentProviders(IApplicationThread caller, 6462 List<ContentProviderHolder> providers) { 6463 if (providers == null) { 6464 return; 6465 } 6466 6467 enforceNotIsolatedCaller("publishContentProviders"); 6468 synchronized(this) { 6469 final ProcessRecord r = getRecordForAppLocked(caller); 6470 if (DEBUG_MU) 6471 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6472 if (r == null) { 6473 throw new SecurityException( 6474 "Unable to find app for caller " + caller 6475 + " (pid=" + Binder.getCallingPid() 6476 + ") when publishing content providers"); 6477 } 6478 6479 final long origId = Binder.clearCallingIdentity(); 6480 6481 final int N = providers.size(); 6482 for (int i=0; i<N; i++) { 6483 ContentProviderHolder src = providers.get(i); 6484 if (src == null || src.info == null || src.provider == null) { 6485 continue; 6486 } 6487 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6488 if (DEBUG_MU) 6489 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6490 if (dst != null) { 6491 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6492 mProviderMap.putProviderByClass(comp, dst); 6493 String names[] = dst.info.authority.split(";"); 6494 for (int j = 0; j < names.length; j++) { 6495 mProviderMap.putProviderByName(names[j], dst); 6496 } 6497 6498 int NL = mLaunchingProviders.size(); 6499 int j; 6500 for (j=0; j<NL; j++) { 6501 if (mLaunchingProviders.get(j) == dst) { 6502 mLaunchingProviders.remove(j); 6503 j--; 6504 NL--; 6505 } 6506 } 6507 synchronized (dst) { 6508 dst.provider = src.provider; 6509 dst.proc = r; 6510 dst.notifyAll(); 6511 } 6512 updateOomAdjLocked(r); 6513 } 6514 } 6515 6516 Binder.restoreCallingIdentity(origId); 6517 } 6518 } 6519 6520 public static final void installSystemProviders() { 6521 List<ProviderInfo> providers; 6522 synchronized (mSelf) { 6523 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6524 providers = mSelf.generateApplicationProvidersLocked(app); 6525 if (providers != null) { 6526 for (int i=providers.size()-1; i>=0; i--) { 6527 ProviderInfo pi = (ProviderInfo)providers.get(i); 6528 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6529 Slog.w(TAG, "Not installing system proc provider " + pi.name 6530 + ": not system .apk"); 6531 providers.remove(i); 6532 } 6533 } 6534 } 6535 } 6536 if (providers != null) { 6537 mSystemThread.installSystemProviders(providers); 6538 } 6539 6540 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6541 6542 mSelf.mUsageStatsService.monitorPackages(); 6543 } 6544 6545 /** 6546 * Allows app to retrieve the MIME type of a URI without having permission 6547 * to access its content provider. 6548 * 6549 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6550 * 6551 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6552 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6553 */ 6554 public String getProviderMimeType(Uri uri) { 6555 enforceNotIsolatedCaller("getProviderMimeType"); 6556 final String name = uri.getAuthority(); 6557 final long ident = Binder.clearCallingIdentity(); 6558 ContentProviderHolder holder = null; 6559 6560 try { 6561 holder = getContentProviderExternalUnchecked(name, null); 6562 if (holder != null) { 6563 return holder.provider.getType(uri); 6564 } 6565 } catch (RemoteException e) { 6566 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6567 return null; 6568 } finally { 6569 if (holder != null) { 6570 removeContentProviderExternalUnchecked(name, null); 6571 } 6572 Binder.restoreCallingIdentity(ident); 6573 } 6574 6575 return null; 6576 } 6577 6578 // ========================================================= 6579 // GLOBAL MANAGEMENT 6580 // ========================================================= 6581 6582 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6583 ApplicationInfo info, String customProcess, boolean isolated) { 6584 String proc = customProcess != null ? customProcess : info.processName; 6585 BatteryStatsImpl.Uid.Proc ps = null; 6586 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6587 int uid = info.uid; 6588 if (isolated) { 6589 int userId = UserId.getUserId(uid); 6590 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6591 uid = 0; 6592 while (true) { 6593 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6594 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6595 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6596 } 6597 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6598 mNextIsolatedProcessUid++; 6599 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6600 // No process for this uid, use it. 6601 break; 6602 } 6603 stepsLeft--; 6604 if (stepsLeft <= 0) { 6605 return null; 6606 } 6607 } 6608 } 6609 synchronized (stats) { 6610 ps = stats.getProcessStatsLocked(info.uid, proc); 6611 } 6612 return new ProcessRecord(ps, thread, info, proc, uid); 6613 } 6614 6615 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6616 ProcessRecord app; 6617 if (!isolated) { 6618 app = getProcessRecordLocked(info.processName, info.uid); 6619 } else { 6620 app = null; 6621 } 6622 6623 if (app == null) { 6624 app = newProcessRecordLocked(null, info, null, isolated); 6625 mProcessNames.put(info.processName, app.uid, app); 6626 if (isolated) { 6627 mIsolatedProcesses.put(app.uid, app); 6628 } 6629 updateLruProcessLocked(app, true, true); 6630 } 6631 6632 // This package really, really can not be stopped. 6633 try { 6634 AppGlobals.getPackageManager().setPackageStoppedState( 6635 info.packageName, false, UserId.getUserId(app.uid)); 6636 } catch (RemoteException e) { 6637 } catch (IllegalArgumentException e) { 6638 Slog.w(TAG, "Failed trying to unstop package " 6639 + info.packageName + ": " + e); 6640 } 6641 6642 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6643 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6644 app.persistent = true; 6645 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6646 } 6647 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6648 mPersistentStartingProcesses.add(app); 6649 startProcessLocked(app, "added application", app.processName); 6650 } 6651 6652 return app; 6653 } 6654 6655 public void unhandledBack() { 6656 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6657 "unhandledBack()"); 6658 6659 synchronized(this) { 6660 int count = mMainStack.mHistory.size(); 6661 if (DEBUG_SWITCH) Slog.d( 6662 TAG, "Performing unhandledBack(): stack size = " + count); 6663 if (count > 1) { 6664 final long origId = Binder.clearCallingIdentity(); 6665 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6666 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6667 Binder.restoreCallingIdentity(origId); 6668 } 6669 } 6670 } 6671 6672 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6673 enforceNotIsolatedCaller("openContentUri"); 6674 String name = uri.getAuthority(); 6675 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6676 ParcelFileDescriptor pfd = null; 6677 if (cph != null) { 6678 // We record the binder invoker's uid in thread-local storage before 6679 // going to the content provider to open the file. Later, in the code 6680 // that handles all permissions checks, we look for this uid and use 6681 // that rather than the Activity Manager's own uid. The effect is that 6682 // we do the check against the caller's permissions even though it looks 6683 // to the content provider like the Activity Manager itself is making 6684 // the request. 6685 sCallerIdentity.set(new Identity( 6686 Binder.getCallingPid(), Binder.getCallingUid())); 6687 try { 6688 pfd = cph.provider.openFile(uri, "r"); 6689 } catch (FileNotFoundException e) { 6690 // do nothing; pfd will be returned null 6691 } finally { 6692 // Ensure that whatever happens, we clean up the identity state 6693 sCallerIdentity.remove(); 6694 } 6695 6696 // We've got the fd now, so we're done with the provider. 6697 removeContentProviderExternalUnchecked(name, null); 6698 } else { 6699 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6700 } 6701 return pfd; 6702 } 6703 6704 // Actually is sleeping or shutting down or whatever else in the future 6705 // is an inactive state. 6706 public boolean isSleeping() { 6707 return mSleeping || mShuttingDown; 6708 } 6709 6710 public void goingToSleep() { 6711 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6712 != PackageManager.PERMISSION_GRANTED) { 6713 throw new SecurityException("Requires permission " 6714 + android.Manifest.permission.DEVICE_POWER); 6715 } 6716 6717 synchronized(this) { 6718 mWentToSleep = true; 6719 updateEventDispatchingLocked(); 6720 6721 if (!mSleeping) { 6722 mSleeping = true; 6723 mMainStack.stopIfSleepingLocked(); 6724 6725 // Initialize the wake times of all processes. 6726 checkExcessivePowerUsageLocked(false); 6727 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6728 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6729 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6730 } 6731 } 6732 } 6733 6734 public boolean shutdown(int timeout) { 6735 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6736 != PackageManager.PERMISSION_GRANTED) { 6737 throw new SecurityException("Requires permission " 6738 + android.Manifest.permission.SHUTDOWN); 6739 } 6740 6741 boolean timedout = false; 6742 6743 synchronized(this) { 6744 mShuttingDown = true; 6745 updateEventDispatchingLocked(); 6746 6747 if (mMainStack.mResumedActivity != null) { 6748 mMainStack.stopIfSleepingLocked(); 6749 final long endTime = System.currentTimeMillis() + timeout; 6750 while (mMainStack.mResumedActivity != null 6751 || mMainStack.mPausingActivity != null) { 6752 long delay = endTime - System.currentTimeMillis(); 6753 if (delay <= 0) { 6754 Slog.w(TAG, "Activity manager shutdown timed out"); 6755 timedout = true; 6756 break; 6757 } 6758 try { 6759 this.wait(); 6760 } catch (InterruptedException e) { 6761 } 6762 } 6763 } 6764 } 6765 6766 mUsageStatsService.shutdown(); 6767 mBatteryStatsService.shutdown(); 6768 6769 return timedout; 6770 } 6771 6772 public final void activitySlept(IBinder token) { 6773 if (localLOGV) Slog.v( 6774 TAG, "Activity slept: token=" + token); 6775 6776 ActivityRecord r = null; 6777 6778 final long origId = Binder.clearCallingIdentity(); 6779 6780 synchronized (this) { 6781 r = mMainStack.isInStackLocked(token); 6782 if (r != null) { 6783 mMainStack.activitySleptLocked(r); 6784 } 6785 } 6786 6787 Binder.restoreCallingIdentity(origId); 6788 } 6789 6790 private void comeOutOfSleepIfNeededLocked() { 6791 if (!mWentToSleep && !mLockScreenShown) { 6792 if (mSleeping) { 6793 mSleeping = false; 6794 mMainStack.awakeFromSleepingLocked(); 6795 mMainStack.resumeTopActivityLocked(null); 6796 } 6797 } 6798 } 6799 6800 public void wakingUp() { 6801 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6802 != PackageManager.PERMISSION_GRANTED) { 6803 throw new SecurityException("Requires permission " 6804 + android.Manifest.permission.DEVICE_POWER); 6805 } 6806 6807 synchronized(this) { 6808 mWentToSleep = false; 6809 updateEventDispatchingLocked(); 6810 comeOutOfSleepIfNeededLocked(); 6811 } 6812 } 6813 6814 private void updateEventDispatchingLocked() { 6815 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6816 } 6817 6818 public void setLockScreenShown(boolean shown) { 6819 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6820 != PackageManager.PERMISSION_GRANTED) { 6821 throw new SecurityException("Requires permission " 6822 + android.Manifest.permission.DEVICE_POWER); 6823 } 6824 6825 synchronized(this) { 6826 mLockScreenShown = shown; 6827 comeOutOfSleepIfNeededLocked(); 6828 } 6829 } 6830 6831 public void stopAppSwitches() { 6832 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6833 != PackageManager.PERMISSION_GRANTED) { 6834 throw new SecurityException("Requires permission " 6835 + android.Manifest.permission.STOP_APP_SWITCHES); 6836 } 6837 6838 synchronized(this) { 6839 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6840 + APP_SWITCH_DELAY_TIME; 6841 mDidAppSwitch = false; 6842 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6843 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6844 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6845 } 6846 } 6847 6848 public void resumeAppSwitches() { 6849 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6850 != PackageManager.PERMISSION_GRANTED) { 6851 throw new SecurityException("Requires permission " 6852 + android.Manifest.permission.STOP_APP_SWITCHES); 6853 } 6854 6855 synchronized(this) { 6856 // Note that we don't execute any pending app switches... we will 6857 // let those wait until either the timeout, or the next start 6858 // activity request. 6859 mAppSwitchesAllowedTime = 0; 6860 } 6861 } 6862 6863 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6864 String name) { 6865 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6866 return true; 6867 } 6868 6869 final int perm = checkComponentPermission( 6870 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6871 callingUid, -1, true); 6872 if (perm == PackageManager.PERMISSION_GRANTED) { 6873 return true; 6874 } 6875 6876 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6877 return false; 6878 } 6879 6880 public void setDebugApp(String packageName, boolean waitForDebugger, 6881 boolean persistent) { 6882 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 6883 "setDebugApp()"); 6884 6885 // Note that this is not really thread safe if there are multiple 6886 // callers into it at the same time, but that's not a situation we 6887 // care about. 6888 if (persistent) { 6889 final ContentResolver resolver = mContext.getContentResolver(); 6890 Settings.System.putString( 6891 resolver, Settings.System.DEBUG_APP, 6892 packageName); 6893 Settings.System.putInt( 6894 resolver, Settings.System.WAIT_FOR_DEBUGGER, 6895 waitForDebugger ? 1 : 0); 6896 } 6897 6898 synchronized (this) { 6899 if (!persistent) { 6900 mOrigDebugApp = mDebugApp; 6901 mOrigWaitForDebugger = mWaitForDebugger; 6902 } 6903 mDebugApp = packageName; 6904 mWaitForDebugger = waitForDebugger; 6905 mDebugTransient = !persistent; 6906 if (packageName != null) { 6907 final long origId = Binder.clearCallingIdentity(); 6908 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 6909 Binder.restoreCallingIdentity(origId); 6910 } 6911 } 6912 } 6913 6914 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 6915 synchronized (this) { 6916 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6917 if (!isDebuggable) { 6918 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 6919 throw new SecurityException("Process not debuggable: " + app.packageName); 6920 } 6921 } 6922 6923 mOpenGlTraceApp = processName; 6924 } 6925 } 6926 6927 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 6928 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 6929 synchronized (this) { 6930 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6931 if (!isDebuggable) { 6932 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 6933 throw new SecurityException("Process not debuggable: " + app.packageName); 6934 } 6935 } 6936 mProfileApp = processName; 6937 mProfileFile = profileFile; 6938 if (mProfileFd != null) { 6939 try { 6940 mProfileFd.close(); 6941 } catch (IOException e) { 6942 } 6943 mProfileFd = null; 6944 } 6945 mProfileFd = profileFd; 6946 mProfileType = 0; 6947 mAutoStopProfiler = autoStopProfiler; 6948 } 6949 } 6950 6951 public void setAlwaysFinish(boolean enabled) { 6952 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 6953 "setAlwaysFinish()"); 6954 6955 Settings.System.putInt( 6956 mContext.getContentResolver(), 6957 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 6958 6959 synchronized (this) { 6960 mAlwaysFinishActivities = enabled; 6961 } 6962 } 6963 6964 public void setActivityController(IActivityController controller) { 6965 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 6966 "setActivityController()"); 6967 synchronized (this) { 6968 mController = controller; 6969 } 6970 } 6971 6972 public boolean isUserAMonkey() { 6973 // For now the fact that there is a controller implies 6974 // we have a monkey. 6975 synchronized (this) { 6976 return mController != null; 6977 } 6978 } 6979 6980 public void registerProcessObserver(IProcessObserver observer) { 6981 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 6982 "registerProcessObserver()"); 6983 synchronized (this) { 6984 mProcessObservers.register(observer); 6985 } 6986 } 6987 6988 public void unregisterProcessObserver(IProcessObserver observer) { 6989 synchronized (this) { 6990 mProcessObservers.unregister(observer); 6991 } 6992 } 6993 6994 public void setImmersive(IBinder token, boolean immersive) { 6995 synchronized(this) { 6996 ActivityRecord r = mMainStack.isInStackLocked(token); 6997 if (r == null) { 6998 throw new IllegalArgumentException(); 6999 } 7000 r.immersive = immersive; 7001 } 7002 } 7003 7004 public boolean isImmersive(IBinder token) { 7005 synchronized (this) { 7006 ActivityRecord r = mMainStack.isInStackLocked(token); 7007 if (r == null) { 7008 throw new IllegalArgumentException(); 7009 } 7010 return r.immersive; 7011 } 7012 } 7013 7014 public boolean isTopActivityImmersive() { 7015 enforceNotIsolatedCaller("startActivity"); 7016 synchronized (this) { 7017 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7018 return (r != null) ? r.immersive : false; 7019 } 7020 } 7021 7022 public final void enterSafeMode() { 7023 synchronized(this) { 7024 // It only makes sense to do this before the system is ready 7025 // and started launching other packages. 7026 if (!mSystemReady) { 7027 try { 7028 AppGlobals.getPackageManager().enterSafeMode(); 7029 } catch (RemoteException e) { 7030 } 7031 } 7032 } 7033 } 7034 7035 public final void showSafeModeOverlay() { 7036 View v = LayoutInflater.from(mContext).inflate( 7037 com.android.internal.R.layout.safe_mode, null); 7038 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7039 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7040 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7041 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7042 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 7043 lp.format = v.getBackground().getOpacity(); 7044 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7045 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7046 ((WindowManager)mContext.getSystemService( 7047 Context.WINDOW_SERVICE)).addView(v, lp); 7048 } 7049 7050 public void noteWakeupAlarm(IIntentSender sender) { 7051 if (!(sender instanceof PendingIntentRecord)) { 7052 return; 7053 } 7054 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7055 synchronized (stats) { 7056 if (mBatteryStatsService.isOnBattery()) { 7057 mBatteryStatsService.enforceCallingPermission(); 7058 PendingIntentRecord rec = (PendingIntentRecord)sender; 7059 int MY_UID = Binder.getCallingUid(); 7060 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7061 BatteryStatsImpl.Uid.Pkg pkg = 7062 stats.getPackageStatsLocked(uid, rec.key.packageName); 7063 pkg.incWakeupsLocked(); 7064 } 7065 } 7066 } 7067 7068 public boolean killPids(int[] pids, String pReason, boolean secure) { 7069 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7070 throw new SecurityException("killPids only available to the system"); 7071 } 7072 String reason = (pReason == null) ? "Unknown" : pReason; 7073 // XXX Note: don't acquire main activity lock here, because the window 7074 // manager calls in with its locks held. 7075 7076 boolean killed = false; 7077 synchronized (mPidsSelfLocked) { 7078 int[] types = new int[pids.length]; 7079 int worstType = 0; 7080 for (int i=0; i<pids.length; i++) { 7081 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7082 if (proc != null) { 7083 int type = proc.setAdj; 7084 types[i] = type; 7085 if (type > worstType) { 7086 worstType = type; 7087 } 7088 } 7089 } 7090 7091 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7092 // then constrain it so we will kill all hidden procs. 7093 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7094 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7095 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7096 } 7097 7098 // If this is not a secure call, don't let it kill processes that 7099 // are important. 7100 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7101 worstType = ProcessList.SERVICE_ADJ; 7102 } 7103 7104 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7105 for (int i=0; i<pids.length; i++) { 7106 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7107 if (proc == null) { 7108 continue; 7109 } 7110 int adj = proc.setAdj; 7111 if (adj >= worstType && !proc.killedBackground) { 7112 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7113 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7114 proc.processName, adj, reason); 7115 killed = true; 7116 proc.killedBackground = true; 7117 Process.killProcessQuiet(pids[i]); 7118 } 7119 } 7120 } 7121 return killed; 7122 } 7123 7124 @Override 7125 public boolean killProcessesBelowForeground(String reason) { 7126 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7127 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7128 } 7129 7130 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7131 } 7132 7133 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7134 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7135 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7136 } 7137 7138 boolean killed = false; 7139 synchronized (mPidsSelfLocked) { 7140 final int size = mPidsSelfLocked.size(); 7141 for (int i = 0; i < size; i++) { 7142 final int pid = mPidsSelfLocked.keyAt(i); 7143 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7144 if (proc == null) continue; 7145 7146 final int adj = proc.setAdj; 7147 if (adj > belowAdj && !proc.killedBackground) { 7148 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7149 EventLog.writeEvent( 7150 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7151 killed = true; 7152 proc.killedBackground = true; 7153 Process.killProcessQuiet(pid); 7154 } 7155 } 7156 } 7157 return killed; 7158 } 7159 7160 public final void startRunning(String pkg, String cls, String action, 7161 String data) { 7162 synchronized(this) { 7163 if (mStartRunning) { 7164 return; 7165 } 7166 mStartRunning = true; 7167 mTopComponent = pkg != null && cls != null 7168 ? new ComponentName(pkg, cls) : null; 7169 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7170 mTopData = data; 7171 if (!mSystemReady) { 7172 return; 7173 } 7174 } 7175 7176 systemReady(null); 7177 } 7178 7179 private void retrieveSettings() { 7180 final ContentResolver resolver = mContext.getContentResolver(); 7181 String debugApp = Settings.System.getString( 7182 resolver, Settings.System.DEBUG_APP); 7183 boolean waitForDebugger = Settings.System.getInt( 7184 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7185 boolean alwaysFinishActivities = Settings.System.getInt( 7186 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7187 7188 Configuration configuration = new Configuration(); 7189 Settings.System.getConfiguration(resolver, configuration); 7190 7191 synchronized (this) { 7192 mDebugApp = mOrigDebugApp = debugApp; 7193 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7194 mAlwaysFinishActivities = alwaysFinishActivities; 7195 // This happens before any activities are started, so we can 7196 // change mConfiguration in-place. 7197 updateConfigurationLocked(configuration, null, false, true); 7198 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7199 } 7200 } 7201 7202 public boolean testIsSystemReady() { 7203 // no need to synchronize(this) just to read & return the value 7204 return mSystemReady; 7205 } 7206 7207 private static File getCalledPreBootReceiversFile() { 7208 File dataDir = Environment.getDataDirectory(); 7209 File systemDir = new File(dataDir, "system"); 7210 File fname = new File(systemDir, "called_pre_boots.dat"); 7211 return fname; 7212 } 7213 7214 static final int LAST_DONE_VERSION = 10000; 7215 7216 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7217 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7218 File file = getCalledPreBootReceiversFile(); 7219 FileInputStream fis = null; 7220 try { 7221 fis = new FileInputStream(file); 7222 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7223 int fvers = dis.readInt(); 7224 if (fvers == LAST_DONE_VERSION) { 7225 String vers = dis.readUTF(); 7226 String codename = dis.readUTF(); 7227 String build = dis.readUTF(); 7228 if (android.os.Build.VERSION.RELEASE.equals(vers) 7229 && android.os.Build.VERSION.CODENAME.equals(codename) 7230 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7231 int num = dis.readInt(); 7232 while (num > 0) { 7233 num--; 7234 String pkg = dis.readUTF(); 7235 String cls = dis.readUTF(); 7236 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7237 } 7238 } 7239 } 7240 } catch (FileNotFoundException e) { 7241 } catch (IOException e) { 7242 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7243 } finally { 7244 if (fis != null) { 7245 try { 7246 fis.close(); 7247 } catch (IOException e) { 7248 } 7249 } 7250 } 7251 return lastDoneReceivers; 7252 } 7253 7254 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7255 File file = getCalledPreBootReceiversFile(); 7256 FileOutputStream fos = null; 7257 DataOutputStream dos = null; 7258 try { 7259 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7260 fos = new FileOutputStream(file); 7261 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7262 dos.writeInt(LAST_DONE_VERSION); 7263 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7264 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7265 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7266 dos.writeInt(list.size()); 7267 for (int i=0; i<list.size(); i++) { 7268 dos.writeUTF(list.get(i).getPackageName()); 7269 dos.writeUTF(list.get(i).getClassName()); 7270 } 7271 } catch (IOException e) { 7272 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7273 file.delete(); 7274 } finally { 7275 FileUtils.sync(fos); 7276 if (dos != null) { 7277 try { 7278 dos.close(); 7279 } catch (IOException e) { 7280 // TODO Auto-generated catch block 7281 e.printStackTrace(); 7282 } 7283 } 7284 } 7285 } 7286 7287 public void systemReady(final Runnable goingCallback) { 7288 synchronized(this) { 7289 if (mSystemReady) { 7290 if (goingCallback != null) goingCallback.run(); 7291 return; 7292 } 7293 7294 // Check to see if there are any update receivers to run. 7295 if (!mDidUpdate) { 7296 if (mWaitingUpdate) { 7297 return; 7298 } 7299 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7300 List<ResolveInfo> ris = null; 7301 try { 7302 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7303 intent, null, 0, 0); 7304 } catch (RemoteException e) { 7305 } 7306 if (ris != null) { 7307 for (int i=ris.size()-1; i>=0; i--) { 7308 if ((ris.get(i).activityInfo.applicationInfo.flags 7309 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7310 ris.remove(i); 7311 } 7312 } 7313 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7314 7315 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7316 7317 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7318 for (int i=0; i<ris.size(); i++) { 7319 ActivityInfo ai = ris.get(i).activityInfo; 7320 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7321 if (lastDoneReceivers.contains(comp)) { 7322 ris.remove(i); 7323 i--; 7324 } 7325 } 7326 7327 for (int i=0; i<ris.size(); i++) { 7328 ActivityInfo ai = ris.get(i).activityInfo; 7329 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7330 doneReceivers.add(comp); 7331 intent.setComponent(comp); 7332 IIntentReceiver finisher = null; 7333 if (i == ris.size()-1) { 7334 finisher = new IIntentReceiver.Stub() { 7335 public void performReceive(Intent intent, int resultCode, 7336 String data, Bundle extras, boolean ordered, 7337 boolean sticky) { 7338 // The raw IIntentReceiver interface is called 7339 // with the AM lock held, so redispatch to 7340 // execute our code without the lock. 7341 mHandler.post(new Runnable() { 7342 public void run() { 7343 synchronized (ActivityManagerService.this) { 7344 mDidUpdate = true; 7345 } 7346 writeLastDonePreBootReceivers(doneReceivers); 7347 showBootMessage(mContext.getText( 7348 R.string.android_upgrading_complete), 7349 false); 7350 systemReady(goingCallback); 7351 } 7352 }); 7353 } 7354 }; 7355 } 7356 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7357 /* TODO: Send this to all users */ 7358 broadcastIntentLocked(null, null, intent, null, finisher, 7359 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7360 0 /* UserId zero */); 7361 if (finisher != null) { 7362 mWaitingUpdate = true; 7363 } 7364 } 7365 } 7366 if (mWaitingUpdate) { 7367 return; 7368 } 7369 mDidUpdate = true; 7370 } 7371 7372 mSystemReady = true; 7373 if (!mStartRunning) { 7374 return; 7375 } 7376 } 7377 7378 ArrayList<ProcessRecord> procsToKill = null; 7379 synchronized(mPidsSelfLocked) { 7380 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7381 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7382 if (!isAllowedWhileBooting(proc.info)){ 7383 if (procsToKill == null) { 7384 procsToKill = new ArrayList<ProcessRecord>(); 7385 } 7386 procsToKill.add(proc); 7387 } 7388 } 7389 } 7390 7391 synchronized(this) { 7392 if (procsToKill != null) { 7393 for (int i=procsToKill.size()-1; i>=0; i--) { 7394 ProcessRecord proc = procsToKill.get(i); 7395 Slog.i(TAG, "Removing system update proc: " + proc); 7396 removeProcessLocked(proc, true, false, "system update done"); 7397 } 7398 } 7399 7400 // Now that we have cleaned up any update processes, we 7401 // are ready to start launching real processes and know that 7402 // we won't trample on them any more. 7403 mProcessesReady = true; 7404 } 7405 7406 Slog.i(TAG, "System now ready"); 7407 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7408 SystemClock.uptimeMillis()); 7409 7410 synchronized(this) { 7411 // Make sure we have no pre-ready processes sitting around. 7412 7413 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7414 ResolveInfo ri = mContext.getPackageManager() 7415 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7416 STOCK_PM_FLAGS); 7417 CharSequence errorMsg = null; 7418 if (ri != null) { 7419 ActivityInfo ai = ri.activityInfo; 7420 ApplicationInfo app = ai.applicationInfo; 7421 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7422 mTopAction = Intent.ACTION_FACTORY_TEST; 7423 mTopData = null; 7424 mTopComponent = new ComponentName(app.packageName, 7425 ai.name); 7426 } else { 7427 errorMsg = mContext.getResources().getText( 7428 com.android.internal.R.string.factorytest_not_system); 7429 } 7430 } else { 7431 errorMsg = mContext.getResources().getText( 7432 com.android.internal.R.string.factorytest_no_action); 7433 } 7434 if (errorMsg != null) { 7435 mTopAction = null; 7436 mTopData = null; 7437 mTopComponent = null; 7438 Message msg = Message.obtain(); 7439 msg.what = SHOW_FACTORY_ERROR_MSG; 7440 msg.getData().putCharSequence("msg", errorMsg); 7441 mHandler.sendMessage(msg); 7442 } 7443 } 7444 } 7445 7446 retrieveSettings(); 7447 7448 if (goingCallback != null) goingCallback.run(); 7449 7450 synchronized (this) { 7451 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7452 try { 7453 List apps = AppGlobals.getPackageManager(). 7454 getPersistentApplications(STOCK_PM_FLAGS); 7455 if (apps != null) { 7456 int N = apps.size(); 7457 int i; 7458 for (i=0; i<N; i++) { 7459 ApplicationInfo info 7460 = (ApplicationInfo)apps.get(i); 7461 if (info != null && 7462 !info.packageName.equals("android")) { 7463 addAppLocked(info, false); 7464 } 7465 } 7466 } 7467 } catch (RemoteException ex) { 7468 // pm is in same process, this will never happen. 7469 } 7470 } 7471 7472 // Start up initial activity. 7473 mBooting = true; 7474 7475 try { 7476 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7477 Message msg = Message.obtain(); 7478 msg.what = SHOW_UID_ERROR_MSG; 7479 mHandler.sendMessage(msg); 7480 } 7481 } catch (RemoteException e) { 7482 } 7483 7484 mMainStack.resumeTopActivityLocked(null); 7485 } 7486 } 7487 7488 private boolean makeAppCrashingLocked(ProcessRecord app, 7489 String shortMsg, String longMsg, String stackTrace) { 7490 app.crashing = true; 7491 app.crashingReport = generateProcessError(app, 7492 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7493 startAppProblemLocked(app); 7494 app.stopFreezingAllLocked(); 7495 return handleAppCrashLocked(app); 7496 } 7497 7498 private void makeAppNotRespondingLocked(ProcessRecord app, 7499 String activity, String shortMsg, String longMsg) { 7500 app.notResponding = true; 7501 app.notRespondingReport = generateProcessError(app, 7502 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7503 activity, shortMsg, longMsg, null); 7504 startAppProblemLocked(app); 7505 app.stopFreezingAllLocked(); 7506 } 7507 7508 /** 7509 * Generate a process error record, suitable for attachment to a ProcessRecord. 7510 * 7511 * @param app The ProcessRecord in which the error occurred. 7512 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7513 * ActivityManager.AppErrorStateInfo 7514 * @param activity The activity associated with the crash, if known. 7515 * @param shortMsg Short message describing the crash. 7516 * @param longMsg Long message describing the crash. 7517 * @param stackTrace Full crash stack trace, may be null. 7518 * 7519 * @return Returns a fully-formed AppErrorStateInfo record. 7520 */ 7521 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7522 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7523 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7524 7525 report.condition = condition; 7526 report.processName = app.processName; 7527 report.pid = app.pid; 7528 report.uid = app.info.uid; 7529 report.tag = activity; 7530 report.shortMsg = shortMsg; 7531 report.longMsg = longMsg; 7532 report.stackTrace = stackTrace; 7533 7534 return report; 7535 } 7536 7537 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7538 synchronized (this) { 7539 app.crashing = false; 7540 app.crashingReport = null; 7541 app.notResponding = false; 7542 app.notRespondingReport = null; 7543 if (app.anrDialog == fromDialog) { 7544 app.anrDialog = null; 7545 } 7546 if (app.waitDialog == fromDialog) { 7547 app.waitDialog = null; 7548 } 7549 if (app.pid > 0 && app.pid != MY_PID) { 7550 handleAppCrashLocked(app); 7551 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7552 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7553 app.processName, app.setAdj, "user's request after error"); 7554 Process.killProcessQuiet(app.pid); 7555 } 7556 } 7557 } 7558 7559 private boolean handleAppCrashLocked(ProcessRecord app) { 7560 if (mHeadless) { 7561 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7562 return false; 7563 } 7564 long now = SystemClock.uptimeMillis(); 7565 7566 Long crashTime; 7567 if (!app.isolated) { 7568 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7569 } else { 7570 crashTime = null; 7571 } 7572 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7573 // This process loses! 7574 Slog.w(TAG, "Process " + app.info.processName 7575 + " has crashed too many times: killing!"); 7576 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7577 app.info.processName, app.uid); 7578 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7579 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7580 if (r.app == app) { 7581 Slog.w(TAG, " Force finishing activity " 7582 + r.intent.getComponent().flattenToShortString()); 7583 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7584 } 7585 } 7586 if (!app.persistent) { 7587 // We don't want to start this process again until the user 7588 // explicitly does so... but for persistent process, we really 7589 // need to keep it running. If a persistent process is actually 7590 // repeatedly crashing, then badness for everyone. 7591 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7592 app.info.processName); 7593 if (!app.isolated) { 7594 // XXX We don't have a way to mark isolated processes 7595 // as bad, since they don't have a peristent identity. 7596 mBadProcesses.put(app.info.processName, app.uid, now); 7597 mProcessCrashTimes.remove(app.info.processName, app.uid); 7598 } 7599 app.bad = true; 7600 app.removed = true; 7601 // Don't let services in this process be restarted and potentially 7602 // annoy the user repeatedly. Unless it is persistent, since those 7603 // processes run critical code. 7604 removeProcessLocked(app, false, false, "crash"); 7605 mMainStack.resumeTopActivityLocked(null); 7606 return false; 7607 } 7608 mMainStack.resumeTopActivityLocked(null); 7609 } else { 7610 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7611 if (r != null && r.app == app) { 7612 // If the top running activity is from this crashing 7613 // process, then terminate it to avoid getting in a loop. 7614 Slog.w(TAG, " Force finishing activity " 7615 + r.intent.getComponent().flattenToShortString()); 7616 int index = mMainStack.indexOfActivityLocked(r); 7617 r.stack.finishActivityLocked(r, index, 7618 Activity.RESULT_CANCELED, null, "crashed"); 7619 // Also terminate any activities below it that aren't yet 7620 // stopped, to avoid a situation where one will get 7621 // re-start our crashing activity once it gets resumed again. 7622 index--; 7623 if (index >= 0) { 7624 r = (ActivityRecord)mMainStack.mHistory.get(index); 7625 if (r.state == ActivityState.RESUMED 7626 || r.state == ActivityState.PAUSING 7627 || r.state == ActivityState.PAUSED) { 7628 if (!r.isHomeActivity || mHomeProcess != r.app) { 7629 Slog.w(TAG, " Force finishing activity " 7630 + r.intent.getComponent().flattenToShortString()); 7631 r.stack.finishActivityLocked(r, index, 7632 Activity.RESULT_CANCELED, null, "crashed"); 7633 } 7634 } 7635 } 7636 } 7637 } 7638 7639 // Bump up the crash count of any services currently running in the proc. 7640 if (app.services.size() != 0) { 7641 // Any services running in the application need to be placed 7642 // back in the pending list. 7643 Iterator<ServiceRecord> it = app.services.iterator(); 7644 while (it.hasNext()) { 7645 ServiceRecord sr = it.next(); 7646 sr.crashCount++; 7647 } 7648 } 7649 7650 // If the crashing process is what we consider to be the "home process" and it has been 7651 // replaced by a third-party app, clear the package preferred activities from packages 7652 // with a home activity running in the process to prevent a repeatedly crashing app 7653 // from blocking the user to manually clear the list. 7654 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7655 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7656 Iterator it = mHomeProcess.activities.iterator(); 7657 while (it.hasNext()) { 7658 ActivityRecord r = (ActivityRecord)it.next(); 7659 if (r.isHomeActivity) { 7660 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7661 try { 7662 ActivityThread.getPackageManager() 7663 .clearPackagePreferredActivities(r.packageName); 7664 } catch (RemoteException c) { 7665 // pm is in same process, this will never happen. 7666 } 7667 } 7668 } 7669 } 7670 7671 if (!app.isolated) { 7672 // XXX Can't keep track of crash times for isolated processes, 7673 // because they don't have a perisistent identity. 7674 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7675 } 7676 7677 return true; 7678 } 7679 7680 void startAppProblemLocked(ProcessRecord app) { 7681 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7682 mContext, app.info.packageName, app.info.flags); 7683 skipCurrentReceiverLocked(app); 7684 } 7685 7686 void skipCurrentReceiverLocked(ProcessRecord app) { 7687 for (BroadcastQueue queue : mBroadcastQueues) { 7688 queue.skipCurrentReceiverLocked(app); 7689 } 7690 } 7691 7692 /** 7693 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7694 * The application process will exit immediately after this call returns. 7695 * @param app object of the crashing app, null for the system server 7696 * @param crashInfo describing the exception 7697 */ 7698 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7699 ProcessRecord r = findAppProcess(app, "Crash"); 7700 final String processName = app == null ? "system_server" 7701 : (r == null ? "unknown" : r.processName); 7702 7703 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7704 processName, 7705 r == null ? -1 : r.info.flags, 7706 crashInfo.exceptionClassName, 7707 crashInfo.exceptionMessage, 7708 crashInfo.throwFileName, 7709 crashInfo.throwLineNumber); 7710 7711 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7712 7713 crashApplication(r, crashInfo); 7714 } 7715 7716 public void handleApplicationStrictModeViolation( 7717 IBinder app, 7718 int violationMask, 7719 StrictMode.ViolationInfo info) { 7720 ProcessRecord r = findAppProcess(app, "StrictMode"); 7721 if (r == null) { 7722 return; 7723 } 7724 7725 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7726 Integer stackFingerprint = info.hashCode(); 7727 boolean logIt = true; 7728 synchronized (mAlreadyLoggedViolatedStacks) { 7729 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7730 logIt = false; 7731 // TODO: sub-sample into EventLog for these, with 7732 // the info.durationMillis? Then we'd get 7733 // the relative pain numbers, without logging all 7734 // the stack traces repeatedly. We'd want to do 7735 // likewise in the client code, which also does 7736 // dup suppression, before the Binder call. 7737 } else { 7738 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7739 mAlreadyLoggedViolatedStacks.clear(); 7740 } 7741 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7742 } 7743 } 7744 if (logIt) { 7745 logStrictModeViolationToDropBox(r, info); 7746 } 7747 } 7748 7749 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7750 AppErrorResult result = new AppErrorResult(); 7751 synchronized (this) { 7752 final long origId = Binder.clearCallingIdentity(); 7753 7754 Message msg = Message.obtain(); 7755 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7756 HashMap<String, Object> data = new HashMap<String, Object>(); 7757 data.put("result", result); 7758 data.put("app", r); 7759 data.put("violationMask", violationMask); 7760 data.put("info", info); 7761 msg.obj = data; 7762 mHandler.sendMessage(msg); 7763 7764 Binder.restoreCallingIdentity(origId); 7765 } 7766 int res = result.get(); 7767 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7768 } 7769 } 7770 7771 // Depending on the policy in effect, there could be a bunch of 7772 // these in quick succession so we try to batch these together to 7773 // minimize disk writes, number of dropbox entries, and maximize 7774 // compression, by having more fewer, larger records. 7775 private void logStrictModeViolationToDropBox( 7776 ProcessRecord process, 7777 StrictMode.ViolationInfo info) { 7778 if (info == null) { 7779 return; 7780 } 7781 final boolean isSystemApp = process == null || 7782 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7783 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7784 final String processName = process == null ? "unknown" : process.processName; 7785 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7786 final DropBoxManager dbox = (DropBoxManager) 7787 mContext.getSystemService(Context.DROPBOX_SERVICE); 7788 7789 // Exit early if the dropbox isn't configured to accept this report type. 7790 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7791 7792 boolean bufferWasEmpty; 7793 boolean needsFlush; 7794 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7795 synchronized (sb) { 7796 bufferWasEmpty = sb.length() == 0; 7797 appendDropBoxProcessHeaders(process, processName, sb); 7798 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7799 sb.append("System-App: ").append(isSystemApp).append("\n"); 7800 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7801 if (info.violationNumThisLoop != 0) { 7802 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7803 } 7804 if (info.numAnimationsRunning != 0) { 7805 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7806 } 7807 if (info.broadcastIntentAction != null) { 7808 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7809 } 7810 if (info.durationMillis != -1) { 7811 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7812 } 7813 if (info.numInstances != -1) { 7814 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7815 } 7816 if (info.tags != null) { 7817 for (String tag : info.tags) { 7818 sb.append("Span-Tag: ").append(tag).append("\n"); 7819 } 7820 } 7821 sb.append("\n"); 7822 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7823 sb.append(info.crashInfo.stackTrace); 7824 } 7825 sb.append("\n"); 7826 7827 // Only buffer up to ~64k. Various logging bits truncate 7828 // things at 128k. 7829 needsFlush = (sb.length() > 64 * 1024); 7830 } 7831 7832 // Flush immediately if the buffer's grown too large, or this 7833 // is a non-system app. Non-system apps are isolated with a 7834 // different tag & policy and not batched. 7835 // 7836 // Batching is useful during internal testing with 7837 // StrictMode settings turned up high. Without batching, 7838 // thousands of separate files could be created on boot. 7839 if (!isSystemApp || needsFlush) { 7840 new Thread("Error dump: " + dropboxTag) { 7841 @Override 7842 public void run() { 7843 String report; 7844 synchronized (sb) { 7845 report = sb.toString(); 7846 sb.delete(0, sb.length()); 7847 sb.trimToSize(); 7848 } 7849 if (report.length() != 0) { 7850 dbox.addText(dropboxTag, report); 7851 } 7852 } 7853 }.start(); 7854 return; 7855 } 7856 7857 // System app batching: 7858 if (!bufferWasEmpty) { 7859 // An existing dropbox-writing thread is outstanding, so 7860 // we don't need to start it up. The existing thread will 7861 // catch the buffer appends we just did. 7862 return; 7863 } 7864 7865 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7866 // (After this point, we shouldn't access AMS internal data structures.) 7867 new Thread("Error dump: " + dropboxTag) { 7868 @Override 7869 public void run() { 7870 // 5 second sleep to let stacks arrive and be batched together 7871 try { 7872 Thread.sleep(5000); // 5 seconds 7873 } catch (InterruptedException e) {} 7874 7875 String errorReport; 7876 synchronized (mStrictModeBuffer) { 7877 errorReport = mStrictModeBuffer.toString(); 7878 if (errorReport.length() == 0) { 7879 return; 7880 } 7881 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 7882 mStrictModeBuffer.trimToSize(); 7883 } 7884 dbox.addText(dropboxTag, errorReport); 7885 } 7886 }.start(); 7887 } 7888 7889 /** 7890 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 7891 * @param app object of the crashing app, null for the system server 7892 * @param tag reported by the caller 7893 * @param crashInfo describing the context of the error 7894 * @return true if the process should exit immediately (WTF is fatal) 7895 */ 7896 public boolean handleApplicationWtf(IBinder app, String tag, 7897 ApplicationErrorReport.CrashInfo crashInfo) { 7898 ProcessRecord r = findAppProcess(app, "WTF"); 7899 final String processName = app == null ? "system_server" 7900 : (r == null ? "unknown" : r.processName); 7901 7902 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 7903 processName, 7904 r == null ? -1 : r.info.flags, 7905 tag, crashInfo.exceptionMessage); 7906 7907 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 7908 7909 if (r != null && r.pid != Process.myPid() && 7910 Settings.Secure.getInt(mContext.getContentResolver(), 7911 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 7912 crashApplication(r, crashInfo); 7913 return true; 7914 } else { 7915 return false; 7916 } 7917 } 7918 7919 /** 7920 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 7921 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 7922 */ 7923 private ProcessRecord findAppProcess(IBinder app, String reason) { 7924 if (app == null) { 7925 return null; 7926 } 7927 7928 synchronized (this) { 7929 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 7930 final int NA = apps.size(); 7931 for (int ia=0; ia<NA; ia++) { 7932 ProcessRecord p = apps.valueAt(ia); 7933 if (p.thread != null && p.thread.asBinder() == app) { 7934 return p; 7935 } 7936 } 7937 } 7938 7939 Slog.w(TAG, "Can't find mystery application for " + reason 7940 + " from pid=" + Binder.getCallingPid() 7941 + " uid=" + Binder.getCallingUid() + ": " + app); 7942 return null; 7943 } 7944 } 7945 7946 /** 7947 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 7948 * to append various headers to the dropbox log text. 7949 */ 7950 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 7951 StringBuilder sb) { 7952 // Watchdog thread ends up invoking this function (with 7953 // a null ProcessRecord) to add the stack file to dropbox. 7954 // Do not acquire a lock on this (am) in such cases, as it 7955 // could cause a potential deadlock, if and when watchdog 7956 // is invoked due to unavailability of lock on am and it 7957 // would prevent watchdog from killing system_server. 7958 if (process == null) { 7959 sb.append("Process: ").append(processName).append("\n"); 7960 return; 7961 } 7962 // Note: ProcessRecord 'process' is guarded by the service 7963 // instance. (notably process.pkgList, which could otherwise change 7964 // concurrently during execution of this method) 7965 synchronized (this) { 7966 sb.append("Process: ").append(processName).append("\n"); 7967 int flags = process.info.flags; 7968 IPackageManager pm = AppGlobals.getPackageManager(); 7969 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 7970 for (String pkg : process.pkgList) { 7971 sb.append("Package: ").append(pkg); 7972 try { 7973 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 7974 if (pi != null) { 7975 sb.append(" v").append(pi.versionCode); 7976 if (pi.versionName != null) { 7977 sb.append(" (").append(pi.versionName).append(")"); 7978 } 7979 } 7980 } catch (RemoteException e) { 7981 Slog.e(TAG, "Error getting package info: " + pkg, e); 7982 } 7983 sb.append("\n"); 7984 } 7985 } 7986 } 7987 7988 private static String processClass(ProcessRecord process) { 7989 if (process == null || process.pid == MY_PID) { 7990 return "system_server"; 7991 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7992 return "system_app"; 7993 } else { 7994 return "data_app"; 7995 } 7996 } 7997 7998 /** 7999 * Write a description of an error (crash, WTF, ANR) to the drop box. 8000 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8001 * @param process which caused the error, null means the system server 8002 * @param activity which triggered the error, null if unknown 8003 * @param parent activity related to the error, null if unknown 8004 * @param subject line related to the error, null if absent 8005 * @param report in long form describing the error, null if absent 8006 * @param logFile to include in the report, null if none 8007 * @param crashInfo giving an application stack trace, null if absent 8008 */ 8009 public void addErrorToDropBox(String eventType, 8010 ProcessRecord process, String processName, ActivityRecord activity, 8011 ActivityRecord parent, String subject, 8012 final String report, final File logFile, 8013 final ApplicationErrorReport.CrashInfo crashInfo) { 8014 // NOTE -- this must never acquire the ActivityManagerService lock, 8015 // otherwise the watchdog may be prevented from resetting the system. 8016 8017 final String dropboxTag = processClass(process) + "_" + eventType; 8018 final DropBoxManager dbox = (DropBoxManager) 8019 mContext.getSystemService(Context.DROPBOX_SERVICE); 8020 8021 // Exit early if the dropbox isn't configured to accept this report type. 8022 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8023 8024 final StringBuilder sb = new StringBuilder(1024); 8025 appendDropBoxProcessHeaders(process, processName, sb); 8026 if (activity != null) { 8027 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8028 } 8029 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8030 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8031 } 8032 if (parent != null && parent != activity) { 8033 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8034 } 8035 if (subject != null) { 8036 sb.append("Subject: ").append(subject).append("\n"); 8037 } 8038 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8039 if (Debug.isDebuggerConnected()) { 8040 sb.append("Debugger: Connected\n"); 8041 } 8042 sb.append("\n"); 8043 8044 // Do the rest in a worker thread to avoid blocking the caller on I/O 8045 // (After this point, we shouldn't access AMS internal data structures.) 8046 Thread worker = new Thread("Error dump: " + dropboxTag) { 8047 @Override 8048 public void run() { 8049 if (report != null) { 8050 sb.append(report); 8051 } 8052 if (logFile != null) { 8053 try { 8054 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8055 } catch (IOException e) { 8056 Slog.e(TAG, "Error reading " + logFile, e); 8057 } 8058 } 8059 if (crashInfo != null && crashInfo.stackTrace != null) { 8060 sb.append(crashInfo.stackTrace); 8061 } 8062 8063 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8064 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8065 if (lines > 0) { 8066 sb.append("\n"); 8067 8068 // Merge several logcat streams, and take the last N lines 8069 InputStreamReader input = null; 8070 try { 8071 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8072 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8073 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8074 8075 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8076 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8077 input = new InputStreamReader(logcat.getInputStream()); 8078 8079 int num; 8080 char[] buf = new char[8192]; 8081 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8082 } catch (IOException e) { 8083 Slog.e(TAG, "Error running logcat", e); 8084 } finally { 8085 if (input != null) try { input.close(); } catch (IOException e) {} 8086 } 8087 } 8088 8089 dbox.addText(dropboxTag, sb.toString()); 8090 } 8091 }; 8092 8093 if (process == null) { 8094 // If process is null, we are being called from some internal code 8095 // and may be about to die -- run this synchronously. 8096 worker.run(); 8097 } else { 8098 worker.start(); 8099 } 8100 } 8101 8102 /** 8103 * Bring up the "unexpected error" dialog box for a crashing app. 8104 * Deal with edge cases (intercepts from instrumented applications, 8105 * ActivityController, error intent receivers, that sort of thing). 8106 * @param r the application crashing 8107 * @param crashInfo describing the failure 8108 */ 8109 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8110 long timeMillis = System.currentTimeMillis(); 8111 String shortMsg = crashInfo.exceptionClassName; 8112 String longMsg = crashInfo.exceptionMessage; 8113 String stackTrace = crashInfo.stackTrace; 8114 if (shortMsg != null && longMsg != null) { 8115 longMsg = shortMsg + ": " + longMsg; 8116 } else if (shortMsg != null) { 8117 longMsg = shortMsg; 8118 } 8119 8120 AppErrorResult result = new AppErrorResult(); 8121 synchronized (this) { 8122 if (mController != null) { 8123 try { 8124 String name = r != null ? r.processName : null; 8125 int pid = r != null ? r.pid : Binder.getCallingPid(); 8126 if (!mController.appCrashed(name, pid, 8127 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8128 Slog.w(TAG, "Force-killing crashed app " + name 8129 + " at watcher's request"); 8130 Process.killProcess(pid); 8131 return; 8132 } 8133 } catch (RemoteException e) { 8134 mController = null; 8135 } 8136 } 8137 8138 final long origId = Binder.clearCallingIdentity(); 8139 8140 // If this process is running instrumentation, finish it. 8141 if (r != null && r.instrumentationClass != null) { 8142 Slog.w(TAG, "Error in app " + r.processName 8143 + " running instrumentation " + r.instrumentationClass + ":"); 8144 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8145 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8146 Bundle info = new Bundle(); 8147 info.putString("shortMsg", shortMsg); 8148 info.putString("longMsg", longMsg); 8149 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8150 Binder.restoreCallingIdentity(origId); 8151 return; 8152 } 8153 8154 // If we can't identify the process or it's already exceeded its crash quota, 8155 // quit right away without showing a crash dialog. 8156 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8157 Binder.restoreCallingIdentity(origId); 8158 return; 8159 } 8160 8161 Message msg = Message.obtain(); 8162 msg.what = SHOW_ERROR_MSG; 8163 HashMap data = new HashMap(); 8164 data.put("result", result); 8165 data.put("app", r); 8166 msg.obj = data; 8167 mHandler.sendMessage(msg); 8168 8169 Binder.restoreCallingIdentity(origId); 8170 } 8171 8172 int res = result.get(); 8173 8174 Intent appErrorIntent = null; 8175 synchronized (this) { 8176 if (r != null && !r.isolated) { 8177 // XXX Can't keep track of crash time for isolated processes, 8178 // since they don't have a persistent identity. 8179 mProcessCrashTimes.put(r.info.processName, r.uid, 8180 SystemClock.uptimeMillis()); 8181 } 8182 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8183 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8184 } 8185 } 8186 8187 if (appErrorIntent != null) { 8188 try { 8189 mContext.startActivity(appErrorIntent); 8190 } catch (ActivityNotFoundException e) { 8191 Slog.w(TAG, "bug report receiver dissappeared", e); 8192 } 8193 } 8194 } 8195 8196 Intent createAppErrorIntentLocked(ProcessRecord r, 8197 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8198 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8199 if (report == null) { 8200 return null; 8201 } 8202 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8203 result.setComponent(r.errorReportReceiver); 8204 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8205 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8206 return result; 8207 } 8208 8209 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8210 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8211 if (r.errorReportReceiver == null) { 8212 return null; 8213 } 8214 8215 if (!r.crashing && !r.notResponding) { 8216 return null; 8217 } 8218 8219 ApplicationErrorReport report = new ApplicationErrorReport(); 8220 report.packageName = r.info.packageName; 8221 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8222 report.processName = r.processName; 8223 report.time = timeMillis; 8224 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8225 8226 if (r.crashing) { 8227 report.type = ApplicationErrorReport.TYPE_CRASH; 8228 report.crashInfo = crashInfo; 8229 } else if (r.notResponding) { 8230 report.type = ApplicationErrorReport.TYPE_ANR; 8231 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8232 8233 report.anrInfo.activity = r.notRespondingReport.tag; 8234 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8235 report.anrInfo.info = r.notRespondingReport.longMsg; 8236 } 8237 8238 return report; 8239 } 8240 8241 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8242 enforceNotIsolatedCaller("getProcessesInErrorState"); 8243 // assume our apps are happy - lazy create the list 8244 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8245 8246 synchronized (this) { 8247 8248 // iterate across all processes 8249 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8250 ProcessRecord app = mLruProcesses.get(i); 8251 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8252 // This one's in trouble, so we'll generate a report for it 8253 // crashes are higher priority (in case there's a crash *and* an anr) 8254 ActivityManager.ProcessErrorStateInfo report = null; 8255 if (app.crashing) { 8256 report = app.crashingReport; 8257 } else if (app.notResponding) { 8258 report = app.notRespondingReport; 8259 } 8260 8261 if (report != null) { 8262 if (errList == null) { 8263 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8264 } 8265 errList.add(report); 8266 } else { 8267 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8268 " crashing = " + app.crashing + 8269 " notResponding = " + app.notResponding); 8270 } 8271 } 8272 } 8273 } 8274 8275 return errList; 8276 } 8277 8278 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8279 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8280 if (currApp != null) { 8281 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8282 } 8283 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8284 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8285 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8286 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8287 if (currApp != null) { 8288 currApp.lru = 0; 8289 } 8290 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8291 } else if (adj >= ProcessList.SERVICE_ADJ) { 8292 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8293 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8294 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8295 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8296 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8297 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8298 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8299 } else { 8300 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8301 } 8302 } 8303 8304 private void fillInProcMemInfo(ProcessRecord app, 8305 ActivityManager.RunningAppProcessInfo outInfo) { 8306 outInfo.pid = app.pid; 8307 outInfo.uid = app.info.uid; 8308 if (mHeavyWeightProcess == app) { 8309 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8310 } 8311 if (app.persistent) { 8312 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8313 } 8314 outInfo.lastTrimLevel = app.trimMemoryLevel; 8315 int adj = app.curAdj; 8316 outInfo.importance = oomAdjToImportance(adj, outInfo); 8317 outInfo.importanceReasonCode = app.adjTypeCode; 8318 } 8319 8320 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8321 enforceNotIsolatedCaller("getRunningAppProcesses"); 8322 // Lazy instantiation of list 8323 List<ActivityManager.RunningAppProcessInfo> runList = null; 8324 synchronized (this) { 8325 // Iterate across all processes 8326 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8327 ProcessRecord app = mLruProcesses.get(i); 8328 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8329 // Generate process state info for running application 8330 ActivityManager.RunningAppProcessInfo currApp = 8331 new ActivityManager.RunningAppProcessInfo(app.processName, 8332 app.pid, app.getPackageList()); 8333 fillInProcMemInfo(app, currApp); 8334 if (app.adjSource instanceof ProcessRecord) { 8335 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8336 currApp.importanceReasonImportance = oomAdjToImportance( 8337 app.adjSourceOom, null); 8338 } else if (app.adjSource instanceof ActivityRecord) { 8339 ActivityRecord r = (ActivityRecord)app.adjSource; 8340 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8341 } 8342 if (app.adjTarget instanceof ComponentName) { 8343 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8344 } 8345 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8346 // + " lru=" + currApp.lru); 8347 if (runList == null) { 8348 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8349 } 8350 runList.add(currApp); 8351 } 8352 } 8353 } 8354 return runList; 8355 } 8356 8357 public List<ApplicationInfo> getRunningExternalApplications() { 8358 enforceNotIsolatedCaller("getRunningExternalApplications"); 8359 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8360 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8361 if (runningApps != null && runningApps.size() > 0) { 8362 Set<String> extList = new HashSet<String>(); 8363 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8364 if (app.pkgList != null) { 8365 for (String pkg : app.pkgList) { 8366 extList.add(pkg); 8367 } 8368 } 8369 } 8370 IPackageManager pm = AppGlobals.getPackageManager(); 8371 for (String pkg : extList) { 8372 try { 8373 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8374 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8375 retList.add(info); 8376 } 8377 } catch (RemoteException e) { 8378 } 8379 } 8380 } 8381 return retList; 8382 } 8383 8384 @Override 8385 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8386 enforceNotIsolatedCaller("getMyMemoryState"); 8387 synchronized (this) { 8388 ProcessRecord proc; 8389 synchronized (mPidsSelfLocked) { 8390 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8391 } 8392 fillInProcMemInfo(proc, outInfo); 8393 } 8394 } 8395 8396 @Override 8397 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8398 if (checkCallingPermission(android.Manifest.permission.DUMP) 8399 != PackageManager.PERMISSION_GRANTED) { 8400 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8401 + Binder.getCallingPid() 8402 + ", uid=" + Binder.getCallingUid() 8403 + " without permission " 8404 + android.Manifest.permission.DUMP); 8405 return; 8406 } 8407 8408 boolean dumpAll = false; 8409 boolean dumpClient = false; 8410 String dumpPackage = null; 8411 8412 int opti = 0; 8413 while (opti < args.length) { 8414 String opt = args[opti]; 8415 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8416 break; 8417 } 8418 opti++; 8419 if ("-a".equals(opt)) { 8420 dumpAll = true; 8421 } else if ("-c".equals(opt)) { 8422 dumpClient = true; 8423 } else if ("-h".equals(opt)) { 8424 pw.println("Activity manager dump options:"); 8425 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8426 pw.println(" cmd may be one of:"); 8427 pw.println(" a[ctivities]: activity stack state"); 8428 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8429 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8430 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8431 pw.println(" o[om]: out of memory management"); 8432 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8433 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8434 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8435 pw.println(" service [COMP_SPEC]: service client-side state"); 8436 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8437 pw.println(" all: dump all activities"); 8438 pw.println(" top: dump the top activity"); 8439 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8440 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8441 pw.println(" a partial substring in a component name, a"); 8442 pw.println(" hex object identifier."); 8443 pw.println(" -a: include all available server state."); 8444 pw.println(" -c: include client state."); 8445 return; 8446 } else { 8447 pw.println("Unknown argument: " + opt + "; use -h for help"); 8448 } 8449 } 8450 8451 long origId = Binder.clearCallingIdentity(); 8452 boolean more = false; 8453 // Is the caller requesting to dump a particular piece of data? 8454 if (opti < args.length) { 8455 String cmd = args[opti]; 8456 opti++; 8457 if ("activities".equals(cmd) || "a".equals(cmd)) { 8458 synchronized (this) { 8459 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8460 } 8461 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8462 String[] newArgs; 8463 String name; 8464 if (opti >= args.length) { 8465 name = null; 8466 newArgs = EMPTY_STRING_ARRAY; 8467 } else { 8468 name = args[opti]; 8469 opti++; 8470 newArgs = new String[args.length - opti]; 8471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8472 args.length - opti); 8473 } 8474 synchronized (this) { 8475 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8476 } 8477 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8478 String[] newArgs; 8479 String name; 8480 if (opti >= args.length) { 8481 name = null; 8482 newArgs = EMPTY_STRING_ARRAY; 8483 } else { 8484 name = args[opti]; 8485 opti++; 8486 newArgs = new String[args.length - opti]; 8487 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8488 args.length - opti); 8489 } 8490 synchronized (this) { 8491 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8492 } 8493 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8494 String[] newArgs; 8495 String name; 8496 if (opti >= args.length) { 8497 name = null; 8498 newArgs = EMPTY_STRING_ARRAY; 8499 } else { 8500 name = args[opti]; 8501 opti++; 8502 newArgs = new String[args.length - opti]; 8503 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8504 args.length - opti); 8505 } 8506 synchronized (this) { 8507 dumpProcessesLocked(fd, pw, args, opti, true, name); 8508 } 8509 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8510 synchronized (this) { 8511 dumpOomLocked(fd, pw, args, opti, true); 8512 } 8513 } else if ("provider".equals(cmd)) { 8514 String[] newArgs; 8515 String name; 8516 if (opti >= args.length) { 8517 name = null; 8518 newArgs = EMPTY_STRING_ARRAY; 8519 } else { 8520 name = args[opti]; 8521 opti++; 8522 newArgs = new String[args.length - opti]; 8523 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8524 } 8525 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8526 pw.println("No providers match: " + name); 8527 pw.println("Use -h for help."); 8528 } 8529 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8530 synchronized (this) { 8531 dumpProvidersLocked(fd, pw, args, opti, true, null); 8532 } 8533 } else if ("service".equals(cmd)) { 8534 String[] newArgs; 8535 String name; 8536 if (opti >= args.length) { 8537 name = null; 8538 newArgs = EMPTY_STRING_ARRAY; 8539 } else { 8540 name = args[opti]; 8541 opti++; 8542 newArgs = new String[args.length - opti]; 8543 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8544 args.length - opti); 8545 } 8546 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8547 pw.println("No services match: " + name); 8548 pw.println("Use -h for help."); 8549 } 8550 } else if ("package".equals(cmd)) { 8551 String[] newArgs; 8552 if (opti >= args.length) { 8553 pw.println("package: no package name specified"); 8554 pw.println("Use -h for help."); 8555 } else { 8556 dumpPackage = args[opti]; 8557 opti++; 8558 newArgs = new String[args.length - opti]; 8559 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8560 args.length - opti); 8561 args = newArgs; 8562 opti = 0; 8563 more = true; 8564 } 8565 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8566 synchronized (this) { 8567 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8568 } 8569 } else { 8570 // Dumping a single activity? 8571 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8572 pw.println("Bad activity command, or no activities match: " + cmd); 8573 pw.println("Use -h for help."); 8574 } 8575 } 8576 if (!more) { 8577 Binder.restoreCallingIdentity(origId); 8578 return; 8579 } 8580 } 8581 8582 // No piece of data specified, dump everything. 8583 synchronized (this) { 8584 boolean needSep; 8585 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8586 if (needSep) { 8587 pw.println(" "); 8588 } 8589 if (dumpAll) { 8590 pw.println("-------------------------------------------------------------------------------"); 8591 } 8592 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8593 if (needSep) { 8594 pw.println(" "); 8595 } 8596 if (dumpAll) { 8597 pw.println("-------------------------------------------------------------------------------"); 8598 } 8599 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8600 if (needSep) { 8601 pw.println(" "); 8602 } 8603 if (dumpAll) { 8604 pw.println("-------------------------------------------------------------------------------"); 8605 } 8606 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8607 if (needSep) { 8608 pw.println(" "); 8609 } 8610 if (dumpAll) { 8611 pw.println("-------------------------------------------------------------------------------"); 8612 } 8613 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8614 if (needSep) { 8615 pw.println(" "); 8616 } 8617 if (dumpAll) { 8618 pw.println("-------------------------------------------------------------------------------"); 8619 } 8620 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8621 } 8622 Binder.restoreCallingIdentity(origId); 8623 } 8624 8625 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8626 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8627 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8628 pw.println(" Main stack:"); 8629 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8630 dumpPackage); 8631 pw.println(" "); 8632 pw.println(" Running activities (most recent first):"); 8633 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8634 dumpPackage); 8635 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8636 pw.println(" "); 8637 pw.println(" Activities waiting for another to become visible:"); 8638 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8639 !dumpAll, false, dumpPackage); 8640 } 8641 if (mMainStack.mStoppingActivities.size() > 0) { 8642 pw.println(" "); 8643 pw.println(" Activities waiting to stop:"); 8644 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8645 !dumpAll, false, dumpPackage); 8646 } 8647 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8648 pw.println(" "); 8649 pw.println(" Activities waiting to sleep:"); 8650 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8651 !dumpAll, false, dumpPackage); 8652 } 8653 if (mMainStack.mFinishingActivities.size() > 0) { 8654 pw.println(" "); 8655 pw.println(" Activities waiting to finish:"); 8656 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8657 !dumpAll, false, dumpPackage); 8658 } 8659 8660 pw.println(" "); 8661 if (mMainStack.mPausingActivity != null) { 8662 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8663 } 8664 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8665 pw.println(" mFocusedActivity: " + mFocusedActivity); 8666 if (dumpAll) { 8667 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8668 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8669 pw.println(" mDismissKeyguardOnNextActivity: " 8670 + mMainStack.mDismissKeyguardOnNextActivity); 8671 } 8672 8673 if (mRecentTasks.size() > 0) { 8674 pw.println(); 8675 pw.println(" Recent tasks:"); 8676 8677 final int N = mRecentTasks.size(); 8678 for (int i=0; i<N; i++) { 8679 TaskRecord tr = mRecentTasks.get(i); 8680 if (dumpPackage != null) { 8681 if (tr.realActivity == null || 8682 !dumpPackage.equals(tr.realActivity)) { 8683 continue; 8684 } 8685 } 8686 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8687 pw.println(tr); 8688 if (dumpAll) { 8689 mRecentTasks.get(i).dump(pw, " "); 8690 } 8691 } 8692 } 8693 8694 if (dumpAll) { 8695 pw.println(" "); 8696 pw.println(" mCurTask: " + mCurTask); 8697 } 8698 8699 return true; 8700 } 8701 8702 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8703 int opti, boolean dumpAll, String dumpPackage) { 8704 boolean needSep = false; 8705 int numPers = 0; 8706 8707 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8708 8709 if (dumpAll) { 8710 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8711 final int NA = procs.size(); 8712 for (int ia=0; ia<NA; ia++) { 8713 ProcessRecord r = procs.valueAt(ia); 8714 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8715 continue; 8716 } 8717 if (!needSep) { 8718 pw.println(" All known processes:"); 8719 needSep = true; 8720 } 8721 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8722 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8723 pw.print(" "); pw.println(r); 8724 r.dump(pw, " "); 8725 if (r.persistent) { 8726 numPers++; 8727 } 8728 } 8729 } 8730 } 8731 8732 if (mIsolatedProcesses.size() > 0) { 8733 if (needSep) pw.println(" "); 8734 needSep = true; 8735 pw.println(" Isolated process list (sorted by uid):"); 8736 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8737 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8738 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8739 continue; 8740 } 8741 pw.println(String.format("%sIsolated #%2d: %s", 8742 " ", i, r.toString())); 8743 } 8744 } 8745 8746 if (mLruProcesses.size() > 0) { 8747 if (needSep) pw.println(" "); 8748 needSep = true; 8749 pw.println(" Process LRU list (sorted by oom_adj):"); 8750 dumpProcessOomList(pw, this, mLruProcesses, " ", 8751 "Proc", "PERS", false, dumpPackage); 8752 needSep = true; 8753 } 8754 8755 if (dumpAll) { 8756 synchronized (mPidsSelfLocked) { 8757 boolean printed = false; 8758 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8759 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8760 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8761 continue; 8762 } 8763 if (!printed) { 8764 if (needSep) pw.println(" "); 8765 needSep = true; 8766 pw.println(" PID mappings:"); 8767 printed = true; 8768 } 8769 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8770 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8771 } 8772 } 8773 } 8774 8775 if (mForegroundProcesses.size() > 0) { 8776 synchronized (mPidsSelfLocked) { 8777 boolean printed = false; 8778 for (int i=0; i<mForegroundProcesses.size(); i++) { 8779 ProcessRecord r = mPidsSelfLocked.get( 8780 mForegroundProcesses.valueAt(i).pid); 8781 if (dumpPackage != null && (r == null 8782 || !dumpPackage.equals(r.info.packageName))) { 8783 continue; 8784 } 8785 if (!printed) { 8786 if (needSep) pw.println(" "); 8787 needSep = true; 8788 pw.println(" Foreground Processes:"); 8789 printed = true; 8790 } 8791 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8792 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8793 } 8794 } 8795 } 8796 8797 if (mPersistentStartingProcesses.size() > 0) { 8798 if (needSep) pw.println(" "); 8799 needSep = true; 8800 pw.println(" Persisent processes that are starting:"); 8801 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8802 "Starting Norm", "Restarting PERS", dumpPackage); 8803 } 8804 8805 if (mRemovedProcesses.size() > 0) { 8806 if (needSep) pw.println(" "); 8807 needSep = true; 8808 pw.println(" Processes that are being removed:"); 8809 dumpProcessList(pw, this, mRemovedProcesses, " ", 8810 "Removed Norm", "Removed PERS", dumpPackage); 8811 } 8812 8813 if (mProcessesOnHold.size() > 0) { 8814 if (needSep) pw.println(" "); 8815 needSep = true; 8816 pw.println(" Processes that are on old until the system is ready:"); 8817 dumpProcessList(pw, this, mProcessesOnHold, " ", 8818 "OnHold Norm", "OnHold PERS", dumpPackage); 8819 } 8820 8821 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8822 8823 if (mProcessCrashTimes.getMap().size() > 0) { 8824 boolean printed = false; 8825 long now = SystemClock.uptimeMillis(); 8826 for (Map.Entry<String, SparseArray<Long>> procs 8827 : mProcessCrashTimes.getMap().entrySet()) { 8828 String pname = procs.getKey(); 8829 SparseArray<Long> uids = procs.getValue(); 8830 final int N = uids.size(); 8831 for (int i=0; i<N; i++) { 8832 int puid = uids.keyAt(i); 8833 ProcessRecord r = mProcessNames.get(pname, puid); 8834 if (dumpPackage != null && (r == null 8835 || !dumpPackage.equals(r.info.packageName))) { 8836 continue; 8837 } 8838 if (!printed) { 8839 if (needSep) pw.println(" "); 8840 needSep = true; 8841 pw.println(" Time since processes crashed:"); 8842 printed = true; 8843 } 8844 pw.print(" Process "); pw.print(pname); 8845 pw.print(" uid "); pw.print(puid); 8846 pw.print(": last crashed "); 8847 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8848 pw.println(" ago"); 8849 } 8850 } 8851 } 8852 8853 if (mBadProcesses.getMap().size() > 0) { 8854 boolean printed = false; 8855 for (Map.Entry<String, SparseArray<Long>> procs 8856 : mBadProcesses.getMap().entrySet()) { 8857 String pname = procs.getKey(); 8858 SparseArray<Long> uids = procs.getValue(); 8859 final int N = uids.size(); 8860 for (int i=0; i<N; i++) { 8861 int puid = uids.keyAt(i); 8862 ProcessRecord r = mProcessNames.get(pname, puid); 8863 if (dumpPackage != null && (r == null 8864 || !dumpPackage.equals(r.info.packageName))) { 8865 continue; 8866 } 8867 if (!printed) { 8868 if (needSep) pw.println(" "); 8869 needSep = true; 8870 pw.println(" Bad processes:"); 8871 } 8872 pw.print(" Bad process "); pw.print(pname); 8873 pw.print(" uid "); pw.print(puid); 8874 pw.print(": crashed at time "); 8875 pw.println(uids.valueAt(i)); 8876 } 8877 } 8878 } 8879 8880 pw.println(); 8881 pw.println(" mHomeProcess: " + mHomeProcess); 8882 pw.println(" mPreviousProcess: " + mPreviousProcess); 8883 if (dumpAll) { 8884 StringBuilder sb = new StringBuilder(128); 8885 sb.append(" mPreviousProcessVisibleTime: "); 8886 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 8887 pw.println(sb); 8888 } 8889 if (mHeavyWeightProcess != null) { 8890 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8891 } 8892 pw.println(" mConfiguration: " + mConfiguration); 8893 if (dumpAll) { 8894 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 8895 if (mCompatModePackages.getPackages().size() > 0) { 8896 boolean printed = false; 8897 for (Map.Entry<String, Integer> entry 8898 : mCompatModePackages.getPackages().entrySet()) { 8899 String pkg = entry.getKey(); 8900 int mode = entry.getValue(); 8901 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 8902 continue; 8903 } 8904 if (!printed) { 8905 pw.println(" mScreenCompatPackages:"); 8906 printed = true; 8907 } 8908 pw.print(" "); pw.print(pkg); pw.print(": "); 8909 pw.print(mode); pw.println(); 8910 } 8911 } 8912 } 8913 if (mSleeping || mWentToSleep || mLockScreenShown) { 8914 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 8915 + " mLockScreenShown " + mLockScreenShown); 8916 } 8917 if (mShuttingDown) { 8918 pw.println(" mShuttingDown=" + mShuttingDown); 8919 } 8920 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 8921 || mOrigWaitForDebugger) { 8922 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 8923 + " mDebugTransient=" + mDebugTransient 8924 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 8925 } 8926 if (mOpenGlTraceApp != null) { 8927 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 8928 } 8929 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 8930 || mProfileFd != null) { 8931 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 8932 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 8933 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 8934 + mAutoStopProfiler); 8935 } 8936 if (mAlwaysFinishActivities || mController != null) { 8937 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 8938 + " mController=" + mController); 8939 } 8940 if (dumpAll) { 8941 pw.println(" Total persistent processes: " + numPers); 8942 pw.println(" mStartRunning=" + mStartRunning 8943 + " mProcessesReady=" + mProcessesReady 8944 + " mSystemReady=" + mSystemReady); 8945 pw.println(" mBooting=" + mBooting 8946 + " mBooted=" + mBooted 8947 + " mFactoryTest=" + mFactoryTest); 8948 pw.print(" mLastPowerCheckRealtime="); 8949 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 8950 pw.println(""); 8951 pw.print(" mLastPowerCheckUptime="); 8952 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 8953 pw.println(""); 8954 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 8955 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 8956 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 8957 pw.println(" mNumServiceProcs=" + mNumServiceProcs 8958 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 8959 } 8960 8961 return true; 8962 } 8963 8964 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 8965 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 8966 if (mProcessesToGc.size() > 0) { 8967 boolean printed = false; 8968 long now = SystemClock.uptimeMillis(); 8969 for (int i=0; i<mProcessesToGc.size(); i++) { 8970 ProcessRecord proc = mProcessesToGc.get(i); 8971 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 8972 continue; 8973 } 8974 if (!printed) { 8975 if (needSep) pw.println(" "); 8976 needSep = true; 8977 pw.println(" Processes that are waiting to GC:"); 8978 printed = true; 8979 } 8980 pw.print(" Process "); pw.println(proc); 8981 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 8982 pw.print(", last gced="); 8983 pw.print(now-proc.lastRequestedGc); 8984 pw.print(" ms ago, last lowMem="); 8985 pw.print(now-proc.lastLowMemory); 8986 pw.println(" ms ago"); 8987 8988 } 8989 } 8990 return needSep; 8991 } 8992 8993 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8994 int opti, boolean dumpAll) { 8995 boolean needSep = false; 8996 8997 if (mLruProcesses.size() > 0) { 8998 if (needSep) pw.println(" "); 8999 needSep = true; 9000 pw.println(" OOM levels:"); 9001 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9002 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9003 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9004 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9005 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9006 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9007 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9008 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9009 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9010 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9011 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9012 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9013 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9014 9015 if (needSep) pw.println(" "); 9016 needSep = true; 9017 pw.println(" Process OOM control:"); 9018 dumpProcessOomList(pw, this, mLruProcesses, " ", 9019 "Proc", "PERS", true, null); 9020 needSep = true; 9021 } 9022 9023 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9024 9025 pw.println(); 9026 pw.println(" mHomeProcess: " + mHomeProcess); 9027 pw.println(" mPreviousProcess: " + mPreviousProcess); 9028 if (mHeavyWeightProcess != null) { 9029 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9030 } 9031 9032 return true; 9033 } 9034 9035 /** 9036 * There are three ways to call this: 9037 * - no service specified: dump all the services 9038 * - a flattened component name that matched an existing service was specified as the 9039 * first arg: dump that one service 9040 * - the first arg isn't the flattened component name of an existing service: 9041 * dump all services whose component contains the first arg as a substring 9042 */ 9043 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9044 int opti, boolean dumpAll) { 9045 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 9046 9047 if ("all".equals(name)) { 9048 synchronized (this) { 9049 try { 9050 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9051 for (UserInfo user : users) { 9052 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9053 services.add(r1); 9054 } 9055 } 9056 } catch (RemoteException re) { 9057 } 9058 } 9059 } else { 9060 ComponentName componentName = name != null 9061 ? ComponentName.unflattenFromString(name) : null; 9062 int objectId = 0; 9063 if (componentName == null) { 9064 // Not a '/' separated full component name; maybe an object ID? 9065 try { 9066 objectId = Integer.parseInt(name, 16); 9067 name = null; 9068 componentName = null; 9069 } catch (RuntimeException e) { 9070 } 9071 } 9072 9073 synchronized (this) { 9074 try { 9075 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9076 for (UserInfo user : users) { 9077 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9078 if (componentName != null) { 9079 if (r1.name.equals(componentName)) { 9080 services.add(r1); 9081 } 9082 } else if (name != null) { 9083 if (r1.name.flattenToString().contains(name)) { 9084 services.add(r1); 9085 } 9086 } else if (System.identityHashCode(r1) == objectId) { 9087 services.add(r1); 9088 } 9089 } 9090 } 9091 } catch (RemoteException re) { 9092 } 9093 } 9094 } 9095 9096 if (services.size() <= 0) { 9097 return false; 9098 } 9099 9100 boolean needSep = false; 9101 for (int i=0; i<services.size(); i++) { 9102 if (needSep) { 9103 pw.println(); 9104 } 9105 needSep = true; 9106 dumpService("", fd, pw, services.get(i), args, dumpAll); 9107 } 9108 return true; 9109 } 9110 9111 /** 9112 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9113 * there is a thread associated with the service. 9114 */ 9115 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 9116 final ServiceRecord r, String[] args, boolean dumpAll) { 9117 String innerPrefix = prefix + " "; 9118 synchronized (this) { 9119 pw.print(prefix); pw.print("SERVICE "); 9120 pw.print(r.shortName); pw.print(" "); 9121 pw.print(Integer.toHexString(System.identityHashCode(r))); 9122 pw.print(" pid="); 9123 if (r.app != null) pw.println(r.app.pid); 9124 else pw.println("(not running)"); 9125 if (dumpAll) { 9126 r.dump(pw, innerPrefix); 9127 } 9128 } 9129 if (r.app != null && r.app.thread != null) { 9130 pw.print(prefix); pw.println(" Client:"); 9131 pw.flush(); 9132 try { 9133 TransferPipe tp = new TransferPipe(); 9134 try { 9135 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 9136 tp.setBufferPrefix(prefix + " "); 9137 tp.go(fd); 9138 } finally { 9139 tp.kill(); 9140 } 9141 } catch (IOException e) { 9142 pw.println(prefix + " Failure while dumping the service: " + e); 9143 } catch (RemoteException e) { 9144 pw.println(prefix + " Got a RemoteException while dumping the service"); 9145 } 9146 } 9147 } 9148 9149 /** 9150 * There are three ways to call this: 9151 * - no provider specified: dump all the providers 9152 * - a flattened component name that matched an existing provider was specified as the 9153 * first arg: dump that one provider 9154 * - the first arg isn't the flattened component name of an existing provider: 9155 * dump all providers whose component contains the first arg as a substring 9156 */ 9157 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9158 int opti, boolean dumpAll) { 9159 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9160 } 9161 9162 static class ItemMatcher { 9163 ArrayList<ComponentName> components; 9164 ArrayList<String> strings; 9165 ArrayList<Integer> objects; 9166 boolean all; 9167 9168 ItemMatcher() { 9169 all = true; 9170 } 9171 9172 void build(String name) { 9173 ComponentName componentName = ComponentName.unflattenFromString(name); 9174 if (componentName != null) { 9175 if (components == null) { 9176 components = new ArrayList<ComponentName>(); 9177 } 9178 components.add(componentName); 9179 all = false; 9180 } else { 9181 int objectId = 0; 9182 // Not a '/' separated full component name; maybe an object ID? 9183 try { 9184 objectId = Integer.parseInt(name, 16); 9185 if (objects == null) { 9186 objects = new ArrayList<Integer>(); 9187 } 9188 objects.add(objectId); 9189 all = false; 9190 } catch (RuntimeException e) { 9191 // Not an integer; just do string match. 9192 if (strings == null) { 9193 strings = new ArrayList<String>(); 9194 } 9195 strings.add(name); 9196 all = false; 9197 } 9198 } 9199 } 9200 9201 int build(String[] args, int opti) { 9202 for (; opti<args.length; opti++) { 9203 String name = args[opti]; 9204 if ("--".equals(name)) { 9205 return opti+1; 9206 } 9207 build(name); 9208 } 9209 return opti; 9210 } 9211 9212 boolean match(Object object, ComponentName comp) { 9213 if (all) { 9214 return true; 9215 } 9216 if (components != null) { 9217 for (int i=0; i<components.size(); i++) { 9218 if (components.get(i).equals(comp)) { 9219 return true; 9220 } 9221 } 9222 } 9223 if (objects != null) { 9224 for (int i=0; i<objects.size(); i++) { 9225 if (System.identityHashCode(object) == objects.get(i)) { 9226 return true; 9227 } 9228 } 9229 } 9230 if (strings != null) { 9231 String flat = comp.flattenToString(); 9232 for (int i=0; i<strings.size(); i++) { 9233 if (flat.contains(strings.get(i))) { 9234 return true; 9235 } 9236 } 9237 } 9238 return false; 9239 } 9240 } 9241 9242 /** 9243 * There are three things that cmd can be: 9244 * - a flattened component name that matches an existing activity 9245 * - the cmd arg isn't the flattened component name of an existing activity: 9246 * dump all activity whose component contains the cmd as a substring 9247 * - A hex number of the ActivityRecord object instance. 9248 */ 9249 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9250 int opti, boolean dumpAll) { 9251 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9252 9253 if ("all".equals(name)) { 9254 synchronized (this) { 9255 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9256 activities.add(r1); 9257 } 9258 } 9259 } else if ("top".equals(name)) { 9260 synchronized (this) { 9261 final int N = mMainStack.mHistory.size(); 9262 if (N > 0) { 9263 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9264 } 9265 } 9266 } else { 9267 ItemMatcher matcher = new ItemMatcher(); 9268 matcher.build(name); 9269 9270 synchronized (this) { 9271 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9272 if (matcher.match(r1, r1.intent.getComponent())) { 9273 activities.add(r1); 9274 } 9275 } 9276 } 9277 } 9278 9279 if (activities.size() <= 0) { 9280 return false; 9281 } 9282 9283 String[] newArgs = new String[args.length - opti]; 9284 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9285 9286 TaskRecord lastTask = null; 9287 boolean needSep = false; 9288 for (int i=activities.size()-1; i>=0; i--) { 9289 ActivityRecord r = (ActivityRecord)activities.get(i); 9290 if (needSep) { 9291 pw.println(); 9292 } 9293 needSep = true; 9294 synchronized (this) { 9295 if (lastTask != r.task) { 9296 lastTask = r.task; 9297 pw.print("TASK "); pw.print(lastTask.affinity); 9298 pw.print(" id="); pw.println(lastTask.taskId); 9299 if (dumpAll) { 9300 lastTask.dump(pw, " "); 9301 } 9302 } 9303 } 9304 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9305 } 9306 return true; 9307 } 9308 9309 /** 9310 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9311 * there is a thread associated with the activity. 9312 */ 9313 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9314 final ActivityRecord r, String[] args, boolean dumpAll) { 9315 String innerPrefix = prefix + " "; 9316 synchronized (this) { 9317 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9318 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9319 pw.print(" pid="); 9320 if (r.app != null) pw.println(r.app.pid); 9321 else pw.println("(not running)"); 9322 if (dumpAll) { 9323 r.dump(pw, innerPrefix); 9324 } 9325 } 9326 if (r.app != null && r.app.thread != null) { 9327 // flush anything that is already in the PrintWriter since the thread is going 9328 // to write to the file descriptor directly 9329 pw.flush(); 9330 try { 9331 TransferPipe tp = new TransferPipe(); 9332 try { 9333 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9334 r.appToken, innerPrefix, args); 9335 tp.go(fd); 9336 } finally { 9337 tp.kill(); 9338 } 9339 } catch (IOException e) { 9340 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9341 } catch (RemoteException e) { 9342 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9343 } 9344 } 9345 } 9346 9347 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9348 int opti, boolean dumpAll, String dumpPackage) { 9349 boolean needSep = false; 9350 9351 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9352 if (dumpAll) { 9353 if (mRegisteredReceivers.size() > 0) { 9354 boolean printed = false; 9355 Iterator it = mRegisteredReceivers.values().iterator(); 9356 while (it.hasNext()) { 9357 ReceiverList r = (ReceiverList)it.next(); 9358 if (dumpPackage != null && (r.app == null || 9359 !dumpPackage.equals(r.app.info.packageName))) { 9360 continue; 9361 } 9362 if (!printed) { 9363 pw.println(" Registered Receivers:"); 9364 needSep = true; 9365 printed = true; 9366 } 9367 pw.print(" * "); pw.println(r); 9368 r.dump(pw, " "); 9369 } 9370 } 9371 9372 if (mReceiverResolver.dump(pw, needSep ? 9373 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9374 " ", dumpPackage, false)) { 9375 needSep = true; 9376 } 9377 } 9378 9379 for (BroadcastQueue q : mBroadcastQueues) { 9380 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9381 } 9382 9383 needSep = true; 9384 9385 if (mStickyBroadcasts != null && dumpPackage == null) { 9386 if (needSep) { 9387 pw.println(); 9388 } 9389 needSep = true; 9390 pw.println(" Sticky broadcasts:"); 9391 StringBuilder sb = new StringBuilder(128); 9392 for (Map.Entry<String, ArrayList<Intent>> ent 9393 : mStickyBroadcasts.entrySet()) { 9394 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9395 if (dumpAll) { 9396 pw.println(":"); 9397 ArrayList<Intent> intents = ent.getValue(); 9398 final int N = intents.size(); 9399 for (int i=0; i<N; i++) { 9400 sb.setLength(0); 9401 sb.append(" Intent: "); 9402 intents.get(i).toShortString(sb, false, true, false, false); 9403 pw.println(sb.toString()); 9404 Bundle bundle = intents.get(i).getExtras(); 9405 if (bundle != null) { 9406 pw.print(" "); 9407 pw.println(bundle.toString()); 9408 } 9409 } 9410 } else { 9411 pw.println(""); 9412 } 9413 } 9414 needSep = true; 9415 } 9416 9417 if (dumpAll) { 9418 pw.println(); 9419 for (BroadcastQueue queue : mBroadcastQueues) { 9420 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9421 + queue.mBroadcastsScheduled); 9422 } 9423 pw.println(" mHandler:"); 9424 mHandler.dump(new PrintWriterPrinter(pw), " "); 9425 needSep = true; 9426 } 9427 9428 return needSep; 9429 } 9430 9431 /** 9432 * Prints a list of ServiceRecords (dumpsys activity services) 9433 */ 9434 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9435 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9436 boolean needSep = false; 9437 9438 ItemMatcher matcher = new ItemMatcher(); 9439 matcher.build(args, opti); 9440 9441 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 9442 try { 9443 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9444 for (UserInfo user : users) { 9445 if (mServiceMap.getAllServices(user.id).size() > 0) { 9446 boolean printed = false; 9447 long nowReal = SystemClock.elapsedRealtime(); 9448 Iterator<ServiceRecord> it = mServiceMap.getAllServices( 9449 user.id).iterator(); 9450 needSep = false; 9451 while (it.hasNext()) { 9452 ServiceRecord r = it.next(); 9453 if (!matcher.match(r, r.name)) { 9454 continue; 9455 } 9456 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9457 continue; 9458 } 9459 if (!printed) { 9460 pw.println(" Active services:"); 9461 printed = true; 9462 } 9463 if (needSep) { 9464 pw.println(); 9465 } 9466 pw.print(" * "); 9467 pw.println(r); 9468 if (dumpAll) { 9469 r.dump(pw, " "); 9470 needSep = true; 9471 } else { 9472 pw.print(" app="); 9473 pw.println(r.app); 9474 pw.print(" created="); 9475 TimeUtils.formatDuration(r.createTime, nowReal, pw); 9476 pw.print(" started="); 9477 pw.print(r.startRequested); 9478 pw.print(" connections="); 9479 pw.println(r.connections.size()); 9480 if (r.connections.size() > 0) { 9481 pw.println(" Connections:"); 9482 for (ArrayList<ConnectionRecord> clist : r.connections.values()) { 9483 for (int i = 0; i < clist.size(); i++) { 9484 ConnectionRecord conn = clist.get(i); 9485 pw.print(" "); 9486 pw.print(conn.binding.intent.intent.getIntent() 9487 .toShortString(false, false, false, false)); 9488 pw.print(" -> "); 9489 ProcessRecord proc = conn.binding.client; 9490 pw.println(proc != null ? proc.toShortString() : "null"); 9491 } 9492 } 9493 } 9494 } 9495 if (dumpClient && r.app != null && r.app.thread != null) { 9496 pw.println(" Client:"); 9497 pw.flush(); 9498 try { 9499 TransferPipe tp = new TransferPipe(); 9500 try { 9501 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), 9502 r, args); 9503 tp.setBufferPrefix(" "); 9504 // Short timeout, since blocking here can 9505 // deadlock with the application. 9506 tp.go(fd, 2000); 9507 } finally { 9508 tp.kill(); 9509 } 9510 } catch (IOException e) { 9511 pw.println(" Failure while dumping the service: " + e); 9512 } catch (RemoteException e) { 9513 pw.println(" Got a RemoteException while dumping the service"); 9514 } 9515 needSep = true; 9516 } 9517 } 9518 needSep = printed; 9519 } 9520 } 9521 } catch (RemoteException re) { 9522 9523 } 9524 9525 if (mPendingServices.size() > 0) { 9526 boolean printed = false; 9527 for (int i=0; i<mPendingServices.size(); i++) { 9528 ServiceRecord r = mPendingServices.get(i); 9529 if (!matcher.match(r, r.name)) { 9530 continue; 9531 } 9532 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9533 continue; 9534 } 9535 if (!printed) { 9536 if (needSep) pw.println(" "); 9537 needSep = true; 9538 pw.println(" Pending services:"); 9539 printed = true; 9540 } 9541 pw.print(" * Pending "); pw.println(r); 9542 r.dump(pw, " "); 9543 } 9544 needSep = true; 9545 } 9546 9547 if (mRestartingServices.size() > 0) { 9548 boolean printed = false; 9549 for (int i=0; i<mRestartingServices.size(); i++) { 9550 ServiceRecord r = mRestartingServices.get(i); 9551 if (!matcher.match(r, r.name)) { 9552 continue; 9553 } 9554 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9555 continue; 9556 } 9557 if (!printed) { 9558 if (needSep) pw.println(" "); 9559 needSep = true; 9560 pw.println(" Restarting services:"); 9561 printed = true; 9562 } 9563 pw.print(" * Restarting "); pw.println(r); 9564 r.dump(pw, " "); 9565 } 9566 needSep = true; 9567 } 9568 9569 if (mStoppingServices.size() > 0) { 9570 boolean printed = false; 9571 for (int i=0; i<mStoppingServices.size(); i++) { 9572 ServiceRecord r = mStoppingServices.get(i); 9573 if (!matcher.match(r, r.name)) { 9574 continue; 9575 } 9576 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9577 continue; 9578 } 9579 if (!printed) { 9580 if (needSep) pw.println(" "); 9581 needSep = true; 9582 pw.println(" Stopping services:"); 9583 printed = true; 9584 } 9585 pw.print(" * Stopping "); pw.println(r); 9586 r.dump(pw, " "); 9587 } 9588 needSep = true; 9589 } 9590 9591 if (dumpAll) { 9592 if (mServiceConnections.size() > 0) { 9593 boolean printed = false; 9594 Iterator<ArrayList<ConnectionRecord>> it 9595 = mServiceConnections.values().iterator(); 9596 while (it.hasNext()) { 9597 ArrayList<ConnectionRecord> r = it.next(); 9598 for (int i=0; i<r.size(); i++) { 9599 ConnectionRecord cr = r.get(i); 9600 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 9601 continue; 9602 } 9603 if (dumpPackage != null && (cr.binding.client == null 9604 || !dumpPackage.equals(cr.binding.client.info.packageName))) { 9605 continue; 9606 } 9607 if (!printed) { 9608 if (needSep) pw.println(" "); 9609 needSep = true; 9610 pw.println(" Connection bindings to services:"); 9611 printed = true; 9612 } 9613 pw.print(" * "); pw.println(cr); 9614 cr.dump(pw, " "); 9615 } 9616 } 9617 needSep = true; 9618 } 9619 } 9620 9621 return needSep; 9622 } 9623 9624 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9625 int opti, boolean dumpAll, String dumpPackage) { 9626 boolean needSep = true; 9627 9628 ItemMatcher matcher = new ItemMatcher(); 9629 matcher.build(args, opti); 9630 9631 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9632 9633 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9634 9635 if (mLaunchingProviders.size() > 0) { 9636 boolean printed = false; 9637 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9638 ContentProviderRecord r = mLaunchingProviders.get(i); 9639 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9640 continue; 9641 } 9642 if (!printed) { 9643 if (needSep) pw.println(" "); 9644 needSep = true; 9645 pw.println(" Launching content providers:"); 9646 printed = true; 9647 } 9648 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9649 pw.println(r); 9650 } 9651 } 9652 9653 if (mGrantedUriPermissions.size() > 0) { 9654 if (needSep) pw.println(); 9655 needSep = true; 9656 pw.println("Granted Uri Permissions:"); 9657 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9658 int uid = mGrantedUriPermissions.keyAt(i); 9659 HashMap<Uri, UriPermission> perms 9660 = mGrantedUriPermissions.valueAt(i); 9661 pw.print(" * UID "); pw.print(uid); 9662 pw.println(" holds:"); 9663 for (UriPermission perm : perms.values()) { 9664 pw.print(" "); pw.println(perm); 9665 if (dumpAll) { 9666 perm.dump(pw, " "); 9667 } 9668 } 9669 } 9670 needSep = true; 9671 } 9672 9673 return needSep; 9674 } 9675 9676 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9677 int opti, boolean dumpAll, String dumpPackage) { 9678 boolean needSep = false; 9679 9680 if (mIntentSenderRecords.size() > 0) { 9681 boolean printed = false; 9682 Iterator<WeakReference<PendingIntentRecord>> it 9683 = mIntentSenderRecords.values().iterator(); 9684 while (it.hasNext()) { 9685 WeakReference<PendingIntentRecord> ref = it.next(); 9686 PendingIntentRecord rec = ref != null ? ref.get(): null; 9687 if (dumpPackage != null && (rec == null 9688 || !dumpPackage.equals(rec.key.packageName))) { 9689 continue; 9690 } 9691 if (!printed) { 9692 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9693 printed = true; 9694 } 9695 needSep = true; 9696 if (rec != null) { 9697 pw.print(" * "); pw.println(rec); 9698 if (dumpAll) { 9699 rec.dump(pw, " "); 9700 } 9701 } else { 9702 pw.print(" * "); pw.println(ref); 9703 } 9704 } 9705 } 9706 9707 return needSep; 9708 } 9709 9710 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9711 String prefix, String label, boolean complete, boolean brief, boolean client, 9712 String dumpPackage) { 9713 TaskRecord lastTask = null; 9714 boolean needNL = false; 9715 final String innerPrefix = prefix + " "; 9716 final String[] args = new String[0]; 9717 for (int i=list.size()-1; i>=0; i--) { 9718 final ActivityRecord r = (ActivityRecord)list.get(i); 9719 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9720 continue; 9721 } 9722 final boolean full = !brief && (complete || !r.isInHistory()); 9723 if (needNL) { 9724 pw.println(" "); 9725 needNL = false; 9726 } 9727 if (lastTask != r.task) { 9728 lastTask = r.task; 9729 pw.print(prefix); 9730 pw.print(full ? "* " : " "); 9731 pw.println(lastTask); 9732 if (full) { 9733 lastTask.dump(pw, prefix + " "); 9734 } else if (complete) { 9735 // Complete + brief == give a summary. Isn't that obvious?!? 9736 if (lastTask.intent != null) { 9737 pw.print(prefix); pw.print(" "); 9738 pw.println(lastTask.intent.toInsecureStringWithClip()); 9739 } 9740 } 9741 } 9742 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9743 pw.print(" #"); pw.print(i); pw.print(": "); 9744 pw.println(r); 9745 if (full) { 9746 r.dump(pw, innerPrefix); 9747 } else if (complete) { 9748 // Complete + brief == give a summary. Isn't that obvious?!? 9749 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9750 if (r.app != null) { 9751 pw.print(innerPrefix); pw.println(r.app); 9752 } 9753 } 9754 if (client && r.app != null && r.app.thread != null) { 9755 // flush anything that is already in the PrintWriter since the thread is going 9756 // to write to the file descriptor directly 9757 pw.flush(); 9758 try { 9759 TransferPipe tp = new TransferPipe(); 9760 try { 9761 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9762 r.appToken, innerPrefix, args); 9763 // Short timeout, since blocking here can 9764 // deadlock with the application. 9765 tp.go(fd, 2000); 9766 } finally { 9767 tp.kill(); 9768 } 9769 } catch (IOException e) { 9770 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9771 } catch (RemoteException e) { 9772 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9773 } 9774 needNL = true; 9775 } 9776 } 9777 } 9778 9779 private static String buildOomTag(String prefix, String space, int val, int base) { 9780 if (val == base) { 9781 if (space == null) return prefix; 9782 return prefix + " "; 9783 } 9784 return prefix + "+" + Integer.toString(val-base); 9785 } 9786 9787 private static final int dumpProcessList(PrintWriter pw, 9788 ActivityManagerService service, List list, 9789 String prefix, String normalLabel, String persistentLabel, 9790 String dumpPackage) { 9791 int numPers = 0; 9792 final int N = list.size()-1; 9793 for (int i=N; i>=0; i--) { 9794 ProcessRecord r = (ProcessRecord)list.get(i); 9795 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9796 continue; 9797 } 9798 pw.println(String.format("%s%s #%2d: %s", 9799 prefix, (r.persistent ? persistentLabel : normalLabel), 9800 i, r.toString())); 9801 if (r.persistent) { 9802 numPers++; 9803 } 9804 } 9805 return numPers; 9806 } 9807 9808 private static final boolean dumpProcessOomList(PrintWriter pw, 9809 ActivityManagerService service, List<ProcessRecord> origList, 9810 String prefix, String normalLabel, String persistentLabel, 9811 boolean inclDetails, String dumpPackage) { 9812 9813 ArrayList<Pair<ProcessRecord, Integer>> list 9814 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9815 for (int i=0; i<origList.size(); i++) { 9816 ProcessRecord r = origList.get(i); 9817 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9818 continue; 9819 } 9820 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9821 } 9822 9823 if (list.size() <= 0) { 9824 return false; 9825 } 9826 9827 Comparator<Pair<ProcessRecord, Integer>> comparator 9828 = new Comparator<Pair<ProcessRecord, Integer>>() { 9829 @Override 9830 public int compare(Pair<ProcessRecord, Integer> object1, 9831 Pair<ProcessRecord, Integer> object2) { 9832 if (object1.first.setAdj != object2.first.setAdj) { 9833 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9834 } 9835 if (object1.second.intValue() != object2.second.intValue()) { 9836 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9837 } 9838 return 0; 9839 } 9840 }; 9841 9842 Collections.sort(list, comparator); 9843 9844 final long curRealtime = SystemClock.elapsedRealtime(); 9845 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9846 final long curUptime = SystemClock.uptimeMillis(); 9847 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9848 9849 for (int i=list.size()-1; i>=0; i--) { 9850 ProcessRecord r = list.get(i).first; 9851 String oomAdj; 9852 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9853 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9854 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9855 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9856 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9857 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9858 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9859 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9860 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9861 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9862 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9863 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9864 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9865 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9866 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9867 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9868 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9869 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9870 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9871 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9872 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9873 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9874 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9875 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9876 } else { 9877 oomAdj = Integer.toString(r.setAdj); 9878 } 9879 String schedGroup; 9880 switch (r.setSchedGroup) { 9881 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9882 schedGroup = "B"; 9883 break; 9884 case Process.THREAD_GROUP_DEFAULT: 9885 schedGroup = "F"; 9886 break; 9887 default: 9888 schedGroup = Integer.toString(r.setSchedGroup); 9889 break; 9890 } 9891 String foreground; 9892 if (r.foregroundActivities) { 9893 foreground = "A"; 9894 } else if (r.foregroundServices) { 9895 foreground = "S"; 9896 } else { 9897 foreground = " "; 9898 } 9899 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9900 prefix, (r.persistent ? persistentLabel : normalLabel), 9901 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9902 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9903 if (r.adjSource != null || r.adjTarget != null) { 9904 pw.print(prefix); 9905 pw.print(" "); 9906 if (r.adjTarget instanceof ComponentName) { 9907 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9908 } else if (r.adjTarget != null) { 9909 pw.print(r.adjTarget.toString()); 9910 } else { 9911 pw.print("{null}"); 9912 } 9913 pw.print("<="); 9914 if (r.adjSource instanceof ProcessRecord) { 9915 pw.print("Proc{"); 9916 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9917 pw.println("}"); 9918 } else if (r.adjSource != null) { 9919 pw.println(r.adjSource.toString()); 9920 } else { 9921 pw.println("{null}"); 9922 } 9923 } 9924 if (inclDetails) { 9925 pw.print(prefix); 9926 pw.print(" "); 9927 pw.print("oom: max="); pw.print(r.maxAdj); 9928 pw.print(" hidden="); pw.print(r.hiddenAdj); 9929 pw.print(" curRaw="); pw.print(r.curRawAdj); 9930 pw.print(" setRaw="); pw.print(r.setRawAdj); 9931 pw.print(" cur="); pw.print(r.curAdj); 9932 pw.print(" set="); pw.println(r.setAdj); 9933 pw.print(prefix); 9934 pw.print(" "); 9935 pw.print("keeping="); pw.print(r.keeping); 9936 pw.print(" hidden="); pw.print(r.hidden); 9937 pw.print(" empty="); pw.print(r.empty); 9938 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9939 9940 if (!r.keeping) { 9941 if (r.lastWakeTime != 0) { 9942 long wtime; 9943 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9944 synchronized (stats) { 9945 wtime = stats.getProcessWakeTime(r.info.uid, 9946 r.pid, curRealtime); 9947 } 9948 long timeUsed = wtime - r.lastWakeTime; 9949 pw.print(prefix); 9950 pw.print(" "); 9951 pw.print("keep awake over "); 9952 TimeUtils.formatDuration(realtimeSince, pw); 9953 pw.print(" used "); 9954 TimeUtils.formatDuration(timeUsed, pw); 9955 pw.print(" ("); 9956 pw.print((timeUsed*100)/realtimeSince); 9957 pw.println("%)"); 9958 } 9959 if (r.lastCpuTime != 0) { 9960 long timeUsed = r.curCpuTime - r.lastCpuTime; 9961 pw.print(prefix); 9962 pw.print(" "); 9963 pw.print("run cpu over "); 9964 TimeUtils.formatDuration(uptimeSince, pw); 9965 pw.print(" used "); 9966 TimeUtils.formatDuration(timeUsed, pw); 9967 pw.print(" ("); 9968 pw.print((timeUsed*100)/uptimeSince); 9969 pw.println("%)"); 9970 } 9971 } 9972 } 9973 } 9974 return true; 9975 } 9976 9977 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9978 ArrayList<ProcessRecord> procs; 9979 synchronized (this) { 9980 if (args != null && args.length > start 9981 && args[start].charAt(0) != '-') { 9982 procs = new ArrayList<ProcessRecord>(); 9983 int pid = -1; 9984 try { 9985 pid = Integer.parseInt(args[start]); 9986 } catch (NumberFormatException e) { 9987 9988 } 9989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9990 ProcessRecord proc = mLruProcesses.get(i); 9991 if (proc.pid == pid) { 9992 procs.add(proc); 9993 } else if (proc.processName.equals(args[start])) { 9994 procs.add(proc); 9995 } 9996 } 9997 if (procs.size() <= 0) { 9998 pw.println("No process found for: " + args[start]); 9999 return null; 10000 } 10001 } else { 10002 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10003 } 10004 } 10005 return procs; 10006 } 10007 10008 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10009 PrintWriter pw, String[] args) { 10010 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10011 if (procs == null) { 10012 return; 10013 } 10014 10015 long uptime = SystemClock.uptimeMillis(); 10016 long realtime = SystemClock.elapsedRealtime(); 10017 pw.println("Applications Graphics Acceleration Info:"); 10018 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10019 10020 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10021 ProcessRecord r = procs.get(i); 10022 if (r.thread != null) { 10023 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10024 pw.flush(); 10025 try { 10026 TransferPipe tp = new TransferPipe(); 10027 try { 10028 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10029 tp.go(fd); 10030 } finally { 10031 tp.kill(); 10032 } 10033 } catch (IOException e) { 10034 pw.println("Failure while dumping the app: " + r); 10035 pw.flush(); 10036 } catch (RemoteException e) { 10037 pw.println("Got a RemoteException while dumping the app " + r); 10038 pw.flush(); 10039 } 10040 } 10041 } 10042 } 10043 10044 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10045 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10046 if (procs == null) { 10047 return; 10048 } 10049 10050 pw.println("Applications Database Info:"); 10051 10052 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10053 ProcessRecord r = procs.get(i); 10054 if (r.thread != null) { 10055 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10056 pw.flush(); 10057 try { 10058 TransferPipe tp = new TransferPipe(); 10059 try { 10060 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10061 tp.go(fd); 10062 } finally { 10063 tp.kill(); 10064 } 10065 } catch (IOException e) { 10066 pw.println("Failure while dumping the app: " + r); 10067 pw.flush(); 10068 } catch (RemoteException e) { 10069 pw.println("Got a RemoteException while dumping the app " + r); 10070 pw.flush(); 10071 } 10072 } 10073 } 10074 } 10075 10076 final static class MemItem { 10077 final String label; 10078 final String shortLabel; 10079 final long pss; 10080 final int id; 10081 ArrayList<MemItem> subitems; 10082 10083 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10084 label = _label; 10085 shortLabel = _shortLabel; 10086 pss = _pss; 10087 id = _id; 10088 } 10089 } 10090 10091 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10092 boolean sort) { 10093 if (sort) { 10094 Collections.sort(items, new Comparator<MemItem>() { 10095 @Override 10096 public int compare(MemItem lhs, MemItem rhs) { 10097 if (lhs.pss < rhs.pss) { 10098 return 1; 10099 } else if (lhs.pss > rhs.pss) { 10100 return -1; 10101 } 10102 return 0; 10103 } 10104 }); 10105 } 10106 10107 for (int i=0; i<items.size(); i++) { 10108 MemItem mi = items.get(i); 10109 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10110 if (mi.subitems != null) { 10111 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10112 } 10113 } 10114 } 10115 10116 // These are in KB. 10117 static final long[] DUMP_MEM_BUCKETS = new long[] { 10118 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10119 120*1024, 160*1024, 200*1024, 10120 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10121 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10122 }; 10123 10124 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10125 boolean stackLike) { 10126 int start = label.lastIndexOf('.'); 10127 if (start >= 0) start++; 10128 else start = 0; 10129 int end = label.length(); 10130 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10131 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10132 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10133 out.append(bucket); 10134 out.append(stackLike ? "MB." : "MB "); 10135 out.append(label, start, end); 10136 return; 10137 } 10138 } 10139 out.append(memKB/1024); 10140 out.append(stackLike ? "MB." : "MB "); 10141 out.append(label, start, end); 10142 } 10143 10144 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10145 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10146 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10147 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10148 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10149 }; 10150 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10151 "System", "Persistent", "Foreground", 10152 "Visible", "Perceptible", "Heavy Weight", 10153 "Backup", "A Services", "Home", "Previous", 10154 "B Services", "Background" 10155 }; 10156 10157 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10158 PrintWriter pw, String prefix, String[] args, boolean brief, 10159 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10160 boolean dumpAll = false; 10161 boolean oomOnly = false; 10162 10163 int opti = 0; 10164 while (opti < args.length) { 10165 String opt = args[opti]; 10166 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10167 break; 10168 } 10169 opti++; 10170 if ("-a".equals(opt)) { 10171 dumpAll = true; 10172 } else if ("--oom".equals(opt)) { 10173 oomOnly = true; 10174 } else if ("-h".equals(opt)) { 10175 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10176 pw.println(" -a: include all available information for each process."); 10177 pw.println(" --oom: only show processes organized by oom adj."); 10178 pw.println("If [process] is specified it can be the name or "); 10179 pw.println("pid of a specific process to dump."); 10180 return; 10181 } else { 10182 pw.println("Unknown argument: " + opt + "; use -h for help"); 10183 } 10184 } 10185 10186 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10187 if (procs == null) { 10188 return; 10189 } 10190 10191 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10192 long uptime = SystemClock.uptimeMillis(); 10193 long realtime = SystemClock.elapsedRealtime(); 10194 10195 if (procs.size() == 1 || isCheckinRequest) { 10196 dumpAll = true; 10197 } 10198 10199 if (isCheckinRequest) { 10200 // short checkin version 10201 pw.println(uptime + "," + realtime); 10202 pw.flush(); 10203 } else { 10204 pw.println("Applications Memory Usage (kB):"); 10205 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10206 } 10207 10208 String[] innerArgs = new String[args.length-opti]; 10209 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10210 10211 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10212 long nativePss=0, dalvikPss=0, otherPss=0; 10213 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10214 10215 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10216 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10217 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10218 10219 long totalPss = 0; 10220 10221 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10222 ProcessRecord r = procs.get(i); 10223 if (r.thread != null) { 10224 if (!isCheckinRequest && dumpAll) { 10225 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10226 pw.flush(); 10227 } 10228 Debug.MemoryInfo mi = null; 10229 if (dumpAll) { 10230 try { 10231 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10232 } catch (RemoteException e) { 10233 if (!isCheckinRequest) { 10234 pw.println("Got RemoteException!"); 10235 pw.flush(); 10236 } 10237 } 10238 } else { 10239 mi = new Debug.MemoryInfo(); 10240 Debug.getMemoryInfo(r.pid, mi); 10241 } 10242 10243 if (!isCheckinRequest && mi != null) { 10244 long myTotalPss = mi.getTotalPss(); 10245 totalPss += myTotalPss; 10246 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10247 r.processName, myTotalPss, 0); 10248 procMems.add(pssItem); 10249 10250 nativePss += mi.nativePss; 10251 dalvikPss += mi.dalvikPss; 10252 otherPss += mi.otherPss; 10253 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10254 long mem = mi.getOtherPss(j); 10255 miscPss[j] += mem; 10256 otherPss -= mem; 10257 } 10258 10259 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10260 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10261 || oomIndex == (oomPss.length-1)) { 10262 oomPss[oomIndex] += myTotalPss; 10263 if (oomProcs[oomIndex] == null) { 10264 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10265 } 10266 oomProcs[oomIndex].add(pssItem); 10267 break; 10268 } 10269 } 10270 } 10271 } 10272 } 10273 10274 if (!isCheckinRequest && procs.size() > 1) { 10275 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10276 10277 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10278 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10279 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10280 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10281 String label = Debug.MemoryInfo.getOtherLabel(j); 10282 catMems.add(new MemItem(label, label, miscPss[j], j)); 10283 } 10284 10285 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10286 for (int j=0; j<oomPss.length; j++) { 10287 if (oomPss[j] != 0) { 10288 String label = DUMP_MEM_OOM_LABEL[j]; 10289 MemItem item = new MemItem(label, label, oomPss[j], 10290 DUMP_MEM_OOM_ADJ[j]); 10291 item.subitems = oomProcs[j]; 10292 oomMems.add(item); 10293 } 10294 } 10295 10296 if (outTag != null || outStack != null) { 10297 if (outTag != null) { 10298 appendMemBucket(outTag, totalPss, "total", false); 10299 } 10300 if (outStack != null) { 10301 appendMemBucket(outStack, totalPss, "total", true); 10302 } 10303 boolean firstLine = true; 10304 for (int i=0; i<oomMems.size(); i++) { 10305 MemItem miCat = oomMems.get(i); 10306 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10307 continue; 10308 } 10309 if (miCat.id < ProcessList.SERVICE_ADJ 10310 || miCat.id == ProcessList.HOME_APP_ADJ 10311 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10312 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10313 outTag.append(" / "); 10314 } 10315 if (outStack != null) { 10316 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10317 if (firstLine) { 10318 outStack.append(":"); 10319 firstLine = false; 10320 } 10321 outStack.append("\n\t at "); 10322 } else { 10323 outStack.append("$"); 10324 } 10325 } 10326 for (int j=0; j<miCat.subitems.size(); j++) { 10327 MemItem mi = miCat.subitems.get(j); 10328 if (j > 0) { 10329 if (outTag != null) { 10330 outTag.append(" "); 10331 } 10332 if (outStack != null) { 10333 outStack.append("$"); 10334 } 10335 } 10336 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10337 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10338 } 10339 if (outStack != null) { 10340 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10341 } 10342 } 10343 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10344 outStack.append("("); 10345 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10346 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10347 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10348 outStack.append(":"); 10349 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10350 } 10351 } 10352 outStack.append(")"); 10353 } 10354 } 10355 } 10356 } 10357 10358 if (!brief && !oomOnly) { 10359 pw.println(); 10360 pw.println("Total PSS by process:"); 10361 dumpMemItems(pw, " ", procMems, true); 10362 pw.println(); 10363 } 10364 pw.println("Total PSS by OOM adjustment:"); 10365 dumpMemItems(pw, " ", oomMems, false); 10366 if (!oomOnly) { 10367 PrintWriter out = categoryPw != null ? categoryPw : pw; 10368 out.println(); 10369 out.println("Total PSS by category:"); 10370 dumpMemItems(out, " ", catMems, true); 10371 } 10372 pw.println(); 10373 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10374 final int[] SINGLE_LONG_FORMAT = new int[] { 10375 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10376 }; 10377 long[] longOut = new long[1]; 10378 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10379 SINGLE_LONG_FORMAT, null, longOut, null); 10380 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10381 longOut[0] = 0; 10382 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10383 SINGLE_LONG_FORMAT, null, longOut, null); 10384 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10385 longOut[0] = 0; 10386 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10387 SINGLE_LONG_FORMAT, null, longOut, null); 10388 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10389 longOut[0] = 0; 10390 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10391 SINGLE_LONG_FORMAT, null, longOut, null); 10392 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10393 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10394 pw.print(shared); pw.println(" kB"); 10395 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10396 pw.print(voltile); pw.println(" kB volatile"); 10397 } 10398 } 10399 10400 /** 10401 * Searches array of arguments for the specified string 10402 * @param args array of argument strings 10403 * @param value value to search for 10404 * @return true if the value is contained in the array 10405 */ 10406 private static boolean scanArgs(String[] args, String value) { 10407 if (args != null) { 10408 for (String arg : args) { 10409 if (value.equals(arg)) { 10410 return true; 10411 } 10412 } 10413 } 10414 return false; 10415 } 10416 10417 private final void killServicesLocked(ProcessRecord app, 10418 boolean allowRestart) { 10419 // Report disconnected services. 10420 if (false) { 10421 // XXX we are letting the client link to the service for 10422 // death notifications. 10423 if (app.services.size() > 0) { 10424 Iterator<ServiceRecord> it = app.services.iterator(); 10425 while (it.hasNext()) { 10426 ServiceRecord r = it.next(); 10427 if (r.connections.size() > 0) { 10428 Iterator<ArrayList<ConnectionRecord>> jt 10429 = r.connections.values().iterator(); 10430 while (jt.hasNext()) { 10431 ArrayList<ConnectionRecord> cl = jt.next(); 10432 for (int i=0; i<cl.size(); i++) { 10433 ConnectionRecord c = cl.get(i); 10434 if (c.binding.client != app) { 10435 try { 10436 //c.conn.connected(r.className, null); 10437 } catch (Exception e) { 10438 // todo: this should be asynchronous! 10439 Slog.w(TAG, "Exception thrown disconnected servce " 10440 + r.shortName 10441 + " from app " + app.processName, e); 10442 } 10443 } 10444 } 10445 } 10446 } 10447 } 10448 } 10449 } 10450 10451 // Clean up any connections this application has to other services. 10452 if (app.connections.size() > 0) { 10453 Iterator<ConnectionRecord> it = app.connections.iterator(); 10454 while (it.hasNext()) { 10455 ConnectionRecord r = it.next(); 10456 removeConnectionLocked(r, app, null); 10457 } 10458 } 10459 app.connections.clear(); 10460 10461 if (app.services.size() != 0) { 10462 // Any services running in the application need to be placed 10463 // back in the pending list. 10464 Iterator<ServiceRecord> it = app.services.iterator(); 10465 while (it.hasNext()) { 10466 ServiceRecord sr = it.next(); 10467 synchronized (sr.stats.getBatteryStats()) { 10468 sr.stats.stopLaunchedLocked(); 10469 } 10470 sr.app = null; 10471 sr.isolatedProc = null; 10472 sr.executeNesting = 0; 10473 if (mStoppingServices.remove(sr)) { 10474 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10475 } 10476 10477 boolean hasClients = sr.bindings.size() > 0; 10478 if (hasClients) { 10479 Iterator<IntentBindRecord> bindings 10480 = sr.bindings.values().iterator(); 10481 while (bindings.hasNext()) { 10482 IntentBindRecord b = bindings.next(); 10483 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10484 + ": shouldUnbind=" + b.hasBound); 10485 b.binder = null; 10486 b.requested = b.received = b.hasBound = false; 10487 } 10488 } 10489 10490 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 10491 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 10492 Slog.w(TAG, "Service crashed " + sr.crashCount 10493 + " times, stopping: " + sr); 10494 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10495 sr.crashCount, sr.shortName, app.pid); 10496 bringDownServiceLocked(sr, true); 10497 } else if (!allowRestart) { 10498 bringDownServiceLocked(sr, true); 10499 } else { 10500 boolean canceled = scheduleServiceRestartLocked(sr, true); 10501 10502 // Should the service remain running? Note that in the 10503 // extreme case of so many attempts to deliver a command 10504 // that it failed we also will stop it here. 10505 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10506 if (sr.pendingStarts.size() == 0) { 10507 sr.startRequested = false; 10508 if (!hasClients) { 10509 // Whoops, no reason to restart! 10510 bringDownServiceLocked(sr, true); 10511 } 10512 } 10513 } 10514 } 10515 } 10516 10517 if (!allowRestart) { 10518 app.services.clear(); 10519 } 10520 } 10521 10522 // Make sure we have no more records on the stopping list. 10523 int i = mStoppingServices.size(); 10524 while (i > 0) { 10525 i--; 10526 ServiceRecord sr = mStoppingServices.get(i); 10527 if (sr.app == app) { 10528 mStoppingServices.remove(i); 10529 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10530 } 10531 } 10532 10533 app.executingServices.clear(); 10534 } 10535 10536 private final void removeDyingProviderLocked(ProcessRecord proc, 10537 ContentProviderRecord cpr) { 10538 synchronized (cpr) { 10539 cpr.launchingApp = null; 10540 cpr.notifyAll(); 10541 } 10542 10543 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10544 String names[] = cpr.info.authority.split(";"); 10545 for (int j = 0; j < names.length; j++) { 10546 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10547 } 10548 10549 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 10550 while (cit.hasNext()) { 10551 ProcessRecord capp = cit.next(); 10552 if (!capp.persistent && capp.thread != null 10553 && capp.pid != 0 10554 && capp.pid != MY_PID) { 10555 Slog.i(TAG, "Kill " + capp.processName 10556 + " (pid " + capp.pid + "): provider " + cpr.info.name 10557 + " in dying process " + (proc != null ? proc.processName : "??")); 10558 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10559 capp.processName, capp.setAdj, "dying provider " 10560 + cpr.name.toShortString()); 10561 Process.killProcessQuiet(capp.pid); 10562 } 10563 } 10564 10565 mLaunchingProviders.remove(cpr); 10566 } 10567 10568 /** 10569 * Main code for cleaning up a process when it has gone away. This is 10570 * called both as a result of the process dying, or directly when stopping 10571 * a process when running in single process mode. 10572 */ 10573 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10574 boolean restarting, boolean allowRestart, int index) { 10575 if (index >= 0) { 10576 mLruProcesses.remove(index); 10577 } 10578 10579 mProcessesToGc.remove(app); 10580 10581 // Dismiss any open dialogs. 10582 if (app.crashDialog != null) { 10583 app.crashDialog.dismiss(); 10584 app.crashDialog = null; 10585 } 10586 if (app.anrDialog != null) { 10587 app.anrDialog.dismiss(); 10588 app.anrDialog = null; 10589 } 10590 if (app.waitDialog != null) { 10591 app.waitDialog.dismiss(); 10592 app.waitDialog = null; 10593 } 10594 10595 app.crashing = false; 10596 app.notResponding = false; 10597 10598 app.resetPackageList(); 10599 app.unlinkDeathRecipient(); 10600 app.thread = null; 10601 app.forcingToForeground = null; 10602 app.foregroundServices = false; 10603 app.foregroundActivities = false; 10604 app.hasShownUi = false; 10605 app.hasAboveClient = false; 10606 10607 killServicesLocked(app, allowRestart); 10608 10609 boolean restart = false; 10610 10611 int NL = mLaunchingProviders.size(); 10612 10613 // Remove published content providers. 10614 if (!app.pubProviders.isEmpty()) { 10615 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10616 while (it.hasNext()) { 10617 ContentProviderRecord cpr = it.next(); 10618 cpr.provider = null; 10619 cpr.proc = null; 10620 10621 // See if someone is waiting for this provider... in which 10622 // case we don't remove it, but just let it restart. 10623 int i = 0; 10624 if (!app.bad && allowRestart) { 10625 for (; i<NL; i++) { 10626 if (mLaunchingProviders.get(i) == cpr) { 10627 restart = true; 10628 break; 10629 } 10630 } 10631 } else { 10632 i = NL; 10633 } 10634 10635 if (i >= NL) { 10636 removeDyingProviderLocked(app, cpr); 10637 NL = mLaunchingProviders.size(); 10638 } 10639 } 10640 app.pubProviders.clear(); 10641 } 10642 10643 // Take care of any launching providers waiting for this process. 10644 if (checkAppInLaunchingProvidersLocked(app, false)) { 10645 restart = true; 10646 } 10647 10648 // Unregister from connected content providers. 10649 if (!app.conProviders.isEmpty()) { 10650 Iterator it = app.conProviders.keySet().iterator(); 10651 while (it.hasNext()) { 10652 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10653 cpr.clients.remove(app); 10654 } 10655 app.conProviders.clear(); 10656 } 10657 10658 // At this point there may be remaining entries in mLaunchingProviders 10659 // where we were the only one waiting, so they are no longer of use. 10660 // Look for these and clean up if found. 10661 // XXX Commented out for now. Trying to figure out a way to reproduce 10662 // the actual situation to identify what is actually going on. 10663 if (false) { 10664 for (int i=0; i<NL; i++) { 10665 ContentProviderRecord cpr = (ContentProviderRecord) 10666 mLaunchingProviders.get(i); 10667 if (cpr.clients.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10668 synchronized (cpr) { 10669 cpr.launchingApp = null; 10670 cpr.notifyAll(); 10671 } 10672 } 10673 } 10674 } 10675 10676 skipCurrentReceiverLocked(app); 10677 10678 // Unregister any receivers. 10679 if (app.receivers.size() > 0) { 10680 Iterator<ReceiverList> it = app.receivers.iterator(); 10681 while (it.hasNext()) { 10682 removeReceiverLocked(it.next()); 10683 } 10684 app.receivers.clear(); 10685 } 10686 10687 // If the app is undergoing backup, tell the backup manager about it 10688 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10689 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10690 try { 10691 IBackupManager bm = IBackupManager.Stub.asInterface( 10692 ServiceManager.getService(Context.BACKUP_SERVICE)); 10693 bm.agentDisconnected(app.info.packageName); 10694 } catch (RemoteException e) { 10695 // can't happen; backup manager is local 10696 } 10697 } 10698 10699 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10700 10701 // If the caller is restarting this app, then leave it in its 10702 // current lists and let the caller take care of it. 10703 if (restarting) { 10704 return; 10705 } 10706 10707 if (!app.persistent || app.isolated) { 10708 if (DEBUG_PROCESSES) Slog.v(TAG, 10709 "Removing non-persistent process during cleanup: " + app); 10710 mProcessNames.remove(app.processName, app.uid); 10711 mIsolatedProcesses.remove(app.uid); 10712 if (mHeavyWeightProcess == app) { 10713 mHeavyWeightProcess = null; 10714 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10715 } 10716 } else if (!app.removed) { 10717 // This app is persistent, so we need to keep its record around. 10718 // If it is not already on the pending app list, add it there 10719 // and start a new process for it. 10720 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10721 mPersistentStartingProcesses.add(app); 10722 restart = true; 10723 } 10724 } 10725 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10726 "Clean-up removing on hold: " + app); 10727 mProcessesOnHold.remove(app); 10728 10729 if (app == mHomeProcess) { 10730 mHomeProcess = null; 10731 } 10732 if (app == mPreviousProcess) { 10733 mPreviousProcess = null; 10734 } 10735 10736 if (restart && !app.isolated) { 10737 // We have components that still need to be running in the 10738 // process, so re-launch it. 10739 mProcessNames.put(app.processName, app.uid, app); 10740 startProcessLocked(app, "restart", app.processName); 10741 } else if (app.pid > 0 && app.pid != MY_PID) { 10742 // Goodbye! 10743 synchronized (mPidsSelfLocked) { 10744 mPidsSelfLocked.remove(app.pid); 10745 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10746 } 10747 app.setPid(0); 10748 } 10749 } 10750 10751 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10752 // Look through the content providers we are waiting to have launched, 10753 // and if any run in this process then either schedule a restart of 10754 // the process or kill the client waiting for it if this process has 10755 // gone bad. 10756 int NL = mLaunchingProviders.size(); 10757 boolean restart = false; 10758 for (int i=0; i<NL; i++) { 10759 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10760 if (cpr.launchingApp == app) { 10761 if (!alwaysBad && !app.bad) { 10762 restart = true; 10763 } else { 10764 removeDyingProviderLocked(app, cpr); 10765 NL = mLaunchingProviders.size(); 10766 } 10767 } 10768 } 10769 return restart; 10770 } 10771 10772 // ========================================================= 10773 // SERVICES 10774 // ========================================================= 10775 10776 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10777 ActivityManager.RunningServiceInfo info = 10778 new ActivityManager.RunningServiceInfo(); 10779 info.service = r.name; 10780 if (r.app != null) { 10781 info.pid = r.app.pid; 10782 } 10783 info.uid = r.appInfo.uid; 10784 info.process = r.processName; 10785 info.foreground = r.isForeground; 10786 info.activeSince = r.createTime; 10787 info.started = r.startRequested; 10788 info.clientCount = r.connections.size(); 10789 info.crashCount = r.crashCount; 10790 info.lastActivityTime = r.lastActivity; 10791 if (r.isForeground) { 10792 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10793 } 10794 if (r.startRequested) { 10795 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10796 } 10797 if (r.app != null && r.app.pid == MY_PID) { 10798 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10799 } 10800 if (r.app != null && r.app.persistent) { 10801 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10802 } 10803 10804 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 10805 for (int i=0; i<connl.size(); i++) { 10806 ConnectionRecord conn = connl.get(i); 10807 if (conn.clientLabel != 0) { 10808 info.clientPackage = conn.binding.client.info.packageName; 10809 info.clientLabel = conn.clientLabel; 10810 return info; 10811 } 10812 } 10813 } 10814 return info; 10815 } 10816 10817 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10818 int flags) { 10819 enforceNotIsolatedCaller("getServices"); 10820 synchronized (this) { 10821 ArrayList<ActivityManager.RunningServiceInfo> res 10822 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10823 10824 int userId = UserId.getUserId(Binder.getCallingUid()); 10825 if (mServiceMap.getAllServices(userId).size() > 0) { 10826 Iterator<ServiceRecord> it 10827 = mServiceMap.getAllServices(userId).iterator(); 10828 while (it.hasNext() && res.size() < maxNum) { 10829 res.add(makeRunningServiceInfoLocked(it.next())); 10830 } 10831 } 10832 10833 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10834 ServiceRecord r = mRestartingServices.get(i); 10835 ActivityManager.RunningServiceInfo info = 10836 makeRunningServiceInfoLocked(r); 10837 info.restarting = r.nextRestartTime; 10838 res.add(info); 10839 } 10840 10841 return res; 10842 } 10843 } 10844 10845 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10846 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10847 synchronized (this) { 10848 int userId = UserId.getUserId(Binder.getCallingUid()); 10849 ServiceRecord r = mServiceMap.getServiceByName(name, userId); 10850 if (r != null) { 10851 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 10852 for (int i=0; i<conn.size(); i++) { 10853 if (conn.get(i).clientIntent != null) { 10854 return conn.get(i).clientIntent; 10855 } 10856 } 10857 } 10858 } 10859 } 10860 return null; 10861 } 10862 10863 private final ServiceRecord findServiceLocked(ComponentName name, 10864 IBinder token) { 10865 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 10866 return r == token ? r : null; 10867 } 10868 10869 private final class ServiceLookupResult { 10870 final ServiceRecord record; 10871 final String permission; 10872 10873 ServiceLookupResult(ServiceRecord _record, String _permission) { 10874 record = _record; 10875 permission = _permission; 10876 } 10877 }; 10878 10879 private ServiceLookupResult findServiceLocked(Intent service, 10880 String resolvedType, int userId) { 10881 ServiceRecord r = null; 10882 if (service.getComponent() != null) { 10883 r = mServiceMap.getServiceByName(service.getComponent(), userId); 10884 } 10885 if (r == null) { 10886 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10887 r = mServiceMap.getServiceByIntent(filter, userId); 10888 } 10889 10890 if (r == null) { 10891 try { 10892 ResolveInfo rInfo = 10893 AppGlobals.getPackageManager().resolveService( 10894 service, resolvedType, 0, userId); 10895 ServiceInfo sInfo = 10896 rInfo != null ? rInfo.serviceInfo : null; 10897 if (sInfo == null) { 10898 return null; 10899 } 10900 10901 ComponentName name = new ComponentName( 10902 sInfo.applicationInfo.packageName, sInfo.name); 10903 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 10904 } catch (RemoteException ex) { 10905 // pm is in same process, this will never happen. 10906 } 10907 } 10908 if (r != null) { 10909 int callingPid = Binder.getCallingPid(); 10910 int callingUid = Binder.getCallingUid(); 10911 if (checkComponentPermission(r.permission, 10912 callingPid, callingUid, r.appInfo.uid, r.exported) 10913 != PackageManager.PERMISSION_GRANTED) { 10914 if (!r.exported) { 10915 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10916 + " from pid=" + callingPid 10917 + ", uid=" + callingUid 10918 + " that is not exported from uid " + r.appInfo.uid); 10919 return new ServiceLookupResult(null, "not exported from uid " 10920 + r.appInfo.uid); 10921 } 10922 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10923 + " from pid=" + callingPid 10924 + ", uid=" + callingUid 10925 + " requires " + r.permission); 10926 return new ServiceLookupResult(null, r.permission); 10927 } 10928 return new ServiceLookupResult(r, null); 10929 } 10930 return null; 10931 } 10932 10933 private class ServiceRestarter implements Runnable { 10934 private ServiceRecord mService; 10935 10936 void setService(ServiceRecord service) { 10937 mService = service; 10938 } 10939 10940 public void run() { 10941 synchronized(ActivityManagerService.this) { 10942 performServiceRestartLocked(mService); 10943 } 10944 } 10945 } 10946 10947 private ServiceLookupResult retrieveServiceLocked(Intent service, 10948 String resolvedType, int callingPid, int callingUid, int userId) { 10949 ServiceRecord r = null; 10950 if (DEBUG_SERVICE) 10951 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType 10952 + " callingUid=" + callingUid); 10953 10954 if (service.getComponent() != null) { 10955 r = mServiceMap.getServiceByName(service.getComponent(), userId); 10956 } 10957 if (r == null) { 10958 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10959 r = mServiceMap.getServiceByIntent(filter, userId); 10960 } 10961 if (r == null) { 10962 try { 10963 ResolveInfo rInfo = 10964 AppGlobals.getPackageManager().resolveService( 10965 service, resolvedType, STOCK_PM_FLAGS, userId); 10966 ServiceInfo sInfo = 10967 rInfo != null ? rInfo.serviceInfo : null; 10968 if (sInfo == null) { 10969 Slog.w(TAG, "Unable to start service " + service + 10970 ": not found"); 10971 return null; 10972 } 10973 if (userId > 0) { 10974 if (isSingleton(sInfo.processName, sInfo.applicationInfo)) { 10975 userId = 0; 10976 } 10977 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId); 10978 } 10979 ComponentName name = new ComponentName( 10980 sInfo.applicationInfo.packageName, sInfo.name); 10981 r = mServiceMap.getServiceByName(name, userId); 10982 if (r == null) { 10983 Intent.FilterComparison filter = new Intent.FilterComparison( 10984 service.cloneFilter()); 10985 ServiceRestarter res = new ServiceRestarter(); 10986 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10987 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10988 synchronized (stats) { 10989 ss = stats.getServiceStatsLocked( 10990 sInfo.applicationInfo.uid, sInfo.packageName, 10991 sInfo.name); 10992 } 10993 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 10994 res.setService(r); 10995 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r); 10996 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r); 10997 10998 // Make sure this component isn't in the pending list. 10999 int N = mPendingServices.size(); 11000 for (int i=0; i<N; i++) { 11001 ServiceRecord pr = mPendingServices.get(i); 11002 if (pr.name.equals(name)) { 11003 mPendingServices.remove(i); 11004 i--; 11005 N--; 11006 } 11007 } 11008 } 11009 } catch (RemoteException ex) { 11010 // pm is in same process, this will never happen. 11011 } 11012 } 11013 if (r != null) { 11014 if (checkComponentPermission(r.permission, 11015 callingPid, callingUid, r.appInfo.uid, r.exported) 11016 != PackageManager.PERMISSION_GRANTED) { 11017 if (!r.exported) { 11018 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11019 + " from pid=" + callingPid 11020 + ", uid=" + callingUid 11021 + " that is not exported from uid " + r.appInfo.uid); 11022 return new ServiceLookupResult(null, "not exported from uid " 11023 + r.appInfo.uid); 11024 } 11025 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11026 + " from pid=" + callingPid 11027 + ", uid=" + callingUid 11028 + " requires " + r.permission); 11029 return new ServiceLookupResult(null, r.permission); 11030 } 11031 return new ServiceLookupResult(r, null); 11032 } 11033 return null; 11034 } 11035 11036 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 11037 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 11038 + why + " of " + r + " in app " + r.app); 11039 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 11040 + why + " of " + r.shortName); 11041 long now = SystemClock.uptimeMillis(); 11042 if (r.executeNesting == 0 && r.app != null) { 11043 if (r.app.executingServices.size() == 0) { 11044 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11045 msg.obj = r.app; 11046 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 11047 } 11048 r.app.executingServices.add(r); 11049 } 11050 r.executeNesting++; 11051 r.executingStart = now; 11052 } 11053 11054 private final void sendServiceArgsLocked(ServiceRecord r, 11055 boolean oomAdjusted) { 11056 final int N = r.pendingStarts.size(); 11057 if (N == 0) { 11058 return; 11059 } 11060 11061 while (r.pendingStarts.size() > 0) { 11062 try { 11063 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 11064 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 11065 + r + " " + r.intent + " args=" + si.intent); 11066 if (si.intent == null && N > 1) { 11067 // If somehow we got a dummy null intent in the middle, 11068 // then skip it. DO NOT skip a null intent when it is 11069 // the only one in the list -- this is to support the 11070 // onStartCommand(null) case. 11071 continue; 11072 } 11073 si.deliveredTime = SystemClock.uptimeMillis(); 11074 r.deliveredStarts.add(si); 11075 si.deliveryCount++; 11076 if (si.neededGrants != null) { 11077 grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, 11078 si.getUriPermissionsLocked()); 11079 } 11080 bumpServiceExecutingLocked(r, "start"); 11081 if (!oomAdjusted) { 11082 oomAdjusted = true; 11083 updateOomAdjLocked(r.app); 11084 } 11085 int flags = 0; 11086 if (si.deliveryCount > 1) { 11087 flags |= Service.START_FLAG_RETRY; 11088 } 11089 if (si.doneExecutingCount > 0) { 11090 flags |= Service.START_FLAG_REDELIVERY; 11091 } 11092 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 11093 } catch (RemoteException e) { 11094 // Remote process gone... we'll let the normal cleanup take 11095 // care of this. 11096 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 11097 break; 11098 } catch (Exception e) { 11099 Slog.w(TAG, "Unexpected exception", e); 11100 break; 11101 } 11102 } 11103 } 11104 11105 private final boolean requestServiceBindingLocked(ServiceRecord r, 11106 IntentBindRecord i, boolean rebind) { 11107 if (r.app == null || r.app.thread == null) { 11108 // If service is not currently running, can't yet bind. 11109 return false; 11110 } 11111 if ((!i.requested || rebind) && i.apps.size() > 0) { 11112 try { 11113 bumpServiceExecutingLocked(r, "bind"); 11114 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 11115 if (!rebind) { 11116 i.requested = true; 11117 } 11118 i.hasBound = true; 11119 i.doRebind = false; 11120 } catch (RemoteException e) { 11121 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 11122 return false; 11123 } 11124 } 11125 return true; 11126 } 11127 11128 private final void requestServiceBindingsLocked(ServiceRecord r) { 11129 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 11130 while (bindings.hasNext()) { 11131 IntentBindRecord i = bindings.next(); 11132 if (!requestServiceBindingLocked(r, i, false)) { 11133 break; 11134 } 11135 } 11136 } 11137 11138 private final void realStartServiceLocked(ServiceRecord r, 11139 ProcessRecord app) throws RemoteException { 11140 if (app.thread == null) { 11141 throw new RemoteException(); 11142 } 11143 if (DEBUG_MU) 11144 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid 11145 + ", ProcessRecord.uid = " + app.uid); 11146 r.app = app; 11147 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 11148 11149 app.services.add(r); 11150 bumpServiceExecutingLocked(r, "create"); 11151 updateLruProcessLocked(app, true, true); 11152 11153 boolean created = false; 11154 try { 11155 mStringBuilder.setLength(0); 11156 r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false); 11157 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 11158 System.identityHashCode(r), r.shortName, 11159 mStringBuilder.toString(), r.app.pid); 11160 synchronized (r.stats.getBatteryStats()) { 11161 r.stats.startLaunchedLocked(); 11162 } 11163 ensurePackageDexOpt(r.serviceInfo.packageName); 11164 app.thread.scheduleCreateService(r, r.serviceInfo, 11165 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 11166 r.postNotification(); 11167 created = true; 11168 } finally { 11169 if (!created) { 11170 app.services.remove(r); 11171 scheduleServiceRestartLocked(r, false); 11172 } 11173 } 11174 11175 requestServiceBindingsLocked(r); 11176 11177 // If the service is in the started state, and there are no 11178 // pending arguments, then fake up one so its onStartCommand() will 11179 // be called. 11180 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 11181 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11182 null, null)); 11183 } 11184 11185 sendServiceArgsLocked(r, true); 11186 } 11187 11188 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 11189 boolean allowCancel) { 11190 boolean canceled = false; 11191 11192 final long now = SystemClock.uptimeMillis(); 11193 long minDuration = SERVICE_RESTART_DURATION; 11194 long resetTime = SERVICE_RESET_RUN_DURATION; 11195 11196 if ((r.serviceInfo.applicationInfo.flags 11197 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11198 minDuration /= 4; 11199 } 11200 11201 // Any delivered but not yet finished starts should be put back 11202 // on the pending list. 11203 final int N = r.deliveredStarts.size(); 11204 if (N > 0) { 11205 for (int i=N-1; i>=0; i--) { 11206 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 11207 si.removeUriPermissionsLocked(); 11208 if (si.intent == null) { 11209 // We'll generate this again if needed. 11210 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 11211 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 11212 r.pendingStarts.add(0, si); 11213 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 11214 dur *= 2; 11215 if (minDuration < dur) minDuration = dur; 11216 if (resetTime < dur) resetTime = dur; 11217 } else { 11218 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 11219 + r.name); 11220 canceled = true; 11221 } 11222 } 11223 r.deliveredStarts.clear(); 11224 } 11225 11226 r.totalRestartCount++; 11227 if (r.restartDelay == 0) { 11228 r.restartCount++; 11229 r.restartDelay = minDuration; 11230 } else { 11231 // If it has been a "reasonably long time" since the service 11232 // was started, then reset our restart duration back to 11233 // the beginning, so we don't infinitely increase the duration 11234 // on a service that just occasionally gets killed (which is 11235 // a normal case, due to process being killed to reclaim memory). 11236 if (now > (r.restartTime+resetTime)) { 11237 r.restartCount = 1; 11238 r.restartDelay = minDuration; 11239 } else { 11240 if ((r.serviceInfo.applicationInfo.flags 11241 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11242 // Services in peristent processes will restart much more 11243 // quickly, since they are pretty important. (Think SystemUI). 11244 r.restartDelay += minDuration/2; 11245 } else { 11246 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 11247 if (r.restartDelay < minDuration) { 11248 r.restartDelay = minDuration; 11249 } 11250 } 11251 } 11252 } 11253 11254 r.nextRestartTime = now + r.restartDelay; 11255 11256 // Make sure that we don't end up restarting a bunch of services 11257 // all at the same time. 11258 boolean repeat; 11259 do { 11260 repeat = false; 11261 for (int i=mRestartingServices.size()-1; i>=0; i--) { 11262 ServiceRecord r2 = mRestartingServices.get(i); 11263 if (r2 != r && r.nextRestartTime 11264 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 11265 && r.nextRestartTime 11266 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 11267 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 11268 r.restartDelay = r.nextRestartTime - now; 11269 repeat = true; 11270 break; 11271 } 11272 } 11273 } while (repeat); 11274 11275 if (!mRestartingServices.contains(r)) { 11276 mRestartingServices.add(r); 11277 } 11278 11279 r.cancelNotification(); 11280 11281 mHandler.removeCallbacks(r.restarter); 11282 mHandler.postAtTime(r.restarter, r.nextRestartTime); 11283 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 11284 Slog.w(TAG, "Scheduling restart of crashed service " 11285 + r.shortName + " in " + r.restartDelay + "ms"); 11286 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 11287 r.shortName, r.restartDelay); 11288 11289 return canceled; 11290 } 11291 11292 final void performServiceRestartLocked(ServiceRecord r) { 11293 if (!mRestartingServices.contains(r)) { 11294 return; 11295 } 11296 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 11297 } 11298 11299 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 11300 if (r.restartDelay == 0) { 11301 return false; 11302 } 11303 r.resetRestartCounter(); 11304 mRestartingServices.remove(r); 11305 mHandler.removeCallbacks(r.restarter); 11306 return true; 11307 } 11308 11309 private final boolean bringUpServiceLocked(ServiceRecord r, 11310 int intentFlags, boolean whileRestarting) { 11311 //Slog.i(TAG, "Bring up service:"); 11312 //r.dump(" "); 11313 11314 if (r.app != null && r.app.thread != null) { 11315 sendServiceArgsLocked(r, false); 11316 return true; 11317 } 11318 11319 if (!whileRestarting && r.restartDelay > 0) { 11320 // If waiting for a restart, then do nothing. 11321 return true; 11322 } 11323 11324 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 11325 11326 // We are now bringing the service up, so no longer in the 11327 // restarting state. 11328 mRestartingServices.remove(r); 11329 11330 // Service is now being launched, its package can't be stopped. 11331 try { 11332 AppGlobals.getPackageManager().setPackageStoppedState( 11333 r.packageName, false, r.userId); 11334 } catch (RemoteException e) { 11335 } catch (IllegalArgumentException e) { 11336 Slog.w(TAG, "Failed trying to unstop package " 11337 + r.packageName + ": " + e); 11338 } 11339 11340 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; 11341 final String appName = r.processName; 11342 ProcessRecord app; 11343 11344 if (!isolated) { 11345 app = getProcessRecordLocked(appName, r.appInfo.uid); 11346 if (DEBUG_MU) 11347 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); 11348 if (app != null && app.thread != null) { 11349 try { 11350 app.addPackage(r.appInfo.packageName); 11351 realStartServiceLocked(r, app); 11352 return true; 11353 } catch (RemoteException e) { 11354 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 11355 } 11356 11357 // If a dead object exception was thrown -- fall through to 11358 // restart the application. 11359 } 11360 } else { 11361 // If this service runs in an isolated process, then each time 11362 // we call startProcessLocked() we will get a new isolated 11363 // process, starting another process if we are currently waiting 11364 // for a previous process to come up. To deal with this, we store 11365 // in the service any current isolated process it is running in or 11366 // waiting to have come up. 11367 app = r.isolatedProc; 11368 } 11369 11370 // Not running -- get it started, and enqueue this service record 11371 // to be executed when the app comes up. 11372 if (app == null) { 11373 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags, 11374 "service", r.name, false, isolated)) == null) { 11375 Slog.w(TAG, "Unable to launch app " 11376 + r.appInfo.packageName + "/" 11377 + r.appInfo.uid + " for service " 11378 + r.intent.getIntent() + ": process is bad"); 11379 bringDownServiceLocked(r, true); 11380 return false; 11381 } 11382 if (isolated) { 11383 r.isolatedProc = app; 11384 } 11385 } 11386 11387 if (!mPendingServices.contains(r)) { 11388 mPendingServices.add(r); 11389 } 11390 11391 return true; 11392 } 11393 11394 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 11395 //Slog.i(TAG, "Bring down service:"); 11396 //r.dump(" "); 11397 11398 // Does it still need to run? 11399 if (!force && r.startRequested) { 11400 return; 11401 } 11402 if (r.connections.size() > 0) { 11403 if (!force) { 11404 // XXX should probably keep a count of the number of auto-create 11405 // connections directly in the service. 11406 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11407 while (it.hasNext()) { 11408 ArrayList<ConnectionRecord> cr = it.next(); 11409 for (int i=0; i<cr.size(); i++) { 11410 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 11411 return; 11412 } 11413 } 11414 } 11415 } 11416 11417 // Report to all of the connections that the service is no longer 11418 // available. 11419 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11420 while (it.hasNext()) { 11421 ArrayList<ConnectionRecord> c = it.next(); 11422 for (int i=0; i<c.size(); i++) { 11423 ConnectionRecord cr = c.get(i); 11424 // There is still a connection to the service that is 11425 // being brought down. Mark it as dead. 11426 cr.serviceDead = true; 11427 try { 11428 cr.conn.connected(r.name, null); 11429 } catch (Exception e) { 11430 Slog.w(TAG, "Failure disconnecting service " + r.name + 11431 " to connection " + c.get(i).conn.asBinder() + 11432 " (in " + c.get(i).binding.client.processName + ")", e); 11433 } 11434 } 11435 } 11436 } 11437 11438 // Tell the service that it has been unbound. 11439 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 11440 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 11441 while (it.hasNext()) { 11442 IntentBindRecord ibr = it.next(); 11443 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 11444 + ": hasBound=" + ibr.hasBound); 11445 if (r.app != null && r.app.thread != null && ibr.hasBound) { 11446 try { 11447 bumpServiceExecutingLocked(r, "bring down unbind"); 11448 updateOomAdjLocked(r.app); 11449 ibr.hasBound = false; 11450 r.app.thread.scheduleUnbindService(r, 11451 ibr.intent.getIntent()); 11452 } catch (Exception e) { 11453 Slog.w(TAG, "Exception when unbinding service " 11454 + r.shortName, e); 11455 serviceDoneExecutingLocked(r, true); 11456 } 11457 } 11458 } 11459 } 11460 11461 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 11462 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 11463 System.identityHashCode(r), r.shortName, 11464 (r.app != null) ? r.app.pid : -1); 11465 11466 mServiceMap.removeServiceByName(r.name, r.userId); 11467 mServiceMap.removeServiceByIntent(r.intent, r.userId); 11468 r.totalRestartCount = 0; 11469 unscheduleServiceRestartLocked(r); 11470 11471 // Also make sure it is not on the pending list. 11472 int N = mPendingServices.size(); 11473 for (int i=0; i<N; i++) { 11474 if (mPendingServices.get(i) == r) { 11475 mPendingServices.remove(i); 11476 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 11477 i--; 11478 N--; 11479 } 11480 } 11481 11482 r.cancelNotification(); 11483 r.isForeground = false; 11484 r.foregroundId = 0; 11485 r.foregroundNoti = null; 11486 11487 // Clear start entries. 11488 r.clearDeliveredStartsLocked(); 11489 r.pendingStarts.clear(); 11490 11491 if (r.app != null) { 11492 synchronized (r.stats.getBatteryStats()) { 11493 r.stats.stopLaunchedLocked(); 11494 } 11495 r.app.services.remove(r); 11496 if (r.app.thread != null) { 11497 try { 11498 bumpServiceExecutingLocked(r, "stop"); 11499 mStoppingServices.add(r); 11500 updateOomAdjLocked(r.app); 11501 r.app.thread.scheduleStopService(r); 11502 } catch (Exception e) { 11503 Slog.w(TAG, "Exception when stopping service " 11504 + r.shortName, e); 11505 serviceDoneExecutingLocked(r, true); 11506 } 11507 updateServiceForegroundLocked(r.app, false); 11508 } else { 11509 if (DEBUG_SERVICE) Slog.v( 11510 TAG, "Removed service that has no process: " + r); 11511 } 11512 } else { 11513 if (DEBUG_SERVICE) Slog.v( 11514 TAG, "Removed service that is not running: " + r); 11515 } 11516 11517 if (r.bindings.size() > 0) { 11518 r.bindings.clear(); 11519 } 11520 11521 if (r.restarter instanceof ServiceRestarter) { 11522 ((ServiceRestarter)r.restarter).setService(null); 11523 } 11524 } 11525 11526 ComponentName startServiceLocked(IApplicationThread caller, 11527 Intent service, String resolvedType, 11528 int callingPid, int callingUid) { 11529 synchronized(this) { 11530 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11531 + " type=" + resolvedType + " args=" + service.getExtras()); 11532 11533 if (caller != null) { 11534 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11535 if (callerApp == null) { 11536 throw new SecurityException( 11537 "Unable to find app for caller " + caller 11538 + " (pid=" + Binder.getCallingPid() 11539 + ") when starting service " + service); 11540 } 11541 } 11542 11543 ServiceLookupResult res = 11544 retrieveServiceLocked(service, resolvedType, 11545 callingPid, callingUid, UserId.getUserId(callingUid)); 11546 if (res == null) { 11547 return null; 11548 } 11549 if (res.record == null) { 11550 return new ComponentName("!", res.permission != null 11551 ? res.permission : "private to package"); 11552 } 11553 ServiceRecord r = res.record; 11554 NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked( 11555 callingUid, r.packageName, service, service.getFlags(), null); 11556 if (unscheduleServiceRestartLocked(r)) { 11557 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 11558 } 11559 r.startRequested = true; 11560 r.callStart = false; 11561 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11562 service, neededGrants)); 11563 r.lastActivity = SystemClock.uptimeMillis(); 11564 synchronized (r.stats.getBatteryStats()) { 11565 r.stats.startRunningLocked(); 11566 } 11567 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11568 return new ComponentName("!", "Service process is bad"); 11569 } 11570 return r.name; 11571 } 11572 } 11573 11574 public ComponentName startService(IApplicationThread caller, Intent service, 11575 String resolvedType) { 11576 enforceNotIsolatedCaller("startService"); 11577 // Refuse possible leaked file descriptors 11578 if (service != null && service.hasFileDescriptors() == true) { 11579 throw new IllegalArgumentException("File descriptors passed in Intent"); 11580 } 11581 11582 if (DEBUG_SERVICE) 11583 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 11584 synchronized(this) { 11585 final int callingPid = Binder.getCallingPid(); 11586 final int callingUid = Binder.getCallingUid(); 11587 final long origId = Binder.clearCallingIdentity(); 11588 ComponentName res = startServiceLocked(caller, service, 11589 resolvedType, callingPid, callingUid); 11590 Binder.restoreCallingIdentity(origId); 11591 return res; 11592 } 11593 } 11594 11595 ComponentName startServiceInPackage(int uid, 11596 Intent service, String resolvedType) { 11597 synchronized(this) { 11598 if (DEBUG_SERVICE) 11599 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 11600 final long origId = Binder.clearCallingIdentity(); 11601 ComponentName res = startServiceLocked(null, service, 11602 resolvedType, -1, uid); 11603 Binder.restoreCallingIdentity(origId); 11604 return res; 11605 } 11606 } 11607 11608 private void stopServiceLocked(ServiceRecord service) { 11609 synchronized (service.stats.getBatteryStats()) { 11610 service.stats.stopRunningLocked(); 11611 } 11612 service.startRequested = false; 11613 service.callStart = false; 11614 bringDownServiceLocked(service, false); 11615 } 11616 11617 public int stopService(IApplicationThread caller, Intent service, 11618 String resolvedType) { 11619 enforceNotIsolatedCaller("stopService"); 11620 // Refuse possible leaked file descriptors 11621 if (service != null && service.hasFileDescriptors() == true) { 11622 throw new IllegalArgumentException("File descriptors passed in Intent"); 11623 } 11624 11625 synchronized(this) { 11626 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11627 + " type=" + resolvedType); 11628 11629 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11630 if (caller != null && callerApp == null) { 11631 throw new SecurityException( 11632 "Unable to find app for caller " + caller 11633 + " (pid=" + Binder.getCallingPid() 11634 + ") when stopping service " + service); 11635 } 11636 11637 // If this service is active, make sure it is stopped. 11638 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11639 callerApp == null ? UserId.getCallingUserId() : callerApp.userId); 11640 if (r != null) { 11641 if (r.record != null) { 11642 final long origId = Binder.clearCallingIdentity(); 11643 try { 11644 stopServiceLocked(r.record); 11645 } finally { 11646 Binder.restoreCallingIdentity(origId); 11647 } 11648 return 1; 11649 } 11650 return -1; 11651 } 11652 } 11653 11654 return 0; 11655 } 11656 11657 public IBinder peekService(Intent service, String resolvedType) { 11658 enforceNotIsolatedCaller("peekService"); 11659 // Refuse possible leaked file descriptors 11660 if (service != null && service.hasFileDescriptors() == true) { 11661 throw new IllegalArgumentException("File descriptors passed in Intent"); 11662 } 11663 11664 IBinder ret = null; 11665 11666 synchronized(this) { 11667 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11668 UserId.getCallingUserId()); 11669 11670 if (r != null) { 11671 // r.record is null if findServiceLocked() failed the caller permission check 11672 if (r.record == null) { 11673 throw new SecurityException( 11674 "Permission Denial: Accessing service " + r.record.name 11675 + " from pid=" + Binder.getCallingPid() 11676 + ", uid=" + Binder.getCallingUid() 11677 + " requires " + r.permission); 11678 } 11679 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11680 if (ib != null) { 11681 ret = ib.binder; 11682 } 11683 } 11684 } 11685 11686 return ret; 11687 } 11688 11689 public boolean stopServiceToken(ComponentName className, IBinder token, 11690 int startId) { 11691 synchronized(this) { 11692 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11693 + " " + token + " startId=" + startId); 11694 ServiceRecord r = findServiceLocked(className, token); 11695 if (r != null) { 11696 if (startId >= 0) { 11697 // Asked to only stop if done with all work. Note that 11698 // to avoid leaks, we will take this as dropping all 11699 // start items up to and including this one. 11700 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11701 if (si != null) { 11702 while (r.deliveredStarts.size() > 0) { 11703 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 11704 cur.removeUriPermissionsLocked(); 11705 if (cur == si) { 11706 break; 11707 } 11708 } 11709 } 11710 11711 if (r.getLastStartId() != startId) { 11712 return false; 11713 } 11714 11715 if (r.deliveredStarts.size() > 0) { 11716 Slog.w(TAG, "stopServiceToken startId " + startId 11717 + " is last, but have " + r.deliveredStarts.size() 11718 + " remaining args"); 11719 } 11720 } 11721 11722 synchronized (r.stats.getBatteryStats()) { 11723 r.stats.stopRunningLocked(); 11724 r.startRequested = false; 11725 r.callStart = false; 11726 } 11727 final long origId = Binder.clearCallingIdentity(); 11728 bringDownServiceLocked(r, false); 11729 Binder.restoreCallingIdentity(origId); 11730 return true; 11731 } 11732 } 11733 return false; 11734 } 11735 11736 public void setServiceForeground(ComponentName className, IBinder token, 11737 int id, Notification notification, boolean removeNotification) { 11738 final long origId = Binder.clearCallingIdentity(); 11739 try { 11740 synchronized(this) { 11741 ServiceRecord r = findServiceLocked(className, token); 11742 if (r != null) { 11743 if (id != 0) { 11744 if (notification == null) { 11745 throw new IllegalArgumentException("null notification"); 11746 } 11747 if (r.foregroundId != id) { 11748 r.cancelNotification(); 11749 r.foregroundId = id; 11750 } 11751 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11752 r.foregroundNoti = notification; 11753 r.isForeground = true; 11754 r.postNotification(); 11755 if (r.app != null) { 11756 updateServiceForegroundLocked(r.app, true); 11757 } 11758 } else { 11759 if (r.isForeground) { 11760 r.isForeground = false; 11761 if (r.app != null) { 11762 updateLruProcessLocked(r.app, false, true); 11763 updateServiceForegroundLocked(r.app, true); 11764 } 11765 } 11766 if (removeNotification) { 11767 r.cancelNotification(); 11768 r.foregroundId = 0; 11769 r.foregroundNoti = null; 11770 } 11771 } 11772 } 11773 } 11774 } finally { 11775 Binder.restoreCallingIdentity(origId); 11776 } 11777 } 11778 11779 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11780 boolean anyForeground = false; 11781 for (ServiceRecord sr : proc.services) { 11782 if (sr.isForeground) { 11783 anyForeground = true; 11784 break; 11785 } 11786 } 11787 if (anyForeground != proc.foregroundServices) { 11788 proc.foregroundServices = anyForeground; 11789 if (oomAdj) { 11790 updateOomAdjLocked(); 11791 } 11792 } 11793 } 11794 11795 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) { 11796 boolean result = false; 11797 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11798 result = false; 11799 } else if (componentProcessName == aInfo.packageName) { 11800 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11801 } else if ("system".equals(componentProcessName)) { 11802 result = true; 11803 } 11804 if (DEBUG_MU) { 11805 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result); 11806 } 11807 return result; 11808 } 11809 11810 public int bindService(IApplicationThread caller, IBinder token, 11811 Intent service, String resolvedType, 11812 IServiceConnection connection, int flags, int userId) { 11813 enforceNotIsolatedCaller("bindService"); 11814 // Refuse possible leaked file descriptors 11815 if (service != null && service.hasFileDescriptors() == true) { 11816 throw new IllegalArgumentException("File descriptors passed in Intent"); 11817 } 11818 11819 checkValidCaller(Binder.getCallingUid(), userId); 11820 11821 synchronized(this) { 11822 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 11823 + " type=" + resolvedType + " conn=" + connection.asBinder() 11824 + " flags=0x" + Integer.toHexString(flags)); 11825 if (DEBUG_MU) 11826 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid=" 11827 + Binder.getOrigCallingUid()); 11828 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11829 if (callerApp == null) { 11830 throw new SecurityException( 11831 "Unable to find app for caller " + caller 11832 + " (pid=" + Binder.getCallingPid() 11833 + ") when binding service " + service); 11834 } 11835 11836 ActivityRecord activity = null; 11837 if (token != null) { 11838 activity = mMainStack.isInStackLocked(token); 11839 if (activity == null) { 11840 Slog.w(TAG, "Binding with unknown activity: " + token); 11841 return 0; 11842 } 11843 } 11844 11845 int clientLabel = 0; 11846 PendingIntent clientIntent = null; 11847 11848 if (callerApp.info.uid == Process.SYSTEM_UID) { 11849 // Hacky kind of thing -- allow system stuff to tell us 11850 // what they are, so we can report this elsewhere for 11851 // others to know why certain services are running. 11852 try { 11853 clientIntent = (PendingIntent)service.getParcelableExtra( 11854 Intent.EXTRA_CLIENT_INTENT); 11855 } catch (RuntimeException e) { 11856 } 11857 if (clientIntent != null) { 11858 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11859 if (clientLabel != 0) { 11860 // There are no useful extras in the intent, trash them. 11861 // System code calling with this stuff just needs to know 11862 // this will happen. 11863 service = service.cloneFilter(); 11864 } 11865 } 11866 } 11867 11868 ServiceLookupResult res = 11869 retrieveServiceLocked(service, resolvedType, 11870 Binder.getCallingPid(), Binder.getCallingUid(), userId); 11871 if (res == null) { 11872 return 0; 11873 } 11874 if (res.record == null) { 11875 return -1; 11876 } 11877 if (isSingleton(res.record.processName, res.record.appInfo)) { 11878 userId = 0; 11879 res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(), 11880 Binder.getCallingUid(), 0); 11881 } 11882 ServiceRecord s = res.record; 11883 11884 final long origId = Binder.clearCallingIdentity(); 11885 11886 if (unscheduleServiceRestartLocked(s)) { 11887 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11888 + s); 11889 } 11890 11891 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11892 ConnectionRecord c = new ConnectionRecord(b, activity, 11893 connection, flags, clientLabel, clientIntent); 11894 11895 IBinder binder = connection.asBinder(); 11896 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 11897 if (clist == null) { 11898 clist = new ArrayList<ConnectionRecord>(); 11899 s.connections.put(binder, clist); 11900 } 11901 clist.add(c); 11902 b.connections.add(c); 11903 if (activity != null) { 11904 if (activity.connections == null) { 11905 activity.connections = new HashSet<ConnectionRecord>(); 11906 } 11907 activity.connections.add(c); 11908 } 11909 b.client.connections.add(c); 11910 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 11911 b.client.hasAboveClient = true; 11912 } 11913 clist = mServiceConnections.get(binder); 11914 if (clist == null) { 11915 clist = new ArrayList<ConnectionRecord>(); 11916 mServiceConnections.put(binder, clist); 11917 } 11918 clist.add(c); 11919 11920 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11921 s.lastActivity = SystemClock.uptimeMillis(); 11922 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11923 return 0; 11924 } 11925 } 11926 11927 if (s.app != null) { 11928 // This could have made the service more important. 11929 updateOomAdjLocked(s.app); 11930 } 11931 11932 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 11933 + ": received=" + b.intent.received 11934 + " apps=" + b.intent.apps.size() 11935 + " doRebind=" + b.intent.doRebind); 11936 11937 if (s.app != null && b.intent.received) { 11938 // Service is already running, so we can immediately 11939 // publish the connection. 11940 try { 11941 c.conn.connected(s.name, b.intent.binder); 11942 } catch (Exception e) { 11943 Slog.w(TAG, "Failure sending service " + s.shortName 11944 + " to connection " + c.conn.asBinder() 11945 + " (in " + c.binding.client.processName + ")", e); 11946 } 11947 11948 // If this is the first app connected back to this binding, 11949 // and the service had previously asked to be told when 11950 // rebound, then do so. 11951 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11952 requestServiceBindingLocked(s, b.intent, true); 11953 } 11954 } else if (!b.intent.requested) { 11955 requestServiceBindingLocked(s, b.intent, false); 11956 } 11957 11958 Binder.restoreCallingIdentity(origId); 11959 } 11960 11961 return 1; 11962 } 11963 11964 void removeConnectionLocked( 11965 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 11966 IBinder binder = c.conn.asBinder(); 11967 AppBindRecord b = c.binding; 11968 ServiceRecord s = b.service; 11969 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 11970 if (clist != null) { 11971 clist.remove(c); 11972 if (clist.size() == 0) { 11973 s.connections.remove(binder); 11974 } 11975 } 11976 b.connections.remove(c); 11977 if (c.activity != null && c.activity != skipAct) { 11978 if (c.activity.connections != null) { 11979 c.activity.connections.remove(c); 11980 } 11981 } 11982 if (b.client != skipApp) { 11983 b.client.connections.remove(c); 11984 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 11985 b.client.updateHasAboveClientLocked(); 11986 } 11987 } 11988 clist = mServiceConnections.get(binder); 11989 if (clist != null) { 11990 clist.remove(c); 11991 if (clist.size() == 0) { 11992 mServiceConnections.remove(binder); 11993 } 11994 } 11995 11996 if (b.connections.size() == 0) { 11997 b.intent.apps.remove(b.client); 11998 } 11999 12000 if (!c.serviceDead) { 12001 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 12002 + ": shouldUnbind=" + b.intent.hasBound); 12003 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 12004 && b.intent.hasBound) { 12005 try { 12006 bumpServiceExecutingLocked(s, "unbind"); 12007 updateOomAdjLocked(s.app); 12008 b.intent.hasBound = false; 12009 // Assume the client doesn't want to know about a rebind; 12010 // we will deal with that later if it asks for one. 12011 b.intent.doRebind = false; 12012 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 12013 } catch (Exception e) { 12014 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 12015 serviceDoneExecutingLocked(s, true); 12016 } 12017 } 12018 12019 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 12020 bringDownServiceLocked(s, false); 12021 } 12022 } 12023 } 12024 12025 public boolean unbindService(IServiceConnection connection) { 12026 synchronized (this) { 12027 IBinder binder = connection.asBinder(); 12028 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 12029 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 12030 if (clist == null) { 12031 Slog.w(TAG, "Unbind failed: could not find connection for " 12032 + connection.asBinder()); 12033 return false; 12034 } 12035 12036 final long origId = Binder.clearCallingIdentity(); 12037 12038 while (clist.size() > 0) { 12039 ConnectionRecord r = clist.get(0); 12040 removeConnectionLocked(r, null, null); 12041 12042 if (r.binding.service.app != null) { 12043 // This could have made the service less important. 12044 updateOomAdjLocked(r.binding.service.app); 12045 } 12046 } 12047 12048 Binder.restoreCallingIdentity(origId); 12049 } 12050 12051 return true; 12052 } 12053 12054 public void publishService(IBinder token, Intent intent, IBinder service) { 12055 // Refuse possible leaked file descriptors 12056 if (intent != null && intent.hasFileDescriptors() == true) { 12057 throw new IllegalArgumentException("File descriptors passed in Intent"); 12058 } 12059 12060 synchronized(this) { 12061 if (!(token instanceof ServiceRecord)) { 12062 throw new IllegalArgumentException("Invalid service token"); 12063 } 12064 ServiceRecord r = (ServiceRecord)token; 12065 12066 final long origId = Binder.clearCallingIdentity(); 12067 12068 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 12069 + " " + intent + ": " + service); 12070 if (r != null) { 12071 Intent.FilterComparison filter 12072 = new Intent.FilterComparison(intent); 12073 IntentBindRecord b = r.bindings.get(filter); 12074 if (b != null && !b.received) { 12075 b.binder = service; 12076 b.requested = true; 12077 b.received = true; 12078 if (r.connections.size() > 0) { 12079 Iterator<ArrayList<ConnectionRecord>> it 12080 = r.connections.values().iterator(); 12081 while (it.hasNext()) { 12082 ArrayList<ConnectionRecord> clist = it.next(); 12083 for (int i=0; i<clist.size(); i++) { 12084 ConnectionRecord c = clist.get(i); 12085 if (!filter.equals(c.binding.intent.intent)) { 12086 if (DEBUG_SERVICE) Slog.v( 12087 TAG, "Not publishing to: " + c); 12088 if (DEBUG_SERVICE) Slog.v( 12089 TAG, "Bound intent: " + c.binding.intent.intent); 12090 if (DEBUG_SERVICE) Slog.v( 12091 TAG, "Published intent: " + intent); 12092 continue; 12093 } 12094 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 12095 try { 12096 c.conn.connected(r.name, service); 12097 } catch (Exception e) { 12098 Slog.w(TAG, "Failure sending service " + r.name + 12099 " to connection " + c.conn.asBinder() + 12100 " (in " + c.binding.client.processName + ")", e); 12101 } 12102 } 12103 } 12104 } 12105 } 12106 12107 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 12108 12109 Binder.restoreCallingIdentity(origId); 12110 } 12111 } 12112 } 12113 12114 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12115 // Refuse possible leaked file descriptors 12116 if (intent != null && intent.hasFileDescriptors() == true) { 12117 throw new IllegalArgumentException("File descriptors passed in Intent"); 12118 } 12119 12120 synchronized(this) { 12121 if (!(token instanceof ServiceRecord)) { 12122 throw new IllegalArgumentException("Invalid service token"); 12123 } 12124 ServiceRecord r = (ServiceRecord)token; 12125 12126 final long origId = Binder.clearCallingIdentity(); 12127 12128 if (r != null) { 12129 Intent.FilterComparison filter 12130 = new Intent.FilterComparison(intent); 12131 IntentBindRecord b = r.bindings.get(filter); 12132 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 12133 + " at " + b + ": apps=" 12134 + (b != null ? b.apps.size() : 0)); 12135 12136 boolean inStopping = mStoppingServices.contains(r); 12137 if (b != null) { 12138 if (b.apps.size() > 0 && !inStopping) { 12139 // Applications have already bound since the last 12140 // unbind, so just rebind right here. 12141 requestServiceBindingLocked(r, b, true); 12142 } else { 12143 // Note to tell the service the next time there is 12144 // a new client. 12145 b.doRebind = true; 12146 } 12147 } 12148 12149 serviceDoneExecutingLocked(r, inStopping); 12150 12151 Binder.restoreCallingIdentity(origId); 12152 } 12153 } 12154 } 12155 12156 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12157 synchronized(this) { 12158 if (!(token instanceof ServiceRecord)) { 12159 throw new IllegalArgumentException("Invalid service token"); 12160 } 12161 ServiceRecord r = (ServiceRecord)token; 12162 boolean inStopping = mStoppingServices.contains(token); 12163 if (r != null) { 12164 if (r != token) { 12165 Slog.w(TAG, "Done executing service " + r.name 12166 + " with incorrect token: given " + token 12167 + ", expected " + r); 12168 return; 12169 } 12170 12171 if (type == 1) { 12172 // This is a call from a service start... take care of 12173 // book-keeping. 12174 r.callStart = true; 12175 switch (res) { 12176 case Service.START_STICKY_COMPATIBILITY: 12177 case Service.START_STICKY: { 12178 // We are done with the associated start arguments. 12179 r.findDeliveredStart(startId, true); 12180 // Don't stop if killed. 12181 r.stopIfKilled = false; 12182 break; 12183 } 12184 case Service.START_NOT_STICKY: { 12185 // We are done with the associated start arguments. 12186 r.findDeliveredStart(startId, true); 12187 if (r.getLastStartId() == startId) { 12188 // There is no more work, and this service 12189 // doesn't want to hang around if killed. 12190 r.stopIfKilled = true; 12191 } 12192 break; 12193 } 12194 case Service.START_REDELIVER_INTENT: { 12195 // We'll keep this item until they explicitly 12196 // call stop for it, but keep track of the fact 12197 // that it was delivered. 12198 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 12199 if (si != null) { 12200 si.deliveryCount = 0; 12201 si.doneExecutingCount++; 12202 // Don't stop if killed. 12203 r.stopIfKilled = true; 12204 } 12205 break; 12206 } 12207 case Service.START_TASK_REMOVED_COMPLETE: { 12208 // Special processing for onTaskRemoved(). Don't 12209 // impact normal onStartCommand() processing. 12210 r.findDeliveredStart(startId, true); 12211 break; 12212 } 12213 default: 12214 throw new IllegalArgumentException( 12215 "Unknown service start result: " + res); 12216 } 12217 if (res == Service.START_STICKY_COMPATIBILITY) { 12218 r.callStart = false; 12219 } 12220 } 12221 if (DEBUG_MU) 12222 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid=" 12223 + Binder.getOrigCallingUid()); 12224 final long origId = Binder.clearCallingIdentity(); 12225 serviceDoneExecutingLocked(r, inStopping); 12226 Binder.restoreCallingIdentity(origId); 12227 } else { 12228 Slog.w(TAG, "Done executing unknown service from pid " 12229 + Binder.getCallingPid()); 12230 } 12231 } 12232 } 12233 12234 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 12235 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 12236 + ": nesting=" + r.executeNesting 12237 + ", inStopping=" + inStopping + ", app=" + r.app); 12238 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 12239 r.executeNesting--; 12240 if (r.executeNesting <= 0 && r.app != null) { 12241 if (DEBUG_SERVICE) Slog.v(TAG, 12242 "Nesting at 0 of " + r.shortName); 12243 r.app.executingServices.remove(r); 12244 if (r.app.executingServices.size() == 0) { 12245 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 12246 "No more executingServices of " + r.shortName); 12247 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 12248 } 12249 if (inStopping) { 12250 if (DEBUG_SERVICE) Slog.v(TAG, 12251 "doneExecuting remove stopping " + r); 12252 mStoppingServices.remove(r); 12253 r.bindings.clear(); 12254 } 12255 updateOomAdjLocked(r.app); 12256 } 12257 } 12258 12259 void serviceTimeout(ProcessRecord proc) { 12260 String anrMessage = null; 12261 12262 synchronized(this) { 12263 if (proc.executingServices.size() == 0 || proc.thread == null) { 12264 return; 12265 } 12266 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 12267 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 12268 ServiceRecord timeout = null; 12269 long nextTime = 0; 12270 while (it.hasNext()) { 12271 ServiceRecord sr = it.next(); 12272 if (sr.executingStart < maxTime) { 12273 timeout = sr; 12274 break; 12275 } 12276 if (sr.executingStart > nextTime) { 12277 nextTime = sr.executingStart; 12278 } 12279 } 12280 if (timeout != null && mLruProcesses.contains(proc)) { 12281 Slog.w(TAG, "Timeout executing service: " + timeout); 12282 anrMessage = "Executing service " + timeout.shortName; 12283 } else { 12284 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 12285 msg.obj = proc; 12286 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 12287 } 12288 } 12289 12290 if (anrMessage != null) { 12291 appNotResponding(proc, null, null, anrMessage); 12292 } 12293 } 12294 12295 // ========================================================= 12296 // BACKUP AND RESTORE 12297 // ========================================================= 12298 12299 // Cause the target app to be launched if necessary and its backup agent 12300 // instantiated. The backup agent will invoke backupAgentCreated() on the 12301 // activity manager to announce its creation. 12302 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12303 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 12304 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 12305 12306 synchronized(this) { 12307 // !!! TODO: currently no check here that we're already bound 12308 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12309 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12310 synchronized (stats) { 12311 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12312 } 12313 12314 // Backup agent is now in use, its package can't be stopped. 12315 try { 12316 AppGlobals.getPackageManager().setPackageStoppedState( 12317 app.packageName, false, UserId.getUserId(app.uid)); 12318 } catch (RemoteException e) { 12319 } catch (IllegalArgumentException e) { 12320 Slog.w(TAG, "Failed trying to unstop package " 12321 + app.packageName + ": " + e); 12322 } 12323 12324 BackupRecord r = new BackupRecord(ss, app, backupMode); 12325 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12326 ? new ComponentName(app.packageName, app.backupAgentName) 12327 : new ComponentName("android", "FullBackupAgent"); 12328 // startProcessLocked() returns existing proc's record if it's already running 12329 ProcessRecord proc = startProcessLocked(app.processName, app, 12330 false, 0, "backup", hostingName, false, false); 12331 if (proc == null) { 12332 Slog.e(TAG, "Unable to start backup agent process " + r); 12333 return false; 12334 } 12335 12336 r.app = proc; 12337 mBackupTarget = r; 12338 mBackupAppName = app.packageName; 12339 12340 // Try not to kill the process during backup 12341 updateOomAdjLocked(proc); 12342 12343 // If the process is already attached, schedule the creation of the backup agent now. 12344 // If it is not yet live, this will be done when it attaches to the framework. 12345 if (proc.thread != null) { 12346 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12347 try { 12348 proc.thread.scheduleCreateBackupAgent(app, 12349 compatibilityInfoForPackageLocked(app), backupMode); 12350 } catch (RemoteException e) { 12351 // Will time out on the backup manager side 12352 } 12353 } else { 12354 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12355 } 12356 // Invariants: at this point, the target app process exists and the application 12357 // is either already running or in the process of coming up. mBackupTarget and 12358 // mBackupAppName describe the app, so that when it binds back to the AM we 12359 // know that it's scheduled for a backup-agent operation. 12360 } 12361 12362 return true; 12363 } 12364 12365 // A backup agent has just come up 12366 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12367 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12368 + " = " + agent); 12369 12370 synchronized(this) { 12371 if (!agentPackageName.equals(mBackupAppName)) { 12372 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12373 return; 12374 } 12375 } 12376 12377 long oldIdent = Binder.clearCallingIdentity(); 12378 try { 12379 IBackupManager bm = IBackupManager.Stub.asInterface( 12380 ServiceManager.getService(Context.BACKUP_SERVICE)); 12381 bm.agentConnected(agentPackageName, agent); 12382 } catch (RemoteException e) { 12383 // can't happen; the backup manager service is local 12384 } catch (Exception e) { 12385 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12386 e.printStackTrace(); 12387 } finally { 12388 Binder.restoreCallingIdentity(oldIdent); 12389 } 12390 } 12391 12392 // done with this agent 12393 public void unbindBackupAgent(ApplicationInfo appInfo) { 12394 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12395 if (appInfo == null) { 12396 Slog.w(TAG, "unbind backup agent for null app"); 12397 return; 12398 } 12399 12400 synchronized(this) { 12401 if (mBackupAppName == null) { 12402 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12403 return; 12404 } 12405 12406 if (!mBackupAppName.equals(appInfo.packageName)) { 12407 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12408 return; 12409 } 12410 12411 ProcessRecord proc = mBackupTarget.app; 12412 mBackupTarget = null; 12413 mBackupAppName = null; 12414 12415 // Not backing this app up any more; reset its OOM adjustment 12416 updateOomAdjLocked(proc); 12417 12418 // If the app crashed during backup, 'thread' will be null here 12419 if (proc.thread != null) { 12420 try { 12421 proc.thread.scheduleDestroyBackupAgent(appInfo, 12422 compatibilityInfoForPackageLocked(appInfo)); 12423 } catch (Exception e) { 12424 Slog.e(TAG, "Exception when unbinding backup agent:"); 12425 e.printStackTrace(); 12426 } 12427 } 12428 } 12429 } 12430 // ========================================================= 12431 // BROADCASTS 12432 // ========================================================= 12433 12434 private final List getStickiesLocked(String action, IntentFilter filter, 12435 List cur) { 12436 final ContentResolver resolver = mContext.getContentResolver(); 12437 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 12438 if (list == null) { 12439 return cur; 12440 } 12441 int N = list.size(); 12442 for (int i=0; i<N; i++) { 12443 Intent intent = list.get(i); 12444 if (filter.match(resolver, intent, true, TAG) >= 0) { 12445 if (cur == null) { 12446 cur = new ArrayList<Intent>(); 12447 } 12448 cur.add(intent); 12449 } 12450 } 12451 return cur; 12452 } 12453 12454 boolean isPendingBroadcastProcessLocked(int pid) { 12455 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12456 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12457 } 12458 12459 void skipPendingBroadcastLocked(int pid) { 12460 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12461 for (BroadcastQueue queue : mBroadcastQueues) { 12462 queue.skipPendingBroadcastLocked(pid); 12463 } 12464 } 12465 12466 // The app just attached; send any pending broadcasts that it should receive 12467 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12468 boolean didSomething = false; 12469 for (BroadcastQueue queue : mBroadcastQueues) { 12470 didSomething |= queue.sendPendingBroadcastsLocked(app); 12471 } 12472 return didSomething; 12473 } 12474 12475 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12476 IIntentReceiver receiver, IntentFilter filter, String permission) { 12477 enforceNotIsolatedCaller("registerReceiver"); 12478 synchronized(this) { 12479 ProcessRecord callerApp = null; 12480 if (caller != null) { 12481 callerApp = getRecordForAppLocked(caller); 12482 if (callerApp == null) { 12483 throw new SecurityException( 12484 "Unable to find app for caller " + caller 12485 + " (pid=" + Binder.getCallingPid() 12486 + ") when registering receiver " + receiver); 12487 } 12488 if (callerApp.info.uid != Process.SYSTEM_UID && 12489 !callerApp.pkgList.contains(callerPackage)) { 12490 throw new SecurityException("Given caller package " + callerPackage 12491 + " is not running in process " + callerApp); 12492 } 12493 } else { 12494 callerPackage = null; 12495 } 12496 12497 List allSticky = null; 12498 12499 // Look for any matching sticky broadcasts... 12500 Iterator actions = filter.actionsIterator(); 12501 if (actions != null) { 12502 while (actions.hasNext()) { 12503 String action = (String)actions.next(); 12504 allSticky = getStickiesLocked(action, filter, allSticky); 12505 } 12506 } else { 12507 allSticky = getStickiesLocked(null, filter, allSticky); 12508 } 12509 12510 // The first sticky in the list is returned directly back to 12511 // the client. 12512 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12513 12514 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12515 + ": " + sticky); 12516 12517 if (receiver == null) { 12518 return sticky; 12519 } 12520 12521 ReceiverList rl 12522 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12523 if (rl == null) { 12524 rl = new ReceiverList(this, callerApp, 12525 Binder.getCallingPid(), 12526 Binder.getCallingUid(), receiver); 12527 if (rl.app != null) { 12528 rl.app.receivers.add(rl); 12529 } else { 12530 try { 12531 receiver.asBinder().linkToDeath(rl, 0); 12532 } catch (RemoteException e) { 12533 return sticky; 12534 } 12535 rl.linkedToDeath = true; 12536 } 12537 mRegisteredReceivers.put(receiver.asBinder(), rl); 12538 } 12539 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 12540 rl.add(bf); 12541 if (!bf.debugCheck()) { 12542 Slog.w(TAG, "==> For Dynamic broadast"); 12543 } 12544 mReceiverResolver.addFilter(bf); 12545 12546 // Enqueue broadcasts for all existing stickies that match 12547 // this filter. 12548 if (allSticky != null) { 12549 ArrayList receivers = new ArrayList(); 12550 receivers.add(bf); 12551 12552 int N = allSticky.size(); 12553 for (int i=0; i<N; i++) { 12554 Intent intent = (Intent)allSticky.get(i); 12555 BroadcastQueue queue = broadcastQueueForIntent(intent); 12556 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12557 null, -1, -1, null, receivers, null, 0, null, null, 12558 false, true, true); 12559 queue.enqueueParallelBroadcastLocked(r); 12560 queue.scheduleBroadcastsLocked(); 12561 } 12562 } 12563 12564 return sticky; 12565 } 12566 } 12567 12568 public void unregisterReceiver(IIntentReceiver receiver) { 12569 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12570 12571 final long origId = Binder.clearCallingIdentity(); 12572 try { 12573 boolean doTrim = false; 12574 12575 synchronized(this) { 12576 ReceiverList rl 12577 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12578 if (rl != null) { 12579 if (rl.curBroadcast != null) { 12580 BroadcastRecord r = rl.curBroadcast; 12581 final boolean doNext = finishReceiverLocked( 12582 receiver.asBinder(), r.resultCode, r.resultData, 12583 r.resultExtras, r.resultAbort, true); 12584 if (doNext) { 12585 doTrim = true; 12586 r.queue.processNextBroadcast(false); 12587 } 12588 } 12589 12590 if (rl.app != null) { 12591 rl.app.receivers.remove(rl); 12592 } 12593 removeReceiverLocked(rl); 12594 if (rl.linkedToDeath) { 12595 rl.linkedToDeath = false; 12596 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12597 } 12598 } 12599 } 12600 12601 // If we actually concluded any broadcasts, we might now be able 12602 // to trim the recipients' apps from our working set 12603 if (doTrim) { 12604 trimApplications(); 12605 return; 12606 } 12607 12608 } finally { 12609 Binder.restoreCallingIdentity(origId); 12610 } 12611 } 12612 12613 void removeReceiverLocked(ReceiverList rl) { 12614 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12615 int N = rl.size(); 12616 for (int i=0; i<N; i++) { 12617 mReceiverResolver.removeFilter(rl.get(i)); 12618 } 12619 } 12620 12621 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12622 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12623 ProcessRecord r = mLruProcesses.get(i); 12624 if (r.thread != null) { 12625 try { 12626 r.thread.dispatchPackageBroadcast(cmd, packages); 12627 } catch (RemoteException ex) { 12628 } 12629 } 12630 } 12631 } 12632 12633 private final int broadcastIntentLocked(ProcessRecord callerApp, 12634 String callerPackage, Intent intent, String resolvedType, 12635 IIntentReceiver resultTo, int resultCode, String resultData, 12636 Bundle map, String requiredPermission, 12637 boolean ordered, boolean sticky, int callingPid, int callingUid, 12638 int userId) { 12639 intent = new Intent(intent); 12640 12641 // By default broadcasts do not go to stopped apps. 12642 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 12643 12644 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12645 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12646 + " ordered=" + ordered + " userid=" + userId); 12647 if ((resultTo != null) && !ordered) { 12648 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12649 } 12650 12651 // Handle special intents: if this broadcast is from the package 12652 // manager about a package being removed, we need to remove all of 12653 // its activities from the history stack. 12654 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 12655 intent.getAction()); 12656 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12657 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12658 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12659 || uidRemoved) { 12660 if (checkComponentPermission( 12661 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12662 callingPid, callingUid, -1, true) 12663 == PackageManager.PERMISSION_GRANTED) { 12664 if (uidRemoved) { 12665 final Bundle intentExtras = intent.getExtras(); 12666 final int uid = intentExtras != null 12667 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12668 if (uid >= 0) { 12669 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12670 synchronized (bs) { 12671 bs.removeUidStatsLocked(uid); 12672 } 12673 } 12674 } else { 12675 // If resources are unvailble just force stop all 12676 // those packages and flush the attribute cache as well. 12677 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12678 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12679 if (list != null && (list.length > 0)) { 12680 for (String pkg : list) { 12681 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 12682 } 12683 sendPackageBroadcastLocked( 12684 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12685 } 12686 } else { 12687 Uri data = intent.getData(); 12688 String ssp; 12689 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12690 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12691 forceStopPackageLocked(ssp, 12692 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 12693 false, userId); 12694 } 12695 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12696 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12697 new String[] {ssp}); 12698 } 12699 } 12700 } 12701 } 12702 } else { 12703 String msg = "Permission Denial: " + intent.getAction() 12704 + " broadcast from " + callerPackage + " (pid=" + callingPid 12705 + ", uid=" + callingUid + ")" 12706 + " requires " 12707 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12708 Slog.w(TAG, msg); 12709 throw new SecurityException(msg); 12710 } 12711 12712 // Special case for adding a package: by default turn on compatibility 12713 // mode. 12714 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12715 Uri data = intent.getData(); 12716 String ssp; 12717 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12718 mCompatModePackages.handlePackageAddedLocked(ssp, 12719 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12720 } 12721 } 12722 12723 /* 12724 * If this is the time zone changed action, queue up a message that will reset the timezone 12725 * of all currently running processes. This message will get queued up before the broadcast 12726 * happens. 12727 */ 12728 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12729 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12730 } 12731 12732 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12733 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12734 } 12735 12736 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12737 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12738 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12739 } 12740 12741 /* 12742 * Prevent non-system code (defined here to be non-persistent 12743 * processes) from sending protected broadcasts. 12744 */ 12745 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12746 || callingUid == Process.SHELL_UID || callingUid == 0) { 12747 // Always okay. 12748 } else if (callerApp == null || !callerApp.persistent) { 12749 try { 12750 if (AppGlobals.getPackageManager().isProtectedBroadcast( 12751 intent.getAction())) { 12752 String msg = "Permission Denial: not allowed to send broadcast " 12753 + intent.getAction() + " from pid=" 12754 + callingPid + ", uid=" + callingUid; 12755 Slog.w(TAG, msg); 12756 throw new SecurityException(msg); 12757 } 12758 } catch (RemoteException e) { 12759 Slog.w(TAG, "Remote exception", e); 12760 return ActivityManager.BROADCAST_SUCCESS; 12761 } 12762 } 12763 12764 // Add to the sticky list if requested. 12765 if (sticky) { 12766 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12767 callingPid, callingUid) 12768 != PackageManager.PERMISSION_GRANTED) { 12769 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12770 + callingPid + ", uid=" + callingUid 12771 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12772 Slog.w(TAG, msg); 12773 throw new SecurityException(msg); 12774 } 12775 if (requiredPermission != null) { 12776 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12777 + " and enforce permission " + requiredPermission); 12778 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12779 } 12780 if (intent.getComponent() != null) { 12781 throw new SecurityException( 12782 "Sticky broadcasts can't target a specific component"); 12783 } 12784 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12785 if (list == null) { 12786 list = new ArrayList<Intent>(); 12787 mStickyBroadcasts.put(intent.getAction(), list); 12788 } 12789 int N = list.size(); 12790 int i; 12791 for (i=0; i<N; i++) { 12792 if (intent.filterEquals(list.get(i))) { 12793 // This sticky already exists, replace it. 12794 list.set(i, new Intent(intent)); 12795 break; 12796 } 12797 } 12798 if (i >= N) { 12799 list.add(new Intent(intent)); 12800 } 12801 } 12802 12803 // Figure out who all will receive this broadcast. 12804 List receivers = null; 12805 List<BroadcastFilter> registeredReceivers = null; 12806 try { 12807 if (intent.getComponent() != null) { 12808 // Broadcast is going to one specific receiver class... 12809 ActivityInfo ai = AppGlobals.getPackageManager(). 12810 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId); 12811 if (ai != null) { 12812 receivers = new ArrayList(); 12813 ResolveInfo ri = new ResolveInfo(); 12814 if (isSingleton(ai.processName, ai.applicationInfo)) { 12815 ri.activityInfo = getActivityInfoForUser(ai, 0); 12816 } else { 12817 ri.activityInfo = getActivityInfoForUser(ai, userId); 12818 } 12819 receivers.add(ri); 12820 } 12821 } else { 12822 // Need to resolve the intent to interested receivers... 12823 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12824 == 0) { 12825 receivers = 12826 AppGlobals.getPackageManager().queryIntentReceivers( 12827 intent, resolvedType, STOCK_PM_FLAGS, userId); 12828 } 12829 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, 12830 userId); 12831 } 12832 } catch (RemoteException ex) { 12833 // pm is in same process, this will never happen. 12834 } 12835 12836 final boolean replacePending = 12837 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12838 12839 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 12840 + " replacePending=" + replacePending); 12841 12842 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12843 if (!ordered && NR > 0) { 12844 // If we are not serializing this broadcast, then send the 12845 // registered receivers separately so they don't wait for the 12846 // components to be launched. 12847 final BroadcastQueue queue = broadcastQueueForIntent(intent); 12848 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 12849 callerPackage, callingPid, callingUid, requiredPermission, 12850 registeredReceivers, resultTo, resultCode, resultData, map, 12851 ordered, sticky, false); 12852 if (DEBUG_BROADCAST) Slog.v( 12853 TAG, "Enqueueing parallel broadcast " + r); 12854 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 12855 if (!replaced) { 12856 queue.enqueueParallelBroadcastLocked(r); 12857 queue.scheduleBroadcastsLocked(); 12858 } 12859 registeredReceivers = null; 12860 NR = 0; 12861 } 12862 12863 // Merge into one list. 12864 int ir = 0; 12865 if (receivers != null) { 12866 // A special case for PACKAGE_ADDED: do not allow the package 12867 // being added to see this broadcast. This prevents them from 12868 // using this as a back door to get run as soon as they are 12869 // installed. Maybe in the future we want to have a special install 12870 // broadcast or such for apps, but we'd like to deliberately make 12871 // this decision. 12872 String skipPackages[] = null; 12873 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 12874 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 12875 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12876 Uri data = intent.getData(); 12877 if (data != null) { 12878 String pkgName = data.getSchemeSpecificPart(); 12879 if (pkgName != null) { 12880 skipPackages = new String[] { pkgName }; 12881 } 12882 } 12883 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 12884 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12885 } 12886 if (skipPackages != null && (skipPackages.length > 0)) { 12887 for (String skipPackage : skipPackages) { 12888 if (skipPackage != null) { 12889 int NT = receivers.size(); 12890 for (int it=0; it<NT; it++) { 12891 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12892 if (curt.activityInfo.packageName.equals(skipPackage)) { 12893 receivers.remove(it); 12894 it--; 12895 NT--; 12896 } 12897 } 12898 } 12899 } 12900 } 12901 12902 int NT = receivers != null ? receivers.size() : 0; 12903 int it = 0; 12904 ResolveInfo curt = null; 12905 BroadcastFilter curr = null; 12906 while (it < NT && ir < NR) { 12907 if (curt == null) { 12908 curt = (ResolveInfo)receivers.get(it); 12909 } 12910 if (curr == null) { 12911 curr = registeredReceivers.get(ir); 12912 } 12913 if (curr.getPriority() >= curt.priority) { 12914 // Insert this broadcast record into the final list. 12915 receivers.add(it, curr); 12916 ir++; 12917 curr = null; 12918 it++; 12919 NT++; 12920 } else { 12921 // Skip to the next ResolveInfo in the final list. 12922 it++; 12923 curt = null; 12924 } 12925 } 12926 } 12927 while (ir < NR) { 12928 if (receivers == null) { 12929 receivers = new ArrayList(); 12930 } 12931 receivers.add(registeredReceivers.get(ir)); 12932 ir++; 12933 } 12934 12935 if ((receivers != null && receivers.size() > 0) 12936 || resultTo != null) { 12937 BroadcastQueue queue = broadcastQueueForIntent(intent); 12938 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 12939 callerPackage, callingPid, callingUid, requiredPermission, 12940 receivers, resultTo, resultCode, resultData, map, ordered, 12941 sticky, false); 12942 if (DEBUG_BROADCAST) Slog.v( 12943 TAG, "Enqueueing ordered broadcast " + r 12944 + ": prev had " + queue.mOrderedBroadcasts.size()); 12945 if (DEBUG_BROADCAST) { 12946 int seq = r.intent.getIntExtra("seq", -1); 12947 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12948 } 12949 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 12950 if (!replaced) { 12951 queue.enqueueOrderedBroadcastLocked(r); 12952 queue.scheduleBroadcastsLocked(); 12953 } 12954 } 12955 12956 return ActivityManager.BROADCAST_SUCCESS; 12957 } 12958 12959 final Intent verifyBroadcastLocked(Intent intent) { 12960 // Refuse possible leaked file descriptors 12961 if (intent != null && intent.hasFileDescriptors() == true) { 12962 throw new IllegalArgumentException("File descriptors passed in Intent"); 12963 } 12964 12965 int flags = intent.getFlags(); 12966 12967 if (!mProcessesReady) { 12968 // if the caller really truly claims to know what they're doing, go 12969 // ahead and allow the broadcast without launching any receivers 12970 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12971 intent = new Intent(intent); 12972 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12973 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 12974 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12975 + " before boot completion"); 12976 throw new IllegalStateException("Cannot broadcast before boot completed"); 12977 } 12978 } 12979 12980 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12981 throw new IllegalArgumentException( 12982 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12983 } 12984 12985 return intent; 12986 } 12987 12988 public final int broadcastIntent(IApplicationThread caller, 12989 Intent intent, String resolvedType, IIntentReceiver resultTo, 12990 int resultCode, String resultData, Bundle map, 12991 String requiredPermission, boolean serialized, boolean sticky, int userId) { 12992 enforceNotIsolatedCaller("broadcastIntent"); 12993 synchronized(this) { 12994 intent = verifyBroadcastLocked(intent); 12995 12996 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12997 final int callingPid = Binder.getCallingPid(); 12998 final int callingUid = Binder.getCallingUid(); 12999 final long origId = Binder.clearCallingIdentity(); 13000 int res = broadcastIntentLocked(callerApp, 13001 callerApp != null ? callerApp.info.packageName : null, 13002 intent, resolvedType, resultTo, 13003 resultCode, resultData, map, requiredPermission, serialized, sticky, 13004 callingPid, callingUid, userId); 13005 Binder.restoreCallingIdentity(origId); 13006 return res; 13007 } 13008 } 13009 13010 int broadcastIntentInPackage(String packageName, int uid, 13011 Intent intent, String resolvedType, IIntentReceiver resultTo, 13012 int resultCode, String resultData, Bundle map, 13013 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13014 synchronized(this) { 13015 intent = verifyBroadcastLocked(intent); 13016 13017 final long origId = Binder.clearCallingIdentity(); 13018 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13019 resultTo, resultCode, resultData, map, requiredPermission, 13020 serialized, sticky, -1, uid, userId); 13021 Binder.restoreCallingIdentity(origId); 13022 return res; 13023 } 13024 } 13025 13026 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 13027 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13028 // Refuse possible leaked file descriptors 13029 if (intent != null && intent.hasFileDescriptors() == true) { 13030 throw new IllegalArgumentException("File descriptors passed in Intent"); 13031 } 13032 13033 synchronized(this) { 13034 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13035 != PackageManager.PERMISSION_GRANTED) { 13036 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13037 + Binder.getCallingPid() 13038 + ", uid=" + Binder.getCallingUid() 13039 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13040 Slog.w(TAG, msg); 13041 throw new SecurityException(msg); 13042 } 13043 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 13044 if (list != null) { 13045 int N = list.size(); 13046 int i; 13047 for (i=0; i<N; i++) { 13048 if (intent.filterEquals(list.get(i))) { 13049 list.remove(i); 13050 break; 13051 } 13052 } 13053 } 13054 } 13055 } 13056 13057 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13058 String resultData, Bundle resultExtras, boolean resultAbort, 13059 boolean explicit) { 13060 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13061 if (r == null) { 13062 Slog.w(TAG, "finishReceiver called but not found on queue"); 13063 return false; 13064 } 13065 13066 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 13067 explicit); 13068 } 13069 13070 public void finishReceiver(IBinder who, int resultCode, String resultData, 13071 Bundle resultExtras, boolean resultAbort) { 13072 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13073 13074 // Refuse possible leaked file descriptors 13075 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13076 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13077 } 13078 13079 final long origId = Binder.clearCallingIdentity(); 13080 try { 13081 boolean doNext = false; 13082 BroadcastRecord r = null; 13083 13084 synchronized(this) { 13085 r = broadcastRecordForReceiverLocked(who); 13086 if (r != null) { 13087 doNext = r.queue.finishReceiverLocked(r, resultCode, 13088 resultData, resultExtras, resultAbort, true); 13089 } 13090 } 13091 13092 if (doNext) { 13093 r.queue.processNextBroadcast(false); 13094 } 13095 trimApplications(); 13096 } finally { 13097 Binder.restoreCallingIdentity(origId); 13098 } 13099 } 13100 13101 // ========================================================= 13102 // INSTRUMENTATION 13103 // ========================================================= 13104 13105 public boolean startInstrumentation(ComponentName className, 13106 String profileFile, int flags, Bundle arguments, 13107 IInstrumentationWatcher watcher) { 13108 enforceNotIsolatedCaller("startInstrumentation"); 13109 // Refuse possible leaked file descriptors 13110 if (arguments != null && arguments.hasFileDescriptors()) { 13111 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13112 } 13113 13114 synchronized(this) { 13115 InstrumentationInfo ii = null; 13116 ApplicationInfo ai = null; 13117 try { 13118 ii = mContext.getPackageManager().getInstrumentationInfo( 13119 className, STOCK_PM_FLAGS); 13120 ai = mContext.getPackageManager().getApplicationInfo( 13121 ii.targetPackage, STOCK_PM_FLAGS); 13122 } catch (PackageManager.NameNotFoundException e) { 13123 } 13124 if (ii == null) { 13125 reportStartInstrumentationFailure(watcher, className, 13126 "Unable to find instrumentation info for: " + className); 13127 return false; 13128 } 13129 if (ai == null) { 13130 reportStartInstrumentationFailure(watcher, className, 13131 "Unable to find instrumentation target package: " + ii.targetPackage); 13132 return false; 13133 } 13134 13135 int match = mContext.getPackageManager().checkSignatures( 13136 ii.targetPackage, ii.packageName); 13137 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13138 String msg = "Permission Denial: starting instrumentation " 13139 + className + " from pid=" 13140 + Binder.getCallingPid() 13141 + ", uid=" + Binder.getCallingPid() 13142 + " not allowed because package " + ii.packageName 13143 + " does not have a signature matching the target " 13144 + ii.targetPackage; 13145 reportStartInstrumentationFailure(watcher, className, msg); 13146 throw new SecurityException(msg); 13147 } 13148 13149 int userId = UserId.getCallingUserId(); 13150 final long origId = Binder.clearCallingIdentity(); 13151 // Instrumentation can kill and relaunch even persistent processes 13152 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 13153 ProcessRecord app = addAppLocked(ai, false); 13154 app.instrumentationClass = className; 13155 app.instrumentationInfo = ai; 13156 app.instrumentationProfileFile = profileFile; 13157 app.instrumentationArguments = arguments; 13158 app.instrumentationWatcher = watcher; 13159 app.instrumentationResultClass = className; 13160 Binder.restoreCallingIdentity(origId); 13161 } 13162 13163 return true; 13164 } 13165 13166 /** 13167 * Report errors that occur while attempting to start Instrumentation. Always writes the 13168 * error to the logs, but if somebody is watching, send the report there too. This enables 13169 * the "am" command to report errors with more information. 13170 * 13171 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13172 * @param cn The component name of the instrumentation. 13173 * @param report The error report. 13174 */ 13175 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13176 ComponentName cn, String report) { 13177 Slog.w(TAG, report); 13178 try { 13179 if (watcher != null) { 13180 Bundle results = new Bundle(); 13181 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13182 results.putString("Error", report); 13183 watcher.instrumentationStatus(cn, -1, results); 13184 } 13185 } catch (RemoteException e) { 13186 Slog.w(TAG, e); 13187 } 13188 } 13189 13190 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13191 if (app.instrumentationWatcher != null) { 13192 try { 13193 // NOTE: IInstrumentationWatcher *must* be oneway here 13194 app.instrumentationWatcher.instrumentationFinished( 13195 app.instrumentationClass, 13196 resultCode, 13197 results); 13198 } catch (RemoteException e) { 13199 } 13200 } 13201 app.instrumentationWatcher = null; 13202 app.instrumentationClass = null; 13203 app.instrumentationInfo = null; 13204 app.instrumentationProfileFile = null; 13205 app.instrumentationArguments = null; 13206 13207 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 13208 } 13209 13210 public void finishInstrumentation(IApplicationThread target, 13211 int resultCode, Bundle results) { 13212 int userId = UserId.getCallingUserId(); 13213 // Refuse possible leaked file descriptors 13214 if (results != null && results.hasFileDescriptors()) { 13215 throw new IllegalArgumentException("File descriptors passed in Intent"); 13216 } 13217 13218 synchronized(this) { 13219 ProcessRecord app = getRecordForAppLocked(target); 13220 if (app == null) { 13221 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13222 return; 13223 } 13224 final long origId = Binder.clearCallingIdentity(); 13225 finishInstrumentationLocked(app, resultCode, results); 13226 Binder.restoreCallingIdentity(origId); 13227 } 13228 } 13229 13230 // ========================================================= 13231 // CONFIGURATION 13232 // ========================================================= 13233 13234 public ConfigurationInfo getDeviceConfigurationInfo() { 13235 ConfigurationInfo config = new ConfigurationInfo(); 13236 synchronized (this) { 13237 config.reqTouchScreen = mConfiguration.touchscreen; 13238 config.reqKeyboardType = mConfiguration.keyboard; 13239 config.reqNavigation = mConfiguration.navigation; 13240 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13241 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13242 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13243 } 13244 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13245 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13246 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13247 } 13248 config.reqGlEsVersion = GL_ES_VERSION; 13249 } 13250 return config; 13251 } 13252 13253 public Configuration getConfiguration() { 13254 Configuration ci; 13255 synchronized(this) { 13256 ci = new Configuration(mConfiguration); 13257 } 13258 return ci; 13259 } 13260 13261 public void updatePersistentConfiguration(Configuration values) { 13262 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13263 "updateConfiguration()"); 13264 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13265 "updateConfiguration()"); 13266 if (values == null) { 13267 throw new NullPointerException("Configuration must not be null"); 13268 } 13269 13270 synchronized(this) { 13271 final long origId = Binder.clearCallingIdentity(); 13272 updateConfigurationLocked(values, null, true, false); 13273 Binder.restoreCallingIdentity(origId); 13274 } 13275 } 13276 13277 public void updateConfiguration(Configuration values) { 13278 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13279 "updateConfiguration()"); 13280 13281 synchronized(this) { 13282 if (values == null && mWindowManager != null) { 13283 // sentinel: fetch the current configuration from the window manager 13284 values = mWindowManager.computeNewConfiguration(); 13285 } 13286 13287 if (mWindowManager != null) { 13288 mProcessList.applyDisplaySize(mWindowManager); 13289 } 13290 13291 final long origId = Binder.clearCallingIdentity(); 13292 if (values != null) { 13293 Settings.System.clearConfiguration(values); 13294 } 13295 updateConfigurationLocked(values, null, false, false); 13296 Binder.restoreCallingIdentity(origId); 13297 } 13298 } 13299 13300 /** 13301 * Do either or both things: (1) change the current configuration, and (2) 13302 * make sure the given activity is running with the (now) current 13303 * configuration. Returns true if the activity has been left running, or 13304 * false if <var>starting</var> is being destroyed to match the new 13305 * configuration. 13306 * @param persistent TODO 13307 */ 13308 boolean updateConfigurationLocked(Configuration values, 13309 ActivityRecord starting, boolean persistent, boolean initLocale) { 13310 // do nothing if we are headless 13311 if (mHeadless) return true; 13312 13313 int changes = 0; 13314 13315 boolean kept = true; 13316 13317 if (values != null) { 13318 Configuration newConfig = new Configuration(mConfiguration); 13319 changes = newConfig.updateFrom(values); 13320 if (changes != 0) { 13321 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13322 Slog.i(TAG, "Updating configuration to: " + values); 13323 } 13324 13325 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13326 13327 if (values.locale != null && !initLocale) { 13328 saveLocaleLocked(values.locale, 13329 !values.locale.equals(mConfiguration.locale), 13330 values.userSetLocale); 13331 } 13332 13333 mConfigurationSeq++; 13334 if (mConfigurationSeq <= 0) { 13335 mConfigurationSeq = 1; 13336 } 13337 newConfig.seq = mConfigurationSeq; 13338 mConfiguration = newConfig; 13339 Slog.i(TAG, "Config changed: " + newConfig); 13340 13341 final Configuration configCopy = new Configuration(mConfiguration); 13342 13343 // TODO: If our config changes, should we auto dismiss any currently 13344 // showing dialogs? 13345 mShowDialogs = shouldShowDialogs(newConfig); 13346 13347 AttributeCache ac = AttributeCache.instance(); 13348 if (ac != null) { 13349 ac.updateConfiguration(configCopy); 13350 } 13351 13352 // Make sure all resources in our process are updated 13353 // right now, so that anyone who is going to retrieve 13354 // resource values after we return will be sure to get 13355 // the new ones. This is especially important during 13356 // boot, where the first config change needs to guarantee 13357 // all resources have that config before following boot 13358 // code is executed. 13359 mSystemThread.applyConfigurationToResources(configCopy); 13360 13361 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13362 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13363 msg.obj = new Configuration(configCopy); 13364 mHandler.sendMessage(msg); 13365 } 13366 13367 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13368 ProcessRecord app = mLruProcesses.get(i); 13369 try { 13370 if (app.thread != null) { 13371 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13372 + app.processName + " new config " + mConfiguration); 13373 app.thread.scheduleConfigurationChanged(configCopy); 13374 } 13375 } catch (Exception e) { 13376 } 13377 } 13378 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13379 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13380 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13381 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13382 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13383 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13384 broadcastIntentLocked(null, null, 13385 new Intent(Intent.ACTION_LOCALE_CHANGED), 13386 null, null, 0, null, null, 13387 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13388 } 13389 } 13390 } 13391 13392 if (changes != 0 && starting == null) { 13393 // If the configuration changed, and the caller is not already 13394 // in the process of starting an activity, then find the top 13395 // activity to check if its configuration needs to change. 13396 starting = mMainStack.topRunningActivityLocked(null); 13397 } 13398 13399 if (starting != null) { 13400 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 13401 // And we need to make sure at this point that all other activities 13402 // are made visible with the correct configuration. 13403 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 13404 } 13405 13406 if (values != null && mWindowManager != null) { 13407 mWindowManager.setNewConfiguration(mConfiguration); 13408 } 13409 13410 return kept; 13411 } 13412 13413 /** 13414 * Decide based on the configuration whether we should shouw the ANR, 13415 * crash, etc dialogs. The idea is that if there is no affordnace to 13416 * press the on-screen buttons, we shouldn't show the dialog. 13417 * 13418 * A thought: SystemUI might also want to get told about this, the Power 13419 * dialog / global actions also might want different behaviors. 13420 */ 13421 private static final boolean shouldShowDialogs(Configuration config) { 13422 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 13423 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 13424 } 13425 13426 /** 13427 * Save the locale. You must be inside a synchronized (this) block. 13428 */ 13429 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13430 if(isDiff) { 13431 SystemProperties.set("user.language", l.getLanguage()); 13432 SystemProperties.set("user.region", l.getCountry()); 13433 } 13434 13435 if(isPersist) { 13436 SystemProperties.set("persist.sys.language", l.getLanguage()); 13437 SystemProperties.set("persist.sys.country", l.getCountry()); 13438 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13439 } 13440 } 13441 13442 @Override 13443 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 13444 ActivityRecord srec = ActivityRecord.forToken(token); 13445 return srec != null && srec.task.affinity != null && 13446 srec.task.affinity.equals(destAffinity); 13447 } 13448 13449 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 13450 Intent resultData) { 13451 ComponentName dest = destIntent.getComponent(); 13452 13453 synchronized (this) { 13454 ActivityRecord srec = ActivityRecord.forToken(token); 13455 if (srec == null) { 13456 return false; 13457 } 13458 ArrayList<ActivityRecord> history = srec.stack.mHistory; 13459 final int start = history.indexOf(srec); 13460 if (start < 0) { 13461 // Current activity is not in history stack; do nothing. 13462 return false; 13463 } 13464 int finishTo = start - 1; 13465 ActivityRecord parent = null; 13466 boolean foundParentInTask = false; 13467 if (dest != null) { 13468 TaskRecord tr = srec.task; 13469 for (int i = start - 1; i >= 0; i--) { 13470 ActivityRecord r = history.get(i); 13471 if (tr != r.task) { 13472 // Couldn't find parent in the same task; stop at the one above this. 13473 // (Root of current task; in-app "home" behavior) 13474 // Always at least finish the current activity. 13475 finishTo = Math.min(start - 1, i + 1); 13476 parent = history.get(finishTo); 13477 break; 13478 } else if (r.info.packageName.equals(dest.getPackageName()) && 13479 r.info.name.equals(dest.getClassName())) { 13480 finishTo = i; 13481 parent = r; 13482 foundParentInTask = true; 13483 break; 13484 } 13485 } 13486 } 13487 13488 if (mController != null) { 13489 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 13490 if (next != null) { 13491 // ask watcher if this is allowed 13492 boolean resumeOK = true; 13493 try { 13494 resumeOK = mController.activityResuming(next.packageName); 13495 } catch (RemoteException e) { 13496 mController = null; 13497 } 13498 13499 if (!resumeOK) { 13500 return false; 13501 } 13502 } 13503 } 13504 final long origId = Binder.clearCallingIdentity(); 13505 for (int i = start; i > finishTo; i--) { 13506 ActivityRecord r = history.get(i); 13507 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 13508 "navigate-up"); 13509 // Only return the supplied result for the first activity finished 13510 resultCode = Activity.RESULT_CANCELED; 13511 resultData = null; 13512 } 13513 13514 if (parent != null && foundParentInTask) { 13515 final int parentLaunchMode = parent.info.launchMode; 13516 final int destIntentFlags = destIntent.getFlags(); 13517 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 13518 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 13519 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 13520 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 13521 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 13522 } else { 13523 try { 13524 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 13525 destIntent.getComponent(), 0, UserId.getCallingUserId()); 13526 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 13527 null, aInfo, parent.appToken, null, 13528 0, -1, parent.launchedFromUid, 0, null, true, null); 13529 foundParentInTask = res == ActivityManager.START_SUCCESS; 13530 } catch (RemoteException e) { 13531 foundParentInTask = false; 13532 } 13533 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 13534 resultData, "navigate-up"); 13535 } 13536 } 13537 Binder.restoreCallingIdentity(origId); 13538 return foundParentInTask; 13539 } 13540 } 13541 13542 // ========================================================= 13543 // LIFETIME MANAGEMENT 13544 // ========================================================= 13545 13546 // Returns which broadcast queue the app is the current [or imminent] receiver 13547 // on, or 'null' if the app is not an active broadcast recipient. 13548 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 13549 BroadcastRecord r = app.curReceiver; 13550 if (r != null) { 13551 return r.queue; 13552 } 13553 13554 // It's not the current receiver, but it might be starting up to become one 13555 synchronized (this) { 13556 for (BroadcastQueue queue : mBroadcastQueues) { 13557 r = queue.mPendingBroadcast; 13558 if (r != null && r.curApp == app) { 13559 // found it; report which queue it's in 13560 return queue; 13561 } 13562 } 13563 } 13564 13565 return null; 13566 } 13567 13568 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13569 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 13570 if (mAdjSeq == app.adjSeq) { 13571 // This adjustment has already been computed. If we are calling 13572 // from the top, we may have already computed our adjustment with 13573 // an earlier hidden adjustment that isn't really for us... if 13574 // so, use the new hidden adjustment. 13575 if (!recursed && app.hidden) { 13576 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 13577 } 13578 return app.curRawAdj; 13579 } 13580 13581 if (app.thread == null) { 13582 app.adjSeq = mAdjSeq; 13583 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13584 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 13585 } 13586 13587 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13588 app.adjSource = null; 13589 app.adjTarget = null; 13590 app.empty = false; 13591 app.hidden = false; 13592 13593 final int activitiesSize = app.activities.size(); 13594 13595 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13596 // The max adjustment doesn't allow this app to be anything 13597 // below foreground, so it is not worth doing work for it. 13598 app.adjType = "fixed"; 13599 app.adjSeq = mAdjSeq; 13600 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 13601 app.foregroundActivities = false; 13602 app.keeping = true; 13603 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13604 // System process can do UI, and when they do we want to have 13605 // them trim their memory after the user leaves the UI. To 13606 // facilitate this, here we need to determine whether or not it 13607 // is currently showing UI. 13608 app.systemNoUi = true; 13609 if (app == TOP_APP) { 13610 app.systemNoUi = false; 13611 } else if (activitiesSize > 0) { 13612 for (int j = 0; j < activitiesSize; j++) { 13613 final ActivityRecord r = app.activities.get(j); 13614 if (r.visible) { 13615 app.systemNoUi = false; 13616 break; 13617 } 13618 } 13619 } 13620 return (app.curAdj=app.maxAdj); 13621 } 13622 13623 final boolean hadForegroundActivities = app.foregroundActivities; 13624 13625 app.foregroundActivities = false; 13626 app.keeping = false; 13627 app.systemNoUi = false; 13628 13629 // Determine the importance of the process, starting with most 13630 // important to least, and assign an appropriate OOM adjustment. 13631 int adj; 13632 int schedGroup; 13633 BroadcastQueue queue; 13634 if (app == TOP_APP) { 13635 // The last app on the list is the foreground app. 13636 adj = ProcessList.FOREGROUND_APP_ADJ; 13637 schedGroup = Process.THREAD_GROUP_DEFAULT; 13638 app.adjType = "top-activity"; 13639 app.foregroundActivities = true; 13640 } else if (app.instrumentationClass != null) { 13641 // Don't want to kill running instrumentation. 13642 adj = ProcessList.FOREGROUND_APP_ADJ; 13643 schedGroup = Process.THREAD_GROUP_DEFAULT; 13644 app.adjType = "instrumentation"; 13645 } else if ((queue = isReceivingBroadcast(app)) != null) { 13646 // An app that is currently receiving a broadcast also 13647 // counts as being in the foreground for OOM killer purposes. 13648 // It's placed in a sched group based on the nature of the 13649 // broadcast as reflected by which queue it's active in. 13650 adj = ProcessList.FOREGROUND_APP_ADJ; 13651 schedGroup = (queue == mFgBroadcastQueue) 13652 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 13653 app.adjType = "broadcast"; 13654 } else if (app.executingServices.size() > 0) { 13655 // An app that is currently executing a service callback also 13656 // counts as being in the foreground. 13657 adj = ProcessList.FOREGROUND_APP_ADJ; 13658 schedGroup = Process.THREAD_GROUP_DEFAULT; 13659 app.adjType = "exec-service"; 13660 } else if (activitiesSize > 0) { 13661 // This app is in the background with paused activities. 13662 // We inspect activities to potentially upgrade adjustment further below. 13663 adj = hiddenAdj; 13664 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13665 app.hidden = true; 13666 app.adjType = "bg-activities"; 13667 } else { 13668 // A very not-needed process. If this is lower in the lru list, 13669 // we will push it in to the empty bucket. 13670 adj = hiddenAdj; 13671 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13672 app.hidden = true; 13673 app.empty = true; 13674 app.adjType = "bg-empty"; 13675 } 13676 13677 boolean hasStoppingActivities = false; 13678 13679 // Examine all activities if not already foreground. 13680 if (!app.foregroundActivities && activitiesSize > 0) { 13681 for (int j = 0; j < activitiesSize; j++) { 13682 final ActivityRecord r = app.activities.get(j); 13683 if (r.visible) { 13684 // App has a visible activity; only upgrade adjustment. 13685 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13686 adj = ProcessList.VISIBLE_APP_ADJ; 13687 app.adjType = "visible"; 13688 } 13689 schedGroup = Process.THREAD_GROUP_DEFAULT; 13690 app.hidden = false; 13691 app.foregroundActivities = true; 13692 break; 13693 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 13694 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13695 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13696 app.adjType = "pausing"; 13697 } 13698 app.hidden = false; 13699 app.foregroundActivities = true; 13700 } else if (r.state == ActivityState.STOPPING) { 13701 // We will apply the actual adjustment later, because 13702 // we want to allow this process to immediately go through 13703 // any memory trimming that is in effect. 13704 app.hidden = false; 13705 app.foregroundActivities = true; 13706 hasStoppingActivities = true; 13707 } 13708 } 13709 } 13710 13711 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13712 if (app.foregroundServices) { 13713 // The user is aware of this app, so make it visible. 13714 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13715 app.hidden = false; 13716 app.adjType = "foreground-service"; 13717 schedGroup = Process.THREAD_GROUP_DEFAULT; 13718 } else if (app.forcingToForeground != null) { 13719 // The user is aware of this app, so make it visible. 13720 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13721 app.hidden = false; 13722 app.adjType = "force-foreground"; 13723 app.adjSource = app.forcingToForeground; 13724 schedGroup = Process.THREAD_GROUP_DEFAULT; 13725 } 13726 } 13727 13728 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13729 // We don't want to kill the current heavy-weight process. 13730 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13731 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13732 app.hidden = false; 13733 app.adjType = "heavy"; 13734 } 13735 13736 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13737 // This process is hosting what we currently consider to be the 13738 // home app, so we don't want to let it go into the background. 13739 adj = ProcessList.HOME_APP_ADJ; 13740 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13741 app.hidden = false; 13742 app.adjType = "home"; 13743 } 13744 13745 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13746 && app.activities.size() > 0) { 13747 // This was the previous process that showed UI to the user. 13748 // We want to try to keep it around more aggressively, to give 13749 // a good experience around switching between two apps. 13750 adj = ProcessList.PREVIOUS_APP_ADJ; 13751 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13752 app.hidden = false; 13753 app.adjType = "previous"; 13754 } 13755 13756 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13757 + " reason=" + app.adjType); 13758 13759 // By default, we use the computed adjustment. It may be changed if 13760 // there are applications dependent on our services or providers, but 13761 // this gives us a baseline and makes sure we don't get into an 13762 // infinite recursion. 13763 app.adjSeq = mAdjSeq; 13764 app.curRawAdj = app.nonStoppingAdj = adj; 13765 13766 if (mBackupTarget != null && app == mBackupTarget.app) { 13767 // If possible we want to avoid killing apps while they're being backed up 13768 if (adj > ProcessList.BACKUP_APP_ADJ) { 13769 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13770 adj = ProcessList.BACKUP_APP_ADJ; 13771 app.adjType = "backup"; 13772 app.hidden = false; 13773 } 13774 } 13775 13776 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13777 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13778 final long now = SystemClock.uptimeMillis(); 13779 // This process is more important if the top activity is 13780 // bound to the service. 13781 Iterator<ServiceRecord> jt = app.services.iterator(); 13782 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13783 ServiceRecord s = jt.next(); 13784 if (s.startRequested) { 13785 if (app.hasShownUi && app != mHomeProcess) { 13786 // If this process has shown some UI, let it immediately 13787 // go to the LRU list because it may be pretty heavy with 13788 // UI stuff. We'll tag it with a label just to help 13789 // debug and understand what is going on. 13790 if (adj > ProcessList.SERVICE_ADJ) { 13791 app.adjType = "started-bg-ui-services"; 13792 } 13793 } else { 13794 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13795 // This service has seen some activity within 13796 // recent memory, so we will keep its process ahead 13797 // of the background processes. 13798 if (adj > ProcessList.SERVICE_ADJ) { 13799 adj = ProcessList.SERVICE_ADJ; 13800 app.adjType = "started-services"; 13801 app.hidden = false; 13802 } 13803 } 13804 // If we have let the service slide into the background 13805 // state, still have some text describing what it is doing 13806 // even though the service no longer has an impact. 13807 if (adj > ProcessList.SERVICE_ADJ) { 13808 app.adjType = "started-bg-services"; 13809 } 13810 } 13811 // Don't kill this process because it is doing work; it 13812 // has said it is doing work. 13813 app.keeping = true; 13814 } 13815 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13816 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13817 Iterator<ArrayList<ConnectionRecord>> kt 13818 = s.connections.values().iterator(); 13819 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13820 ArrayList<ConnectionRecord> clist = kt.next(); 13821 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 13822 // XXX should compute this based on the max of 13823 // all connected clients. 13824 ConnectionRecord cr = clist.get(i); 13825 if (cr.binding.client == app) { 13826 // Binding to ourself is not interesting. 13827 continue; 13828 } 13829 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 13830 ProcessRecord client = cr.binding.client; 13831 int clientAdj = adj; 13832 int myHiddenAdj = hiddenAdj; 13833 if (myHiddenAdj > client.hiddenAdj) { 13834 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 13835 myHiddenAdj = client.hiddenAdj; 13836 } else { 13837 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 13838 } 13839 } 13840 clientAdj = computeOomAdjLocked( 13841 client, myHiddenAdj, TOP_APP, true, doingAll); 13842 String adjType = null; 13843 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 13844 // Not doing bind OOM management, so treat 13845 // this guy more like a started service. 13846 if (app.hasShownUi && app != mHomeProcess) { 13847 // If this process has shown some UI, let it immediately 13848 // go to the LRU list because it may be pretty heavy with 13849 // UI stuff. We'll tag it with a label just to help 13850 // debug and understand what is going on. 13851 if (adj > clientAdj) { 13852 adjType = "bound-bg-ui-services"; 13853 } 13854 app.hidden = false; 13855 clientAdj = adj; 13856 } else { 13857 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13858 // This service has not seen activity within 13859 // recent memory, so allow it to drop to the 13860 // LRU list if there is no other reason to keep 13861 // it around. We'll also tag it with a label just 13862 // to help debug and undertand what is going on. 13863 if (adj > clientAdj) { 13864 adjType = "bound-bg-services"; 13865 } 13866 clientAdj = adj; 13867 } 13868 } 13869 } 13870 if (adj > clientAdj) { 13871 // If this process has recently shown UI, and 13872 // the process that is binding to it is less 13873 // important than being visible, then we don't 13874 // care about the binding as much as we care 13875 // about letting this process get into the LRU 13876 // list to be killed and restarted if needed for 13877 // memory. 13878 if (app.hasShownUi && app != mHomeProcess 13879 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13880 adjType = "bound-bg-ui-services"; 13881 } else { 13882 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 13883 |Context.BIND_IMPORTANT)) != 0) { 13884 adj = clientAdj; 13885 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 13886 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 13887 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13888 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13889 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 13890 adj = clientAdj; 13891 } else { 13892 app.pendingUiClean = true; 13893 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13894 adj = ProcessList.VISIBLE_APP_ADJ; 13895 } 13896 } 13897 if (!client.hidden) { 13898 app.hidden = false; 13899 } 13900 if (client.keeping) { 13901 app.keeping = true; 13902 } 13903 adjType = "service"; 13904 } 13905 } 13906 if (adjType != null) { 13907 app.adjType = adjType; 13908 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13909 .REASON_SERVICE_IN_USE; 13910 app.adjSource = cr.binding.client; 13911 app.adjSourceOom = clientAdj; 13912 app.adjTarget = s.name; 13913 } 13914 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13915 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13916 schedGroup = Process.THREAD_GROUP_DEFAULT; 13917 } 13918 } 13919 } 13920 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 13921 ActivityRecord a = cr.activity; 13922 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 13923 (a.visible || a.state == ActivityState.RESUMED 13924 || a.state == ActivityState.PAUSING)) { 13925 adj = ProcessList.FOREGROUND_APP_ADJ; 13926 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13927 schedGroup = Process.THREAD_GROUP_DEFAULT; 13928 } 13929 app.hidden = false; 13930 app.adjType = "service"; 13931 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13932 .REASON_SERVICE_IN_USE; 13933 app.adjSource = a; 13934 app.adjSourceOom = adj; 13935 app.adjTarget = s.name; 13936 } 13937 } 13938 } 13939 } 13940 } 13941 } 13942 13943 // Finally, if this process has active services running in it, we 13944 // would like to avoid killing it unless it would prevent the current 13945 // application from running. By default we put the process in 13946 // with the rest of the background processes; as we scan through 13947 // its services we may bump it up from there. 13948 if (adj > hiddenAdj) { 13949 adj = hiddenAdj; 13950 app.hidden = false; 13951 app.adjType = "bg-services"; 13952 } 13953 } 13954 13955 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13956 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13957 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13958 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13959 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13960 ContentProviderRecord cpr = jt.next(); 13961 if (cpr.clients.size() != 0) { 13962 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13963 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13964 ProcessRecord client = kt.next(); 13965 if (client == app) { 13966 // Being our own client is not interesting. 13967 continue; 13968 } 13969 int myHiddenAdj = hiddenAdj; 13970 if (myHiddenAdj > client.hiddenAdj) { 13971 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13972 myHiddenAdj = client.hiddenAdj; 13973 } else { 13974 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13975 } 13976 } 13977 int clientAdj = computeOomAdjLocked( 13978 client, myHiddenAdj, TOP_APP, true, doingAll); 13979 if (adj > clientAdj) { 13980 if (app.hasShownUi && app != mHomeProcess 13981 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13982 app.adjType = "bg-ui-provider"; 13983 } else { 13984 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13985 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13986 app.adjType = "provider"; 13987 } 13988 if (!client.hidden) { 13989 app.hidden = false; 13990 } 13991 if (client.keeping) { 13992 app.keeping = true; 13993 } 13994 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13995 .REASON_PROVIDER_IN_USE; 13996 app.adjSource = client; 13997 app.adjSourceOom = clientAdj; 13998 app.adjTarget = cpr.name; 13999 } 14000 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14001 schedGroup = Process.THREAD_GROUP_DEFAULT; 14002 } 14003 } 14004 } 14005 // If the provider has external (non-framework) process 14006 // dependencies, ensure that its adjustment is at least 14007 // FOREGROUND_APP_ADJ. 14008 if (cpr.hasExternalProcessHandles()) { 14009 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14010 adj = ProcessList.FOREGROUND_APP_ADJ; 14011 schedGroup = Process.THREAD_GROUP_DEFAULT; 14012 app.hidden = false; 14013 app.keeping = true; 14014 app.adjType = "provider"; 14015 app.adjTarget = cpr.name; 14016 } 14017 } 14018 } 14019 } 14020 14021 if (adj == ProcessList.SERVICE_ADJ) { 14022 if (doingAll) { 14023 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 14024 mNewNumServiceProcs++; 14025 } 14026 if (app.serviceb) { 14027 adj = ProcessList.SERVICE_B_ADJ; 14028 } 14029 } else { 14030 app.serviceb = false; 14031 } 14032 14033 app.nonStoppingAdj = adj; 14034 14035 if (hasStoppingActivities) { 14036 // Only upgrade adjustment. 14037 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14038 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14039 app.adjType = "stopping"; 14040 } 14041 } 14042 14043 app.curRawAdj = adj; 14044 14045 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14046 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14047 if (adj > app.maxAdj) { 14048 adj = app.maxAdj; 14049 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14050 schedGroup = Process.THREAD_GROUP_DEFAULT; 14051 } 14052 } 14053 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14054 app.keeping = true; 14055 } 14056 14057 if (app.hasAboveClient) { 14058 // If this process has bound to any services with BIND_ABOVE_CLIENT, 14059 // then we need to drop its adjustment to be lower than the service's 14060 // in order to honor the request. We want to drop it by one adjustment 14061 // level... but there is special meaning applied to various levels so 14062 // we will skip some of them. 14063 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 14064 // System process will not get dropped, ever 14065 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 14066 adj = ProcessList.VISIBLE_APP_ADJ; 14067 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 14068 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14069 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14070 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 14071 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 14072 adj++; 14073 } 14074 } 14075 14076 app.curAdj = adj; 14077 app.curSchedGroup = schedGroup; 14078 14079 if (hadForegroundActivities != app.foregroundActivities) { 14080 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid, 14081 app.foregroundActivities).sendToTarget(); 14082 } 14083 14084 return app.curRawAdj; 14085 } 14086 14087 /** 14088 * Ask a given process to GC right now. 14089 */ 14090 final void performAppGcLocked(ProcessRecord app) { 14091 try { 14092 app.lastRequestedGc = SystemClock.uptimeMillis(); 14093 if (app.thread != null) { 14094 if (app.reportLowMemory) { 14095 app.reportLowMemory = false; 14096 app.thread.scheduleLowMemory(); 14097 } else { 14098 app.thread.processInBackground(); 14099 } 14100 } 14101 } catch (Exception e) { 14102 // whatever. 14103 } 14104 } 14105 14106 /** 14107 * Returns true if things are idle enough to perform GCs. 14108 */ 14109 private final boolean canGcNowLocked() { 14110 boolean processingBroadcasts = false; 14111 for (BroadcastQueue q : mBroadcastQueues) { 14112 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14113 processingBroadcasts = true; 14114 } 14115 } 14116 return !processingBroadcasts 14117 && (mSleeping || (mMainStack.mResumedActivity != null && 14118 mMainStack.mResumedActivity.idle)); 14119 } 14120 14121 /** 14122 * Perform GCs on all processes that are waiting for it, but only 14123 * if things are idle. 14124 */ 14125 final void performAppGcsLocked() { 14126 final int N = mProcessesToGc.size(); 14127 if (N <= 0) { 14128 return; 14129 } 14130 if (canGcNowLocked()) { 14131 while (mProcessesToGc.size() > 0) { 14132 ProcessRecord proc = mProcessesToGc.remove(0); 14133 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14134 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14135 <= SystemClock.uptimeMillis()) { 14136 // To avoid spamming the system, we will GC processes one 14137 // at a time, waiting a few seconds between each. 14138 performAppGcLocked(proc); 14139 scheduleAppGcsLocked(); 14140 return; 14141 } else { 14142 // It hasn't been long enough since we last GCed this 14143 // process... put it in the list to wait for its time. 14144 addProcessToGcListLocked(proc); 14145 break; 14146 } 14147 } 14148 } 14149 14150 scheduleAppGcsLocked(); 14151 } 14152 } 14153 14154 /** 14155 * If all looks good, perform GCs on all processes waiting for them. 14156 */ 14157 final void performAppGcsIfAppropriateLocked() { 14158 if (canGcNowLocked()) { 14159 performAppGcsLocked(); 14160 return; 14161 } 14162 // Still not idle, wait some more. 14163 scheduleAppGcsLocked(); 14164 } 14165 14166 /** 14167 * Schedule the execution of all pending app GCs. 14168 */ 14169 final void scheduleAppGcsLocked() { 14170 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14171 14172 if (mProcessesToGc.size() > 0) { 14173 // Schedule a GC for the time to the next process. 14174 ProcessRecord proc = mProcessesToGc.get(0); 14175 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14176 14177 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14178 long now = SystemClock.uptimeMillis(); 14179 if (when < (now+GC_TIMEOUT)) { 14180 when = now + GC_TIMEOUT; 14181 } 14182 mHandler.sendMessageAtTime(msg, when); 14183 } 14184 } 14185 14186 /** 14187 * Add a process to the array of processes waiting to be GCed. Keeps the 14188 * list in sorted order by the last GC time. The process can't already be 14189 * on the list. 14190 */ 14191 final void addProcessToGcListLocked(ProcessRecord proc) { 14192 boolean added = false; 14193 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14194 if (mProcessesToGc.get(i).lastRequestedGc < 14195 proc.lastRequestedGc) { 14196 added = true; 14197 mProcessesToGc.add(i+1, proc); 14198 break; 14199 } 14200 } 14201 if (!added) { 14202 mProcessesToGc.add(0, proc); 14203 } 14204 } 14205 14206 /** 14207 * Set up to ask a process to GC itself. This will either do it 14208 * immediately, or put it on the list of processes to gc the next 14209 * time things are idle. 14210 */ 14211 final void scheduleAppGcLocked(ProcessRecord app) { 14212 long now = SystemClock.uptimeMillis(); 14213 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14214 return; 14215 } 14216 if (!mProcessesToGc.contains(app)) { 14217 addProcessToGcListLocked(app); 14218 scheduleAppGcsLocked(); 14219 } 14220 } 14221 14222 final void checkExcessivePowerUsageLocked(boolean doKills) { 14223 updateCpuStatsNow(); 14224 14225 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14226 boolean doWakeKills = doKills; 14227 boolean doCpuKills = doKills; 14228 if (mLastPowerCheckRealtime == 0) { 14229 doWakeKills = false; 14230 } 14231 if (mLastPowerCheckUptime == 0) { 14232 doCpuKills = false; 14233 } 14234 if (stats.isScreenOn()) { 14235 doWakeKills = false; 14236 } 14237 final long curRealtime = SystemClock.elapsedRealtime(); 14238 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14239 final long curUptime = SystemClock.uptimeMillis(); 14240 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14241 mLastPowerCheckRealtime = curRealtime; 14242 mLastPowerCheckUptime = curUptime; 14243 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14244 doWakeKills = false; 14245 } 14246 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14247 doCpuKills = false; 14248 } 14249 int i = mLruProcesses.size(); 14250 while (i > 0) { 14251 i--; 14252 ProcessRecord app = mLruProcesses.get(i); 14253 if (!app.keeping) { 14254 long wtime; 14255 synchronized (stats) { 14256 wtime = stats.getProcessWakeTime(app.info.uid, 14257 app.pid, curRealtime); 14258 } 14259 long wtimeUsed = wtime - app.lastWakeTime; 14260 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14261 if (DEBUG_POWER) { 14262 StringBuilder sb = new StringBuilder(128); 14263 sb.append("Wake for "); 14264 app.toShortString(sb); 14265 sb.append(": over "); 14266 TimeUtils.formatDuration(realtimeSince, sb); 14267 sb.append(" used "); 14268 TimeUtils.formatDuration(wtimeUsed, sb); 14269 sb.append(" ("); 14270 sb.append((wtimeUsed*100)/realtimeSince); 14271 sb.append("%)"); 14272 Slog.i(TAG, sb.toString()); 14273 sb.setLength(0); 14274 sb.append("CPU for "); 14275 app.toShortString(sb); 14276 sb.append(": over "); 14277 TimeUtils.formatDuration(uptimeSince, sb); 14278 sb.append(" used "); 14279 TimeUtils.formatDuration(cputimeUsed, sb); 14280 sb.append(" ("); 14281 sb.append((cputimeUsed*100)/uptimeSince); 14282 sb.append("%)"); 14283 Slog.i(TAG, sb.toString()); 14284 } 14285 // If a process has held a wake lock for more 14286 // than 50% of the time during this period, 14287 // that sounds bad. Kill! 14288 if (doWakeKills && realtimeSince > 0 14289 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14290 synchronized (stats) { 14291 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14292 realtimeSince, wtimeUsed); 14293 } 14294 Slog.w(TAG, "Excessive wake lock in " + app.processName 14295 + " (pid " + app.pid + "): held " + wtimeUsed 14296 + " during " + realtimeSince); 14297 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14298 app.processName, app.setAdj, "excessive wake lock"); 14299 Process.killProcessQuiet(app.pid); 14300 } else if (doCpuKills && uptimeSince > 0 14301 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14302 synchronized (stats) { 14303 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 14304 uptimeSince, cputimeUsed); 14305 } 14306 Slog.w(TAG, "Excessive CPU in " + app.processName 14307 + " (pid " + app.pid + "): used " + cputimeUsed 14308 + " during " + uptimeSince); 14309 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14310 app.processName, app.setAdj, "excessive cpu"); 14311 Process.killProcessQuiet(app.pid); 14312 } else { 14313 app.lastWakeTime = wtime; 14314 app.lastCpuTime = app.curCpuTime; 14315 } 14316 } 14317 } 14318 } 14319 14320 private final boolean updateOomAdjLocked( 14321 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 14322 app.hiddenAdj = hiddenAdj; 14323 14324 if (app.thread == null) { 14325 return false; 14326 } 14327 14328 final boolean wasKeeping = app.keeping; 14329 14330 boolean success = true; 14331 14332 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 14333 14334 if (app.curRawAdj != app.setRawAdj) { 14335 if (wasKeeping && !app.keeping) { 14336 // This app is no longer something we want to keep. Note 14337 // its current wake lock time to later know to kill it if 14338 // it is not behaving well. 14339 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14340 synchronized (stats) { 14341 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 14342 app.pid, SystemClock.elapsedRealtime()); 14343 } 14344 app.lastCpuTime = app.curCpuTime; 14345 } 14346 14347 app.setRawAdj = app.curRawAdj; 14348 } 14349 14350 if (app.curAdj != app.setAdj) { 14351 if (Process.setOomAdj(app.pid, app.curAdj)) { 14352 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 14353 TAG, "Set " + app.pid + " " + app.processName + 14354 " adj " + app.curAdj + ": " + app.adjType); 14355 app.setAdj = app.curAdj; 14356 } else { 14357 success = false; 14358 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 14359 } 14360 } 14361 if (app.setSchedGroup != app.curSchedGroup) { 14362 app.setSchedGroup = app.curSchedGroup; 14363 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 14364 "Setting process group of " + app.processName 14365 + " to " + app.curSchedGroup); 14366 if (app.waitingToKill != null && 14367 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 14368 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 14369 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14370 app.processName, app.setAdj, app.waitingToKill); 14371 Process.killProcessQuiet(app.pid); 14372 success = false; 14373 } else { 14374 if (true) { 14375 long oldId = Binder.clearCallingIdentity(); 14376 try { 14377 Process.setProcessGroup(app.pid, app.curSchedGroup); 14378 } catch (Exception e) { 14379 Slog.w(TAG, "Failed setting process group of " + app.pid 14380 + " to " + app.curSchedGroup); 14381 e.printStackTrace(); 14382 } finally { 14383 Binder.restoreCallingIdentity(oldId); 14384 } 14385 } else { 14386 if (app.thread != null) { 14387 try { 14388 app.thread.setSchedulingGroup(app.curSchedGroup); 14389 } catch (RemoteException e) { 14390 } 14391 } 14392 } 14393 } 14394 } 14395 return success; 14396 } 14397 14398 private final ActivityRecord resumedAppLocked() { 14399 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 14400 if (resumedActivity == null || resumedActivity.app == null) { 14401 resumedActivity = mMainStack.mPausingActivity; 14402 if (resumedActivity == null || resumedActivity.app == null) { 14403 resumedActivity = mMainStack.topRunningActivityLocked(null); 14404 } 14405 } 14406 return resumedActivity; 14407 } 14408 14409 private final boolean updateOomAdjLocked(ProcessRecord app) { 14410 final ActivityRecord TOP_ACT = resumedAppLocked(); 14411 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14412 int curAdj = app.curAdj; 14413 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14414 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14415 14416 mAdjSeq++; 14417 14418 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 14419 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14420 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14421 if (nowHidden != wasHidden) { 14422 // Changed to/from hidden state, so apps after it in the LRU 14423 // list may also be changed. 14424 updateOomAdjLocked(); 14425 } 14426 return success; 14427 } 14428 14429 final void updateOomAdjLocked() { 14430 final ActivityRecord TOP_ACT = resumedAppLocked(); 14431 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14432 14433 if (false) { 14434 RuntimeException e = new RuntimeException(); 14435 e.fillInStackTrace(); 14436 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 14437 } 14438 14439 mAdjSeq++; 14440 mNewNumServiceProcs = 0; 14441 14442 // Let's determine how many processes we have running vs. 14443 // how many slots we have for background processes; we may want 14444 // to put multiple processes in a slot of there are enough of 14445 // them. 14446 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 14447 int factor = (mLruProcesses.size()-4)/numSlots; 14448 if (factor < 1) factor = 1; 14449 int step = 0; 14450 int numHidden = 0; 14451 int numTrimming = 0; 14452 14453 // First update the OOM adjustment for each of the 14454 // application processes based on their current state. 14455 int i = mLruProcesses.size(); 14456 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 14457 while (i > 0) { 14458 i--; 14459 ProcessRecord app = mLruProcesses.get(i); 14460 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 14461 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 14462 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 14463 && app.curAdj == curHiddenAdj) { 14464 step++; 14465 if (step >= factor) { 14466 step = 0; 14467 curHiddenAdj++; 14468 } 14469 } 14470 if (!app.killedBackground) { 14471 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14472 numHidden++; 14473 if (numHidden > mProcessLimit) { 14474 Slog.i(TAG, "No longer want " + app.processName 14475 + " (pid " + app.pid + "): hidden #" + numHidden); 14476 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14477 app.processName, app.setAdj, "too many background"); 14478 app.killedBackground = true; 14479 Process.killProcessQuiet(app.pid); 14480 } 14481 } 14482 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 14483 // If this is an isolated process, and there are no 14484 // services running in it, then the process is no longer 14485 // needed. We agressively kill these because we can by 14486 // definition not re-use the same process again, and it is 14487 // good to avoid having whatever code was running in them 14488 // left sitting around after no longer needed. 14489 Slog.i(TAG, "Isolated process " + app.processName 14490 + " (pid " + app.pid + ") no longer needed"); 14491 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14492 app.processName, app.setAdj, "isolated not needed"); 14493 app.killedBackground = true; 14494 Process.killProcessQuiet(app.pid); 14495 } 14496 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14497 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14498 && !app.killedBackground) { 14499 numTrimming++; 14500 } 14501 } 14502 } 14503 14504 mNumServiceProcs = mNewNumServiceProcs; 14505 14506 // Now determine the memory trimming level of background processes. 14507 // Unfortunately we need to start at the back of the list to do this 14508 // properly. We only do this if the number of background apps we 14509 // are managing to keep around is less than half the maximum we desire; 14510 // if we are keeping a good number around, we'll let them use whatever 14511 // memory they want. 14512 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 14513 final int N = mLruProcesses.size(); 14514 factor = numTrimming/3; 14515 int minFactor = 2; 14516 if (mHomeProcess != null) minFactor++; 14517 if (mPreviousProcess != null) minFactor++; 14518 if (factor < minFactor) factor = minFactor; 14519 step = 0; 14520 int fgTrimLevel; 14521 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 14522 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 14523 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 14524 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 14525 } else { 14526 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 14527 } 14528 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14529 for (i=0; i<N; i++) { 14530 ProcessRecord app = mLruProcesses.get(i); 14531 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14532 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14533 && !app.killedBackground) { 14534 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14535 try { 14536 app.thread.scheduleTrimMemory(curLevel); 14537 } catch (RemoteException e) { 14538 } 14539 if (false) { 14540 // For now we won't do this; our memory trimming seems 14541 // to be good enough at this point that destroying 14542 // activities causes more harm than good. 14543 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14544 && app != mHomeProcess && app != mPreviousProcess) { 14545 // Need to do this on its own message because the stack may not 14546 // be in a consistent state at this point. 14547 // For these apps we will also finish their activities 14548 // to help them free memory. 14549 mMainStack.scheduleDestroyActivities(app, false, "trim"); 14550 } 14551 } 14552 } 14553 app.trimMemoryLevel = curLevel; 14554 step++; 14555 if (step >= factor) { 14556 step = 0; 14557 switch (curLevel) { 14558 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14559 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14560 break; 14561 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14562 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14563 break; 14564 } 14565 } 14566 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14567 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14568 && app.thread != null) { 14569 try { 14570 app.thread.scheduleTrimMemory( 14571 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14572 } catch (RemoteException e) { 14573 } 14574 } 14575 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14576 } else { 14577 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14578 && app.pendingUiClean) { 14579 // If this application is now in the background and it 14580 // had done UI, then give it the special trim level to 14581 // have it free UI resources. 14582 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14583 if (app.trimMemoryLevel < level && app.thread != null) { 14584 try { 14585 app.thread.scheduleTrimMemory(level); 14586 } catch (RemoteException e) { 14587 } 14588 } 14589 app.pendingUiClean = false; 14590 } 14591 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 14592 try { 14593 app.thread.scheduleTrimMemory(fgTrimLevel); 14594 } catch (RemoteException e) { 14595 } 14596 } 14597 app.trimMemoryLevel = fgTrimLevel; 14598 } 14599 } 14600 } else { 14601 final int N = mLruProcesses.size(); 14602 for (i=0; i<N; i++) { 14603 ProcessRecord app = mLruProcesses.get(i); 14604 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14605 && app.pendingUiClean) { 14606 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14607 && app.thread != null) { 14608 try { 14609 app.thread.scheduleTrimMemory( 14610 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14611 } catch (RemoteException e) { 14612 } 14613 } 14614 app.pendingUiClean = false; 14615 } 14616 app.trimMemoryLevel = 0; 14617 } 14618 } 14619 14620 if (mAlwaysFinishActivities) { 14621 // Need to do this on its own message because the stack may not 14622 // be in a consistent state at this point. 14623 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 14624 } 14625 } 14626 14627 final void trimApplications() { 14628 synchronized (this) { 14629 int i; 14630 14631 // First remove any unused application processes whose package 14632 // has been removed. 14633 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14634 final ProcessRecord app = mRemovedProcesses.get(i); 14635 if (app.activities.size() == 0 14636 && app.curReceiver == null && app.services.size() == 0) { 14637 Slog.i( 14638 TAG, "Exiting empty application process " 14639 + app.processName + " (" 14640 + (app.thread != null ? app.thread.asBinder() : null) 14641 + ")\n"); 14642 if (app.pid > 0 && app.pid != MY_PID) { 14643 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14644 app.processName, app.setAdj, "empty"); 14645 Process.killProcessQuiet(app.pid); 14646 } else { 14647 try { 14648 app.thread.scheduleExit(); 14649 } catch (Exception e) { 14650 // Ignore exceptions. 14651 } 14652 } 14653 cleanUpApplicationRecordLocked(app, false, true, -1); 14654 mRemovedProcesses.remove(i); 14655 14656 if (app.persistent) { 14657 if (app.persistent) { 14658 addAppLocked(app.info, false); 14659 } 14660 } 14661 } 14662 } 14663 14664 // Now update the oom adj for all processes. 14665 updateOomAdjLocked(); 14666 } 14667 } 14668 14669 /** This method sends the specified signal to each of the persistent apps */ 14670 public void signalPersistentProcesses(int sig) throws RemoteException { 14671 if (sig != Process.SIGNAL_USR1) { 14672 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14673 } 14674 14675 synchronized (this) { 14676 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14677 != PackageManager.PERMISSION_GRANTED) { 14678 throw new SecurityException("Requires permission " 14679 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14680 } 14681 14682 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14683 ProcessRecord r = mLruProcesses.get(i); 14684 if (r.thread != null && r.persistent) { 14685 Process.sendSignal(r.pid, sig); 14686 } 14687 } 14688 } 14689 } 14690 14691 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14692 if (proc == null || proc == mProfileProc) { 14693 proc = mProfileProc; 14694 path = mProfileFile; 14695 profileType = mProfileType; 14696 clearProfilerLocked(); 14697 } 14698 if (proc == null) { 14699 return; 14700 } 14701 try { 14702 proc.thread.profilerControl(false, path, null, profileType); 14703 } catch (RemoteException e) { 14704 throw new IllegalStateException("Process disappeared"); 14705 } 14706 } 14707 14708 private void clearProfilerLocked() { 14709 if (mProfileFd != null) { 14710 try { 14711 mProfileFd.close(); 14712 } catch (IOException e) { 14713 } 14714 } 14715 mProfileApp = null; 14716 mProfileProc = null; 14717 mProfileFile = null; 14718 mProfileType = 0; 14719 mAutoStopProfiler = false; 14720 } 14721 14722 public boolean profileControl(String process, boolean start, 14723 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14724 14725 try { 14726 synchronized (this) { 14727 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14728 // its own permission. 14729 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14730 != PackageManager.PERMISSION_GRANTED) { 14731 throw new SecurityException("Requires permission " 14732 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14733 } 14734 14735 if (start && fd == null) { 14736 throw new IllegalArgumentException("null fd"); 14737 } 14738 14739 ProcessRecord proc = null; 14740 if (process != null) { 14741 try { 14742 int pid = Integer.parseInt(process); 14743 synchronized (mPidsSelfLocked) { 14744 proc = mPidsSelfLocked.get(pid); 14745 } 14746 } catch (NumberFormatException e) { 14747 } 14748 14749 if (proc == null) { 14750 HashMap<String, SparseArray<ProcessRecord>> all 14751 = mProcessNames.getMap(); 14752 SparseArray<ProcessRecord> procs = all.get(process); 14753 if (procs != null && procs.size() > 0) { 14754 proc = procs.valueAt(0); 14755 } 14756 } 14757 } 14758 14759 if (start && (proc == null || proc.thread == null)) { 14760 throw new IllegalArgumentException("Unknown process: " + process); 14761 } 14762 14763 if (start) { 14764 stopProfilerLocked(null, null, 0); 14765 setProfileApp(proc.info, proc.processName, path, fd, false); 14766 mProfileProc = proc; 14767 mProfileType = profileType; 14768 try { 14769 fd = fd.dup(); 14770 } catch (IOException e) { 14771 fd = null; 14772 } 14773 proc.thread.profilerControl(start, path, fd, profileType); 14774 fd = null; 14775 mProfileFd = null; 14776 } else { 14777 stopProfilerLocked(proc, path, profileType); 14778 if (fd != null) { 14779 try { 14780 fd.close(); 14781 } catch (IOException e) { 14782 } 14783 } 14784 } 14785 14786 return true; 14787 } 14788 } catch (RemoteException e) { 14789 throw new IllegalStateException("Process disappeared"); 14790 } finally { 14791 if (fd != null) { 14792 try { 14793 fd.close(); 14794 } catch (IOException e) { 14795 } 14796 } 14797 } 14798 } 14799 14800 public boolean dumpHeap(String process, boolean managed, 14801 String path, ParcelFileDescriptor fd) throws RemoteException { 14802 14803 try { 14804 synchronized (this) { 14805 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14806 // its own permission (same as profileControl). 14807 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14808 != PackageManager.PERMISSION_GRANTED) { 14809 throw new SecurityException("Requires permission " 14810 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14811 } 14812 14813 if (fd == null) { 14814 throw new IllegalArgumentException("null fd"); 14815 } 14816 14817 ProcessRecord proc = null; 14818 try { 14819 int pid = Integer.parseInt(process); 14820 synchronized (mPidsSelfLocked) { 14821 proc = mPidsSelfLocked.get(pid); 14822 } 14823 } catch (NumberFormatException e) { 14824 } 14825 14826 if (proc == null) { 14827 HashMap<String, SparseArray<ProcessRecord>> all 14828 = mProcessNames.getMap(); 14829 SparseArray<ProcessRecord> procs = all.get(process); 14830 if (procs != null && procs.size() > 0) { 14831 proc = procs.valueAt(0); 14832 } 14833 } 14834 14835 if (proc == null || proc.thread == null) { 14836 throw new IllegalArgumentException("Unknown process: " + process); 14837 } 14838 14839 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14840 if (!isDebuggable) { 14841 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14842 throw new SecurityException("Process not debuggable: " + proc); 14843 } 14844 } 14845 14846 proc.thread.dumpHeap(managed, path, fd); 14847 fd = null; 14848 return true; 14849 } 14850 } catch (RemoteException e) { 14851 throw new IllegalStateException("Process disappeared"); 14852 } finally { 14853 if (fd != null) { 14854 try { 14855 fd.close(); 14856 } catch (IOException e) { 14857 } 14858 } 14859 } 14860 } 14861 14862 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14863 public void monitor() { 14864 synchronized (this) { } 14865 } 14866 14867 void onCoreSettingsChange(Bundle settings) { 14868 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14869 ProcessRecord processRecord = mLruProcesses.get(i); 14870 try { 14871 if (processRecord.thread != null) { 14872 processRecord.thread.setCoreSettings(settings); 14873 } 14874 } catch (RemoteException re) { 14875 /* ignore */ 14876 } 14877 } 14878 } 14879 14880 // Multi-user methods 14881 14882 private int mCurrentUserId; 14883 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 14884 14885 public boolean switchUser(int userId) { 14886 final int callingUid = Binder.getCallingUid(); 14887 if (callingUid != 0 && callingUid != Process.myUid()) { 14888 Slog.e(TAG, "Trying to switch user from unauthorized app"); 14889 return false; 14890 } 14891 if (mCurrentUserId == userId) 14892 return true; 14893 14894 synchronized (this) { 14895 // Check if user is already logged in, otherwise check if user exists first before 14896 // adding to the list of logged in users. 14897 if (mLoggedInUsers.indexOfKey(userId) < 0) { 14898 if (!userExists(userId)) { 14899 return false; 14900 } 14901 mLoggedInUsers.append(userId, userId); 14902 } 14903 14904 mCurrentUserId = userId; 14905 boolean haveActivities = mMainStack.switchUser(userId); 14906 if (!haveActivities) { 14907 startHomeActivityLocked(userId); 14908 } 14909 14910 } 14911 14912 // Inform of user switch 14913 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 14914 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 14915 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 14916 14917 return true; 14918 } 14919 14920 @Override 14921 public UserInfo getCurrentUser() throws RemoteException { 14922 final int callingUid = Binder.getCallingUid(); 14923 if (callingUid != 0 && callingUid != Process.myUid()) { 14924 Slog.e(TAG, "Trying to get user from unauthorized app"); 14925 return null; 14926 } 14927 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 14928 } 14929 14930 private void onUserRemoved(Intent intent) { 14931 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 14932 if (extraUserId < 1) return; 14933 14934 // Kill all the processes for the user 14935 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 14936 synchronized (this) { 14937 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 14938 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 14939 SparseArray<ProcessRecord> uids = uidMap.getValue(); 14940 for (int i = 0; i < uids.size(); i++) { 14941 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 14942 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 14943 } 14944 } 14945 } 14946 14947 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 14948 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 14949 false, false, true, true, extraUserId); 14950 } 14951 } 14952 } 14953 14954 private boolean userExists(int userId) { 14955 try { 14956 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 14957 return user != null; 14958 } catch (RemoteException re) { 14959 // Won't happen, in same process 14960 } 14961 14962 return false; 14963 } 14964 14965 private void checkValidCaller(int uid, int userId) { 14966 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14967 14968 throw new SecurityException("Caller uid=" + uid 14969 + " is not privileged to communicate with user=" + userId); 14970 } 14971 14972 private int applyUserId(int uid, int userId) { 14973 return UserId.getUid(userId, uid); 14974 } 14975 14976 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14977 if (info == null) return null; 14978 ApplicationInfo newInfo = new ApplicationInfo(info); 14979 newInfo.uid = applyUserId(info.uid, userId); 14980 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14981 + info.packageName; 14982 return newInfo; 14983 } 14984 14985 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14986 if (aInfo == null 14987 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 14988 return aInfo; 14989 } 14990 14991 ActivityInfo info = new ActivityInfo(aInfo); 14992 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14993 return info; 14994 } 14995 14996 static class ServiceMap { 14997 14998 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser 14999 = new SparseArray<HashMap<ComponentName, ServiceRecord>>(); 15000 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>> 15001 mServicesByIntentPerUser = new SparseArray< 15002 HashMap<Intent.FilterComparison, ServiceRecord>>(); 15003 15004 ServiceRecord getServiceByName(ComponentName name, int callingUser) { 15005 // TODO: Deal with global services 15006 if (DEBUG_MU) 15007 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser); 15008 return getServices(callingUser).get(name); 15009 } 15010 15011 ServiceRecord getServiceByName(ComponentName name) { 15012 return getServiceByName(name, -1); 15013 } 15014 15015 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15016 // TODO: Deal with global services 15017 if (DEBUG_MU) 15018 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser); 15019 return getServicesByIntent(callingUser).get(filter); 15020 } 15021 15022 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) { 15023 return getServiceByIntent(filter, -1); 15024 } 15025 15026 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) { 15027 // TODO: Deal with global services 15028 getServices(callingUser).put(name, value); 15029 } 15030 15031 void putServiceByIntent(Intent.FilterComparison filter, int callingUser, 15032 ServiceRecord value) { 15033 // TODO: Deal with global services 15034 getServicesByIntent(callingUser).put(filter, value); 15035 } 15036 15037 void removeServiceByName(ComponentName name, int callingUser) { 15038 // TODO: Deal with global services 15039 ServiceRecord removed = getServices(callingUser).remove(name); 15040 if (DEBUG_MU) 15041 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name 15042 + " removed=" + removed); 15043 } 15044 15045 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15046 // TODO: Deal with global services 15047 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter); 15048 if (DEBUG_MU) 15049 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter 15050 + " removed=" + removed); 15051 } 15052 15053 Collection<ServiceRecord> getAllServices(int callingUser) { 15054 // TODO: Deal with global services 15055 return getServices(callingUser).values(); 15056 } 15057 15058 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) { 15059 HashMap map = mServicesByNamePerUser.get(callingUser); 15060 if (map == null) { 15061 map = new HashMap<ComponentName, ServiceRecord>(); 15062 mServicesByNamePerUser.put(callingUser, map); 15063 } 15064 return map; 15065 } 15066 15067 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent( 15068 int callingUser) { 15069 HashMap map = mServicesByIntentPerUser.get(callingUser); 15070 if (map == null) { 15071 map = new HashMap<Intent.FilterComparison, ServiceRecord>(); 15072 mServicesByIntentPerUser.put(callingUser, map); 15073 } 15074 return map; 15075 } 15076 } 15077} 15078