ActivityManagerService.java revision e217ee4d7a8223289a1af7363627c69956c46d41
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.IStopUserCallback; 50import android.app.IThumbnailReceiver; 51import android.app.Instrumentation; 52import android.app.Notification; 53import android.app.NotificationManager; 54import android.app.PendingIntent; 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.IContentProvider; 66import android.content.IIntentReceiver; 67import android.content.IIntentSender; 68import android.content.Intent; 69import android.content.IntentFilter; 70import android.content.IntentSender; 71import android.content.pm.ActivityInfo; 72import android.content.pm.ApplicationInfo; 73import android.content.pm.ConfigurationInfo; 74import android.content.pm.IPackageDataObserver; 75import android.content.pm.IPackageManager; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.PackageInfo; 78import android.content.pm.PackageManager; 79import android.content.pm.UserInfo; 80import android.content.pm.PackageManager.NameNotFoundException; 81import android.content.pm.PathPermission; 82import android.content.pm.ProviderInfo; 83import android.content.pm.ResolveInfo; 84import android.content.pm.ServiceInfo; 85import android.content.res.CompatibilityInfo; 86import android.content.res.Configuration; 87import android.graphics.Bitmap; 88import android.net.Proxy; 89import android.net.ProxyProperties; 90import android.net.Uri; 91import android.os.Binder; 92import android.os.Build; 93import android.os.Bundle; 94import android.os.Debug; 95import android.os.DropBoxManager; 96import android.os.Environment; 97import android.os.FileObserver; 98import android.os.FileUtils; 99import android.os.Handler; 100import android.os.IBinder; 101import android.os.IPermissionController; 102import android.os.Looper; 103import android.os.Message; 104import android.os.Parcel; 105import android.os.ParcelFileDescriptor; 106import android.os.Process; 107import android.os.RemoteCallbackList; 108import android.os.RemoteException; 109import android.os.SELinux; 110import android.os.ServiceManager; 111import android.os.StrictMode; 112import android.os.SystemClock; 113import android.os.SystemProperties; 114import android.os.UserHandle; 115import android.os.UserManager; 116import android.provider.Settings; 117import android.text.format.Time; 118import android.util.EventLog; 119import android.util.Log; 120import android.util.Pair; 121import android.util.PrintWriterPrinter; 122import android.util.Slog; 123import android.util.SparseArray; 124import android.util.SparseIntArray; 125import android.util.TimeUtils; 126import android.view.Gravity; 127import android.view.LayoutInflater; 128import android.view.View; 129import android.view.WindowManager; 130import android.view.WindowManagerPolicy; 131 132import java.io.BufferedInputStream; 133import java.io.BufferedOutputStream; 134import java.io.BufferedReader; 135import java.io.DataInputStream; 136import java.io.DataOutputStream; 137import java.io.File; 138import java.io.FileDescriptor; 139import java.io.FileInputStream; 140import java.io.FileNotFoundException; 141import java.io.FileOutputStream; 142import java.io.IOException; 143import java.io.InputStreamReader; 144import java.io.PrintWriter; 145import java.io.StringWriter; 146import java.lang.ref.WeakReference; 147import java.util.ArrayList; 148import java.util.Collections; 149import java.util.Comparator; 150import java.util.HashMap; 151import java.util.HashSet; 152import java.util.Iterator; 153import java.util.List; 154import java.util.Locale; 155import java.util.Map; 156import java.util.Map.Entry; 157import java.util.Set; 158import java.util.concurrent.atomic.AtomicBoolean; 159import java.util.concurrent.atomic.AtomicLong; 160 161public final class ActivityManagerService extends ActivityManagerNative 162 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 163 private static final String USER_DATA_DIR = "/data/user/"; 164 static final String TAG = "ActivityManager"; 165 static final String TAG_MU = "ActivityManagerServiceMU"; 166 static final boolean DEBUG = false; 167 static final boolean localLOGV = DEBUG; 168 static final boolean DEBUG_SWITCH = localLOGV || false; 169 static final boolean DEBUG_TASKS = localLOGV || false; 170 static final boolean DEBUG_PAUSE = localLOGV || false; 171 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 172 static final boolean DEBUG_TRANSITION = localLOGV || false; 173 static final boolean DEBUG_BROADCAST = localLOGV || false; 174 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_SERVICE = localLOGV || false; 177 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 178 static final boolean DEBUG_VISBILITY = localLOGV || false; 179 static final boolean DEBUG_PROCESSES = localLOGV || false; 180 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 181 static final boolean DEBUG_PROVIDER = localLOGV || false; 182 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 183 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 184 static final boolean DEBUG_RESULTS = localLOGV || false; 185 static final boolean DEBUG_BACKUP = localLOGV || false; 186 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 187 static final boolean DEBUG_POWER = localLOGV || false; 188 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 189 static final boolean DEBUG_MU = localLOGV || false; 190 static final boolean VALIDATE_TOKENS = false; 191 static final boolean SHOW_ACTIVITY_START_TIME = true; 192 193 // Control over CPU and battery monitoring. 194 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 195 static final boolean MONITOR_CPU_USAGE = true; 196 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 197 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 198 static final boolean MONITOR_THREAD_CPU_USAGE = false; 199 200 // The flags that are set for all calls we make to the package manager. 201 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 202 203 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 204 205 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 206 207 // Maximum number of recent tasks that we can remember. 208 static final int MAX_RECENT_TASKS = 20; 209 210 // Amount of time after a call to stopAppSwitches() during which we will 211 // prevent further untrusted switches from happening. 212 static final long APP_SWITCH_DELAY_TIME = 5*1000; 213 214 // How long we wait for a launched process to attach to the activity manager 215 // before we decide it's never going to come up for real. 216 static final int PROC_START_TIMEOUT = 10*1000; 217 218 // How long we wait for a launched process to attach to the activity manager 219 // before we decide it's never going to come up for real, when the process was 220 // started with a wrapper for instrumentation (such as Valgrind) because it 221 // could take much longer than usual. 222 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 223 224 // How long to wait after going idle before forcing apps to GC. 225 static final int GC_TIMEOUT = 5*1000; 226 227 // The minimum amount of time between successive GC requests for a process. 228 static final int GC_MIN_INTERVAL = 60*1000; 229 230 // The rate at which we check for apps using excessive power -- 15 mins. 231 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 232 233 // The minimum sample duration we will allow before deciding we have 234 // enough data on wake locks to start killing things. 235 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on CPU usage to start killing things. 239 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // How long we allow a receiver to run before giving up on it. 242 static final int BROADCAST_FG_TIMEOUT = 10*1000; 243 static final int BROADCAST_BG_TIMEOUT = 60*1000; 244 245 // How long we wait until we timeout on key dispatching. 246 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 247 248 // How long we wait until we timeout on key dispatching during instrumentation. 249 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 250 251 static final int MY_PID = Process.myPid(); 252 253 static final String[] EMPTY_STRING_ARRAY = new String[0]; 254 255 public ActivityStack mMainStack; 256 257 private final boolean mHeadless; 258 259 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 260 // default actuion automatically. Important for devices without direct input 261 // devices. 262 private boolean mShowDialogs = true; 263 264 /** 265 * Description of a request to start a new activity, which has been held 266 * due to app switches being disabled. 267 */ 268 static class PendingActivityLaunch { 269 ActivityRecord r; 270 ActivityRecord sourceRecord; 271 int startFlags; 272 } 273 274 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 275 = new ArrayList<PendingActivityLaunch>(); 276 277 278 BroadcastQueue mFgBroadcastQueue; 279 BroadcastQueue mBgBroadcastQueue; 280 // Convenient for easy iteration over the queues. Foreground is first 281 // so that dispatch of foreground broadcasts gets precedence. 282 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 283 284 BroadcastQueue broadcastQueueForIntent(Intent intent) { 285 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 286 if (DEBUG_BACKGROUND_BROADCAST) { 287 Slog.i(TAG, "Broadcast intent " + intent + " on " 288 + (isFg ? "foreground" : "background") 289 + " queue"); 290 } 291 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 292 } 293 294 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 295 for (BroadcastQueue queue : mBroadcastQueues) { 296 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 297 if (r != null) { 298 return r; 299 } 300 } 301 return null; 302 } 303 304 /** 305 * Activity we have told the window manager to have key focus. 306 */ 307 ActivityRecord mFocusedActivity = null; 308 /** 309 * List of intents that were used to start the most recent tasks. 310 */ 311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 312 313 /** 314 * Process management. 315 */ 316 final ProcessList mProcessList = new ProcessList(); 317 318 /** 319 * All of the applications we currently have running organized by name. 320 * The keys are strings of the application package name (as 321 * returned by the package manager), and the keys are ApplicationRecord 322 * objects. 323 */ 324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 325 326 /** 327 * The currently running isolated processes. 328 */ 329 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 330 331 /** 332 * Counter for assigning isolated process uids, to avoid frequently reusing the 333 * same ones. 334 */ 335 int mNextIsolatedProcessUid = 0; 336 337 /** 338 * The currently running heavy-weight process, if any. 339 */ 340 ProcessRecord mHeavyWeightProcess = null; 341 342 /** 343 * The last time that various processes have crashed. 344 */ 345 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 346 347 /** 348 * Set of applications that we consider to be bad, and will reject 349 * incoming broadcasts from (which the user has no control over). 350 * Processes are added to this set when they have crashed twice within 351 * a minimum amount of time; they are removed from it when they are 352 * later restarted (hopefully due to some user action). The value is the 353 * time it was added to the list. 354 */ 355 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 356 357 /** 358 * All of the processes we currently have running organized by pid. 359 * The keys are the pid running the application. 360 * 361 * <p>NOTE: This object is protected by its own lock, NOT the global 362 * activity manager lock! 363 */ 364 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 365 366 /** 367 * All of the processes that have been forced to be foreground. The key 368 * is the pid of the caller who requested it (we hold a death 369 * link on it). 370 */ 371 abstract class ForegroundToken implements IBinder.DeathRecipient { 372 int pid; 373 IBinder token; 374 } 375 final SparseArray<ForegroundToken> mForegroundProcesses 376 = new SparseArray<ForegroundToken>(); 377 378 /** 379 * List of records for processes that someone had tried to start before the 380 * system was ready. We don't start them at that point, but ensure they 381 * are started by the time booting is complete. 382 */ 383 final ArrayList<ProcessRecord> mProcessesOnHold 384 = new ArrayList<ProcessRecord>(); 385 386 /** 387 * List of persistent applications that are in the process 388 * of being started. 389 */ 390 final ArrayList<ProcessRecord> mPersistentStartingProcesses 391 = new ArrayList<ProcessRecord>(); 392 393 /** 394 * Processes that are being forcibly torn down. 395 */ 396 final ArrayList<ProcessRecord> mRemovedProcesses 397 = new ArrayList<ProcessRecord>(); 398 399 /** 400 * List of running applications, sorted by recent usage. 401 * The first entry in the list is the least recently used. 402 * It contains ApplicationRecord objects. This list does NOT include 403 * any persistent application records (since we never want to exit them). 404 */ 405 final ArrayList<ProcessRecord> mLruProcesses 406 = new ArrayList<ProcessRecord>(); 407 408 /** 409 * List of processes that should gc as soon as things are idle. 410 */ 411 final ArrayList<ProcessRecord> mProcessesToGc 412 = new ArrayList<ProcessRecord>(); 413 414 /** 415 * This is the process holding what we currently consider to be 416 * the "home" activity. 417 */ 418 ProcessRecord mHomeProcess; 419 420 /** 421 * This is the process holding the activity the user last visited that 422 * is in a different process from the one they are currently in. 423 */ 424 ProcessRecord mPreviousProcess; 425 426 /** 427 * The time at which the previous process was last visible. 428 */ 429 long mPreviousProcessVisibleTime; 430 431 /** 432 * Which uses have been started, so are allowed to run code. 433 */ 434 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 435 436 /** 437 * Packages that the user has asked to have run in screen size 438 * compatibility mode instead of filling the screen. 439 */ 440 final CompatModePackages mCompatModePackages; 441 442 /** 443 * Set of PendingResultRecord objects that are currently active. 444 */ 445 final HashSet mPendingResultRecords = new HashSet(); 446 447 /** 448 * Set of IntentSenderRecord objects that are currently active. 449 */ 450 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 451 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 452 453 /** 454 * Fingerprints (hashCode()) of stack traces that we've 455 * already logged DropBox entries for. Guarded by itself. If 456 * something (rogue user app) forces this over 457 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 458 */ 459 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 460 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 461 462 /** 463 * Strict Mode background batched logging state. 464 * 465 * The string buffer is guarded by itself, and its lock is also 466 * used to determine if another batched write is already 467 * in-flight. 468 */ 469 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 470 471 /** 472 * Keeps track of all IIntentReceivers that have been registered for 473 * broadcasts. Hash keys are the receiver IBinder, hash value is 474 * a ReceiverList. 475 */ 476 final HashMap mRegisteredReceivers = new HashMap(); 477 478 /** 479 * Resolver for broadcast intents to registered receivers. 480 * Holds BroadcastFilter (subclass of IntentFilter). 481 */ 482 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 483 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 484 @Override 485 protected boolean allowFilterResult( 486 BroadcastFilter filter, List<BroadcastFilter> dest) { 487 IBinder target = filter.receiverList.receiver.asBinder(); 488 for (int i=dest.size()-1; i>=0; i--) { 489 if (dest.get(i).receiverList.receiver.asBinder() == target) { 490 return false; 491 } 492 } 493 return true; 494 } 495 496 @Override 497 protected BroadcastFilter[] newArray(int size) { 498 return new BroadcastFilter[size]; 499 } 500 501 @Override 502 protected String packageForFilter(BroadcastFilter filter) { 503 return filter.packageName; 504 } 505 }; 506 507 /** 508 * State of all active sticky broadcasts. Keys are the action of the 509 * sticky Intent, values are an ArrayList of all broadcasted intents with 510 * that action (which should usually be one). 511 */ 512 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 513 new HashMap<String, ArrayList<Intent>>(); 514 515 final ActiveServices mServices; 516 517 /** 518 * Backup/restore process management 519 */ 520 String mBackupAppName = null; 521 BackupRecord mBackupTarget = null; 522 523 /** 524 * List of PendingThumbnailsRecord objects of clients who are still 525 * waiting to receive all of the thumbnails for a task. 526 */ 527 final ArrayList mPendingThumbnails = new ArrayList(); 528 529 /** 530 * List of HistoryRecord objects that have been finished and must 531 * still report back to a pending thumbnail receiver. 532 */ 533 final ArrayList mCancelledThumbnails = new ArrayList(); 534 535 final ProviderMap mProviderMap = new ProviderMap(); 536 537 /** 538 * List of content providers who have clients waiting for them. The 539 * application is currently being launched and the provider will be 540 * removed from this list once it is published. 541 */ 542 final ArrayList<ContentProviderRecord> mLaunchingProviders 543 = new ArrayList<ContentProviderRecord>(); 544 545 /** 546 * Global set of specific Uri permissions that have been granted. 547 */ 548 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 549 = new SparseArray<HashMap<Uri, UriPermission>>(); 550 551 CoreSettingsObserver mCoreSettingsObserver; 552 553 /** 554 * Thread-local storage used to carry caller permissions over through 555 * indirect content-provider access. 556 * @see #ActivityManagerService.openContentUri() 557 */ 558 private class Identity { 559 public int pid; 560 public int uid; 561 562 Identity(int _pid, int _uid) { 563 pid = _pid; 564 uid = _uid; 565 } 566 } 567 568 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 569 570 /** 571 * All information we have collected about the runtime performance of 572 * any user id that can impact battery performance. 573 */ 574 final BatteryStatsService mBatteryStatsService; 575 576 /** 577 * information about component usage 578 */ 579 final UsageStatsService mUsageStatsService; 580 581 /** 582 * Current configuration information. HistoryRecord objects are given 583 * a reference to this object to indicate which configuration they are 584 * currently running in, so this object must be kept immutable. 585 */ 586 Configuration mConfiguration = new Configuration(); 587 588 /** 589 * Current sequencing integer of the configuration, for skipping old 590 * configurations. 591 */ 592 int mConfigurationSeq = 0; 593 594 /** 595 * Hardware-reported OpenGLES version. 596 */ 597 final int GL_ES_VERSION; 598 599 /** 600 * List of initialization arguments to pass to all processes when binding applications to them. 601 * For example, references to the commonly used services. 602 */ 603 HashMap<String, IBinder> mAppBindArgs; 604 605 /** 606 * Temporary to avoid allocations. Protected by main lock. 607 */ 608 final StringBuilder mStringBuilder = new StringBuilder(256); 609 610 /** 611 * Used to control how we initialize the service. 612 */ 613 boolean mStartRunning = false; 614 ComponentName mTopComponent; 615 String mTopAction; 616 String mTopData; 617 boolean mProcessesReady = false; 618 boolean mSystemReady = false; 619 boolean mBooting = false; 620 boolean mWaitingUpdate = false; 621 boolean mDidUpdate = false; 622 boolean mOnBattery = false; 623 boolean mLaunchWarningShown = false; 624 625 Context mContext; 626 627 int mFactoryTest; 628 629 boolean mCheckedForSetup; 630 631 /** 632 * The time at which we will allow normal application switches again, 633 * after a call to {@link #stopAppSwitches()}. 634 */ 635 long mAppSwitchesAllowedTime; 636 637 /** 638 * This is set to true after the first switch after mAppSwitchesAllowedTime 639 * is set; any switches after that will clear the time. 640 */ 641 boolean mDidAppSwitch; 642 643 /** 644 * Last time (in realtime) at which we checked for power usage. 645 */ 646 long mLastPowerCheckRealtime; 647 648 /** 649 * Last time (in uptime) at which we checked for power usage. 650 */ 651 long mLastPowerCheckUptime; 652 653 /** 654 * Set while we are wanting to sleep, to prevent any 655 * activities from being started/resumed. 656 */ 657 boolean mSleeping = false; 658 659 /** 660 * State of external calls telling us if the device is asleep. 661 */ 662 boolean mWentToSleep = false; 663 664 /** 665 * State of external call telling us if the lock screen is shown. 666 */ 667 boolean mLockScreenShown = false; 668 669 /** 670 * Set if we are shutting down the system, similar to sleeping. 671 */ 672 boolean mShuttingDown = false; 673 674 /** 675 * Task identifier that activities are currently being started 676 * in. Incremented each time a new task is created. 677 * todo: Replace this with a TokenSpace class that generates non-repeating 678 * integers that won't wrap. 679 */ 680 int mCurTask = 1; 681 682 /** 683 * Current sequence id for oom_adj computation traversal. 684 */ 685 int mAdjSeq = 0; 686 687 /** 688 * Current sequence id for process LRU updating. 689 */ 690 int mLruSeq = 0; 691 692 /** 693 * Keep track of the non-hidden/empty process we last found, to help 694 * determine how to distribute hidden/empty processes next time. 695 */ 696 int mNumNonHiddenProcs = 0; 697 698 /** 699 * Keep track of the number of hidden procs, to balance oom adj 700 * distribution between those and empty procs. 701 */ 702 int mNumHiddenProcs = 0; 703 704 /** 705 * Keep track of the number of service processes we last found, to 706 * determine on the next iteration which should be B services. 707 */ 708 int mNumServiceProcs = 0; 709 int mNewNumServiceProcs = 0; 710 711 /** 712 * System monitoring: number of processes that died since the last 713 * N procs were started. 714 */ 715 int[] mProcDeaths = new int[20]; 716 717 /** 718 * This is set if we had to do a delayed dexopt of an app before launching 719 * it, to increasing the ANR timeouts in that case. 720 */ 721 boolean mDidDexOpt; 722 723 String mDebugApp = null; 724 boolean mWaitForDebugger = false; 725 boolean mDebugTransient = false; 726 String mOrigDebugApp = null; 727 boolean mOrigWaitForDebugger = false; 728 boolean mAlwaysFinishActivities = false; 729 IActivityController mController = null; 730 String mProfileApp = null; 731 ProcessRecord mProfileProc = null; 732 String mProfileFile; 733 ParcelFileDescriptor mProfileFd; 734 int mProfileType = 0; 735 boolean mAutoStopProfiler = false; 736 String mOpenGlTraceApp = null; 737 738 static class ProcessChangeItem { 739 static final int CHANGE_ACTIVITIES = 1<<0; 740 static final int CHANGE_IMPORTANCE= 1<<1; 741 int changes; 742 int uid; 743 int pid; 744 int importance; 745 boolean foregroundActivities; 746 } 747 748 final RemoteCallbackList<IProcessObserver> mProcessObservers 749 = new RemoteCallbackList<IProcessObserver>(); 750 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 751 752 final ArrayList<ProcessChangeItem> mPendingProcessChanges 753 = new ArrayList<ProcessChangeItem>(); 754 final ArrayList<ProcessChangeItem> mAvailProcessChanges 755 = new ArrayList<ProcessChangeItem>(); 756 757 /** 758 * Callback of last caller to {@link #requestPss}. 759 */ 760 Runnable mRequestPssCallback; 761 762 /** 763 * Remaining processes for which we are waiting results from the last 764 * call to {@link #requestPss}. 765 */ 766 final ArrayList<ProcessRecord> mRequestPssList 767 = new ArrayList<ProcessRecord>(); 768 769 /** 770 * Runtime statistics collection thread. This object's lock is used to 771 * protect all related state. 772 */ 773 final Thread mProcessStatsThread; 774 775 /** 776 * Used to collect process stats when showing not responding dialog. 777 * Protected by mProcessStatsThread. 778 */ 779 final ProcessStats mProcessStats = new ProcessStats( 780 MONITOR_THREAD_CPU_USAGE); 781 final AtomicLong mLastCpuTime = new AtomicLong(0); 782 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 783 784 long mLastWriteTime = 0; 785 786 /** 787 * Set to true after the system has finished booting. 788 */ 789 boolean mBooted = false; 790 791 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 792 int mProcessLimitOverride = -1; 793 794 WindowManagerService mWindowManager; 795 796 static ActivityManagerService mSelf; 797 static ActivityThread mSystemThread; 798 799 private int mCurrentUserId; 800 private UserManager mUserManager; 801 802 private final class AppDeathRecipient implements IBinder.DeathRecipient { 803 final ProcessRecord mApp; 804 final int mPid; 805 final IApplicationThread mAppThread; 806 807 AppDeathRecipient(ProcessRecord app, int pid, 808 IApplicationThread thread) { 809 if (localLOGV) Slog.v( 810 TAG, "New death recipient " + this 811 + " for thread " + thread.asBinder()); 812 mApp = app; 813 mPid = pid; 814 mAppThread = thread; 815 } 816 817 public void binderDied() { 818 if (localLOGV) Slog.v( 819 TAG, "Death received in " + this 820 + " for thread " + mAppThread.asBinder()); 821 synchronized(ActivityManagerService.this) { 822 appDiedLocked(mApp, mPid, mAppThread); 823 } 824 } 825 } 826 827 static final int SHOW_ERROR_MSG = 1; 828 static final int SHOW_NOT_RESPONDING_MSG = 2; 829 static final int SHOW_FACTORY_ERROR_MSG = 3; 830 static final int UPDATE_CONFIGURATION_MSG = 4; 831 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 832 static final int WAIT_FOR_DEBUGGER_MSG = 6; 833 static final int SERVICE_TIMEOUT_MSG = 12; 834 static final int UPDATE_TIME_ZONE = 13; 835 static final int SHOW_UID_ERROR_MSG = 14; 836 static final int IM_FEELING_LUCKY_MSG = 15; 837 static final int PROC_START_TIMEOUT_MSG = 20; 838 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 839 static final int KILL_APPLICATION_MSG = 22; 840 static final int FINALIZE_PENDING_INTENT_MSG = 23; 841 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 842 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 843 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 844 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 845 static final int CLEAR_DNS_CACHE = 28; 846 static final int UPDATE_HTTP_PROXY = 29; 847 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 848 static final int DISPATCH_PROCESSES_CHANGED = 31; 849 static final int DISPATCH_PROCESS_DIED = 32; 850 static final int REPORT_MEM_USAGE = 33; 851 852 static final int FIRST_ACTIVITY_STACK_MSG = 100; 853 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 854 static final int FIRST_COMPAT_MODE_MSG = 300; 855 856 AlertDialog mUidAlert; 857 CompatModeDialog mCompatModeDialog; 858 long mLastMemUsageReportTime = 0; 859 860 final Handler mHandler = new Handler() { 861 //public Handler() { 862 // if (localLOGV) Slog.v(TAG, "Handler started!"); 863 //} 864 865 public void handleMessage(Message msg) { 866 switch (msg.what) { 867 case SHOW_ERROR_MSG: { 868 HashMap data = (HashMap) msg.obj; 869 synchronized (ActivityManagerService.this) { 870 ProcessRecord proc = (ProcessRecord)data.get("app"); 871 if (proc != null && proc.crashDialog != null) { 872 Slog.e(TAG, "App already has crash dialog: " + proc); 873 return; 874 } 875 AppErrorResult res = (AppErrorResult) data.get("result"); 876 if (mShowDialogs && !mSleeping && !mShuttingDown) { 877 Dialog d = new AppErrorDialog(mContext, res, proc); 878 d.show(); 879 proc.crashDialog = d; 880 } else { 881 // The device is asleep, so just pretend that the user 882 // saw a crash dialog and hit "force quit". 883 res.set(0); 884 } 885 } 886 887 ensureBootCompleted(); 888 } break; 889 case SHOW_NOT_RESPONDING_MSG: { 890 synchronized (ActivityManagerService.this) { 891 HashMap data = (HashMap) msg.obj; 892 ProcessRecord proc = (ProcessRecord)data.get("app"); 893 if (proc != null && proc.anrDialog != null) { 894 Slog.e(TAG, "App already has anr dialog: " + proc); 895 return; 896 } 897 898 Intent intent = new Intent("android.intent.action.ANR"); 899 if (!mProcessesReady) { 900 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 901 | Intent.FLAG_RECEIVER_FOREGROUND); 902 } 903 broadcastIntentLocked(null, null, intent, 904 null, null, 0, null, null, null, 905 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 906 907 if (mShowDialogs) { 908 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 909 mContext, proc, (ActivityRecord)data.get("activity")); 910 d.show(); 911 proc.anrDialog = d; 912 } else { 913 // Just kill the app if there is no dialog to be shown. 914 killAppAtUsersRequest(proc, null); 915 } 916 } 917 918 ensureBootCompleted(); 919 } break; 920 case SHOW_STRICT_MODE_VIOLATION_MSG: { 921 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 922 synchronized (ActivityManagerService.this) { 923 ProcessRecord proc = (ProcessRecord) data.get("app"); 924 if (proc == null) { 925 Slog.e(TAG, "App not found when showing strict mode dialog."); 926 break; 927 } 928 if (proc.crashDialog != null) { 929 Slog.e(TAG, "App already has strict mode dialog: " + proc); 930 return; 931 } 932 AppErrorResult res = (AppErrorResult) data.get("result"); 933 if (mShowDialogs && !mSleeping && !mShuttingDown) { 934 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 935 d.show(); 936 proc.crashDialog = d; 937 } else { 938 // The device is asleep, so just pretend that the user 939 // saw a crash dialog and hit "force quit". 940 res.set(0); 941 } 942 } 943 ensureBootCompleted(); 944 } break; 945 case SHOW_FACTORY_ERROR_MSG: { 946 Dialog d = new FactoryErrorDialog( 947 mContext, msg.getData().getCharSequence("msg")); 948 d.show(); 949 ensureBootCompleted(); 950 } break; 951 case UPDATE_CONFIGURATION_MSG: { 952 final ContentResolver resolver = mContext.getContentResolver(); 953 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 954 } break; 955 case GC_BACKGROUND_PROCESSES_MSG: { 956 synchronized (ActivityManagerService.this) { 957 performAppGcsIfAppropriateLocked(); 958 } 959 } break; 960 case WAIT_FOR_DEBUGGER_MSG: { 961 synchronized (ActivityManagerService.this) { 962 ProcessRecord app = (ProcessRecord)msg.obj; 963 if (msg.arg1 != 0) { 964 if (!app.waitedForDebugger) { 965 Dialog d = new AppWaitingForDebuggerDialog( 966 ActivityManagerService.this, 967 mContext, app); 968 app.waitDialog = d; 969 app.waitedForDebugger = true; 970 d.show(); 971 } 972 } else { 973 if (app.waitDialog != null) { 974 app.waitDialog.dismiss(); 975 app.waitDialog = null; 976 } 977 } 978 } 979 } break; 980 case SERVICE_TIMEOUT_MSG: { 981 if (mDidDexOpt) { 982 mDidDexOpt = false; 983 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 984 nmsg.obj = msg.obj; 985 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 986 return; 987 } 988 mServices.serviceTimeout((ProcessRecord)msg.obj); 989 } break; 990 case UPDATE_TIME_ZONE: { 991 synchronized (ActivityManagerService.this) { 992 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 993 ProcessRecord r = mLruProcesses.get(i); 994 if (r.thread != null) { 995 try { 996 r.thread.updateTimeZone(); 997 } catch (RemoteException ex) { 998 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 999 } 1000 } 1001 } 1002 } 1003 } break; 1004 case CLEAR_DNS_CACHE: { 1005 synchronized (ActivityManagerService.this) { 1006 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1007 ProcessRecord r = mLruProcesses.get(i); 1008 if (r.thread != null) { 1009 try { 1010 r.thread.clearDnsCache(); 1011 } catch (RemoteException ex) { 1012 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1013 } 1014 } 1015 } 1016 } 1017 } break; 1018 case UPDATE_HTTP_PROXY: { 1019 ProxyProperties proxy = (ProxyProperties)msg.obj; 1020 String host = ""; 1021 String port = ""; 1022 String exclList = ""; 1023 if (proxy != null) { 1024 host = proxy.getHost(); 1025 port = Integer.toString(proxy.getPort()); 1026 exclList = proxy.getExclusionList(); 1027 } 1028 synchronized (ActivityManagerService.this) { 1029 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1030 ProcessRecord r = mLruProcesses.get(i); 1031 if (r.thread != null) { 1032 try { 1033 r.thread.setHttpProxy(host, port, exclList); 1034 } catch (RemoteException ex) { 1035 Slog.w(TAG, "Failed to update http proxy for: " + 1036 r.info.processName); 1037 } 1038 } 1039 } 1040 } 1041 } break; 1042 case SHOW_UID_ERROR_MSG: { 1043 String title = "System UIDs Inconsistent"; 1044 String text = "UIDs on the system are inconsistent, you need to wipe your" 1045 + " data partition or your device will be unstable."; 1046 Log.e(TAG, title + ": " + text); 1047 if (mShowDialogs) { 1048 // XXX This is a temporary dialog, no need to localize. 1049 AlertDialog d = new BaseErrorDialog(mContext); 1050 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1051 d.setCancelable(false); 1052 d.setTitle(title); 1053 d.setMessage(text); 1054 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1055 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1056 mUidAlert = d; 1057 d.show(); 1058 } 1059 } break; 1060 case IM_FEELING_LUCKY_MSG: { 1061 if (mUidAlert != null) { 1062 mUidAlert.dismiss(); 1063 mUidAlert = null; 1064 } 1065 } break; 1066 case PROC_START_TIMEOUT_MSG: { 1067 if (mDidDexOpt) { 1068 mDidDexOpt = false; 1069 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1070 nmsg.obj = msg.obj; 1071 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1072 return; 1073 } 1074 ProcessRecord app = (ProcessRecord)msg.obj; 1075 synchronized (ActivityManagerService.this) { 1076 processStartTimedOutLocked(app); 1077 } 1078 } break; 1079 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1080 synchronized (ActivityManagerService.this) { 1081 doPendingActivityLaunchesLocked(true); 1082 } 1083 } break; 1084 case KILL_APPLICATION_MSG: { 1085 synchronized (ActivityManagerService.this) { 1086 int uid = msg.arg1; 1087 boolean restart = (msg.arg2 == 1); 1088 String pkg = (String) msg.obj; 1089 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1090 UserHandle.getUserId(uid)); 1091 } 1092 } break; 1093 case FINALIZE_PENDING_INTENT_MSG: { 1094 ((PendingIntentRecord)msg.obj).completeFinalize(); 1095 } break; 1096 case POST_HEAVY_NOTIFICATION_MSG: { 1097 INotificationManager inm = NotificationManager.getService(); 1098 if (inm == null) { 1099 return; 1100 } 1101 1102 ActivityRecord root = (ActivityRecord)msg.obj; 1103 ProcessRecord process = root.app; 1104 if (process == null) { 1105 return; 1106 } 1107 1108 try { 1109 Context context = mContext.createPackageContext(process.info.packageName, 0); 1110 String text = mContext.getString(R.string.heavy_weight_notification, 1111 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1112 Notification notification = new Notification(); 1113 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1114 notification.when = 0; 1115 notification.flags = Notification.FLAG_ONGOING_EVENT; 1116 notification.tickerText = text; 1117 notification.defaults = 0; // please be quiet 1118 notification.sound = null; 1119 notification.vibrate = null; 1120 notification.setLatestEventInfo(context, text, 1121 mContext.getText(R.string.heavy_weight_notification_detail), 1122 PendingIntent.getActivity(mContext, 0, root.intent, 1123 PendingIntent.FLAG_CANCEL_CURRENT)); 1124 1125 try { 1126 int[] outId = new int[1]; 1127 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1128 notification, outId); 1129 } catch (RuntimeException e) { 1130 Slog.w(ActivityManagerService.TAG, 1131 "Error showing notification for heavy-weight app", e); 1132 } catch (RemoteException e) { 1133 } 1134 } catch (NameNotFoundException e) { 1135 Slog.w(TAG, "Unable to create context for heavy notification", e); 1136 } 1137 } break; 1138 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1139 INotificationManager inm = NotificationManager.getService(); 1140 if (inm == null) { 1141 return; 1142 } 1143 try { 1144 inm.cancelNotification("android", 1145 R.string.heavy_weight_notification); 1146 } catch (RuntimeException e) { 1147 Slog.w(ActivityManagerService.TAG, 1148 "Error canceling notification for service", e); 1149 } catch (RemoteException e) { 1150 } 1151 } break; 1152 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1153 synchronized (ActivityManagerService.this) { 1154 checkExcessivePowerUsageLocked(true); 1155 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1156 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1157 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1158 } 1159 } break; 1160 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1161 synchronized (ActivityManagerService.this) { 1162 ActivityRecord ar = (ActivityRecord)msg.obj; 1163 if (mCompatModeDialog != null) { 1164 if (mCompatModeDialog.mAppInfo.packageName.equals( 1165 ar.info.applicationInfo.packageName)) { 1166 return; 1167 } 1168 mCompatModeDialog.dismiss(); 1169 mCompatModeDialog = null; 1170 } 1171 if (ar != null && false) { 1172 if (mCompatModePackages.getPackageAskCompatModeLocked( 1173 ar.packageName)) { 1174 int mode = mCompatModePackages.computeCompatModeLocked( 1175 ar.info.applicationInfo); 1176 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1177 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1178 mCompatModeDialog = new CompatModeDialog( 1179 ActivityManagerService.this, mContext, 1180 ar.info.applicationInfo); 1181 mCompatModeDialog.show(); 1182 } 1183 } 1184 } 1185 } 1186 break; 1187 } 1188 case DISPATCH_PROCESSES_CHANGED: { 1189 dispatchProcessesChanged(); 1190 break; 1191 } 1192 case DISPATCH_PROCESS_DIED: { 1193 final int pid = msg.arg1; 1194 final int uid = msg.arg2; 1195 dispatchProcessDied(pid, uid); 1196 break; 1197 } 1198 case REPORT_MEM_USAGE: { 1199 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1200 if (!isDebuggable) { 1201 return; 1202 } 1203 synchronized (ActivityManagerService.this) { 1204 long now = SystemClock.uptimeMillis(); 1205 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1206 // Don't report more than every 5 minutes to somewhat 1207 // avoid spamming. 1208 return; 1209 } 1210 mLastMemUsageReportTime = now; 1211 } 1212 Thread thread = new Thread() { 1213 @Override public void run() { 1214 StringBuilder dropBuilder = new StringBuilder(1024); 1215 StringBuilder logBuilder = new StringBuilder(1024); 1216 StringWriter oomSw = new StringWriter(); 1217 PrintWriter oomPw = new PrintWriter(oomSw); 1218 StringWriter catSw = new StringWriter(); 1219 PrintWriter catPw = new PrintWriter(catSw); 1220 String[] emptyArgs = new String[] { }; 1221 StringBuilder tag = new StringBuilder(128); 1222 StringBuilder stack = new StringBuilder(128); 1223 tag.append("Low on memory -- "); 1224 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1225 tag, stack); 1226 dropBuilder.append(stack); 1227 dropBuilder.append('\n'); 1228 dropBuilder.append('\n'); 1229 String oomString = oomSw.toString(); 1230 dropBuilder.append(oomString); 1231 dropBuilder.append('\n'); 1232 logBuilder.append(oomString); 1233 try { 1234 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1235 "procrank", }); 1236 final InputStreamReader converter = new InputStreamReader( 1237 proc.getInputStream()); 1238 BufferedReader in = new BufferedReader(converter); 1239 String line; 1240 while (true) { 1241 line = in.readLine(); 1242 if (line == null) { 1243 break; 1244 } 1245 if (line.length() > 0) { 1246 logBuilder.append(line); 1247 logBuilder.append('\n'); 1248 } 1249 dropBuilder.append(line); 1250 dropBuilder.append('\n'); 1251 } 1252 converter.close(); 1253 } catch (IOException e) { 1254 } 1255 synchronized (ActivityManagerService.this) { 1256 catPw.println(); 1257 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1258 catPw.println(); 1259 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1260 false, false, null); 1261 catPw.println(); 1262 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1263 } 1264 dropBuilder.append(catSw.toString()); 1265 addErrorToDropBox("lowmem", null, "system_server", null, 1266 null, tag.toString(), dropBuilder.toString(), null, null); 1267 Slog.i(TAG, logBuilder.toString()); 1268 synchronized (ActivityManagerService.this) { 1269 long now = SystemClock.uptimeMillis(); 1270 if (mLastMemUsageReportTime < now) { 1271 mLastMemUsageReportTime = now; 1272 } 1273 } 1274 } 1275 }; 1276 thread.start(); 1277 break; 1278 } 1279 } 1280 } 1281 }; 1282 1283 public static void setSystemProcess() { 1284 try { 1285 ActivityManagerService m = mSelf; 1286 1287 ServiceManager.addService("activity", m, true); 1288 ServiceManager.addService("meminfo", new MemBinder(m)); 1289 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1290 ServiceManager.addService("dbinfo", new DbBinder(m)); 1291 if (MONITOR_CPU_USAGE) { 1292 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1293 } 1294 ServiceManager.addService("permission", new PermissionController(m)); 1295 1296 ApplicationInfo info = 1297 mSelf.mContext.getPackageManager().getApplicationInfo( 1298 "android", STOCK_PM_FLAGS); 1299 mSystemThread.installSystemApplicationInfo(info); 1300 1301 synchronized (mSelf) { 1302 ProcessRecord app = mSelf.newProcessRecordLocked( 1303 mSystemThread.getApplicationThread(), info, 1304 info.processName, false); 1305 app.persistent = true; 1306 app.pid = MY_PID; 1307 app.maxAdj = ProcessList.SYSTEM_ADJ; 1308 mSelf.mProcessNames.put(app.processName, app.uid, app); 1309 synchronized (mSelf.mPidsSelfLocked) { 1310 mSelf.mPidsSelfLocked.put(app.pid, app); 1311 } 1312 mSelf.updateLruProcessLocked(app, true, true); 1313 } 1314 } catch (PackageManager.NameNotFoundException e) { 1315 throw new RuntimeException( 1316 "Unable to find android system package", e); 1317 } 1318 } 1319 1320 public void setWindowManager(WindowManagerService wm) { 1321 mWindowManager = wm; 1322 } 1323 1324 public static final Context main(int factoryTest) { 1325 AThread thr = new AThread(); 1326 thr.start(); 1327 1328 synchronized (thr) { 1329 while (thr.mService == null) { 1330 try { 1331 thr.wait(); 1332 } catch (InterruptedException e) { 1333 } 1334 } 1335 } 1336 1337 ActivityManagerService m = thr.mService; 1338 mSelf = m; 1339 ActivityThread at = ActivityThread.systemMain(); 1340 mSystemThread = at; 1341 Context context = at.getSystemContext(); 1342 context.setTheme(android.R.style.Theme_Holo); 1343 m.mContext = context; 1344 m.mFactoryTest = factoryTest; 1345 m.mMainStack = new ActivityStack(m, context, true); 1346 1347 m.mBatteryStatsService.publish(context); 1348 m.mUsageStatsService.publish(context); 1349 1350 synchronized (thr) { 1351 thr.mReady = true; 1352 thr.notifyAll(); 1353 } 1354 1355 m.startRunning(null, null, null, null); 1356 1357 return context; 1358 } 1359 1360 public static ActivityManagerService self() { 1361 return mSelf; 1362 } 1363 1364 static class AThread extends Thread { 1365 ActivityManagerService mService; 1366 boolean mReady = false; 1367 1368 public AThread() { 1369 super("ActivityManager"); 1370 } 1371 1372 public void run() { 1373 Looper.prepare(); 1374 1375 android.os.Process.setThreadPriority( 1376 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1377 android.os.Process.setCanSelfBackground(false); 1378 1379 ActivityManagerService m = new ActivityManagerService(); 1380 1381 synchronized (this) { 1382 mService = m; 1383 notifyAll(); 1384 } 1385 1386 synchronized (this) { 1387 while (!mReady) { 1388 try { 1389 wait(); 1390 } catch (InterruptedException e) { 1391 } 1392 } 1393 } 1394 1395 // For debug builds, log event loop stalls to dropbox for analysis. 1396 if (StrictMode.conditionallyEnableDebugLogging()) { 1397 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1398 } 1399 1400 Looper.loop(); 1401 } 1402 } 1403 1404 static class MemBinder extends Binder { 1405 ActivityManagerService mActivityManagerService; 1406 MemBinder(ActivityManagerService activityManagerService) { 1407 mActivityManagerService = activityManagerService; 1408 } 1409 1410 @Override 1411 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1412 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1413 != PackageManager.PERMISSION_GRANTED) { 1414 pw.println("Permission Denial: can't dump meminfo from from pid=" 1415 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1416 + " without permission " + android.Manifest.permission.DUMP); 1417 return; 1418 } 1419 1420 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1421 false, null, null, null); 1422 } 1423 } 1424 1425 static class GraphicsBinder extends Binder { 1426 ActivityManagerService mActivityManagerService; 1427 GraphicsBinder(ActivityManagerService activityManagerService) { 1428 mActivityManagerService = activityManagerService; 1429 } 1430 1431 @Override 1432 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1433 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1434 != PackageManager.PERMISSION_GRANTED) { 1435 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1436 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1437 + " without permission " + android.Manifest.permission.DUMP); 1438 return; 1439 } 1440 1441 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1442 } 1443 } 1444 1445 static class DbBinder extends Binder { 1446 ActivityManagerService mActivityManagerService; 1447 DbBinder(ActivityManagerService activityManagerService) { 1448 mActivityManagerService = activityManagerService; 1449 } 1450 1451 @Override 1452 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1453 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1454 != PackageManager.PERMISSION_GRANTED) { 1455 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1456 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1457 + " without permission " + android.Manifest.permission.DUMP); 1458 return; 1459 } 1460 1461 mActivityManagerService.dumpDbInfo(fd, pw, args); 1462 } 1463 } 1464 1465 static class CpuBinder extends Binder { 1466 ActivityManagerService mActivityManagerService; 1467 CpuBinder(ActivityManagerService activityManagerService) { 1468 mActivityManagerService = activityManagerService; 1469 } 1470 1471 @Override 1472 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1473 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1474 != PackageManager.PERMISSION_GRANTED) { 1475 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1476 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1477 + " without permission " + android.Manifest.permission.DUMP); 1478 return; 1479 } 1480 1481 synchronized (mActivityManagerService.mProcessStatsThread) { 1482 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1483 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1484 SystemClock.uptimeMillis())); 1485 } 1486 } 1487 } 1488 1489 private ActivityManagerService() { 1490 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1491 1492 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1493 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1494 mBroadcastQueues[0] = mFgBroadcastQueue; 1495 mBroadcastQueues[1] = mBgBroadcastQueue; 1496 1497 mServices = new ActiveServices(this); 1498 1499 File dataDir = Environment.getDataDirectory(); 1500 File systemDir = new File(dataDir, "system"); 1501 systemDir.mkdirs(); 1502 mBatteryStatsService = new BatteryStatsService(new File( 1503 systemDir, "batterystats.bin").toString()); 1504 mBatteryStatsService.getActiveStatistics().readLocked(); 1505 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1506 mOnBattery = DEBUG_POWER ? true 1507 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1508 mBatteryStatsService.getActiveStatistics().setCallback(this); 1509 1510 mUsageStatsService = new UsageStatsService(new File( 1511 systemDir, "usagestats").toString()); 1512 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1513 1514 // User 0 is the first and only user that runs at boot. 1515 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1516 1517 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1518 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1519 1520 mConfiguration.setToDefaults(); 1521 mConfiguration.locale = Locale.getDefault(); 1522 mConfigurationSeq = mConfiguration.seq = 1; 1523 mProcessStats.init(); 1524 1525 mCompatModePackages = new CompatModePackages(this, systemDir); 1526 1527 // Add ourself to the Watchdog monitors. 1528 Watchdog.getInstance().addMonitor(this); 1529 1530 mProcessStatsThread = new Thread("ProcessStats") { 1531 public void run() { 1532 while (true) { 1533 try { 1534 try { 1535 synchronized(this) { 1536 final long now = SystemClock.uptimeMillis(); 1537 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1538 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1539 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1540 // + ", write delay=" + nextWriteDelay); 1541 if (nextWriteDelay < nextCpuDelay) { 1542 nextCpuDelay = nextWriteDelay; 1543 } 1544 if (nextCpuDelay > 0) { 1545 mProcessStatsMutexFree.set(true); 1546 this.wait(nextCpuDelay); 1547 } 1548 } 1549 } catch (InterruptedException e) { 1550 } 1551 updateCpuStatsNow(); 1552 } catch (Exception e) { 1553 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1554 } 1555 } 1556 } 1557 }; 1558 mProcessStatsThread.start(); 1559 } 1560 1561 @Override 1562 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1563 throws RemoteException { 1564 if (code == SYSPROPS_TRANSACTION) { 1565 // We need to tell all apps about the system property change. 1566 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1567 synchronized(this) { 1568 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1569 final int NA = apps.size(); 1570 for (int ia=0; ia<NA; ia++) { 1571 ProcessRecord app = apps.valueAt(ia); 1572 if (app.thread != null) { 1573 procs.add(app.thread.asBinder()); 1574 } 1575 } 1576 } 1577 } 1578 1579 int N = procs.size(); 1580 for (int i=0; i<N; i++) { 1581 Parcel data2 = Parcel.obtain(); 1582 try { 1583 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1584 } catch (RemoteException e) { 1585 } 1586 data2.recycle(); 1587 } 1588 } 1589 try { 1590 return super.onTransact(code, data, reply, flags); 1591 } catch (RuntimeException e) { 1592 // The activity manager only throws security exceptions, so let's 1593 // log all others. 1594 if (!(e instanceof SecurityException)) { 1595 Slog.e(TAG, "Activity Manager Crash", e); 1596 } 1597 throw e; 1598 } 1599 } 1600 1601 void updateCpuStats() { 1602 final long now = SystemClock.uptimeMillis(); 1603 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1604 return; 1605 } 1606 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1607 synchronized (mProcessStatsThread) { 1608 mProcessStatsThread.notify(); 1609 } 1610 } 1611 } 1612 1613 void updateCpuStatsNow() { 1614 synchronized (mProcessStatsThread) { 1615 mProcessStatsMutexFree.set(false); 1616 final long now = SystemClock.uptimeMillis(); 1617 boolean haveNewCpuStats = false; 1618 1619 if (MONITOR_CPU_USAGE && 1620 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1621 mLastCpuTime.set(now); 1622 haveNewCpuStats = true; 1623 mProcessStats.update(); 1624 //Slog.i(TAG, mProcessStats.printCurrentState()); 1625 //Slog.i(TAG, "Total CPU usage: " 1626 // + mProcessStats.getTotalCpuPercent() + "%"); 1627 1628 // Slog the cpu usage if the property is set. 1629 if ("true".equals(SystemProperties.get("events.cpu"))) { 1630 int user = mProcessStats.getLastUserTime(); 1631 int system = mProcessStats.getLastSystemTime(); 1632 int iowait = mProcessStats.getLastIoWaitTime(); 1633 int irq = mProcessStats.getLastIrqTime(); 1634 int softIrq = mProcessStats.getLastSoftIrqTime(); 1635 int idle = mProcessStats.getLastIdleTime(); 1636 1637 int total = user + system + iowait + irq + softIrq + idle; 1638 if (total == 0) total = 1; 1639 1640 EventLog.writeEvent(EventLogTags.CPU, 1641 ((user+system+iowait+irq+softIrq) * 100) / total, 1642 (user * 100) / total, 1643 (system * 100) / total, 1644 (iowait * 100) / total, 1645 (irq * 100) / total, 1646 (softIrq * 100) / total); 1647 } 1648 } 1649 1650 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1651 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1652 synchronized(bstats) { 1653 synchronized(mPidsSelfLocked) { 1654 if (haveNewCpuStats) { 1655 if (mOnBattery) { 1656 int perc = bstats.startAddingCpuLocked(); 1657 int totalUTime = 0; 1658 int totalSTime = 0; 1659 final int N = mProcessStats.countStats(); 1660 for (int i=0; i<N; i++) { 1661 ProcessStats.Stats st = mProcessStats.getStats(i); 1662 if (!st.working) { 1663 continue; 1664 } 1665 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1666 int otherUTime = (st.rel_utime*perc)/100; 1667 int otherSTime = (st.rel_stime*perc)/100; 1668 totalUTime += otherUTime; 1669 totalSTime += otherSTime; 1670 if (pr != null) { 1671 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1672 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1673 st.rel_stime-otherSTime); 1674 ps.addSpeedStepTimes(cpuSpeedTimes); 1675 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1676 } else { 1677 BatteryStatsImpl.Uid.Proc ps = 1678 bstats.getProcessStatsLocked(st.name, st.pid); 1679 if (ps != null) { 1680 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1681 st.rel_stime-otherSTime); 1682 ps.addSpeedStepTimes(cpuSpeedTimes); 1683 } 1684 } 1685 } 1686 bstats.finishAddingCpuLocked(perc, totalUTime, 1687 totalSTime, cpuSpeedTimes); 1688 } 1689 } 1690 } 1691 1692 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1693 mLastWriteTime = now; 1694 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1695 } 1696 } 1697 } 1698 } 1699 1700 @Override 1701 public void batteryNeedsCpuUpdate() { 1702 updateCpuStatsNow(); 1703 } 1704 1705 @Override 1706 public void batteryPowerChanged(boolean onBattery) { 1707 // When plugging in, update the CPU stats first before changing 1708 // the plug state. 1709 updateCpuStatsNow(); 1710 synchronized (this) { 1711 synchronized(mPidsSelfLocked) { 1712 mOnBattery = DEBUG_POWER ? true : onBattery; 1713 } 1714 } 1715 } 1716 1717 /** 1718 * Initialize the application bind args. These are passed to each 1719 * process when the bindApplication() IPC is sent to the process. They're 1720 * lazily setup to make sure the services are running when they're asked for. 1721 */ 1722 private HashMap<String, IBinder> getCommonServicesLocked() { 1723 if (mAppBindArgs == null) { 1724 mAppBindArgs = new HashMap<String, IBinder>(); 1725 1726 // Setup the application init args 1727 mAppBindArgs.put("package", ServiceManager.getService("package")); 1728 mAppBindArgs.put("window", ServiceManager.getService("window")); 1729 mAppBindArgs.put(Context.ALARM_SERVICE, 1730 ServiceManager.getService(Context.ALARM_SERVICE)); 1731 } 1732 return mAppBindArgs; 1733 } 1734 1735 final void setFocusedActivityLocked(ActivityRecord r) { 1736 if (mFocusedActivity != r) { 1737 mFocusedActivity = r; 1738 if (r != null) { 1739 mWindowManager.setFocusedApp(r.appToken, true); 1740 } 1741 } 1742 } 1743 1744 private final void updateLruProcessInternalLocked(ProcessRecord app, 1745 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1746 // put it on the LRU to keep track of when it should be exited. 1747 int lrui = mLruProcesses.indexOf(app); 1748 if (lrui >= 0) mLruProcesses.remove(lrui); 1749 1750 int i = mLruProcesses.size()-1; 1751 int skipTop = 0; 1752 1753 app.lruSeq = mLruSeq; 1754 1755 // compute the new weight for this process. 1756 if (updateActivityTime) { 1757 app.lastActivityTime = SystemClock.uptimeMillis(); 1758 } 1759 if (app.activities.size() > 0) { 1760 // If this process has activities, we more strongly want to keep 1761 // it around. 1762 app.lruWeight = app.lastActivityTime; 1763 } else if (app.pubProviders.size() > 0) { 1764 // If this process contains content providers, we want to keep 1765 // it a little more strongly. 1766 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1767 // Also don't let it kick out the first few "real" hidden processes. 1768 skipTop = ProcessList.MIN_HIDDEN_APPS; 1769 } else { 1770 // If this process doesn't have activities, we less strongly 1771 // want to keep it around, and generally want to avoid getting 1772 // in front of any very recently used activities. 1773 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1774 // Also don't let it kick out the first few "real" hidden processes. 1775 skipTop = ProcessList.MIN_HIDDEN_APPS; 1776 } 1777 1778 while (i >= 0) { 1779 ProcessRecord p = mLruProcesses.get(i); 1780 // If this app shouldn't be in front of the first N background 1781 // apps, then skip over that many that are currently hidden. 1782 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1783 skipTop--; 1784 } 1785 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1786 mLruProcesses.add(i+1, app); 1787 break; 1788 } 1789 i--; 1790 } 1791 if (i < 0) { 1792 mLruProcesses.add(0, app); 1793 } 1794 1795 // If the app is currently using a content provider or service, 1796 // bump those processes as well. 1797 if (app.connections.size() > 0) { 1798 for (ConnectionRecord cr : app.connections) { 1799 if (cr.binding != null && cr.binding.service != null 1800 && cr.binding.service.app != null 1801 && cr.binding.service.app.lruSeq != mLruSeq) { 1802 updateLruProcessInternalLocked(cr.binding.service.app, false, 1803 updateActivityTime, i+1); 1804 } 1805 } 1806 } 1807 for (int j=app.conProviders.size()-1; j>=0; j--) { 1808 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1809 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1810 updateLruProcessInternalLocked(cpr.proc, false, 1811 updateActivityTime, i+1); 1812 } 1813 } 1814 1815 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1816 if (oomAdj) { 1817 updateOomAdjLocked(); 1818 } 1819 } 1820 1821 final void updateLruProcessLocked(ProcessRecord app, 1822 boolean oomAdj, boolean updateActivityTime) { 1823 mLruSeq++; 1824 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1825 } 1826 1827 final ProcessRecord getProcessRecordLocked( 1828 String processName, int uid) { 1829 if (uid == Process.SYSTEM_UID) { 1830 // The system gets to run in any process. If there are multiple 1831 // processes with the same uid, just pick the first (this 1832 // should never happen). 1833 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1834 processName); 1835 if (procs == null) return null; 1836 final int N = procs.size(); 1837 for (int i = 0; i < N; i++) { 1838 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1839 } 1840 } 1841 ProcessRecord proc = mProcessNames.get(processName, uid); 1842 return proc; 1843 } 1844 1845 void ensurePackageDexOpt(String packageName) { 1846 IPackageManager pm = AppGlobals.getPackageManager(); 1847 try { 1848 if (pm.performDexOpt(packageName)) { 1849 mDidDexOpt = true; 1850 } 1851 } catch (RemoteException e) { 1852 } 1853 } 1854 1855 boolean isNextTransitionForward() { 1856 int transit = mWindowManager.getPendingAppTransition(); 1857 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1858 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1859 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1860 } 1861 1862 final ProcessRecord startProcessLocked(String processName, 1863 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1864 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1865 boolean isolated) { 1866 ProcessRecord app; 1867 if (!isolated) { 1868 app = getProcessRecordLocked(processName, info.uid); 1869 } else { 1870 // If this is an isolated process, it can't re-use an existing process. 1871 app = null; 1872 } 1873 // We don't have to do anything more if: 1874 // (1) There is an existing application record; and 1875 // (2) The caller doesn't think it is dead, OR there is no thread 1876 // object attached to it so we know it couldn't have crashed; and 1877 // (3) There is a pid assigned to it, so it is either starting or 1878 // already running. 1879 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1880 + " app=" + app + " knownToBeDead=" + knownToBeDead 1881 + " thread=" + (app != null ? app.thread : null) 1882 + " pid=" + (app != null ? app.pid : -1)); 1883 if (app != null && app.pid > 0) { 1884 if (!knownToBeDead || app.thread == null) { 1885 // We already have the app running, or are waiting for it to 1886 // come up (we have a pid but not yet its thread), so keep it. 1887 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1888 // If this is a new package in the process, add the package to the list 1889 app.addPackage(info.packageName); 1890 return app; 1891 } else { 1892 // An application record is attached to a previous process, 1893 // clean it up now. 1894 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1895 handleAppDiedLocked(app, true, true); 1896 } 1897 } 1898 1899 String hostingNameStr = hostingName != null 1900 ? hostingName.flattenToShortString() : null; 1901 1902 if (!isolated) { 1903 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1904 // If we are in the background, then check to see if this process 1905 // is bad. If so, we will just silently fail. 1906 if (mBadProcesses.get(info.processName, info.uid) != null) { 1907 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1908 + "/" + info.processName); 1909 return null; 1910 } 1911 } else { 1912 // When the user is explicitly starting a process, then clear its 1913 // crash count so that we won't make it bad until they see at 1914 // least one crash dialog again, and make the process good again 1915 // if it had been bad. 1916 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1917 + "/" + info.processName); 1918 mProcessCrashTimes.remove(info.processName, info.uid); 1919 if (mBadProcesses.get(info.processName, info.uid) != null) { 1920 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1921 info.processName); 1922 mBadProcesses.remove(info.processName, info.uid); 1923 if (app != null) { 1924 app.bad = false; 1925 } 1926 } 1927 } 1928 } 1929 1930 if (app == null) { 1931 app = newProcessRecordLocked(null, info, processName, isolated); 1932 if (app == null) { 1933 Slog.w(TAG, "Failed making new process record for " 1934 + processName + "/" + info.uid + " isolated=" + isolated); 1935 return null; 1936 } 1937 mProcessNames.put(processName, app.uid, app); 1938 if (isolated) { 1939 mIsolatedProcesses.put(app.uid, app); 1940 } 1941 } else { 1942 // If this is a new package in the process, add the package to the list 1943 app.addPackage(info.packageName); 1944 } 1945 1946 // If the system is not ready yet, then hold off on starting this 1947 // process until it is. 1948 if (!mProcessesReady 1949 && !isAllowedWhileBooting(info) 1950 && !allowWhileBooting) { 1951 if (!mProcessesOnHold.contains(app)) { 1952 mProcessesOnHold.add(app); 1953 } 1954 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1955 return app; 1956 } 1957 1958 startProcessLocked(app, hostingType, hostingNameStr); 1959 return (app.pid != 0) ? app : null; 1960 } 1961 1962 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1963 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1964 } 1965 1966 private final void startProcessLocked(ProcessRecord app, 1967 String hostingType, String hostingNameStr) { 1968 if (app.pid > 0 && app.pid != MY_PID) { 1969 synchronized (mPidsSelfLocked) { 1970 mPidsSelfLocked.remove(app.pid); 1971 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1972 } 1973 app.setPid(0); 1974 } 1975 1976 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1977 "startProcessLocked removing on hold: " + app); 1978 mProcessesOnHold.remove(app); 1979 1980 updateCpuStats(); 1981 1982 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1983 mProcDeaths[0] = 0; 1984 1985 try { 1986 int uid = app.uid; 1987 1988 int[] gids = null; 1989 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1990 if (!app.isolated) { 1991 try { 1992 final PackageManager pm = mContext.getPackageManager(); 1993 gids = pm.getPackageGids(app.info.packageName); 1994 1995 if (Environment.isExternalStorageEmulated()) { 1996 if (pm.checkPermission( 1997 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 1998 app.info.packageName) == PERMISSION_GRANTED) { 1999 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2000 } else { 2001 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2002 } 2003 } 2004 } catch (PackageManager.NameNotFoundException e) { 2005 Slog.w(TAG, "Unable to retrieve gids", e); 2006 } 2007 } 2008 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2009 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2010 && mTopComponent != null 2011 && app.processName.equals(mTopComponent.getPackageName())) { 2012 uid = 0; 2013 } 2014 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2015 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2016 uid = 0; 2017 } 2018 } 2019 int debugFlags = 0; 2020 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2021 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2022 // Also turn on CheckJNI for debuggable apps. It's quite 2023 // awkward to turn on otherwise. 2024 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2025 } 2026 // Run the app in safe mode if its manifest requests so or the 2027 // system is booted in safe mode. 2028 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2029 Zygote.systemInSafeMode == true) { 2030 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2031 } 2032 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2033 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2034 } 2035 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2036 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2037 } 2038 if ("1".equals(SystemProperties.get("debug.assert"))) { 2039 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2040 } 2041 2042 // Start the process. It will either succeed and return a result containing 2043 // the PID of the new process, or else throw a RuntimeException. 2044 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2045 app.processName, uid, uid, gids, debugFlags, mountExternal, 2046 app.info.targetSdkVersion, null, null); 2047 2048 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2049 synchronized (bs) { 2050 if (bs.isOnBattery()) { 2051 app.batteryStats.incStartsLocked(); 2052 } 2053 } 2054 2055 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2056 app.processName, hostingType, 2057 hostingNameStr != null ? hostingNameStr : ""); 2058 2059 if (app.persistent) { 2060 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2061 } 2062 2063 StringBuilder buf = mStringBuilder; 2064 buf.setLength(0); 2065 buf.append("Start proc "); 2066 buf.append(app.processName); 2067 buf.append(" for "); 2068 buf.append(hostingType); 2069 if (hostingNameStr != null) { 2070 buf.append(" "); 2071 buf.append(hostingNameStr); 2072 } 2073 buf.append(": pid="); 2074 buf.append(startResult.pid); 2075 buf.append(" uid="); 2076 buf.append(uid); 2077 buf.append(" gids={"); 2078 if (gids != null) { 2079 for (int gi=0; gi<gids.length; gi++) { 2080 if (gi != 0) buf.append(", "); 2081 buf.append(gids[gi]); 2082 2083 } 2084 } 2085 buf.append("}"); 2086 Slog.i(TAG, buf.toString()); 2087 app.setPid(startResult.pid); 2088 app.usingWrapper = startResult.usingWrapper; 2089 app.removed = false; 2090 synchronized (mPidsSelfLocked) { 2091 this.mPidsSelfLocked.put(startResult.pid, app); 2092 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2093 msg.obj = app; 2094 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2095 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2096 } 2097 } catch (RuntimeException e) { 2098 // XXX do better error recovery. 2099 app.setPid(0); 2100 Slog.e(TAG, "Failure starting process " + app.processName, e); 2101 } 2102 } 2103 2104 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2105 if (resumed) { 2106 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2107 } else { 2108 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2109 } 2110 } 2111 2112 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2113 if (mHeadless) { 2114 // Added because none of the other calls to ensureBootCompleted seem to fire 2115 // when running headless. 2116 ensureBootCompleted(); 2117 return false; 2118 } 2119 2120 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2121 && mTopAction == null) { 2122 // We are running in factory test mode, but unable to find 2123 // the factory test app, so just sit around displaying the 2124 // error message and don't try to start anything. 2125 return false; 2126 } 2127 Intent intent = new Intent( 2128 mTopAction, 2129 mTopData != null ? Uri.parse(mTopData) : null); 2130 intent.setComponent(mTopComponent); 2131 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2132 intent.addCategory(Intent.CATEGORY_HOME); 2133 } 2134 ActivityInfo aInfo = 2135 intent.resolveActivityInfo(mContext.getPackageManager(), 2136 STOCK_PM_FLAGS); 2137 if (aInfo != null) { 2138 intent.setComponent(new ComponentName( 2139 aInfo.applicationInfo.packageName, aInfo.name)); 2140 // Don't do this if the home app is currently being 2141 // instrumented. 2142 aInfo = new ActivityInfo(aInfo); 2143 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2144 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2145 aInfo.applicationInfo.uid); 2146 if (app == null || app.instrumentationClass == null) { 2147 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2148 mMainStack.startActivityLocked(null, intent, null, aInfo, 2149 null, null, 0, 0, 0, 0, null, false, null); 2150 } 2151 } 2152 if (startingUser != null) { 2153 mMainStack.addStartingUserLocked(startingUser); 2154 } 2155 2156 return true; 2157 } 2158 2159 /** 2160 * Starts the "new version setup screen" if appropriate. 2161 */ 2162 void startSetupActivityLocked() { 2163 // Only do this once per boot. 2164 if (mCheckedForSetup) { 2165 return; 2166 } 2167 2168 // We will show this screen if the current one is a different 2169 // version than the last one shown, and we are not running in 2170 // low-level factory test mode. 2171 final ContentResolver resolver = mContext.getContentResolver(); 2172 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2173 Settings.Secure.getInt(resolver, 2174 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2175 mCheckedForSetup = true; 2176 2177 // See if we should be showing the platform update setup UI. 2178 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2179 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2180 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2181 2182 // We don't allow third party apps to replace this. 2183 ResolveInfo ri = null; 2184 for (int i=0; ris != null && i<ris.size(); i++) { 2185 if ((ris.get(i).activityInfo.applicationInfo.flags 2186 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2187 ri = ris.get(i); 2188 break; 2189 } 2190 } 2191 2192 if (ri != null) { 2193 String vers = ri.activityInfo.metaData != null 2194 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2195 : null; 2196 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2197 vers = ri.activityInfo.applicationInfo.metaData.getString( 2198 Intent.METADATA_SETUP_VERSION); 2199 } 2200 String lastVers = Settings.Secure.getString( 2201 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2202 if (vers != null && !vers.equals(lastVers)) { 2203 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2204 intent.setComponent(new ComponentName( 2205 ri.activityInfo.packageName, ri.activityInfo.name)); 2206 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2207 null, null, 0, 0, 0, 0, null, false, null); 2208 } 2209 } 2210 } 2211 } 2212 2213 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2214 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2215 } 2216 2217 void enforceNotIsolatedCaller(String caller) { 2218 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2219 throw new SecurityException("Isolated process not allowed to call " + caller); 2220 } 2221 } 2222 2223 public int getFrontActivityScreenCompatMode() { 2224 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2225 synchronized (this) { 2226 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2227 } 2228 } 2229 2230 public void setFrontActivityScreenCompatMode(int mode) { 2231 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2232 "setFrontActivityScreenCompatMode"); 2233 synchronized (this) { 2234 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2235 } 2236 } 2237 2238 public int getPackageScreenCompatMode(String packageName) { 2239 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2240 synchronized (this) { 2241 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2242 } 2243 } 2244 2245 public void setPackageScreenCompatMode(String packageName, int mode) { 2246 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2247 "setPackageScreenCompatMode"); 2248 synchronized (this) { 2249 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2250 } 2251 } 2252 2253 public boolean getPackageAskScreenCompat(String packageName) { 2254 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2255 synchronized (this) { 2256 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2257 } 2258 } 2259 2260 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2261 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2262 "setPackageAskScreenCompat"); 2263 synchronized (this) { 2264 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2265 } 2266 } 2267 2268 void reportResumedActivityLocked(ActivityRecord r) { 2269 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2270 updateUsageStats(r, true); 2271 } 2272 2273 private void dispatchProcessesChanged() { 2274 int N; 2275 synchronized (this) { 2276 N = mPendingProcessChanges.size(); 2277 if (mActiveProcessChanges.length < N) { 2278 mActiveProcessChanges = new ProcessChangeItem[N]; 2279 } 2280 mPendingProcessChanges.toArray(mActiveProcessChanges); 2281 mAvailProcessChanges.addAll(mPendingProcessChanges); 2282 mPendingProcessChanges.clear(); 2283 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2284 } 2285 int i = mProcessObservers.beginBroadcast(); 2286 while (i > 0) { 2287 i--; 2288 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2289 if (observer != null) { 2290 try { 2291 for (int j=0; j<N; j++) { 2292 ProcessChangeItem item = mActiveProcessChanges[j]; 2293 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2294 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2295 + item.pid + " uid=" + item.uid + ": " 2296 + item.foregroundActivities); 2297 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2298 item.foregroundActivities); 2299 } 2300 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2301 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2302 + item.pid + " uid=" + item.uid + ": " + item.importance); 2303 observer.onImportanceChanged(item.pid, item.uid, 2304 item.importance); 2305 } 2306 } 2307 } catch (RemoteException e) { 2308 } 2309 } 2310 } 2311 mProcessObservers.finishBroadcast(); 2312 } 2313 2314 private void dispatchProcessDied(int pid, int uid) { 2315 int i = mProcessObservers.beginBroadcast(); 2316 while (i > 0) { 2317 i--; 2318 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2319 if (observer != null) { 2320 try { 2321 observer.onProcessDied(pid, uid); 2322 } catch (RemoteException e) { 2323 } 2324 } 2325 } 2326 mProcessObservers.finishBroadcast(); 2327 } 2328 2329 final void doPendingActivityLaunchesLocked(boolean doResume) { 2330 final int N = mPendingActivityLaunches.size(); 2331 if (N <= 0) { 2332 return; 2333 } 2334 for (int i=0; i<N; i++) { 2335 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2336 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2337 pal.startFlags, doResume && i == (N-1), null); 2338 } 2339 mPendingActivityLaunches.clear(); 2340 } 2341 2342 public final int startActivity(IApplicationThread caller, 2343 Intent intent, String resolvedType, IBinder resultTo, 2344 String resultWho, int requestCode, int startFlags, 2345 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2346 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2347 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2348 } 2349 2350 public final int startActivityAsUser(IApplicationThread caller, 2351 Intent intent, String resolvedType, IBinder resultTo, 2352 String resultWho, int requestCode, int startFlags, 2353 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2354 enforceNotIsolatedCaller("startActivity"); 2355 if (userId != UserHandle.getCallingUserId()) { 2356 // Requesting a different user, make sure that they have the permission 2357 if (checkComponentPermission( 2358 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2359 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2360 == PackageManager.PERMISSION_GRANTED) { 2361 // Translate to the current user id, if caller wasn't aware 2362 if (userId == UserHandle.USER_CURRENT) { 2363 userId = mCurrentUserId; 2364 } 2365 } else { 2366 String msg = "Permission Denial: " 2367 + "Request to startActivity as user " + userId 2368 + " but is calling from user " + UserHandle.getCallingUserId() 2369 + "; this requires " 2370 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2371 Slog.w(TAG, msg); 2372 throw new SecurityException(msg); 2373 } 2374 } else { 2375 if (intent.getCategories() != null 2376 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2377 // Requesting home, set the identity to the current user 2378 // HACK! 2379 userId = mCurrentUserId; 2380 } else { 2381 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2382 // the current user's userId 2383 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2384 userId = 0; 2385 } else { 2386 userId = Binder.getOrigCallingUser(); 2387 } 2388 } 2389 } 2390 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2391 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2392 null, null, options, userId); 2393 } 2394 2395 public final WaitResult startActivityAndWait(IApplicationThread caller, 2396 Intent intent, String resolvedType, IBinder resultTo, 2397 String resultWho, int requestCode, int startFlags, String profileFile, 2398 ParcelFileDescriptor profileFd, Bundle options) { 2399 enforceNotIsolatedCaller("startActivityAndWait"); 2400 WaitResult res = new WaitResult(); 2401 int userId = Binder.getOrigCallingUser(); 2402 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2403 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2404 res, null, options, userId); 2405 return res; 2406 } 2407 2408 public final int startActivityWithConfig(IApplicationThread caller, 2409 Intent intent, String resolvedType, IBinder resultTo, 2410 String resultWho, int requestCode, int startFlags, Configuration config, 2411 Bundle options) { 2412 enforceNotIsolatedCaller("startActivityWithConfig"); 2413 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2414 resultTo, resultWho, requestCode, startFlags, 2415 null, null, null, config, options, Binder.getOrigCallingUser()); 2416 return ret; 2417 } 2418 2419 public int startActivityIntentSender(IApplicationThread caller, 2420 IntentSender intent, Intent fillInIntent, String resolvedType, 2421 IBinder resultTo, String resultWho, int requestCode, 2422 int flagsMask, int flagsValues, Bundle options) { 2423 enforceNotIsolatedCaller("startActivityIntentSender"); 2424 // Refuse possible leaked file descriptors 2425 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2426 throw new IllegalArgumentException("File descriptors passed in Intent"); 2427 } 2428 2429 IIntentSender sender = intent.getTarget(); 2430 if (!(sender instanceof PendingIntentRecord)) { 2431 throw new IllegalArgumentException("Bad PendingIntent object"); 2432 } 2433 2434 PendingIntentRecord pir = (PendingIntentRecord)sender; 2435 2436 synchronized (this) { 2437 // If this is coming from the currently resumed activity, it is 2438 // effectively saying that app switches are allowed at this point. 2439 if (mMainStack.mResumedActivity != null 2440 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2441 Binder.getCallingUid()) { 2442 mAppSwitchesAllowedTime = 0; 2443 } 2444 } 2445 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2446 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2447 return ret; 2448 } 2449 2450 public boolean startNextMatchingActivity(IBinder callingActivity, 2451 Intent intent, Bundle options) { 2452 // Refuse possible leaked file descriptors 2453 if (intent != null && intent.hasFileDescriptors() == true) { 2454 throw new IllegalArgumentException("File descriptors passed in Intent"); 2455 } 2456 2457 synchronized (this) { 2458 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2459 if (r == null) { 2460 ActivityOptions.abort(options); 2461 return false; 2462 } 2463 if (r.app == null || r.app.thread == null) { 2464 // The caller is not running... d'oh! 2465 ActivityOptions.abort(options); 2466 return false; 2467 } 2468 intent = new Intent(intent); 2469 // The caller is not allowed to change the data. 2470 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2471 // And we are resetting to find the next component... 2472 intent.setComponent(null); 2473 2474 ActivityInfo aInfo = null; 2475 try { 2476 List<ResolveInfo> resolves = 2477 AppGlobals.getPackageManager().queryIntentActivities( 2478 intent, r.resolvedType, 2479 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2480 UserHandle.getCallingUserId()); 2481 2482 // Look for the original activity in the list... 2483 final int N = resolves != null ? resolves.size() : 0; 2484 for (int i=0; i<N; i++) { 2485 ResolveInfo rInfo = resolves.get(i); 2486 if (rInfo.activityInfo.packageName.equals(r.packageName) 2487 && rInfo.activityInfo.name.equals(r.info.name)) { 2488 // We found the current one... the next matching is 2489 // after it. 2490 i++; 2491 if (i<N) { 2492 aInfo = resolves.get(i).activityInfo; 2493 } 2494 break; 2495 } 2496 } 2497 } catch (RemoteException e) { 2498 } 2499 2500 if (aInfo == null) { 2501 // Nobody who is next! 2502 ActivityOptions.abort(options); 2503 return false; 2504 } 2505 2506 intent.setComponent(new ComponentName( 2507 aInfo.applicationInfo.packageName, aInfo.name)); 2508 intent.setFlags(intent.getFlags()&~( 2509 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2510 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2511 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2512 Intent.FLAG_ACTIVITY_NEW_TASK)); 2513 2514 // Okay now we need to start the new activity, replacing the 2515 // currently running activity. This is a little tricky because 2516 // we want to start the new one as if the current one is finished, 2517 // but not finish the current one first so that there is no flicker. 2518 // And thus... 2519 final boolean wasFinishing = r.finishing; 2520 r.finishing = true; 2521 2522 // Propagate reply information over to the new activity. 2523 final ActivityRecord resultTo = r.resultTo; 2524 final String resultWho = r.resultWho; 2525 final int requestCode = r.requestCode; 2526 r.resultTo = null; 2527 if (resultTo != null) { 2528 resultTo.removeResultsLocked(r, resultWho, requestCode); 2529 } 2530 2531 final long origId = Binder.clearCallingIdentity(); 2532 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2533 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2534 resultWho, requestCode, -1, r.launchedFromUid, 0, 2535 options, false, null); 2536 Binder.restoreCallingIdentity(origId); 2537 2538 r.finishing = wasFinishing; 2539 if (res != ActivityManager.START_SUCCESS) { 2540 return false; 2541 } 2542 return true; 2543 } 2544 } 2545 2546 public final int startActivityInPackage(int uid, 2547 Intent intent, String resolvedType, IBinder resultTo, 2548 String resultWho, int requestCode, int startFlags, Bundle options) { 2549 2550 // This is so super not safe, that only the system (or okay root) 2551 // can do it. 2552 final int callingUid = Binder.getCallingUid(); 2553 if (callingUid != 0 && callingUid != Process.myUid()) { 2554 throw new SecurityException( 2555 "startActivityInPackage only available to the system"); 2556 } 2557 2558 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2559 resultTo, resultWho, requestCode, startFlags, 2560 null, null, null, null, options, UserHandle.getUserId(uid)); 2561 return ret; 2562 } 2563 2564 public final int startActivities(IApplicationThread caller, 2565 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2566 enforceNotIsolatedCaller("startActivities"); 2567 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2568 options, Binder.getOrigCallingUser()); 2569 return ret; 2570 } 2571 2572 public final int startActivitiesInPackage(int uid, 2573 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2574 Bundle options) { 2575 2576 // This is so super not safe, that only the system (or okay root) 2577 // can do it. 2578 final int callingUid = Binder.getCallingUid(); 2579 if (callingUid != 0 && callingUid != Process.myUid()) { 2580 throw new SecurityException( 2581 "startActivityInPackage only available to the system"); 2582 } 2583 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2584 options, UserHandle.getUserId(uid)); 2585 return ret; 2586 } 2587 2588 final void addRecentTaskLocked(TaskRecord task) { 2589 int N = mRecentTasks.size(); 2590 // Quick case: check if the top-most recent task is the same. 2591 if (N > 0 && mRecentTasks.get(0) == task) { 2592 return; 2593 } 2594 // Remove any existing entries that are the same kind of task. 2595 for (int i=0; i<N; i++) { 2596 TaskRecord tr = mRecentTasks.get(i); 2597 if (task.userId == tr.userId 2598 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2599 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2600 mRecentTasks.remove(i); 2601 i--; 2602 N--; 2603 if (task.intent == null) { 2604 // If the new recent task we are adding is not fully 2605 // specified, then replace it with the existing recent task. 2606 task = tr; 2607 } 2608 } 2609 } 2610 if (N >= MAX_RECENT_TASKS) { 2611 mRecentTasks.remove(N-1); 2612 } 2613 mRecentTasks.add(0, task); 2614 } 2615 2616 public void setRequestedOrientation(IBinder token, 2617 int requestedOrientation) { 2618 synchronized (this) { 2619 ActivityRecord r = mMainStack.isInStackLocked(token); 2620 if (r == null) { 2621 return; 2622 } 2623 final long origId = Binder.clearCallingIdentity(); 2624 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2625 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2626 mConfiguration, 2627 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2628 if (config != null) { 2629 r.frozenBeforeDestroy = true; 2630 if (!updateConfigurationLocked(config, r, false, false)) { 2631 mMainStack.resumeTopActivityLocked(null); 2632 } 2633 } 2634 Binder.restoreCallingIdentity(origId); 2635 } 2636 } 2637 2638 public int getRequestedOrientation(IBinder token) { 2639 synchronized (this) { 2640 ActivityRecord r = mMainStack.isInStackLocked(token); 2641 if (r == null) { 2642 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2643 } 2644 return mWindowManager.getAppOrientation(r.appToken); 2645 } 2646 } 2647 2648 /** 2649 * This is the internal entry point for handling Activity.finish(). 2650 * 2651 * @param token The Binder token referencing the Activity we want to finish. 2652 * @param resultCode Result code, if any, from this Activity. 2653 * @param resultData Result data (Intent), if any, from this Activity. 2654 * 2655 * @return Returns true if the activity successfully finished, or false if it is still running. 2656 */ 2657 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2658 // Refuse possible leaked file descriptors 2659 if (resultData != null && resultData.hasFileDescriptors() == true) { 2660 throw new IllegalArgumentException("File descriptors passed in Intent"); 2661 } 2662 2663 synchronized(this) { 2664 if (mController != null) { 2665 // Find the first activity that is not finishing. 2666 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2667 if (next != null) { 2668 // ask watcher if this is allowed 2669 boolean resumeOK = true; 2670 try { 2671 resumeOK = mController.activityResuming(next.packageName); 2672 } catch (RemoteException e) { 2673 mController = null; 2674 } 2675 2676 if (!resumeOK) { 2677 return false; 2678 } 2679 } 2680 } 2681 final long origId = Binder.clearCallingIdentity(); 2682 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2683 resultData, "app-request"); 2684 Binder.restoreCallingIdentity(origId); 2685 return res; 2686 } 2687 } 2688 2689 public final void finishHeavyWeightApp() { 2690 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2691 != PackageManager.PERMISSION_GRANTED) { 2692 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2693 + Binder.getCallingPid() 2694 + ", uid=" + Binder.getCallingUid() 2695 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2696 Slog.w(TAG, msg); 2697 throw new SecurityException(msg); 2698 } 2699 2700 synchronized(this) { 2701 if (mHeavyWeightProcess == null) { 2702 return; 2703 } 2704 2705 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2706 mHeavyWeightProcess.activities); 2707 for (int i=0; i<activities.size(); i++) { 2708 ActivityRecord r = activities.get(i); 2709 if (!r.finishing) { 2710 int index = mMainStack.indexOfTokenLocked(r.appToken); 2711 if (index >= 0) { 2712 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2713 null, "finish-heavy"); 2714 } 2715 } 2716 } 2717 2718 mHeavyWeightProcess = null; 2719 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2720 } 2721 } 2722 2723 public void crashApplication(int uid, int initialPid, String packageName, 2724 String message) { 2725 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2726 != PackageManager.PERMISSION_GRANTED) { 2727 String msg = "Permission Denial: crashApplication() from pid=" 2728 + Binder.getCallingPid() 2729 + ", uid=" + Binder.getCallingUid() 2730 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2731 Slog.w(TAG, msg); 2732 throw new SecurityException(msg); 2733 } 2734 2735 synchronized(this) { 2736 ProcessRecord proc = null; 2737 2738 // Figure out which process to kill. We don't trust that initialPid 2739 // still has any relation to current pids, so must scan through the 2740 // list. 2741 synchronized (mPidsSelfLocked) { 2742 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2743 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2744 if (p.uid != uid) { 2745 continue; 2746 } 2747 if (p.pid == initialPid) { 2748 proc = p; 2749 break; 2750 } 2751 for (String str : p.pkgList) { 2752 if (str.equals(packageName)) { 2753 proc = p; 2754 } 2755 } 2756 } 2757 } 2758 2759 if (proc == null) { 2760 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2761 + " initialPid=" + initialPid 2762 + " packageName=" + packageName); 2763 return; 2764 } 2765 2766 if (proc.thread != null) { 2767 if (proc.pid == Process.myPid()) { 2768 Log.w(TAG, "crashApplication: trying to crash self!"); 2769 return; 2770 } 2771 long ident = Binder.clearCallingIdentity(); 2772 try { 2773 proc.thread.scheduleCrash(message); 2774 } catch (RemoteException e) { 2775 } 2776 Binder.restoreCallingIdentity(ident); 2777 } 2778 } 2779 } 2780 2781 public final void finishSubActivity(IBinder token, String resultWho, 2782 int requestCode) { 2783 synchronized(this) { 2784 final long origId = Binder.clearCallingIdentity(); 2785 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2786 Binder.restoreCallingIdentity(origId); 2787 } 2788 } 2789 2790 public boolean finishActivityAffinity(IBinder token) { 2791 synchronized(this) { 2792 final long origId = Binder.clearCallingIdentity(); 2793 boolean res = mMainStack.finishActivityAffinityLocked(token); 2794 Binder.restoreCallingIdentity(origId); 2795 return res; 2796 } 2797 } 2798 2799 public boolean willActivityBeVisible(IBinder token) { 2800 synchronized(this) { 2801 int i; 2802 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2803 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2804 if (r.appToken == token) { 2805 return true; 2806 } 2807 if (r.fullscreen && !r.finishing) { 2808 return false; 2809 } 2810 } 2811 return true; 2812 } 2813 } 2814 2815 public void overridePendingTransition(IBinder token, String packageName, 2816 int enterAnim, int exitAnim) { 2817 synchronized(this) { 2818 ActivityRecord self = mMainStack.isInStackLocked(token); 2819 if (self == null) { 2820 return; 2821 } 2822 2823 final long origId = Binder.clearCallingIdentity(); 2824 2825 if (self.state == ActivityState.RESUMED 2826 || self.state == ActivityState.PAUSING) { 2827 mWindowManager.overridePendingAppTransition(packageName, 2828 enterAnim, exitAnim, null); 2829 } 2830 2831 Binder.restoreCallingIdentity(origId); 2832 } 2833 } 2834 2835 /** 2836 * Main function for removing an existing process from the activity manager 2837 * as a result of that process going away. Clears out all connections 2838 * to the process. 2839 */ 2840 private final void handleAppDiedLocked(ProcessRecord app, 2841 boolean restarting, boolean allowRestart) { 2842 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2843 if (!restarting) { 2844 mLruProcesses.remove(app); 2845 } 2846 2847 if (mProfileProc == app) { 2848 clearProfilerLocked(); 2849 } 2850 2851 // Just in case... 2852 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2853 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2854 mMainStack.mPausingActivity = null; 2855 } 2856 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2857 mMainStack.mLastPausedActivity = null; 2858 } 2859 2860 // Remove this application's activities from active lists. 2861 mMainStack.removeHistoryRecordsForAppLocked(app); 2862 2863 boolean atTop = true; 2864 boolean hasVisibleActivities = false; 2865 2866 // Clean out the history list. 2867 int i = mMainStack.mHistory.size(); 2868 if (localLOGV) Slog.v( 2869 TAG, "Removing app " + app + " from history with " + i + " entries"); 2870 while (i > 0) { 2871 i--; 2872 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2873 if (localLOGV) Slog.v( 2874 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2875 if (r.app == app) { 2876 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2877 if (ActivityStack.DEBUG_ADD_REMOVE) { 2878 RuntimeException here = new RuntimeException("here"); 2879 here.fillInStackTrace(); 2880 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2881 + ": haveState=" + r.haveState 2882 + " stateNotNeeded=" + r.stateNotNeeded 2883 + " finishing=" + r.finishing 2884 + " state=" + r.state, here); 2885 } 2886 if (!r.finishing) { 2887 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2888 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2889 System.identityHashCode(r), 2890 r.task.taskId, r.shortComponentName, 2891 "proc died without state saved"); 2892 } 2893 mMainStack.removeActivityFromHistoryLocked(r); 2894 2895 } else { 2896 // We have the current state for this activity, so 2897 // it can be restarted later when needed. 2898 if (localLOGV) Slog.v( 2899 TAG, "Keeping entry, setting app to null"); 2900 if (r.visible) { 2901 hasVisibleActivities = true; 2902 } 2903 r.app = null; 2904 r.nowVisible = false; 2905 if (!r.haveState) { 2906 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2907 "App died, clearing saved state of " + r); 2908 r.icicle = null; 2909 } 2910 } 2911 2912 r.stack.cleanUpActivityLocked(r, true, true); 2913 } 2914 atTop = false; 2915 } 2916 2917 app.activities.clear(); 2918 2919 if (app.instrumentationClass != null) { 2920 Slog.w(TAG, "Crash of app " + app.processName 2921 + " running instrumentation " + app.instrumentationClass); 2922 Bundle info = new Bundle(); 2923 info.putString("shortMsg", "Process crashed."); 2924 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2925 } 2926 2927 if (!restarting) { 2928 if (!mMainStack.resumeTopActivityLocked(null)) { 2929 // If there was nothing to resume, and we are not already 2930 // restarting this process, but there is a visible activity that 2931 // is hosted by the process... then make sure all visible 2932 // activities are running, taking care of restarting this 2933 // process. 2934 if (hasVisibleActivities) { 2935 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2936 } 2937 } 2938 } 2939 } 2940 2941 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2942 IBinder threadBinder = thread.asBinder(); 2943 // Find the application record. 2944 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2945 ProcessRecord rec = mLruProcesses.get(i); 2946 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2947 return i; 2948 } 2949 } 2950 return -1; 2951 } 2952 2953 final ProcessRecord getRecordForAppLocked( 2954 IApplicationThread thread) { 2955 if (thread == null) { 2956 return null; 2957 } 2958 2959 int appIndex = getLRURecordIndexForAppLocked(thread); 2960 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2961 } 2962 2963 final void appDiedLocked(ProcessRecord app, int pid, 2964 IApplicationThread thread) { 2965 2966 mProcDeaths[0]++; 2967 2968 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2969 synchronized (stats) { 2970 stats.noteProcessDiedLocked(app.info.uid, pid); 2971 } 2972 2973 // Clean up already done if the process has been re-started. 2974 if (app.pid == pid && app.thread != null && 2975 app.thread.asBinder() == thread.asBinder()) { 2976 if (!app.killedBackground) { 2977 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2978 + ") has died."); 2979 } 2980 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2981 if (localLOGV) Slog.v( 2982 TAG, "Dying app: " + app + ", pid: " + pid 2983 + ", thread: " + thread.asBinder()); 2984 boolean doLowMem = app.instrumentationClass == null; 2985 handleAppDiedLocked(app, false, true); 2986 2987 if (doLowMem) { 2988 // If there are no longer any background processes running, 2989 // and the app that died was not running instrumentation, 2990 // then tell everyone we are now low on memory. 2991 boolean haveBg = false; 2992 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2993 ProcessRecord rec = mLruProcesses.get(i); 2994 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2995 haveBg = true; 2996 break; 2997 } 2998 } 2999 3000 if (!haveBg) { 3001 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3002 long now = SystemClock.uptimeMillis(); 3003 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3004 ProcessRecord rec = mLruProcesses.get(i); 3005 if (rec != app && rec.thread != null && 3006 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3007 // The low memory report is overriding any current 3008 // state for a GC request. Make sure to do 3009 // heavy/important/visible/foreground processes first. 3010 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3011 rec.lastRequestedGc = 0; 3012 } else { 3013 rec.lastRequestedGc = rec.lastLowMemory; 3014 } 3015 rec.reportLowMemory = true; 3016 rec.lastLowMemory = now; 3017 mProcessesToGc.remove(rec); 3018 addProcessToGcListLocked(rec); 3019 } 3020 } 3021 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3022 scheduleAppGcsLocked(); 3023 } 3024 } 3025 } else if (app.pid != pid) { 3026 // A new process has already been started. 3027 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3028 + ") has died and restarted (pid " + app.pid + ")."); 3029 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3030 } else if (DEBUG_PROCESSES) { 3031 Slog.d(TAG, "Received spurious death notification for thread " 3032 + thread.asBinder()); 3033 } 3034 } 3035 3036 /** 3037 * If a stack trace dump file is configured, dump process stack traces. 3038 * @param clearTraces causes the dump file to be erased prior to the new 3039 * traces being written, if true; when false, the new traces will be 3040 * appended to any existing file content. 3041 * @param firstPids of dalvik VM processes to dump stack traces for first 3042 * @param lastPids of dalvik VM processes to dump stack traces for last 3043 * @param nativeProcs optional list of native process names to dump stack crawls 3044 * @return file containing stack traces, or null if no dump file is configured 3045 */ 3046 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3047 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3048 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3049 if (tracesPath == null || tracesPath.length() == 0) { 3050 return null; 3051 } 3052 3053 File tracesFile = new File(tracesPath); 3054 try { 3055 File tracesDir = tracesFile.getParentFile(); 3056 if (!tracesDir.exists()) { 3057 tracesFile.mkdirs(); 3058 if (!SELinux.restorecon(tracesDir)) { 3059 return null; 3060 } 3061 } 3062 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3063 3064 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3065 tracesFile.createNewFile(); 3066 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3067 } catch (IOException e) { 3068 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3069 return null; 3070 } 3071 3072 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3073 return tracesFile; 3074 } 3075 3076 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3077 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3078 // Use a FileObserver to detect when traces finish writing. 3079 // The order of traces is considered important to maintain for legibility. 3080 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3081 public synchronized void onEvent(int event, String path) { notify(); } 3082 }; 3083 3084 try { 3085 observer.startWatching(); 3086 3087 // First collect all of the stacks of the most important pids. 3088 if (firstPids != null) { 3089 try { 3090 int num = firstPids.size(); 3091 for (int i = 0; i < num; i++) { 3092 synchronized (observer) { 3093 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3094 observer.wait(200); // Wait for write-close, give up after 200msec 3095 } 3096 } 3097 } catch (InterruptedException e) { 3098 Log.wtf(TAG, e); 3099 } 3100 } 3101 3102 // Next measure CPU usage. 3103 if (processStats != null) { 3104 processStats.init(); 3105 System.gc(); 3106 processStats.update(); 3107 try { 3108 synchronized (processStats) { 3109 processStats.wait(500); // measure over 1/2 second. 3110 } 3111 } catch (InterruptedException e) { 3112 } 3113 processStats.update(); 3114 3115 // We'll take the stack crawls of just the top apps using CPU. 3116 final int N = processStats.countWorkingStats(); 3117 int numProcs = 0; 3118 for (int i=0; i<N && numProcs<5; i++) { 3119 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3120 if (lastPids.indexOfKey(stats.pid) >= 0) { 3121 numProcs++; 3122 try { 3123 synchronized (observer) { 3124 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3125 observer.wait(200); // Wait for write-close, give up after 200msec 3126 } 3127 } catch (InterruptedException e) { 3128 Log.wtf(TAG, e); 3129 } 3130 3131 } 3132 } 3133 } 3134 3135 } finally { 3136 observer.stopWatching(); 3137 } 3138 3139 if (nativeProcs != null) { 3140 int[] pids = Process.getPidsForCommands(nativeProcs); 3141 if (pids != null) { 3142 for (int pid : pids) { 3143 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3144 } 3145 } 3146 } 3147 } 3148 3149 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3150 if (true || IS_USER_BUILD) { 3151 return; 3152 } 3153 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3154 if (tracesPath == null || tracesPath.length() == 0) { 3155 return; 3156 } 3157 3158 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3159 StrictMode.allowThreadDiskWrites(); 3160 try { 3161 final File tracesFile = new File(tracesPath); 3162 final File tracesDir = tracesFile.getParentFile(); 3163 final File tracesTmp = new File(tracesDir, "__tmp__"); 3164 try { 3165 if (!tracesDir.exists()) { 3166 tracesFile.mkdirs(); 3167 if (!SELinux.restorecon(tracesDir.getPath())) { 3168 return; 3169 } 3170 } 3171 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3172 3173 if (tracesFile.exists()) { 3174 tracesTmp.delete(); 3175 tracesFile.renameTo(tracesTmp); 3176 } 3177 StringBuilder sb = new StringBuilder(); 3178 Time tobj = new Time(); 3179 tobj.set(System.currentTimeMillis()); 3180 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3181 sb.append(": "); 3182 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3183 sb.append(" since "); 3184 sb.append(msg); 3185 FileOutputStream fos = new FileOutputStream(tracesFile); 3186 fos.write(sb.toString().getBytes()); 3187 if (app == null) { 3188 fos.write("\n*** No application process!".getBytes()); 3189 } 3190 fos.close(); 3191 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3192 } catch (IOException e) { 3193 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3194 return; 3195 } 3196 3197 if (app != null) { 3198 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3199 firstPids.add(app.pid); 3200 dumpStackTraces(tracesPath, firstPids, null, null, null); 3201 } 3202 3203 File lastTracesFile = null; 3204 File curTracesFile = null; 3205 for (int i=9; i>=0; i--) { 3206 String name = String.format("slow%02d.txt", i); 3207 curTracesFile = new File(tracesDir, name); 3208 if (curTracesFile.exists()) { 3209 if (lastTracesFile != null) { 3210 curTracesFile.renameTo(lastTracesFile); 3211 } else { 3212 curTracesFile.delete(); 3213 } 3214 } 3215 lastTracesFile = curTracesFile; 3216 } 3217 tracesFile.renameTo(curTracesFile); 3218 if (tracesTmp.exists()) { 3219 tracesTmp.renameTo(tracesFile); 3220 } 3221 } finally { 3222 StrictMode.setThreadPolicy(oldPolicy); 3223 } 3224 } 3225 3226 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3227 ActivityRecord parent, final String annotation) { 3228 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3229 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3230 3231 if (mController != null) { 3232 try { 3233 // 0 == continue, -1 = kill process immediately 3234 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3235 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3236 } catch (RemoteException e) { 3237 mController = null; 3238 } 3239 } 3240 3241 long anrTime = SystemClock.uptimeMillis(); 3242 if (MONITOR_CPU_USAGE) { 3243 updateCpuStatsNow(); 3244 } 3245 3246 synchronized (this) { 3247 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3248 if (mShuttingDown) { 3249 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3250 return; 3251 } else if (app.notResponding) { 3252 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3253 return; 3254 } else if (app.crashing) { 3255 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3256 return; 3257 } 3258 3259 // In case we come through here for the same app before completing 3260 // this one, mark as anring now so we will bail out. 3261 app.notResponding = true; 3262 3263 // Log the ANR to the event log. 3264 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3265 annotation); 3266 3267 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3268 firstPids.add(app.pid); 3269 3270 int parentPid = app.pid; 3271 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3272 if (parentPid != app.pid) firstPids.add(parentPid); 3273 3274 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3275 3276 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3277 ProcessRecord r = mLruProcesses.get(i); 3278 if (r != null && r.thread != null) { 3279 int pid = r.pid; 3280 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3281 if (r.persistent) { 3282 firstPids.add(pid); 3283 } else { 3284 lastPids.put(pid, Boolean.TRUE); 3285 } 3286 } 3287 } 3288 } 3289 } 3290 3291 // Log the ANR to the main log. 3292 StringBuilder info = new StringBuilder(); 3293 info.setLength(0); 3294 info.append("ANR in ").append(app.processName); 3295 if (activity != null && activity.shortComponentName != null) { 3296 info.append(" (").append(activity.shortComponentName).append(")"); 3297 } 3298 info.append("\n"); 3299 if (annotation != null) { 3300 info.append("Reason: ").append(annotation).append("\n"); 3301 } 3302 if (parent != null && parent != activity) { 3303 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3304 } 3305 3306 final ProcessStats processStats = new ProcessStats(true); 3307 3308 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3309 3310 String cpuInfo = null; 3311 if (MONITOR_CPU_USAGE) { 3312 updateCpuStatsNow(); 3313 synchronized (mProcessStatsThread) { 3314 cpuInfo = mProcessStats.printCurrentState(anrTime); 3315 } 3316 info.append(processStats.printCurrentLoad()); 3317 info.append(cpuInfo); 3318 } 3319 3320 info.append(processStats.printCurrentState(anrTime)); 3321 3322 Slog.e(TAG, info.toString()); 3323 if (tracesFile == null) { 3324 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3325 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3326 } 3327 3328 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3329 cpuInfo, tracesFile, null); 3330 3331 if (mController != null) { 3332 try { 3333 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3334 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3335 if (res != 0) { 3336 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3337 return; 3338 } 3339 } catch (RemoteException e) { 3340 mController = null; 3341 } 3342 } 3343 3344 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3345 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3346 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3347 3348 synchronized (this) { 3349 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3350 Slog.w(TAG, "Killing " + app + ": background ANR"); 3351 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3352 app.processName, app.setAdj, "background ANR"); 3353 Process.killProcessQuiet(app.pid); 3354 return; 3355 } 3356 3357 // Set the app's notResponding state, and look up the errorReportReceiver 3358 makeAppNotRespondingLocked(app, 3359 activity != null ? activity.shortComponentName : null, 3360 annotation != null ? "ANR " + annotation : "ANR", 3361 info.toString()); 3362 3363 // Bring up the infamous App Not Responding dialog 3364 Message msg = Message.obtain(); 3365 HashMap map = new HashMap(); 3366 msg.what = SHOW_NOT_RESPONDING_MSG; 3367 msg.obj = map; 3368 map.put("app", app); 3369 if (activity != null) { 3370 map.put("activity", activity); 3371 } 3372 3373 mHandler.sendMessage(msg); 3374 } 3375 } 3376 3377 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3378 if (!mLaunchWarningShown) { 3379 mLaunchWarningShown = true; 3380 mHandler.post(new Runnable() { 3381 @Override 3382 public void run() { 3383 synchronized (ActivityManagerService.this) { 3384 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3385 d.show(); 3386 mHandler.postDelayed(new Runnable() { 3387 @Override 3388 public void run() { 3389 synchronized (ActivityManagerService.this) { 3390 d.dismiss(); 3391 mLaunchWarningShown = false; 3392 } 3393 } 3394 }, 4000); 3395 } 3396 } 3397 }); 3398 } 3399 } 3400 3401 public boolean clearApplicationUserData(final String packageName, 3402 final IPackageDataObserver observer, final int userId) { 3403 enforceNotIsolatedCaller("clearApplicationUserData"); 3404 int uid = Binder.getCallingUid(); 3405 int pid = Binder.getCallingPid(); 3406 long callingId = Binder.clearCallingIdentity(); 3407 try { 3408 IPackageManager pm = AppGlobals.getPackageManager(); 3409 int pkgUid = -1; 3410 synchronized(this) { 3411 try { 3412 pkgUid = pm.getPackageUid(packageName, userId); 3413 } catch (RemoteException e) { 3414 } 3415 if (pkgUid == -1) { 3416 Slog.w(TAG, "Invalid packageName:" + packageName); 3417 return false; 3418 } 3419 if (uid == pkgUid || checkComponentPermission( 3420 android.Manifest.permission.CLEAR_APP_USER_DATA, 3421 pid, uid, -1, true) 3422 == PackageManager.PERMISSION_GRANTED) { 3423 forceStopPackageLocked(packageName, pkgUid); 3424 } else { 3425 throw new SecurityException(pid+" does not have permission:"+ 3426 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3427 "for process:"+packageName); 3428 } 3429 } 3430 3431 try { 3432 //clear application user data 3433 pm.clearApplicationUserData(packageName, observer, userId); 3434 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3435 Uri.fromParts("package", packageName, null)); 3436 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3437 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3438 null, null, 0, null, null, null, false, false, userId); 3439 } catch (RemoteException e) { 3440 } 3441 } finally { 3442 Binder.restoreCallingIdentity(callingId); 3443 } 3444 return true; 3445 } 3446 3447 public void killBackgroundProcesses(final String packageName) { 3448 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3449 != PackageManager.PERMISSION_GRANTED && 3450 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3451 != PackageManager.PERMISSION_GRANTED) { 3452 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3453 + Binder.getCallingPid() 3454 + ", uid=" + Binder.getCallingUid() 3455 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3456 Slog.w(TAG, msg); 3457 throw new SecurityException(msg); 3458 } 3459 3460 int userId = UserHandle.getCallingUserId(); 3461 long callingId = Binder.clearCallingIdentity(); 3462 try { 3463 IPackageManager pm = AppGlobals.getPackageManager(); 3464 int pkgUid = -1; 3465 synchronized(this) { 3466 try { 3467 pkgUid = pm.getPackageUid(packageName, userId); 3468 } catch (RemoteException e) { 3469 } 3470 if (pkgUid == -1) { 3471 Slog.w(TAG, "Invalid packageName: " + packageName); 3472 return; 3473 } 3474 killPackageProcessesLocked(packageName, pkgUid, -1, 3475 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3476 } 3477 } finally { 3478 Binder.restoreCallingIdentity(callingId); 3479 } 3480 } 3481 3482 public void killAllBackgroundProcesses() { 3483 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3484 != PackageManager.PERMISSION_GRANTED) { 3485 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3486 + Binder.getCallingPid() 3487 + ", uid=" + Binder.getCallingUid() 3488 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3489 Slog.w(TAG, msg); 3490 throw new SecurityException(msg); 3491 } 3492 3493 long callingId = Binder.clearCallingIdentity(); 3494 try { 3495 synchronized(this) { 3496 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3497 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3498 final int NA = apps.size(); 3499 for (int ia=0; ia<NA; ia++) { 3500 ProcessRecord app = apps.valueAt(ia); 3501 if (app.persistent) { 3502 // we don't kill persistent processes 3503 continue; 3504 } 3505 if (app.removed) { 3506 procs.add(app); 3507 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3508 app.removed = true; 3509 procs.add(app); 3510 } 3511 } 3512 } 3513 3514 int N = procs.size(); 3515 for (int i=0; i<N; i++) { 3516 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3517 } 3518 } 3519 } finally { 3520 Binder.restoreCallingIdentity(callingId); 3521 } 3522 } 3523 3524 public void forceStopPackage(final String packageName) { 3525 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3526 != PackageManager.PERMISSION_GRANTED) { 3527 String msg = "Permission Denial: forceStopPackage() from pid=" 3528 + Binder.getCallingPid() 3529 + ", uid=" + Binder.getCallingUid() 3530 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3531 Slog.w(TAG, msg); 3532 throw new SecurityException(msg); 3533 } 3534 final int userId = UserHandle.getCallingUserId(); 3535 long callingId = Binder.clearCallingIdentity(); 3536 try { 3537 IPackageManager pm = AppGlobals.getPackageManager(); 3538 int pkgUid = -1; 3539 synchronized(this) { 3540 try { 3541 pkgUid = pm.getPackageUid(packageName, userId); 3542 } catch (RemoteException e) { 3543 } 3544 if (pkgUid == -1) { 3545 Slog.w(TAG, "Invalid packageName: " + packageName); 3546 return; 3547 } 3548 forceStopPackageLocked(packageName, pkgUid); 3549 try { 3550 pm.setPackageStoppedState(packageName, true, userId); 3551 } catch (RemoteException e) { 3552 } catch (IllegalArgumentException e) { 3553 Slog.w(TAG, "Failed trying to unstop package " 3554 + packageName + ": " + e); 3555 } 3556 } 3557 } finally { 3558 Binder.restoreCallingIdentity(callingId); 3559 } 3560 } 3561 3562 /* 3563 * The pkg name and uid have to be specified. 3564 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3565 */ 3566 public void killApplicationWithUid(String pkg, int uid) { 3567 if (pkg == null) { 3568 return; 3569 } 3570 // Make sure the uid is valid. 3571 if (uid < 0) { 3572 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3573 return; 3574 } 3575 int callerUid = Binder.getCallingUid(); 3576 // Only the system server can kill an application 3577 if (callerUid == Process.SYSTEM_UID) { 3578 // Post an aysnc message to kill the application 3579 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3580 msg.arg1 = uid; 3581 msg.arg2 = 0; 3582 msg.obj = pkg; 3583 mHandler.sendMessage(msg); 3584 } else { 3585 throw new SecurityException(callerUid + " cannot kill pkg: " + 3586 pkg); 3587 } 3588 } 3589 3590 public void closeSystemDialogs(String reason) { 3591 enforceNotIsolatedCaller("closeSystemDialogs"); 3592 3593 final int uid = Binder.getCallingUid(); 3594 final long origId = Binder.clearCallingIdentity(); 3595 synchronized (this) { 3596 closeSystemDialogsLocked(uid, reason); 3597 } 3598 Binder.restoreCallingIdentity(origId); 3599 } 3600 3601 void closeSystemDialogsLocked(int callingUid, String reason) { 3602 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3603 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3604 if (reason != null) { 3605 intent.putExtra("reason", reason); 3606 } 3607 mWindowManager.closeSystemDialogs(reason); 3608 3609 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3610 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3611 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3612 r.stack.finishActivityLocked(r, i, 3613 Activity.RESULT_CANCELED, null, "close-sys"); 3614 } 3615 } 3616 3617 broadcastIntentLocked(null, null, intent, null, 3618 null, 0, null, null, null, false, false, -1, 3619 callingUid, 0 /* TODO: Verify */); 3620 } 3621 3622 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3623 throws RemoteException { 3624 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3625 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3626 for (int i=pids.length-1; i>=0; i--) { 3627 infos[i] = new Debug.MemoryInfo(); 3628 Debug.getMemoryInfo(pids[i], infos[i]); 3629 } 3630 return infos; 3631 } 3632 3633 public long[] getProcessPss(int[] pids) throws RemoteException { 3634 enforceNotIsolatedCaller("getProcessPss"); 3635 long[] pss = new long[pids.length]; 3636 for (int i=pids.length-1; i>=0; i--) { 3637 pss[i] = Debug.getPss(pids[i]); 3638 } 3639 return pss; 3640 } 3641 3642 public void killApplicationProcess(String processName, int uid) { 3643 if (processName == null) { 3644 return; 3645 } 3646 3647 int callerUid = Binder.getCallingUid(); 3648 // Only the system server can kill an application 3649 if (callerUid == Process.SYSTEM_UID) { 3650 synchronized (this) { 3651 ProcessRecord app = getProcessRecordLocked(processName, uid); 3652 if (app != null && app.thread != null) { 3653 try { 3654 app.thread.scheduleSuicide(); 3655 } catch (RemoteException e) { 3656 // If the other end already died, then our work here is done. 3657 } 3658 } else { 3659 Slog.w(TAG, "Process/uid not found attempting kill of " 3660 + processName + " / " + uid); 3661 } 3662 } 3663 } else { 3664 throw new SecurityException(callerUid + " cannot kill app process: " + 3665 processName); 3666 } 3667 } 3668 3669 private void forceStopPackageLocked(final String packageName, int uid) { 3670 forceStopPackageLocked(packageName, uid, false, false, true, false, 3671 UserHandle.getUserId(uid)); 3672 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3673 Uri.fromParts("package", packageName, null)); 3674 if (!mProcessesReady) { 3675 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3676 } 3677 intent.putExtra(Intent.EXTRA_UID, uid); 3678 broadcastIntentLocked(null, null, intent, 3679 null, null, 0, null, null, null, 3680 false, false, 3681 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3682 } 3683 3684 private void forceStopUserLocked(int userId) { 3685 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3686 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3687 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3688 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3689 broadcastIntentLocked(null, null, intent, 3690 null, null, 0, null, null, null, 3691 false, false, 3692 MY_PID, Process.SYSTEM_UID, userId); 3693 } 3694 3695 private final boolean killPackageProcessesLocked(String packageName, int uid, 3696 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3697 boolean doit, boolean evenPersistent, String reason) { 3698 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3699 3700 // Remove all processes this package may have touched: all with the 3701 // same UID (except for the system or root user), and all whose name 3702 // matches the package name. 3703 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3704 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3705 final int NA = apps.size(); 3706 for (int ia=0; ia<NA; ia++) { 3707 ProcessRecord app = apps.valueAt(ia); 3708 if (app.persistent && !evenPersistent) { 3709 // we don't kill persistent processes 3710 continue; 3711 } 3712 if (app.removed) { 3713 if (doit) { 3714 procs.add(app); 3715 } 3716 // If no package is specified, we call all processes under the 3717 // give user id. 3718 } else if (packageName == null) { 3719 if (app.userId == userId) { 3720 if (app.setAdj >= minOomAdj) { 3721 if (!doit) { 3722 return true; 3723 } 3724 app.removed = true; 3725 procs.add(app); 3726 } 3727 } 3728 // If uid is specified and the uid and process name match 3729 // Or, the uid is not specified and the process name matches 3730 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3731 || ((app.processName.equals(packageName) 3732 || app.processName.startsWith(procNamePrefix)) 3733 && uid < 0))) { 3734 if (app.setAdj >= minOomAdj) { 3735 if (!doit) { 3736 return true; 3737 } 3738 app.removed = true; 3739 procs.add(app); 3740 } 3741 } 3742 } 3743 } 3744 3745 int N = procs.size(); 3746 for (int i=0; i<N; i++) { 3747 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3748 } 3749 return N > 0; 3750 } 3751 3752 private final boolean forceStopPackageLocked(String name, int uid, 3753 boolean callerWillRestart, boolean purgeCache, boolean doit, 3754 boolean evenPersistent, int userId) { 3755 int i; 3756 int N; 3757 3758 if (uid < 0 && name != null) { 3759 try { 3760 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3761 } catch (RemoteException e) { 3762 } 3763 } 3764 3765 if (doit) { 3766 if (name != null) { 3767 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3768 } else { 3769 Slog.i(TAG, "Force stopping user " + userId); 3770 } 3771 3772 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3773 while (badApps.hasNext()) { 3774 SparseArray<Long> ba = badApps.next(); 3775 for (i=ba.size()-1; i>=0; i--) { 3776 boolean remove = false; 3777 final int entUid = ba.keyAt(i); 3778 if (name != null) { 3779 if (entUid == uid) { 3780 remove = true; 3781 } 3782 } else if (UserHandle.getUserId(entUid) == userId) { 3783 remove = true; 3784 } 3785 if (remove) { 3786 ba.removeAt(i); 3787 } 3788 } 3789 if (ba.size() == 0) { 3790 badApps.remove(); 3791 } 3792 } 3793 } 3794 3795 boolean didSomething = killPackageProcessesLocked(name, uid, 3796 name == null ? userId : -1 , -100, callerWillRestart, false, 3797 doit, evenPersistent, 3798 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3799 3800 TaskRecord lastTask = null; 3801 for (i=0; i<mMainStack.mHistory.size(); i++) { 3802 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3803 final boolean samePackage = r.packageName.equals(name) 3804 || (name == null && r.userId == userId); 3805 if (r.userId == userId 3806 && (samePackage || r.task == lastTask) 3807 && (r.app == null || evenPersistent || !r.app.persistent)) { 3808 if (!doit) { 3809 if (r.finishing) { 3810 // If this activity is just finishing, then it is not 3811 // interesting as far as something to stop. 3812 continue; 3813 } 3814 return true; 3815 } 3816 didSomething = true; 3817 Slog.i(TAG, " Force finishing activity " + r); 3818 if (samePackage) { 3819 if (r.app != null) { 3820 r.app.removed = true; 3821 } 3822 r.app = null; 3823 } 3824 lastTask = r.task; 3825 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3826 null, "force-stop", true)) { 3827 i--; 3828 } 3829 } 3830 } 3831 3832 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3833 if (!doit) { 3834 return true; 3835 } 3836 didSomething = true; 3837 } 3838 3839 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3840 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3841 if ((name == null || provider.info.packageName.equals(name)) 3842 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3843 if (!doit) { 3844 return true; 3845 } 3846 didSomething = true; 3847 providers.add(provider); 3848 } 3849 } 3850 3851 N = providers.size(); 3852 for (i=0; i<N; i++) { 3853 removeDyingProviderLocked(null, providers.get(i), true); 3854 } 3855 3856 if (doit) { 3857 if (purgeCache && name != null) { 3858 AttributeCache ac = AttributeCache.instance(); 3859 if (ac != null) { 3860 ac.removePackage(name); 3861 } 3862 } 3863 if (mBooted) { 3864 mMainStack.resumeTopActivityLocked(null); 3865 mMainStack.scheduleIdleLocked(); 3866 } 3867 } 3868 3869 return didSomething; 3870 } 3871 3872 private final boolean removeProcessLocked(ProcessRecord app, 3873 boolean callerWillRestart, boolean allowRestart, String reason) { 3874 final String name = app.processName; 3875 final int uid = app.uid; 3876 if (DEBUG_PROCESSES) Slog.d( 3877 TAG, "Force removing proc " + app.toShortString() + " (" + name 3878 + "/" + uid + ")"); 3879 3880 mProcessNames.remove(name, uid); 3881 mIsolatedProcesses.remove(app.uid); 3882 if (mHeavyWeightProcess == app) { 3883 mHeavyWeightProcess = null; 3884 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3885 } 3886 boolean needRestart = false; 3887 if (app.pid > 0 && app.pid != MY_PID) { 3888 int pid = app.pid; 3889 synchronized (mPidsSelfLocked) { 3890 mPidsSelfLocked.remove(pid); 3891 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3892 } 3893 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3894 handleAppDiedLocked(app, true, allowRestart); 3895 mLruProcesses.remove(app); 3896 Process.killProcessQuiet(pid); 3897 3898 if (app.persistent && !app.isolated) { 3899 if (!callerWillRestart) { 3900 addAppLocked(app.info, false); 3901 } else { 3902 needRestart = true; 3903 } 3904 } 3905 } else { 3906 mRemovedProcesses.add(app); 3907 } 3908 3909 return needRestart; 3910 } 3911 3912 private final void processStartTimedOutLocked(ProcessRecord app) { 3913 final int pid = app.pid; 3914 boolean gone = false; 3915 synchronized (mPidsSelfLocked) { 3916 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3917 if (knownApp != null && knownApp.thread == null) { 3918 mPidsSelfLocked.remove(pid); 3919 gone = true; 3920 } 3921 } 3922 3923 if (gone) { 3924 Slog.w(TAG, "Process " + app + " failed to attach"); 3925 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3926 app.processName); 3927 mProcessNames.remove(app.processName, app.uid); 3928 mIsolatedProcesses.remove(app.uid); 3929 if (mHeavyWeightProcess == app) { 3930 mHeavyWeightProcess = null; 3931 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3932 } 3933 // Take care of any launching providers waiting for this process. 3934 checkAppInLaunchingProvidersLocked(app, true); 3935 // Take care of any services that are waiting for the process. 3936 mServices.processStartTimedOutLocked(app); 3937 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3938 app.processName, app.setAdj, "start timeout"); 3939 Process.killProcessQuiet(pid); 3940 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3941 Slog.w(TAG, "Unattached app died before backup, skipping"); 3942 try { 3943 IBackupManager bm = IBackupManager.Stub.asInterface( 3944 ServiceManager.getService(Context.BACKUP_SERVICE)); 3945 bm.agentDisconnected(app.info.packageName); 3946 } catch (RemoteException e) { 3947 // Can't happen; the backup manager is local 3948 } 3949 } 3950 if (isPendingBroadcastProcessLocked(pid)) { 3951 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3952 skipPendingBroadcastLocked(pid); 3953 } 3954 } else { 3955 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3956 } 3957 } 3958 3959 private final boolean attachApplicationLocked(IApplicationThread thread, 3960 int pid) { 3961 3962 // Find the application record that is being attached... either via 3963 // the pid if we are running in multiple processes, or just pull the 3964 // next app record if we are emulating process with anonymous threads. 3965 ProcessRecord app; 3966 if (pid != MY_PID && pid >= 0) { 3967 synchronized (mPidsSelfLocked) { 3968 app = mPidsSelfLocked.get(pid); 3969 } 3970 } else { 3971 app = null; 3972 } 3973 3974 if (app == null) { 3975 Slog.w(TAG, "No pending application record for pid " + pid 3976 + " (IApplicationThread " + thread + "); dropping process"); 3977 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3978 if (pid > 0 && pid != MY_PID) { 3979 Process.killProcessQuiet(pid); 3980 } else { 3981 try { 3982 thread.scheduleExit(); 3983 } catch (Exception e) { 3984 // Ignore exceptions. 3985 } 3986 } 3987 return false; 3988 } 3989 3990 // If this application record is still attached to a previous 3991 // process, clean it up now. 3992 if (app.thread != null) { 3993 handleAppDiedLocked(app, true, true); 3994 } 3995 3996 // Tell the process all about itself. 3997 3998 if (localLOGV) Slog.v( 3999 TAG, "Binding process pid " + pid + " to record " + app); 4000 4001 String processName = app.processName; 4002 try { 4003 AppDeathRecipient adr = new AppDeathRecipient( 4004 app, pid, thread); 4005 thread.asBinder().linkToDeath(adr, 0); 4006 app.deathRecipient = adr; 4007 } catch (RemoteException e) { 4008 app.resetPackageList(); 4009 startProcessLocked(app, "link fail", processName); 4010 return false; 4011 } 4012 4013 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4014 4015 app.thread = thread; 4016 app.curAdj = app.setAdj = -100; 4017 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4018 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4019 app.forcingToForeground = null; 4020 app.foregroundServices = false; 4021 app.hasShownUi = false; 4022 app.debugging = false; 4023 4024 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4025 4026 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4027 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4028 4029 if (!normalMode) { 4030 Slog.i(TAG, "Launching preboot mode app: " + app); 4031 } 4032 4033 if (localLOGV) Slog.v( 4034 TAG, "New app record " + app 4035 + " thread=" + thread.asBinder() + " pid=" + pid); 4036 try { 4037 int testMode = IApplicationThread.DEBUG_OFF; 4038 if (mDebugApp != null && mDebugApp.equals(processName)) { 4039 testMode = mWaitForDebugger 4040 ? IApplicationThread.DEBUG_WAIT 4041 : IApplicationThread.DEBUG_ON; 4042 app.debugging = true; 4043 if (mDebugTransient) { 4044 mDebugApp = mOrigDebugApp; 4045 mWaitForDebugger = mOrigWaitForDebugger; 4046 } 4047 } 4048 String profileFile = app.instrumentationProfileFile; 4049 ParcelFileDescriptor profileFd = null; 4050 boolean profileAutoStop = false; 4051 if (mProfileApp != null && mProfileApp.equals(processName)) { 4052 mProfileProc = app; 4053 profileFile = mProfileFile; 4054 profileFd = mProfileFd; 4055 profileAutoStop = mAutoStopProfiler; 4056 } 4057 boolean enableOpenGlTrace = false; 4058 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4059 enableOpenGlTrace = true; 4060 mOpenGlTraceApp = null; 4061 } 4062 4063 // If the app is being launched for restore or full backup, set it up specially 4064 boolean isRestrictedBackupMode = false; 4065 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4066 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4067 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4068 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4069 } 4070 4071 ensurePackageDexOpt(app.instrumentationInfo != null 4072 ? app.instrumentationInfo.packageName 4073 : app.info.packageName); 4074 if (app.instrumentationClass != null) { 4075 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4076 } 4077 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4078 + processName + " with config " + mConfiguration); 4079 ApplicationInfo appInfo = app.instrumentationInfo != null 4080 ? app.instrumentationInfo : app.info; 4081 app.compat = compatibilityInfoForPackageLocked(appInfo); 4082 if (profileFd != null) { 4083 profileFd = profileFd.dup(); 4084 } 4085 thread.bindApplication(processName, appInfo, providers, 4086 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4087 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4088 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4089 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4090 mCoreSettingsObserver.getCoreSettingsLocked()); 4091 updateLruProcessLocked(app, false, true); 4092 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4093 } catch (Exception e) { 4094 // todo: Yikes! What should we do? For now we will try to 4095 // start another process, but that could easily get us in 4096 // an infinite loop of restarting processes... 4097 Slog.w(TAG, "Exception thrown during bind!", e); 4098 4099 app.resetPackageList(); 4100 app.unlinkDeathRecipient(); 4101 startProcessLocked(app, "bind fail", processName); 4102 return false; 4103 } 4104 4105 // Remove this record from the list of starting applications. 4106 mPersistentStartingProcesses.remove(app); 4107 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4108 "Attach application locked removing on hold: " + app); 4109 mProcessesOnHold.remove(app); 4110 4111 boolean badApp = false; 4112 boolean didSomething = false; 4113 4114 // See if the top visible activity is waiting to run in this process... 4115 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4116 if (hr != null && normalMode) { 4117 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4118 && processName.equals(hr.processName)) { 4119 try { 4120 if (mHeadless) { 4121 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4122 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4123 didSomething = true; 4124 } 4125 } catch (Exception e) { 4126 Slog.w(TAG, "Exception in new application when starting activity " 4127 + hr.intent.getComponent().flattenToShortString(), e); 4128 badApp = true; 4129 } 4130 } else { 4131 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4132 } 4133 } 4134 4135 // Find any services that should be running in this process... 4136 if (!badApp) { 4137 try { 4138 didSomething |= mServices.attachApplicationLocked(app, processName); 4139 } catch (Exception e) { 4140 badApp = true; 4141 } 4142 } 4143 4144 // Check if a next-broadcast receiver is in this process... 4145 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4146 try { 4147 didSomething = sendPendingBroadcastsLocked(app); 4148 } catch (Exception e) { 4149 // If the app died trying to launch the receiver we declare it 'bad' 4150 badApp = true; 4151 } 4152 } 4153 4154 // Check whether the next backup agent is in this process... 4155 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4156 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4157 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4158 try { 4159 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4160 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4161 mBackupTarget.backupMode); 4162 } catch (Exception e) { 4163 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4164 e.printStackTrace(); 4165 } 4166 } 4167 4168 if (badApp) { 4169 // todo: Also need to kill application to deal with all 4170 // kinds of exceptions. 4171 handleAppDiedLocked(app, false, true); 4172 return false; 4173 } 4174 4175 if (!didSomething) { 4176 updateOomAdjLocked(); 4177 } 4178 4179 return true; 4180 } 4181 4182 public final void attachApplication(IApplicationThread thread) { 4183 synchronized (this) { 4184 int callingPid = Binder.getCallingPid(); 4185 final long origId = Binder.clearCallingIdentity(); 4186 attachApplicationLocked(thread, callingPid); 4187 Binder.restoreCallingIdentity(origId); 4188 } 4189 } 4190 4191 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4192 final long origId = Binder.clearCallingIdentity(); 4193 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4194 if (stopProfiling) { 4195 synchronized (this) { 4196 if (mProfileProc == r.app) { 4197 if (mProfileFd != null) { 4198 try { 4199 mProfileFd.close(); 4200 } catch (IOException e) { 4201 } 4202 clearProfilerLocked(); 4203 } 4204 } 4205 } 4206 } 4207 Binder.restoreCallingIdentity(origId); 4208 } 4209 4210 void enableScreenAfterBoot() { 4211 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4212 SystemClock.uptimeMillis()); 4213 mWindowManager.enableScreenAfterBoot(); 4214 4215 synchronized (this) { 4216 updateEventDispatchingLocked(); 4217 } 4218 } 4219 4220 public void showBootMessage(final CharSequence msg, final boolean always) { 4221 enforceNotIsolatedCaller("showBootMessage"); 4222 mWindowManager.showBootMessage(msg, always); 4223 } 4224 4225 public void dismissKeyguardOnNextActivity() { 4226 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4227 final long token = Binder.clearCallingIdentity(); 4228 try { 4229 synchronized (this) { 4230 if (mLockScreenShown) { 4231 mLockScreenShown = false; 4232 comeOutOfSleepIfNeededLocked(); 4233 } 4234 mMainStack.dismissKeyguardOnNextActivityLocked(); 4235 } 4236 } finally { 4237 Binder.restoreCallingIdentity(token); 4238 } 4239 } 4240 4241 final void finishBooting() { 4242 IntentFilter pkgFilter = new IntentFilter(); 4243 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4244 pkgFilter.addDataScheme("package"); 4245 mContext.registerReceiver(new BroadcastReceiver() { 4246 @Override 4247 public void onReceive(Context context, Intent intent) { 4248 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4249 if (pkgs != null) { 4250 for (String pkg : pkgs) { 4251 synchronized (ActivityManagerService.this) { 4252 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4253 setResultCode(Activity.RESULT_OK); 4254 return; 4255 } 4256 } 4257 } 4258 } 4259 } 4260 }, pkgFilter); 4261 4262 synchronized (this) { 4263 // Ensure that any processes we had put on hold are now started 4264 // up. 4265 final int NP = mProcessesOnHold.size(); 4266 if (NP > 0) { 4267 ArrayList<ProcessRecord> procs = 4268 new ArrayList<ProcessRecord>(mProcessesOnHold); 4269 for (int ip=0; ip<NP; ip++) { 4270 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4271 + procs.get(ip)); 4272 startProcessLocked(procs.get(ip), "on-hold", null); 4273 } 4274 } 4275 4276 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4277 // Start looking for apps that are abusing wake locks. 4278 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4279 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4280 // Tell anyone interested that we are done booting! 4281 SystemProperties.set("sys.boot_completed", "1"); 4282 SystemProperties.set("dev.bootcomplete", "1"); 4283 for (int i=0; i<mStartedUsers.size(); i++) { 4284 UserStartedState uss = mStartedUsers.valueAt(i); 4285 if (uss.mState == UserStartedState.STATE_BOOTING) { 4286 uss.mState = UserStartedState.STATE_RUNNING; 4287 broadcastIntentLocked(null, null, 4288 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4289 null, null, 0, null, null, 4290 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4291 false, false, MY_PID, Process.SYSTEM_UID, 4292 mStartedUsers.keyAt(i)); 4293 } 4294 } 4295 } 4296 } 4297 } 4298 4299 final void ensureBootCompleted() { 4300 boolean booting; 4301 boolean enableScreen; 4302 synchronized (this) { 4303 booting = mBooting; 4304 mBooting = false; 4305 enableScreen = !mBooted; 4306 mBooted = true; 4307 } 4308 4309 if (booting) { 4310 finishBooting(); 4311 } 4312 4313 if (enableScreen) { 4314 enableScreenAfterBoot(); 4315 } 4316 } 4317 4318 public final void activityPaused(IBinder token) { 4319 final long origId = Binder.clearCallingIdentity(); 4320 mMainStack.activityPaused(token, false); 4321 Binder.restoreCallingIdentity(origId); 4322 } 4323 4324 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4325 CharSequence description) { 4326 if (localLOGV) Slog.v( 4327 TAG, "Activity stopped: token=" + token); 4328 4329 // Refuse possible leaked file descriptors 4330 if (icicle != null && icicle.hasFileDescriptors()) { 4331 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4332 } 4333 4334 ActivityRecord r = null; 4335 4336 final long origId = Binder.clearCallingIdentity(); 4337 4338 synchronized (this) { 4339 r = mMainStack.isInStackLocked(token); 4340 if (r != null) { 4341 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4342 } 4343 } 4344 4345 if (r != null) { 4346 sendPendingThumbnail(r, null, null, null, false); 4347 } 4348 4349 trimApplications(); 4350 4351 Binder.restoreCallingIdentity(origId); 4352 } 4353 4354 public final void activityDestroyed(IBinder token) { 4355 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4356 mMainStack.activityDestroyed(token); 4357 } 4358 4359 public String getCallingPackage(IBinder token) { 4360 synchronized (this) { 4361 ActivityRecord r = getCallingRecordLocked(token); 4362 return r != null && r.app != null ? r.info.packageName : null; 4363 } 4364 } 4365 4366 public ComponentName getCallingActivity(IBinder token) { 4367 synchronized (this) { 4368 ActivityRecord r = getCallingRecordLocked(token); 4369 return r != null ? r.intent.getComponent() : null; 4370 } 4371 } 4372 4373 private ActivityRecord getCallingRecordLocked(IBinder token) { 4374 ActivityRecord r = mMainStack.isInStackLocked(token); 4375 if (r == null) { 4376 return null; 4377 } 4378 return r.resultTo; 4379 } 4380 4381 public ComponentName getActivityClassForToken(IBinder token) { 4382 synchronized(this) { 4383 ActivityRecord r = mMainStack.isInStackLocked(token); 4384 if (r == null) { 4385 return null; 4386 } 4387 return r.intent.getComponent(); 4388 } 4389 } 4390 4391 public String getPackageForToken(IBinder token) { 4392 synchronized(this) { 4393 ActivityRecord r = mMainStack.isInStackLocked(token); 4394 if (r == null) { 4395 return null; 4396 } 4397 return r.packageName; 4398 } 4399 } 4400 4401 public IIntentSender getIntentSender(int type, 4402 String packageName, IBinder token, String resultWho, 4403 int requestCode, Intent[] intents, String[] resolvedTypes, 4404 int flags, Bundle options) { 4405 enforceNotIsolatedCaller("getIntentSender"); 4406 // Refuse possible leaked file descriptors 4407 if (intents != null) { 4408 if (intents.length < 1) { 4409 throw new IllegalArgumentException("Intents array length must be >= 1"); 4410 } 4411 for (int i=0; i<intents.length; i++) { 4412 Intent intent = intents[i]; 4413 if (intent != null) { 4414 if (intent.hasFileDescriptors()) { 4415 throw new IllegalArgumentException("File descriptors passed in Intent"); 4416 } 4417 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4418 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4419 throw new IllegalArgumentException( 4420 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4421 } 4422 intents[i] = new Intent(intent); 4423 } 4424 } 4425 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4426 throw new IllegalArgumentException( 4427 "Intent array length does not match resolvedTypes length"); 4428 } 4429 } 4430 if (options != null) { 4431 if (options.hasFileDescriptors()) { 4432 throw new IllegalArgumentException("File descriptors passed in options"); 4433 } 4434 } 4435 4436 synchronized(this) { 4437 int callingUid = Binder.getCallingUid(); 4438 try { 4439 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4440 int uid = AppGlobals.getPackageManager() 4441 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4442 if (!UserHandle.isSameApp(callingUid, uid)) { 4443 String msg = "Permission Denial: getIntentSender() from pid=" 4444 + Binder.getCallingPid() 4445 + ", uid=" + Binder.getCallingUid() 4446 + ", (need uid=" + uid + ")" 4447 + " is not allowed to send as package " + packageName; 4448 Slog.w(TAG, msg); 4449 throw new SecurityException(msg); 4450 } 4451 } 4452 4453 if (DEBUG_MU) 4454 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4455 + Binder.getOrigCallingUid()); 4456 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4457 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4458 4459 } catch (RemoteException e) { 4460 throw new SecurityException(e); 4461 } 4462 } 4463 } 4464 4465 IIntentSender getIntentSenderLocked(int type, 4466 String packageName, int callingUid, IBinder token, String resultWho, 4467 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4468 Bundle options) { 4469 if (DEBUG_MU) 4470 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4471 ActivityRecord activity = null; 4472 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4473 activity = mMainStack.isInStackLocked(token); 4474 if (activity == null) { 4475 return null; 4476 } 4477 if (activity.finishing) { 4478 return null; 4479 } 4480 } 4481 4482 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4483 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4484 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4485 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4486 |PendingIntent.FLAG_UPDATE_CURRENT); 4487 4488 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4489 type, packageName, activity, resultWho, 4490 requestCode, intents, resolvedTypes, flags, options, 4491 UserHandle.getUserId(callingUid)); 4492 WeakReference<PendingIntentRecord> ref; 4493 ref = mIntentSenderRecords.get(key); 4494 PendingIntentRecord rec = ref != null ? ref.get() : null; 4495 if (rec != null) { 4496 if (!cancelCurrent) { 4497 if (updateCurrent) { 4498 if (rec.key.requestIntent != null) { 4499 rec.key.requestIntent.replaceExtras(intents != null ? 4500 intents[intents.length - 1] : null); 4501 } 4502 if (intents != null) { 4503 intents[intents.length-1] = rec.key.requestIntent; 4504 rec.key.allIntents = intents; 4505 rec.key.allResolvedTypes = resolvedTypes; 4506 } else { 4507 rec.key.allIntents = null; 4508 rec.key.allResolvedTypes = null; 4509 } 4510 } 4511 return rec; 4512 } 4513 rec.canceled = true; 4514 mIntentSenderRecords.remove(key); 4515 } 4516 if (noCreate) { 4517 return rec; 4518 } 4519 rec = new PendingIntentRecord(this, key, callingUid); 4520 mIntentSenderRecords.put(key, rec.ref); 4521 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4522 if (activity.pendingResults == null) { 4523 activity.pendingResults 4524 = new HashSet<WeakReference<PendingIntentRecord>>(); 4525 } 4526 activity.pendingResults.add(rec.ref); 4527 } 4528 return rec; 4529 } 4530 4531 public void cancelIntentSender(IIntentSender sender) { 4532 if (!(sender instanceof PendingIntentRecord)) { 4533 return; 4534 } 4535 synchronized(this) { 4536 PendingIntentRecord rec = (PendingIntentRecord)sender; 4537 try { 4538 int uid = AppGlobals.getPackageManager() 4539 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4540 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4541 String msg = "Permission Denial: cancelIntentSender() from pid=" 4542 + Binder.getCallingPid() 4543 + ", uid=" + Binder.getCallingUid() 4544 + " is not allowed to cancel packges " 4545 + rec.key.packageName; 4546 Slog.w(TAG, msg); 4547 throw new SecurityException(msg); 4548 } 4549 } catch (RemoteException e) { 4550 throw new SecurityException(e); 4551 } 4552 cancelIntentSenderLocked(rec, true); 4553 } 4554 } 4555 4556 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4557 rec.canceled = true; 4558 mIntentSenderRecords.remove(rec.key); 4559 if (cleanActivity && rec.key.activity != null) { 4560 rec.key.activity.pendingResults.remove(rec.ref); 4561 } 4562 } 4563 4564 public String getPackageForIntentSender(IIntentSender pendingResult) { 4565 if (!(pendingResult instanceof PendingIntentRecord)) { 4566 return null; 4567 } 4568 try { 4569 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4570 return res.key.packageName; 4571 } catch (ClassCastException e) { 4572 } 4573 return null; 4574 } 4575 4576 public int getUidForIntentSender(IIntentSender sender) { 4577 if (sender instanceof PendingIntentRecord) { 4578 try { 4579 PendingIntentRecord res = (PendingIntentRecord)sender; 4580 return res.uid; 4581 } catch (ClassCastException e) { 4582 } 4583 } 4584 return -1; 4585 } 4586 4587 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4588 if (!(pendingResult instanceof PendingIntentRecord)) { 4589 return false; 4590 } 4591 try { 4592 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4593 if (res.key.allIntents == null) { 4594 return false; 4595 } 4596 for (int i=0; i<res.key.allIntents.length; i++) { 4597 Intent intent = res.key.allIntents[i]; 4598 if (intent.getPackage() != null && intent.getComponent() != null) { 4599 return false; 4600 } 4601 } 4602 return true; 4603 } catch (ClassCastException e) { 4604 } 4605 return false; 4606 } 4607 4608 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4609 if (!(pendingResult instanceof PendingIntentRecord)) { 4610 return false; 4611 } 4612 try { 4613 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4614 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4615 return true; 4616 } 4617 return false; 4618 } catch (ClassCastException e) { 4619 } 4620 return false; 4621 } 4622 4623 public void setProcessLimit(int max) { 4624 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4625 "setProcessLimit()"); 4626 synchronized (this) { 4627 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4628 mProcessLimitOverride = max; 4629 } 4630 trimApplications(); 4631 } 4632 4633 public int getProcessLimit() { 4634 synchronized (this) { 4635 return mProcessLimitOverride; 4636 } 4637 } 4638 4639 void foregroundTokenDied(ForegroundToken token) { 4640 synchronized (ActivityManagerService.this) { 4641 synchronized (mPidsSelfLocked) { 4642 ForegroundToken cur 4643 = mForegroundProcesses.get(token.pid); 4644 if (cur != token) { 4645 return; 4646 } 4647 mForegroundProcesses.remove(token.pid); 4648 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4649 if (pr == null) { 4650 return; 4651 } 4652 pr.forcingToForeground = null; 4653 pr.foregroundServices = false; 4654 } 4655 updateOomAdjLocked(); 4656 } 4657 } 4658 4659 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4660 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4661 "setProcessForeground()"); 4662 synchronized(this) { 4663 boolean changed = false; 4664 4665 synchronized (mPidsSelfLocked) { 4666 ProcessRecord pr = mPidsSelfLocked.get(pid); 4667 if (pr == null && isForeground) { 4668 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4669 return; 4670 } 4671 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4672 if (oldToken != null) { 4673 oldToken.token.unlinkToDeath(oldToken, 0); 4674 mForegroundProcesses.remove(pid); 4675 if (pr != null) { 4676 pr.forcingToForeground = null; 4677 } 4678 changed = true; 4679 } 4680 if (isForeground && token != null) { 4681 ForegroundToken newToken = new ForegroundToken() { 4682 public void binderDied() { 4683 foregroundTokenDied(this); 4684 } 4685 }; 4686 newToken.pid = pid; 4687 newToken.token = token; 4688 try { 4689 token.linkToDeath(newToken, 0); 4690 mForegroundProcesses.put(pid, newToken); 4691 pr.forcingToForeground = token; 4692 changed = true; 4693 } catch (RemoteException e) { 4694 // If the process died while doing this, we will later 4695 // do the cleanup with the process death link. 4696 } 4697 } 4698 } 4699 4700 if (changed) { 4701 updateOomAdjLocked(); 4702 } 4703 } 4704 } 4705 4706 // ========================================================= 4707 // PERMISSIONS 4708 // ========================================================= 4709 4710 static class PermissionController extends IPermissionController.Stub { 4711 ActivityManagerService mActivityManagerService; 4712 PermissionController(ActivityManagerService activityManagerService) { 4713 mActivityManagerService = activityManagerService; 4714 } 4715 4716 public boolean checkPermission(String permission, int pid, int uid) { 4717 return mActivityManagerService.checkPermission(permission, pid, 4718 uid) == PackageManager.PERMISSION_GRANTED; 4719 } 4720 } 4721 4722 /** 4723 * This can be called with or without the global lock held. 4724 */ 4725 int checkComponentPermission(String permission, int pid, int uid, 4726 int owningUid, boolean exported) { 4727 // We might be performing an operation on behalf of an indirect binder 4728 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4729 // client identity accordingly before proceeding. 4730 Identity tlsIdentity = sCallerIdentity.get(); 4731 if (tlsIdentity != null) { 4732 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4733 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4734 uid = tlsIdentity.uid; 4735 pid = tlsIdentity.pid; 4736 } 4737 4738 if (pid == MY_PID) { 4739 return PackageManager.PERMISSION_GRANTED; 4740 } 4741 4742 return ActivityManager.checkComponentPermission(permission, uid, 4743 owningUid, exported); 4744 } 4745 4746 /** 4747 * As the only public entry point for permissions checking, this method 4748 * can enforce the semantic that requesting a check on a null global 4749 * permission is automatically denied. (Internally a null permission 4750 * string is used when calling {@link #checkComponentPermission} in cases 4751 * when only uid-based security is needed.) 4752 * 4753 * This can be called with or without the global lock held. 4754 */ 4755 public int checkPermission(String permission, int pid, int uid) { 4756 if (permission == null) { 4757 return PackageManager.PERMISSION_DENIED; 4758 } 4759 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4760 } 4761 4762 /** 4763 * Binder IPC calls go through the public entry point. 4764 * This can be called with or without the global lock held. 4765 */ 4766 int checkCallingPermission(String permission) { 4767 return checkPermission(permission, 4768 Binder.getCallingPid(), 4769 UserHandle.getAppId(Binder.getCallingUid())); 4770 } 4771 4772 /** 4773 * This can be called with or without the global lock held. 4774 */ 4775 void enforceCallingPermission(String permission, String func) { 4776 if (checkCallingPermission(permission) 4777 == PackageManager.PERMISSION_GRANTED) { 4778 return; 4779 } 4780 4781 String msg = "Permission Denial: " + func + " from pid=" 4782 + Binder.getCallingPid() 4783 + ", uid=" + Binder.getCallingUid() 4784 + " requires " + permission; 4785 Slog.w(TAG, msg); 4786 throw new SecurityException(msg); 4787 } 4788 4789 /** 4790 * Determine if UID is holding permissions required to access {@link Uri} in 4791 * the given {@link ProviderInfo}. Final permission checking is always done 4792 * in {@link ContentProvider}. 4793 */ 4794 private final boolean checkHoldingPermissionsLocked( 4795 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4796 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4797 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4798 4799 if (pi.applicationInfo.uid == uid) { 4800 return true; 4801 } else if (!pi.exported) { 4802 return false; 4803 } 4804 4805 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4806 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4807 try { 4808 // check if target holds top-level <provider> permissions 4809 if (!readMet && pi.readPermission != null 4810 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4811 readMet = true; 4812 } 4813 if (!writeMet && pi.writePermission != null 4814 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4815 writeMet = true; 4816 } 4817 4818 // track if unprotected read/write is allowed; any denied 4819 // <path-permission> below removes this ability 4820 boolean allowDefaultRead = pi.readPermission == null; 4821 boolean allowDefaultWrite = pi.writePermission == null; 4822 4823 // check if target holds any <path-permission> that match uri 4824 final PathPermission[] pps = pi.pathPermissions; 4825 if (pps != null) { 4826 final String path = uri.getPath(); 4827 int i = pps.length; 4828 while (i > 0 && (!readMet || !writeMet)) { 4829 i--; 4830 PathPermission pp = pps[i]; 4831 if (pp.match(path)) { 4832 if (!readMet) { 4833 final String pprperm = pp.getReadPermission(); 4834 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4835 + pprperm + " for " + pp.getPath() 4836 + ": match=" + pp.match(path) 4837 + " check=" + pm.checkUidPermission(pprperm, uid)); 4838 if (pprperm != null) { 4839 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4840 readMet = true; 4841 } else { 4842 allowDefaultRead = false; 4843 } 4844 } 4845 } 4846 if (!writeMet) { 4847 final String ppwperm = pp.getWritePermission(); 4848 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4849 + ppwperm + " for " + pp.getPath() 4850 + ": match=" + pp.match(path) 4851 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4852 if (ppwperm != null) { 4853 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4854 writeMet = true; 4855 } else { 4856 allowDefaultWrite = false; 4857 } 4858 } 4859 } 4860 } 4861 } 4862 } 4863 4864 // grant unprotected <provider> read/write, if not blocked by 4865 // <path-permission> above 4866 if (allowDefaultRead) readMet = true; 4867 if (allowDefaultWrite) writeMet = true; 4868 4869 } catch (RemoteException e) { 4870 return false; 4871 } 4872 4873 return readMet && writeMet; 4874 } 4875 4876 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4877 int modeFlags) { 4878 // Root gets to do everything. 4879 if (uid == 0) { 4880 return true; 4881 } 4882 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4883 if (perms == null) return false; 4884 UriPermission perm = perms.get(uri); 4885 if (perm == null) return false; 4886 return (modeFlags&perm.modeFlags) == modeFlags; 4887 } 4888 4889 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4890 enforceNotIsolatedCaller("checkUriPermission"); 4891 4892 // Another redirected-binder-call permissions check as in 4893 // {@link checkComponentPermission}. 4894 Identity tlsIdentity = sCallerIdentity.get(); 4895 if (tlsIdentity != null) { 4896 uid = tlsIdentity.uid; 4897 pid = tlsIdentity.pid; 4898 } 4899 4900 uid = UserHandle.getAppId(uid); 4901 // Our own process gets to do everything. 4902 if (pid == MY_PID) { 4903 return PackageManager.PERMISSION_GRANTED; 4904 } 4905 synchronized(this) { 4906 return checkUriPermissionLocked(uri, uid, modeFlags) 4907 ? PackageManager.PERMISSION_GRANTED 4908 : PackageManager.PERMISSION_DENIED; 4909 } 4910 } 4911 4912 /** 4913 * Check if the targetPkg can be granted permission to access uri by 4914 * the callingUid using the given modeFlags. Throws a security exception 4915 * if callingUid is not allowed to do this. Returns the uid of the target 4916 * if the URI permission grant should be performed; returns -1 if it is not 4917 * needed (for example targetPkg already has permission to access the URI). 4918 * If you already know the uid of the target, you can supply it in 4919 * lastTargetUid else set that to -1. 4920 */ 4921 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4922 Uri uri, int modeFlags, int lastTargetUid) { 4923 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4924 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4925 if (modeFlags == 0) { 4926 return -1; 4927 } 4928 4929 if (targetPkg != null) { 4930 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4931 "Checking grant " + targetPkg + " permission to " + uri); 4932 } 4933 4934 final IPackageManager pm = AppGlobals.getPackageManager(); 4935 4936 // If this is not a content: uri, we can't do anything with it. 4937 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4938 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4939 "Can't grant URI permission for non-content URI: " + uri); 4940 return -1; 4941 } 4942 4943 String name = uri.getAuthority(); 4944 ProviderInfo pi = null; 4945 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4946 UserHandle.getUserId(callingUid)); 4947 if (cpr != null) { 4948 pi = cpr.info; 4949 } else { 4950 try { 4951 pi = pm.resolveContentProvider(name, 4952 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4953 } catch (RemoteException ex) { 4954 } 4955 } 4956 if (pi == null) { 4957 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4958 return -1; 4959 } 4960 4961 int targetUid = lastTargetUid; 4962 if (targetUid < 0 && targetPkg != null) { 4963 try { 4964 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4965 if (targetUid < 0) { 4966 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4967 "Can't grant URI permission no uid for: " + targetPkg); 4968 return -1; 4969 } 4970 } catch (RemoteException ex) { 4971 return -1; 4972 } 4973 } 4974 4975 if (targetUid >= 0) { 4976 // First... does the target actually need this permission? 4977 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4978 // No need to grant the target this permission. 4979 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4980 "Target " + targetPkg + " already has full permission to " + uri); 4981 return -1; 4982 } 4983 } else { 4984 // First... there is no target package, so can anyone access it? 4985 boolean allowed = pi.exported; 4986 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4987 if (pi.readPermission != null) { 4988 allowed = false; 4989 } 4990 } 4991 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4992 if (pi.writePermission != null) { 4993 allowed = false; 4994 } 4995 } 4996 if (allowed) { 4997 return -1; 4998 } 4999 } 5000 5001 // Second... is the provider allowing granting of URI permissions? 5002 if (!pi.grantUriPermissions) { 5003 throw new SecurityException("Provider " + pi.packageName 5004 + "/" + pi.name 5005 + " does not allow granting of Uri permissions (uri " 5006 + uri + ")"); 5007 } 5008 if (pi.uriPermissionPatterns != null) { 5009 final int N = pi.uriPermissionPatterns.length; 5010 boolean allowed = false; 5011 for (int i=0; i<N; i++) { 5012 if (pi.uriPermissionPatterns[i] != null 5013 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5014 allowed = true; 5015 break; 5016 } 5017 } 5018 if (!allowed) { 5019 throw new SecurityException("Provider " + pi.packageName 5020 + "/" + pi.name 5021 + " does not allow granting of permission to path of Uri " 5022 + uri); 5023 } 5024 } 5025 5026 // Third... does the caller itself have permission to access 5027 // this uri? 5028 if (callingUid != Process.myUid()) { 5029 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5030 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5031 throw new SecurityException("Uid " + callingUid 5032 + " does not have permission to uri " + uri); 5033 } 5034 } 5035 } 5036 5037 return targetUid; 5038 } 5039 5040 public int checkGrantUriPermission(int callingUid, String targetPkg, 5041 Uri uri, int modeFlags) { 5042 enforceNotIsolatedCaller("checkGrantUriPermission"); 5043 synchronized(this) { 5044 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5045 } 5046 } 5047 5048 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5049 Uri uri, int modeFlags, UriPermissionOwner owner) { 5050 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5051 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5052 if (modeFlags == 0) { 5053 return; 5054 } 5055 5056 // So here we are: the caller has the assumed permission 5057 // to the uri, and the target doesn't. Let's now give this to 5058 // the target. 5059 5060 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5061 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5062 5063 HashMap<Uri, UriPermission> targetUris 5064 = mGrantedUriPermissions.get(targetUid); 5065 if (targetUris == null) { 5066 targetUris = new HashMap<Uri, UriPermission>(); 5067 mGrantedUriPermissions.put(targetUid, targetUris); 5068 } 5069 5070 UriPermission perm = targetUris.get(uri); 5071 if (perm == null) { 5072 perm = new UriPermission(targetUid, uri); 5073 targetUris.put(uri, perm); 5074 } 5075 5076 perm.modeFlags |= modeFlags; 5077 if (owner == null) { 5078 perm.globalModeFlags |= modeFlags; 5079 } else { 5080 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5081 perm.readOwners.add(owner); 5082 owner.addReadPermission(perm); 5083 } 5084 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5085 perm.writeOwners.add(owner); 5086 owner.addWritePermission(perm); 5087 } 5088 } 5089 } 5090 5091 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5092 int modeFlags, UriPermissionOwner owner) { 5093 if (targetPkg == null) { 5094 throw new NullPointerException("targetPkg"); 5095 } 5096 5097 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5098 if (targetUid < 0) { 5099 return; 5100 } 5101 5102 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5103 } 5104 5105 static class NeededUriGrants extends ArrayList<Uri> { 5106 final String targetPkg; 5107 final int targetUid; 5108 final int flags; 5109 5110 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5111 targetPkg = _targetPkg; 5112 targetUid = _targetUid; 5113 flags = _flags; 5114 } 5115 } 5116 5117 /** 5118 * Like checkGrantUriPermissionLocked, but takes an Intent. 5119 */ 5120 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5121 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5122 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5123 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5124 + " clip=" + (intent != null ? intent.getClipData() : null) 5125 + " from " + intent + "; flags=0x" 5126 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5127 5128 if (targetPkg == null) { 5129 throw new NullPointerException("targetPkg"); 5130 } 5131 5132 if (intent == null) { 5133 return null; 5134 } 5135 Uri data = intent.getData(); 5136 ClipData clip = intent.getClipData(); 5137 if (data == null && clip == null) { 5138 return null; 5139 } 5140 if (data != null) { 5141 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5142 mode, needed != null ? needed.targetUid : -1); 5143 if (target > 0) { 5144 if (needed == null) { 5145 needed = new NeededUriGrants(targetPkg, target, mode); 5146 } 5147 needed.add(data); 5148 } 5149 } 5150 if (clip != null) { 5151 for (int i=0; i<clip.getItemCount(); i++) { 5152 Uri uri = clip.getItemAt(i).getUri(); 5153 if (uri != null) { 5154 int target = -1; 5155 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5156 mode, needed != null ? needed.targetUid : -1); 5157 if (target > 0) { 5158 if (needed == null) { 5159 needed = new NeededUriGrants(targetPkg, target, mode); 5160 } 5161 needed.add(uri); 5162 } 5163 } else { 5164 Intent clipIntent = clip.getItemAt(i).getIntent(); 5165 if (clipIntent != null) { 5166 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5167 callingUid, targetPkg, clipIntent, mode, needed); 5168 if (newNeeded != null) { 5169 needed = newNeeded; 5170 } 5171 } 5172 } 5173 } 5174 } 5175 5176 return needed; 5177 } 5178 5179 /** 5180 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5181 */ 5182 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5183 UriPermissionOwner owner) { 5184 if (needed != null) { 5185 for (int i=0; i<needed.size(); i++) { 5186 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5187 needed.get(i), needed.flags, owner); 5188 } 5189 } 5190 } 5191 5192 void grantUriPermissionFromIntentLocked(int callingUid, 5193 String targetPkg, Intent intent, UriPermissionOwner owner) { 5194 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5195 intent, intent != null ? intent.getFlags() : 0, null); 5196 if (needed == null) { 5197 return; 5198 } 5199 5200 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5201 } 5202 5203 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5204 Uri uri, int modeFlags) { 5205 enforceNotIsolatedCaller("grantUriPermission"); 5206 synchronized(this) { 5207 final ProcessRecord r = getRecordForAppLocked(caller); 5208 if (r == null) { 5209 throw new SecurityException("Unable to find app for caller " 5210 + caller 5211 + " when granting permission to uri " + uri); 5212 } 5213 if (targetPkg == null) { 5214 throw new IllegalArgumentException("null target"); 5215 } 5216 if (uri == null) { 5217 throw new IllegalArgumentException("null uri"); 5218 } 5219 5220 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5221 null); 5222 } 5223 } 5224 5225 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5226 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5227 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5228 HashMap<Uri, UriPermission> perms 5229 = mGrantedUriPermissions.get(perm.uid); 5230 if (perms != null) { 5231 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5232 "Removing " + perm.uid + " permission to " + perm.uri); 5233 perms.remove(perm.uri); 5234 if (perms.size() == 0) { 5235 mGrantedUriPermissions.remove(perm.uid); 5236 } 5237 } 5238 } 5239 } 5240 5241 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5242 int modeFlags) { 5243 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5244 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5245 if (modeFlags == 0) { 5246 return; 5247 } 5248 5249 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5250 "Revoking all granted permissions to " + uri); 5251 5252 final IPackageManager pm = AppGlobals.getPackageManager(); 5253 5254 final String authority = uri.getAuthority(); 5255 ProviderInfo pi = null; 5256 int userId = UserHandle.getUserId(callingUid); 5257 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5258 if (cpr != null) { 5259 pi = cpr.info; 5260 } else { 5261 try { 5262 pi = pm.resolveContentProvider(authority, 5263 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5264 } catch (RemoteException ex) { 5265 } 5266 } 5267 if (pi == null) { 5268 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5269 return; 5270 } 5271 5272 // Does the caller have this permission on the URI? 5273 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5274 // Right now, if you are not the original owner of the permission, 5275 // you are not allowed to revoke it. 5276 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5277 throw new SecurityException("Uid " + callingUid 5278 + " does not have permission to uri " + uri); 5279 //} 5280 } 5281 5282 // Go through all of the permissions and remove any that match. 5283 final List<String> SEGMENTS = uri.getPathSegments(); 5284 if (SEGMENTS != null) { 5285 final int NS = SEGMENTS.size(); 5286 int N = mGrantedUriPermissions.size(); 5287 for (int i=0; i<N; i++) { 5288 HashMap<Uri, UriPermission> perms 5289 = mGrantedUriPermissions.valueAt(i); 5290 Iterator<UriPermission> it = perms.values().iterator(); 5291 toploop: 5292 while (it.hasNext()) { 5293 UriPermission perm = it.next(); 5294 Uri targetUri = perm.uri; 5295 if (!authority.equals(targetUri.getAuthority())) { 5296 continue; 5297 } 5298 List<String> targetSegments = targetUri.getPathSegments(); 5299 if (targetSegments == null) { 5300 continue; 5301 } 5302 if (targetSegments.size() < NS) { 5303 continue; 5304 } 5305 for (int j=0; j<NS; j++) { 5306 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5307 continue toploop; 5308 } 5309 } 5310 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5311 "Revoking " + perm.uid + " permission to " + perm.uri); 5312 perm.clearModes(modeFlags); 5313 if (perm.modeFlags == 0) { 5314 it.remove(); 5315 } 5316 } 5317 if (perms.size() == 0) { 5318 mGrantedUriPermissions.remove( 5319 mGrantedUriPermissions.keyAt(i)); 5320 N--; 5321 i--; 5322 } 5323 } 5324 } 5325 } 5326 5327 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5328 int modeFlags) { 5329 enforceNotIsolatedCaller("revokeUriPermission"); 5330 synchronized(this) { 5331 final ProcessRecord r = getRecordForAppLocked(caller); 5332 if (r == null) { 5333 throw new SecurityException("Unable to find app for caller " 5334 + caller 5335 + " when revoking permission to uri " + uri); 5336 } 5337 if (uri == null) { 5338 Slog.w(TAG, "revokeUriPermission: null uri"); 5339 return; 5340 } 5341 5342 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5343 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5344 if (modeFlags == 0) { 5345 return; 5346 } 5347 5348 final IPackageManager pm = AppGlobals.getPackageManager(); 5349 5350 final String authority = uri.getAuthority(); 5351 ProviderInfo pi = null; 5352 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5353 if (cpr != null) { 5354 pi = cpr.info; 5355 } else { 5356 try { 5357 pi = pm.resolveContentProvider(authority, 5358 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5359 } catch (RemoteException ex) { 5360 } 5361 } 5362 if (pi == null) { 5363 Slog.w(TAG, "No content provider found for permission revoke: " 5364 + uri.toSafeString()); 5365 return; 5366 } 5367 5368 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5369 } 5370 } 5371 5372 @Override 5373 public IBinder newUriPermissionOwner(String name) { 5374 enforceNotIsolatedCaller("newUriPermissionOwner"); 5375 synchronized(this) { 5376 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5377 return owner.getExternalTokenLocked(); 5378 } 5379 } 5380 5381 @Override 5382 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5383 Uri uri, int modeFlags) { 5384 synchronized(this) { 5385 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5386 if (owner == null) { 5387 throw new IllegalArgumentException("Unknown owner: " + token); 5388 } 5389 if (fromUid != Binder.getCallingUid()) { 5390 if (Binder.getCallingUid() != Process.myUid()) { 5391 // Only system code can grant URI permissions on behalf 5392 // of other users. 5393 throw new SecurityException("nice try"); 5394 } 5395 } 5396 if (targetPkg == null) { 5397 throw new IllegalArgumentException("null target"); 5398 } 5399 if (uri == null) { 5400 throw new IllegalArgumentException("null uri"); 5401 } 5402 5403 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5404 } 5405 } 5406 5407 @Override 5408 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5409 synchronized(this) { 5410 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5411 if (owner == null) { 5412 throw new IllegalArgumentException("Unknown owner: " + token); 5413 } 5414 5415 if (uri == null) { 5416 owner.removeUriPermissionsLocked(mode); 5417 } else { 5418 owner.removeUriPermissionLocked(uri, mode); 5419 } 5420 } 5421 } 5422 5423 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5424 synchronized (this) { 5425 ProcessRecord app = 5426 who != null ? getRecordForAppLocked(who) : null; 5427 if (app == null) return; 5428 5429 Message msg = Message.obtain(); 5430 msg.what = WAIT_FOR_DEBUGGER_MSG; 5431 msg.obj = app; 5432 msg.arg1 = waiting ? 1 : 0; 5433 mHandler.sendMessage(msg); 5434 } 5435 } 5436 5437 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5438 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5439 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5440 outInfo.availMem = Process.getFreeMemory(); 5441 outInfo.totalMem = Process.getTotalMemory(); 5442 outInfo.threshold = homeAppMem; 5443 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5444 outInfo.hiddenAppThreshold = hiddenAppMem; 5445 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5446 ProcessList.SERVICE_ADJ); 5447 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5448 ProcessList.VISIBLE_APP_ADJ); 5449 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5450 ProcessList.FOREGROUND_APP_ADJ); 5451 } 5452 5453 // ========================================================= 5454 // TASK MANAGEMENT 5455 // ========================================================= 5456 5457 public List getTasks(int maxNum, int flags, 5458 IThumbnailReceiver receiver) { 5459 ArrayList list = new ArrayList(); 5460 5461 PendingThumbnailsRecord pending = null; 5462 IApplicationThread topThumbnail = null; 5463 ActivityRecord topRecord = null; 5464 5465 synchronized(this) { 5466 if (localLOGV) Slog.v( 5467 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5468 + ", receiver=" + receiver); 5469 5470 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5471 != PackageManager.PERMISSION_GRANTED) { 5472 if (receiver != null) { 5473 // If the caller wants to wait for pending thumbnails, 5474 // it ain't gonna get them. 5475 try { 5476 receiver.finished(); 5477 } catch (RemoteException ex) { 5478 } 5479 } 5480 String msg = "Permission Denial: getTasks() from pid=" 5481 + Binder.getCallingPid() 5482 + ", uid=" + Binder.getCallingUid() 5483 + " requires " + android.Manifest.permission.GET_TASKS; 5484 Slog.w(TAG, msg); 5485 throw new SecurityException(msg); 5486 } 5487 5488 int pos = mMainStack.mHistory.size()-1; 5489 ActivityRecord next = 5490 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5491 ActivityRecord top = null; 5492 TaskRecord curTask = null; 5493 int numActivities = 0; 5494 int numRunning = 0; 5495 while (pos >= 0 && maxNum > 0) { 5496 final ActivityRecord r = next; 5497 pos--; 5498 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5499 5500 // Initialize state for next task if needed. 5501 if (top == null || 5502 (top.state == ActivityState.INITIALIZING 5503 && top.task == r.task)) { 5504 top = r; 5505 curTask = r.task; 5506 numActivities = numRunning = 0; 5507 } 5508 5509 // Add 'r' into the current task. 5510 numActivities++; 5511 if (r.app != null && r.app.thread != null) { 5512 numRunning++; 5513 } 5514 5515 if (localLOGV) Slog.v( 5516 TAG, r.intent.getComponent().flattenToShortString() 5517 + ": task=" + r.task); 5518 5519 // If the next one is a different task, generate a new 5520 // TaskInfo entry for what we have. 5521 if (next == null || next.task != curTask) { 5522 ActivityManager.RunningTaskInfo ci 5523 = new ActivityManager.RunningTaskInfo(); 5524 ci.id = curTask.taskId; 5525 ci.baseActivity = r.intent.getComponent(); 5526 ci.topActivity = top.intent.getComponent(); 5527 if (top.thumbHolder != null) { 5528 ci.description = top.thumbHolder.lastDescription; 5529 } 5530 ci.numActivities = numActivities; 5531 ci.numRunning = numRunning; 5532 //System.out.println( 5533 // "#" + maxNum + ": " + " descr=" + ci.description); 5534 if (ci.thumbnail == null && receiver != null) { 5535 if (localLOGV) Slog.v( 5536 TAG, "State=" + top.state + "Idle=" + top.idle 5537 + " app=" + top.app 5538 + " thr=" + (top.app != null ? top.app.thread : null)); 5539 if (top.state == ActivityState.RESUMED 5540 || top.state == ActivityState.PAUSING) { 5541 if (top.idle && top.app != null 5542 && top.app.thread != null) { 5543 topRecord = top; 5544 topThumbnail = top.app.thread; 5545 } else { 5546 top.thumbnailNeeded = true; 5547 } 5548 } 5549 if (pending == null) { 5550 pending = new PendingThumbnailsRecord(receiver); 5551 } 5552 pending.pendingRecords.add(top); 5553 } 5554 list.add(ci); 5555 maxNum--; 5556 top = null; 5557 } 5558 } 5559 5560 if (pending != null) { 5561 mPendingThumbnails.add(pending); 5562 } 5563 } 5564 5565 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5566 5567 if (topThumbnail != null) { 5568 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5569 try { 5570 topThumbnail.requestThumbnail(topRecord.appToken); 5571 } catch (Exception e) { 5572 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5573 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5574 } 5575 } 5576 5577 if (pending == null && receiver != null) { 5578 // In this case all thumbnails were available and the client 5579 // is being asked to be told when the remaining ones come in... 5580 // which is unusually, since the top-most currently running 5581 // activity should never have a canned thumbnail! Oh well. 5582 try { 5583 receiver.finished(); 5584 } catch (RemoteException ex) { 5585 } 5586 } 5587 5588 return list; 5589 } 5590 5591 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5592 int flags, int userId) { 5593 final int callingUid = Binder.getCallingUid(); 5594 if (userId != UserHandle.getCallingUserId()) { 5595 // Check if the caller is holding permissions for cross-user requests. 5596 if (checkComponentPermission( 5597 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5598 Binder.getCallingPid(), callingUid, -1, true) 5599 != PackageManager.PERMISSION_GRANTED) { 5600 String msg = "Permission Denial: " 5601 + "Request to get recent tasks for user " + userId 5602 + " but is calling from user " + UserHandle.getUserId(callingUid) 5603 + "; this requires " 5604 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5605 Slog.w(TAG, msg); 5606 throw new SecurityException(msg); 5607 } else { 5608 if (userId == UserHandle.USER_CURRENT) { 5609 userId = mCurrentUserId; 5610 } 5611 } 5612 } 5613 5614 synchronized (this) { 5615 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5616 "getRecentTasks()"); 5617 final boolean detailed = checkCallingPermission( 5618 android.Manifest.permission.GET_DETAILED_TASKS) 5619 == PackageManager.PERMISSION_GRANTED; 5620 5621 IPackageManager pm = AppGlobals.getPackageManager(); 5622 5623 final int N = mRecentTasks.size(); 5624 ArrayList<ActivityManager.RecentTaskInfo> res 5625 = new ArrayList<ActivityManager.RecentTaskInfo>( 5626 maxNum < N ? maxNum : N); 5627 for (int i=0; i<N && maxNum > 0; i++) { 5628 TaskRecord tr = mRecentTasks.get(i); 5629 // Only add calling user's recent tasks 5630 if (tr.userId != userId) continue; 5631 // Return the entry if desired by the caller. We always return 5632 // the first entry, because callers always expect this to be the 5633 // foreground app. We may filter others if the caller has 5634 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5635 // we should exclude the entry. 5636 5637 if (i == 0 5638 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5639 || (tr.intent == null) 5640 || ((tr.intent.getFlags() 5641 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5642 ActivityManager.RecentTaskInfo rti 5643 = new ActivityManager.RecentTaskInfo(); 5644 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5645 rti.persistentId = tr.taskId; 5646 rti.baseIntent = new Intent( 5647 tr.intent != null ? tr.intent : tr.affinityIntent); 5648 if (!detailed) { 5649 rti.baseIntent.replaceExtras((Bundle)null); 5650 } 5651 rti.origActivity = tr.origActivity; 5652 rti.description = tr.lastDescription; 5653 5654 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5655 // Check whether this activity is currently available. 5656 try { 5657 if (rti.origActivity != null) { 5658 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5659 == null) { 5660 continue; 5661 } 5662 } else if (rti.baseIntent != null) { 5663 if (pm.queryIntentActivities(rti.baseIntent, 5664 null, 0, userId) == null) { 5665 continue; 5666 } 5667 } 5668 } catch (RemoteException e) { 5669 // Will never happen. 5670 } 5671 } 5672 5673 res.add(rti); 5674 maxNum--; 5675 } 5676 } 5677 return res; 5678 } 5679 } 5680 5681 private TaskRecord taskForIdLocked(int id) { 5682 final int N = mRecentTasks.size(); 5683 for (int i=0; i<N; i++) { 5684 TaskRecord tr = mRecentTasks.get(i); 5685 if (tr.taskId == id) { 5686 return tr; 5687 } 5688 } 5689 return null; 5690 } 5691 5692 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5693 synchronized (this) { 5694 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5695 "getTaskThumbnails()"); 5696 TaskRecord tr = taskForIdLocked(id); 5697 if (tr != null) { 5698 return mMainStack.getTaskThumbnailsLocked(tr); 5699 } 5700 } 5701 return null; 5702 } 5703 5704 public boolean removeSubTask(int taskId, int subTaskIndex) { 5705 synchronized (this) { 5706 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5707 "removeSubTask()"); 5708 long ident = Binder.clearCallingIdentity(); 5709 try { 5710 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5711 true) != null; 5712 } finally { 5713 Binder.restoreCallingIdentity(ident); 5714 } 5715 } 5716 } 5717 5718 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5719 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5720 Intent baseIntent = new Intent( 5721 tr.intent != null ? tr.intent : tr.affinityIntent); 5722 ComponentName component = baseIntent.getComponent(); 5723 if (component == null) { 5724 Slog.w(TAG, "Now component for base intent of task: " + tr); 5725 return; 5726 } 5727 5728 // Find any running services associated with this app. 5729 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5730 5731 if (killProcesses) { 5732 // Find any running processes associated with this app. 5733 final String pkg = component.getPackageName(); 5734 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5735 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5736 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5737 for (int i=0; i<uids.size(); i++) { 5738 ProcessRecord proc = uids.valueAt(i); 5739 if (proc.userId != tr.userId) { 5740 continue; 5741 } 5742 if (!proc.pkgList.contains(pkg)) { 5743 continue; 5744 } 5745 procs.add(proc); 5746 } 5747 } 5748 5749 // Kill the running processes. 5750 for (int i=0; i<procs.size(); i++) { 5751 ProcessRecord pr = procs.get(i); 5752 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5753 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5754 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5755 pr.processName, pr.setAdj, "remove task"); 5756 pr.killedBackground = true; 5757 Process.killProcessQuiet(pr.pid); 5758 } else { 5759 pr.waitingToKill = "remove task"; 5760 } 5761 } 5762 } 5763 } 5764 5765 public boolean removeTask(int taskId, int flags) { 5766 synchronized (this) { 5767 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5768 "removeTask()"); 5769 long ident = Binder.clearCallingIdentity(); 5770 try { 5771 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5772 false); 5773 if (r != null) { 5774 mRecentTasks.remove(r.task); 5775 cleanUpRemovedTaskLocked(r.task, flags); 5776 return true; 5777 } else { 5778 TaskRecord tr = null; 5779 int i=0; 5780 while (i < mRecentTasks.size()) { 5781 TaskRecord t = mRecentTasks.get(i); 5782 if (t.taskId == taskId) { 5783 tr = t; 5784 break; 5785 } 5786 i++; 5787 } 5788 if (tr != null) { 5789 if (tr.numActivities <= 0) { 5790 // Caller is just removing a recent task that is 5791 // not actively running. That is easy! 5792 mRecentTasks.remove(i); 5793 cleanUpRemovedTaskLocked(tr, flags); 5794 return true; 5795 } else { 5796 Slog.w(TAG, "removeTask: task " + taskId 5797 + " does not have activities to remove, " 5798 + " but numActivities=" + tr.numActivities 5799 + ": " + tr); 5800 } 5801 } 5802 } 5803 } finally { 5804 Binder.restoreCallingIdentity(ident); 5805 } 5806 } 5807 return false; 5808 } 5809 5810 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5811 int j; 5812 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5813 TaskRecord jt = startTask; 5814 5815 // First look backwards 5816 for (j=startIndex-1; j>=0; j--) { 5817 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5818 if (r.task != jt) { 5819 jt = r.task; 5820 if (affinity.equals(jt.affinity)) { 5821 return j; 5822 } 5823 } 5824 } 5825 5826 // Now look forwards 5827 final int N = mMainStack.mHistory.size(); 5828 jt = startTask; 5829 for (j=startIndex+1; j<N; j++) { 5830 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5831 if (r.task != jt) { 5832 if (affinity.equals(jt.affinity)) { 5833 return j; 5834 } 5835 jt = r.task; 5836 } 5837 } 5838 5839 // Might it be at the top? 5840 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5841 return N-1; 5842 } 5843 5844 return -1; 5845 } 5846 5847 /** 5848 * TODO: Add mController hook 5849 */ 5850 public void moveTaskToFront(int task, int flags, Bundle options) { 5851 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5852 "moveTaskToFront()"); 5853 5854 synchronized(this) { 5855 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5856 Binder.getCallingUid(), "Task to front")) { 5857 ActivityOptions.abort(options); 5858 return; 5859 } 5860 final long origId = Binder.clearCallingIdentity(); 5861 try { 5862 TaskRecord tr = taskForIdLocked(task); 5863 if (tr != null) { 5864 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5865 mMainStack.mUserLeaving = true; 5866 } 5867 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5868 // Caller wants the home activity moved with it. To accomplish this, 5869 // we'll just move the home task to the top first. 5870 mMainStack.moveHomeToFrontLocked(); 5871 } 5872 mMainStack.moveTaskToFrontLocked(tr, null, options); 5873 return; 5874 } 5875 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5876 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5877 if (hr.task.taskId == task) { 5878 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5879 mMainStack.mUserLeaving = true; 5880 } 5881 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5882 // Caller wants the home activity moved with it. To accomplish this, 5883 // we'll just move the home task to the top first. 5884 mMainStack.moveHomeToFrontLocked(); 5885 } 5886 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5887 return; 5888 } 5889 } 5890 } finally { 5891 Binder.restoreCallingIdentity(origId); 5892 } 5893 ActivityOptions.abort(options); 5894 } 5895 } 5896 5897 public void moveTaskToBack(int task) { 5898 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5899 "moveTaskToBack()"); 5900 5901 synchronized(this) { 5902 if (mMainStack.mResumedActivity != null 5903 && mMainStack.mResumedActivity.task.taskId == task) { 5904 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5905 Binder.getCallingUid(), "Task to back")) { 5906 return; 5907 } 5908 } 5909 final long origId = Binder.clearCallingIdentity(); 5910 mMainStack.moveTaskToBackLocked(task, null); 5911 Binder.restoreCallingIdentity(origId); 5912 } 5913 } 5914 5915 /** 5916 * Moves an activity, and all of the other activities within the same task, to the bottom 5917 * of the history stack. The activity's order within the task is unchanged. 5918 * 5919 * @param token A reference to the activity we wish to move 5920 * @param nonRoot If false then this only works if the activity is the root 5921 * of a task; if true it will work for any activity in a task. 5922 * @return Returns true if the move completed, false if not. 5923 */ 5924 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5925 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5926 synchronized(this) { 5927 final long origId = Binder.clearCallingIdentity(); 5928 int taskId = getTaskForActivityLocked(token, !nonRoot); 5929 if (taskId >= 0) { 5930 return mMainStack.moveTaskToBackLocked(taskId, null); 5931 } 5932 Binder.restoreCallingIdentity(origId); 5933 } 5934 return false; 5935 } 5936 5937 public void moveTaskBackwards(int task) { 5938 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5939 "moveTaskBackwards()"); 5940 5941 synchronized(this) { 5942 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5943 Binder.getCallingUid(), "Task backwards")) { 5944 return; 5945 } 5946 final long origId = Binder.clearCallingIdentity(); 5947 moveTaskBackwardsLocked(task); 5948 Binder.restoreCallingIdentity(origId); 5949 } 5950 } 5951 5952 private final void moveTaskBackwardsLocked(int task) { 5953 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5954 } 5955 5956 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5957 synchronized(this) { 5958 return getTaskForActivityLocked(token, onlyRoot); 5959 } 5960 } 5961 5962 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5963 final int N = mMainStack.mHistory.size(); 5964 TaskRecord lastTask = null; 5965 for (int i=0; i<N; i++) { 5966 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5967 if (r.appToken == token) { 5968 if (!onlyRoot || lastTask != r.task) { 5969 return r.task.taskId; 5970 } 5971 return -1; 5972 } 5973 lastTask = r.task; 5974 } 5975 5976 return -1; 5977 } 5978 5979 // ========================================================= 5980 // THUMBNAILS 5981 // ========================================================= 5982 5983 public void reportThumbnail(IBinder token, 5984 Bitmap thumbnail, CharSequence description) { 5985 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5986 final long origId = Binder.clearCallingIdentity(); 5987 sendPendingThumbnail(null, token, thumbnail, description, true); 5988 Binder.restoreCallingIdentity(origId); 5989 } 5990 5991 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5992 Bitmap thumbnail, CharSequence description, boolean always) { 5993 TaskRecord task = null; 5994 ArrayList receivers = null; 5995 5996 //System.out.println("Send pending thumbnail: " + r); 5997 5998 synchronized(this) { 5999 if (r == null) { 6000 r = mMainStack.isInStackLocked(token); 6001 if (r == null) { 6002 return; 6003 } 6004 } 6005 if (thumbnail == null && r.thumbHolder != null) { 6006 thumbnail = r.thumbHolder.lastThumbnail; 6007 description = r.thumbHolder.lastDescription; 6008 } 6009 if (thumbnail == null && !always) { 6010 // If there is no thumbnail, and this entry is not actually 6011 // going away, then abort for now and pick up the next 6012 // thumbnail we get. 6013 return; 6014 } 6015 task = r.task; 6016 6017 int N = mPendingThumbnails.size(); 6018 int i=0; 6019 while (i<N) { 6020 PendingThumbnailsRecord pr = 6021 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6022 //System.out.println("Looking in " + pr.pendingRecords); 6023 if (pr.pendingRecords.remove(r)) { 6024 if (receivers == null) { 6025 receivers = new ArrayList(); 6026 } 6027 receivers.add(pr); 6028 if (pr.pendingRecords.size() == 0) { 6029 pr.finished = true; 6030 mPendingThumbnails.remove(i); 6031 N--; 6032 continue; 6033 } 6034 } 6035 i++; 6036 } 6037 } 6038 6039 if (receivers != null) { 6040 final int N = receivers.size(); 6041 for (int i=0; i<N; i++) { 6042 try { 6043 PendingThumbnailsRecord pr = 6044 (PendingThumbnailsRecord)receivers.get(i); 6045 pr.receiver.newThumbnail( 6046 task != null ? task.taskId : -1, thumbnail, description); 6047 if (pr.finished) { 6048 pr.receiver.finished(); 6049 } 6050 } catch (Exception e) { 6051 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6052 } 6053 } 6054 } 6055 } 6056 6057 // ========================================================= 6058 // CONTENT PROVIDERS 6059 // ========================================================= 6060 6061 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6062 List<ProviderInfo> providers = null; 6063 try { 6064 providers = AppGlobals.getPackageManager(). 6065 queryContentProviders(app.processName, app.uid, 6066 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6067 } catch (RemoteException ex) { 6068 } 6069 if (DEBUG_MU) 6070 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6071 int userId = app.userId; 6072 if (providers != null) { 6073 int N = providers.size(); 6074 for (int i=0; i<N; i++) { 6075 ProviderInfo cpi = 6076 (ProviderInfo)providers.get(i); 6077 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6078 cpi.name, cpi.flags); 6079 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6080 // This is a singleton provider, but a user besides the 6081 // default user is asking to initialize a process it runs 6082 // in... well, no, it doesn't actually run in this process, 6083 // it runs in the process of the default user. Get rid of it. 6084 providers.remove(i); 6085 N--; 6086 continue; 6087 } 6088 6089 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6090 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6091 if (cpr == null) { 6092 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6093 mProviderMap.putProviderByClass(comp, cpr); 6094 } 6095 if (DEBUG_MU) 6096 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6097 app.pubProviders.put(cpi.name, cpr); 6098 app.addPackage(cpi.applicationInfo.packageName); 6099 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6100 } 6101 } 6102 return providers; 6103 } 6104 6105 /** 6106 * Check if {@link ProcessRecord} has a possible chance at accessing the 6107 * given {@link ProviderInfo}. Final permission checking is always done 6108 * in {@link ContentProvider}. 6109 */ 6110 private final String checkContentProviderPermissionLocked( 6111 ProviderInfo cpi, ProcessRecord r) { 6112 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6113 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6114 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6115 cpi.applicationInfo.uid, cpi.exported) 6116 == PackageManager.PERMISSION_GRANTED) { 6117 return null; 6118 } 6119 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6120 cpi.applicationInfo.uid, cpi.exported) 6121 == PackageManager.PERMISSION_GRANTED) { 6122 return null; 6123 } 6124 6125 PathPermission[] pps = cpi.pathPermissions; 6126 if (pps != null) { 6127 int i = pps.length; 6128 while (i > 0) { 6129 i--; 6130 PathPermission pp = pps[i]; 6131 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6132 cpi.applicationInfo.uid, cpi.exported) 6133 == PackageManager.PERMISSION_GRANTED) { 6134 return null; 6135 } 6136 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6137 cpi.applicationInfo.uid, cpi.exported) 6138 == PackageManager.PERMISSION_GRANTED) { 6139 return null; 6140 } 6141 } 6142 } 6143 6144 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6145 if (perms != null) { 6146 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6147 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6148 return null; 6149 } 6150 } 6151 } 6152 6153 String msg; 6154 if (!cpi.exported) { 6155 msg = "Permission Denial: opening provider " + cpi.name 6156 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6157 + ", uid=" + callingUid + ") that is not exported from uid " 6158 + cpi.applicationInfo.uid; 6159 } else { 6160 msg = "Permission Denial: opening provider " + cpi.name 6161 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6162 + ", uid=" + callingUid + ") requires " 6163 + cpi.readPermission + " or " + cpi.writePermission; 6164 } 6165 Slog.w(TAG, msg); 6166 return msg; 6167 } 6168 6169 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6170 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6171 if (r != null) { 6172 for (int i=0; i<r.conProviders.size(); i++) { 6173 ContentProviderConnection conn = r.conProviders.get(i); 6174 if (conn.provider == cpr) { 6175 if (DEBUG_PROVIDER) Slog.v(TAG, 6176 "Adding provider requested by " 6177 + r.processName + " from process " 6178 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6179 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6180 if (stable) { 6181 conn.stableCount++; 6182 conn.numStableIncs++; 6183 } else { 6184 conn.unstableCount++; 6185 conn.numUnstableIncs++; 6186 } 6187 return conn; 6188 } 6189 } 6190 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6191 if (stable) { 6192 conn.stableCount = 1; 6193 conn.numStableIncs = 1; 6194 } else { 6195 conn.unstableCount = 1; 6196 conn.numUnstableIncs = 1; 6197 } 6198 cpr.connections.add(conn); 6199 r.conProviders.add(conn); 6200 return conn; 6201 } 6202 cpr.addExternalProcessHandleLocked(externalProcessToken); 6203 return null; 6204 } 6205 6206 boolean decProviderCountLocked(ContentProviderConnection conn, 6207 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6208 if (conn != null) { 6209 cpr = conn.provider; 6210 if (DEBUG_PROVIDER) Slog.v(TAG, 6211 "Removing provider requested by " 6212 + conn.client.processName + " from process " 6213 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6214 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6215 if (stable) { 6216 conn.stableCount--; 6217 } else { 6218 conn.unstableCount--; 6219 } 6220 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6221 cpr.connections.remove(conn); 6222 conn.client.conProviders.remove(conn); 6223 return true; 6224 } 6225 return false; 6226 } 6227 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6228 return false; 6229 } 6230 6231 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6232 String name, IBinder token, boolean stable) { 6233 ContentProviderRecord cpr; 6234 ContentProviderConnection conn = null; 6235 ProviderInfo cpi = null; 6236 6237 synchronized(this) { 6238 ProcessRecord r = null; 6239 if (caller != null) { 6240 r = getRecordForAppLocked(caller); 6241 if (r == null) { 6242 throw new SecurityException( 6243 "Unable to find app for caller " + caller 6244 + " (pid=" + Binder.getCallingPid() 6245 + ") when getting content provider " + name); 6246 } 6247 } 6248 6249 // First check if this content provider has been published... 6250 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6251 cpr = mProviderMap.getProviderByName(name, userId); 6252 boolean providerRunning = cpr != null; 6253 if (providerRunning) { 6254 cpi = cpr.info; 6255 String msg; 6256 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6257 throw new SecurityException(msg); 6258 } 6259 6260 if (r != null && cpr.canRunHere(r)) { 6261 // This provider has been published or is in the process 6262 // of being published... but it is also allowed to run 6263 // in the caller's process, so don't make a connection 6264 // and just let the caller instantiate its own instance. 6265 ContentProviderHolder holder = cpr.newHolder(null); 6266 // don't give caller the provider object, it needs 6267 // to make its own. 6268 holder.provider = null; 6269 return holder; 6270 } 6271 6272 final long origId = Binder.clearCallingIdentity(); 6273 6274 // In this case the provider instance already exists, so we can 6275 // return it right away. 6276 conn = incProviderCountLocked(r, cpr, token, stable); 6277 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6278 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6279 // If this is a perceptible app accessing the provider, 6280 // make sure to count it as being accessed and thus 6281 // back up on the LRU list. This is good because 6282 // content providers are often expensive to start. 6283 updateLruProcessLocked(cpr.proc, false, true); 6284 } 6285 } 6286 6287 if (cpr.proc != null) { 6288 if (false) { 6289 if (cpr.name.flattenToShortString().equals( 6290 "com.android.providers.calendar/.CalendarProvider2")) { 6291 Slog.v(TAG, "****************** KILLING " 6292 + cpr.name.flattenToShortString()); 6293 Process.killProcess(cpr.proc.pid); 6294 } 6295 } 6296 boolean success = updateOomAdjLocked(cpr.proc); 6297 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6298 // NOTE: there is still a race here where a signal could be 6299 // pending on the process even though we managed to update its 6300 // adj level. Not sure what to do about this, but at least 6301 // the race is now smaller. 6302 if (!success) { 6303 // Uh oh... it looks like the provider's process 6304 // has been killed on us. We need to wait for a new 6305 // process to be started, and make sure its death 6306 // doesn't kill our process. 6307 Slog.i(TAG, 6308 "Existing provider " + cpr.name.flattenToShortString() 6309 + " is crashing; detaching " + r); 6310 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6311 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6312 if (!lastRef) { 6313 // This wasn't the last ref our process had on 6314 // the provider... we have now been killed, bail. 6315 return null; 6316 } 6317 providerRunning = false; 6318 conn = null; 6319 } 6320 } 6321 6322 Binder.restoreCallingIdentity(origId); 6323 } 6324 6325 boolean singleton; 6326 if (!providerRunning) { 6327 try { 6328 cpi = AppGlobals.getPackageManager(). 6329 resolveContentProvider(name, 6330 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6331 } catch (RemoteException ex) { 6332 } 6333 if (cpi == null) { 6334 return null; 6335 } 6336 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6337 cpi.name, cpi.flags); 6338 if (singleton) { 6339 userId = 0; 6340 } 6341 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6342 6343 String msg; 6344 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6345 throw new SecurityException(msg); 6346 } 6347 6348 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6349 && !cpi.processName.equals("system")) { 6350 // If this content provider does not run in the system 6351 // process, and the system is not yet ready to run other 6352 // processes, then fail fast instead of hanging. 6353 throw new IllegalArgumentException( 6354 "Attempt to launch content provider before system ready"); 6355 } 6356 6357 // Make sure that the user who owns this provider is started. If not, 6358 // we don't want to allow it to run. 6359 if (mStartedUsers.get(userId) == null) { 6360 Slog.w(TAG, "Unable to launch app " 6361 + cpi.applicationInfo.packageName + "/" 6362 + cpi.applicationInfo.uid + " for provider " 6363 + name + ": user " + userId + " is stopped"); 6364 return null; 6365 } 6366 6367 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6368 cpr = mProviderMap.getProviderByClass(comp, userId); 6369 final boolean firstClass = cpr == null; 6370 if (firstClass) { 6371 try { 6372 ApplicationInfo ai = 6373 AppGlobals.getPackageManager(). 6374 getApplicationInfo( 6375 cpi.applicationInfo.packageName, 6376 STOCK_PM_FLAGS, userId); 6377 if (ai == null) { 6378 Slog.w(TAG, "No package info for content provider " 6379 + cpi.name); 6380 return null; 6381 } 6382 ai = getAppInfoForUser(ai, userId); 6383 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6384 } catch (RemoteException ex) { 6385 // pm is in same process, this will never happen. 6386 } 6387 } 6388 6389 if (r != null && cpr.canRunHere(r)) { 6390 // If this is a multiprocess provider, then just return its 6391 // info and allow the caller to instantiate it. Only do 6392 // this if the provider is the same user as the caller's 6393 // process, or can run as root (so can be in any process). 6394 return cpr.newHolder(null); 6395 } 6396 6397 if (DEBUG_PROVIDER) { 6398 RuntimeException e = new RuntimeException("here"); 6399 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6400 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6401 } 6402 6403 // This is single process, and our app is now connecting to it. 6404 // See if we are already in the process of launching this 6405 // provider. 6406 final int N = mLaunchingProviders.size(); 6407 int i; 6408 for (i=0; i<N; i++) { 6409 if (mLaunchingProviders.get(i) == cpr) { 6410 break; 6411 } 6412 } 6413 6414 // If the provider is not already being launched, then get it 6415 // started. 6416 if (i >= N) { 6417 final long origId = Binder.clearCallingIdentity(); 6418 6419 try { 6420 // Content provider is now in use, its package can't be stopped. 6421 try { 6422 AppGlobals.getPackageManager().setPackageStoppedState( 6423 cpr.appInfo.packageName, false, userId); 6424 } catch (RemoteException e) { 6425 } catch (IllegalArgumentException e) { 6426 Slog.w(TAG, "Failed trying to unstop package " 6427 + cpr.appInfo.packageName + ": " + e); 6428 } 6429 6430 ProcessRecord proc = startProcessLocked(cpi.processName, 6431 cpr.appInfo, false, 0, "content provider", 6432 new ComponentName(cpi.applicationInfo.packageName, 6433 cpi.name), false, false); 6434 if (proc == null) { 6435 Slog.w(TAG, "Unable to launch app " 6436 + cpi.applicationInfo.packageName + "/" 6437 + cpi.applicationInfo.uid + " for provider " 6438 + name + ": process is bad"); 6439 return null; 6440 } 6441 cpr.launchingApp = proc; 6442 mLaunchingProviders.add(cpr); 6443 } finally { 6444 Binder.restoreCallingIdentity(origId); 6445 } 6446 } 6447 6448 // Make sure the provider is published (the same provider class 6449 // may be published under multiple names). 6450 if (firstClass) { 6451 mProviderMap.putProviderByClass(comp, cpr); 6452 } 6453 6454 mProviderMap.putProviderByName(name, cpr); 6455 conn = incProviderCountLocked(r, cpr, token, stable); 6456 if (conn != null) { 6457 conn.waiting = true; 6458 } 6459 } 6460 } 6461 6462 // Wait for the provider to be published... 6463 synchronized (cpr) { 6464 while (cpr.provider == null) { 6465 if (cpr.launchingApp == null) { 6466 Slog.w(TAG, "Unable to launch app " 6467 + cpi.applicationInfo.packageName + "/" 6468 + cpi.applicationInfo.uid + " for provider " 6469 + name + ": launching app became null"); 6470 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6471 cpi.applicationInfo.packageName, 6472 cpi.applicationInfo.uid, name); 6473 return null; 6474 } 6475 try { 6476 if (DEBUG_MU) { 6477 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6478 + cpr.launchingApp); 6479 } 6480 if (conn != null) { 6481 conn.waiting = true; 6482 } 6483 cpr.wait(); 6484 } catch (InterruptedException ex) { 6485 } finally { 6486 if (conn != null) { 6487 conn.waiting = false; 6488 } 6489 } 6490 } 6491 } 6492 return cpr != null ? cpr.newHolder(conn) : null; 6493 } 6494 6495 public final ContentProviderHolder getContentProvider( 6496 IApplicationThread caller, String name, boolean stable) { 6497 enforceNotIsolatedCaller("getContentProvider"); 6498 if (caller == null) { 6499 String msg = "null IApplicationThread when getting content provider " 6500 + name; 6501 Slog.w(TAG, msg); 6502 throw new SecurityException(msg); 6503 } 6504 6505 return getContentProviderImpl(caller, name, null, stable); 6506 } 6507 6508 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6509 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6510 "Do not have permission in call getContentProviderExternal()"); 6511 return getContentProviderExternalUnchecked(name, token); 6512 } 6513 6514 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6515 return getContentProviderImpl(null, name, token, true); 6516 } 6517 6518 /** 6519 * Drop a content provider from a ProcessRecord's bookkeeping 6520 * @param cpr 6521 */ 6522 public void removeContentProvider(IBinder connection, boolean stable) { 6523 enforceNotIsolatedCaller("removeContentProvider"); 6524 synchronized (this) { 6525 ContentProviderConnection conn; 6526 try { 6527 conn = (ContentProviderConnection)connection; 6528 } catch (ClassCastException e) { 6529 String msg ="removeContentProvider: " + connection 6530 + " not a ContentProviderConnection"; 6531 Slog.w(TAG, msg); 6532 throw new IllegalArgumentException(msg); 6533 } 6534 if (conn == null) { 6535 throw new NullPointerException("connection is null"); 6536 } 6537 if (decProviderCountLocked(conn, null, null, stable)) { 6538 updateOomAdjLocked(); 6539 } 6540 } 6541 } 6542 6543 public void removeContentProviderExternal(String name, IBinder token) { 6544 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6545 "Do not have permission in call removeContentProviderExternal()"); 6546 removeContentProviderExternalUnchecked(name, token); 6547 } 6548 6549 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6550 synchronized (this) { 6551 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6552 Binder.getOrigCallingUser()); 6553 if(cpr == null) { 6554 //remove from mProvidersByClass 6555 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6556 return; 6557 } 6558 6559 //update content provider record entry info 6560 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6561 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6562 Binder.getOrigCallingUser()); 6563 if (localCpr.hasExternalProcessHandles()) { 6564 if (localCpr.removeExternalProcessHandleLocked(token)) { 6565 updateOomAdjLocked(); 6566 } else { 6567 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6568 + " with no external reference for token: " 6569 + token + "."); 6570 } 6571 } else { 6572 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6573 + " with no external references."); 6574 } 6575 } 6576 } 6577 6578 public final void publishContentProviders(IApplicationThread caller, 6579 List<ContentProviderHolder> providers) { 6580 if (providers == null) { 6581 return; 6582 } 6583 6584 enforceNotIsolatedCaller("publishContentProviders"); 6585 synchronized (this) { 6586 final ProcessRecord r = getRecordForAppLocked(caller); 6587 if (DEBUG_MU) 6588 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6589 if (r == null) { 6590 throw new SecurityException( 6591 "Unable to find app for caller " + caller 6592 + " (pid=" + Binder.getCallingPid() 6593 + ") when publishing content providers"); 6594 } 6595 6596 final long origId = Binder.clearCallingIdentity(); 6597 6598 final int N = providers.size(); 6599 for (int i=0; i<N; i++) { 6600 ContentProviderHolder src = providers.get(i); 6601 if (src == null || src.info == null || src.provider == null) { 6602 continue; 6603 } 6604 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6605 if (DEBUG_MU) 6606 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6607 if (dst != null) { 6608 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6609 mProviderMap.putProviderByClass(comp, dst); 6610 String names[] = dst.info.authority.split(";"); 6611 for (int j = 0; j < names.length; j++) { 6612 mProviderMap.putProviderByName(names[j], dst); 6613 } 6614 6615 int NL = mLaunchingProviders.size(); 6616 int j; 6617 for (j=0; j<NL; j++) { 6618 if (mLaunchingProviders.get(j) == dst) { 6619 mLaunchingProviders.remove(j); 6620 j--; 6621 NL--; 6622 } 6623 } 6624 synchronized (dst) { 6625 dst.provider = src.provider; 6626 dst.proc = r; 6627 dst.notifyAll(); 6628 } 6629 updateOomAdjLocked(r); 6630 } 6631 } 6632 6633 Binder.restoreCallingIdentity(origId); 6634 } 6635 } 6636 6637 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6638 ContentProviderConnection conn; 6639 try { 6640 conn = (ContentProviderConnection)connection; 6641 } catch (ClassCastException e) { 6642 String msg ="refContentProvider: " + connection 6643 + " not a ContentProviderConnection"; 6644 Slog.w(TAG, msg); 6645 throw new IllegalArgumentException(msg); 6646 } 6647 if (conn == null) { 6648 throw new NullPointerException("connection is null"); 6649 } 6650 6651 synchronized (this) { 6652 if (stable > 0) { 6653 conn.numStableIncs += stable; 6654 } 6655 stable = conn.stableCount + stable; 6656 if (stable < 0) { 6657 throw new IllegalStateException("stableCount < 0: " + stable); 6658 } 6659 6660 if (unstable > 0) { 6661 conn.numUnstableIncs += unstable; 6662 } 6663 unstable = conn.unstableCount + unstable; 6664 if (unstable < 0) { 6665 throw new IllegalStateException("unstableCount < 0: " + unstable); 6666 } 6667 6668 if ((stable+unstable) <= 0) { 6669 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6670 + stable + " unstable=" + unstable); 6671 } 6672 conn.stableCount = stable; 6673 conn.unstableCount = unstable; 6674 return !conn.dead; 6675 } 6676 } 6677 6678 public void unstableProviderDied(IBinder connection) { 6679 ContentProviderConnection conn; 6680 try { 6681 conn = (ContentProviderConnection)connection; 6682 } catch (ClassCastException e) { 6683 String msg ="refContentProvider: " + connection 6684 + " not a ContentProviderConnection"; 6685 Slog.w(TAG, msg); 6686 throw new IllegalArgumentException(msg); 6687 } 6688 if (conn == null) { 6689 throw new NullPointerException("connection is null"); 6690 } 6691 6692 // Safely retrieve the content provider associated with the connection. 6693 IContentProvider provider; 6694 synchronized (this) { 6695 provider = conn.provider.provider; 6696 } 6697 6698 if (provider == null) { 6699 // Um, yeah, we're way ahead of you. 6700 return; 6701 } 6702 6703 // Make sure the caller is being honest with us. 6704 if (provider.asBinder().pingBinder()) { 6705 // Er, no, still looks good to us. 6706 synchronized (this) { 6707 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6708 + " says " + conn + " died, but we don't agree"); 6709 return; 6710 } 6711 } 6712 6713 // Well look at that! It's dead! 6714 synchronized (this) { 6715 if (conn.provider.provider != provider) { 6716 // But something changed... good enough. 6717 return; 6718 } 6719 6720 ProcessRecord proc = conn.provider.proc; 6721 if (proc == null || proc.thread == null) { 6722 // Seems like the process is already cleaned up. 6723 return; 6724 } 6725 6726 // As far as we're concerned, this is just like receiving a 6727 // death notification... just a bit prematurely. 6728 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6729 + ") early provider death"); 6730 final long ident = Binder.clearCallingIdentity(); 6731 try { 6732 appDiedLocked(proc, proc.pid, proc.thread); 6733 } finally { 6734 Binder.restoreCallingIdentity(ident); 6735 } 6736 } 6737 } 6738 6739 public static final void installSystemProviders() { 6740 List<ProviderInfo> providers; 6741 synchronized (mSelf) { 6742 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6743 providers = mSelf.generateApplicationProvidersLocked(app); 6744 if (providers != null) { 6745 for (int i=providers.size()-1; i>=0; i--) { 6746 ProviderInfo pi = (ProviderInfo)providers.get(i); 6747 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6748 Slog.w(TAG, "Not installing system proc provider " + pi.name 6749 + ": not system .apk"); 6750 providers.remove(i); 6751 } 6752 } 6753 } 6754 } 6755 if (providers != null) { 6756 mSystemThread.installSystemProviders(providers); 6757 } 6758 6759 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6760 6761 mSelf.mUsageStatsService.monitorPackages(); 6762 } 6763 6764 /** 6765 * Allows app to retrieve the MIME type of a URI without having permission 6766 * to access its content provider. 6767 * 6768 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6769 * 6770 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6771 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6772 */ 6773 public String getProviderMimeType(Uri uri) { 6774 enforceNotIsolatedCaller("getProviderMimeType"); 6775 final String name = uri.getAuthority(); 6776 final long ident = Binder.clearCallingIdentity(); 6777 ContentProviderHolder holder = null; 6778 6779 try { 6780 holder = getContentProviderExternalUnchecked(name, null); 6781 if (holder != null) { 6782 return holder.provider.getType(uri); 6783 } 6784 } catch (RemoteException e) { 6785 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6786 return null; 6787 } finally { 6788 if (holder != null) { 6789 removeContentProviderExternalUnchecked(name, null); 6790 } 6791 Binder.restoreCallingIdentity(ident); 6792 } 6793 6794 return null; 6795 } 6796 6797 // ========================================================= 6798 // GLOBAL MANAGEMENT 6799 // ========================================================= 6800 6801 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6802 ApplicationInfo info, String customProcess, boolean isolated) { 6803 String proc = customProcess != null ? customProcess : info.processName; 6804 BatteryStatsImpl.Uid.Proc ps = null; 6805 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6806 int uid = info.uid; 6807 if (isolated) { 6808 int userId = UserHandle.getUserId(uid); 6809 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6810 uid = 0; 6811 while (true) { 6812 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6813 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6814 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6815 } 6816 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6817 mNextIsolatedProcessUid++; 6818 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6819 // No process for this uid, use it. 6820 break; 6821 } 6822 stepsLeft--; 6823 if (stepsLeft <= 0) { 6824 return null; 6825 } 6826 } 6827 } 6828 synchronized (stats) { 6829 ps = stats.getProcessStatsLocked(info.uid, proc); 6830 } 6831 return new ProcessRecord(ps, thread, info, proc, uid); 6832 } 6833 6834 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6835 ProcessRecord app; 6836 if (!isolated) { 6837 app = getProcessRecordLocked(info.processName, info.uid); 6838 } else { 6839 app = null; 6840 } 6841 6842 if (app == null) { 6843 app = newProcessRecordLocked(null, info, null, isolated); 6844 mProcessNames.put(info.processName, app.uid, app); 6845 if (isolated) { 6846 mIsolatedProcesses.put(app.uid, app); 6847 } 6848 updateLruProcessLocked(app, true, true); 6849 } 6850 6851 // This package really, really can not be stopped. 6852 try { 6853 AppGlobals.getPackageManager().setPackageStoppedState( 6854 info.packageName, false, UserHandle.getUserId(app.uid)); 6855 } catch (RemoteException e) { 6856 } catch (IllegalArgumentException e) { 6857 Slog.w(TAG, "Failed trying to unstop package " 6858 + info.packageName + ": " + e); 6859 } 6860 6861 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6862 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6863 app.persistent = true; 6864 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6865 } 6866 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6867 mPersistentStartingProcesses.add(app); 6868 startProcessLocked(app, "added application", app.processName); 6869 } 6870 6871 return app; 6872 } 6873 6874 public void unhandledBack() { 6875 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6876 "unhandledBack()"); 6877 6878 synchronized(this) { 6879 int count = mMainStack.mHistory.size(); 6880 if (DEBUG_SWITCH) Slog.d( 6881 TAG, "Performing unhandledBack(): stack size = " + count); 6882 if (count > 1) { 6883 final long origId = Binder.clearCallingIdentity(); 6884 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6885 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6886 Binder.restoreCallingIdentity(origId); 6887 } 6888 } 6889 } 6890 6891 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6892 enforceNotIsolatedCaller("openContentUri"); 6893 String name = uri.getAuthority(); 6894 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6895 ParcelFileDescriptor pfd = null; 6896 if (cph != null) { 6897 // We record the binder invoker's uid in thread-local storage before 6898 // going to the content provider to open the file. Later, in the code 6899 // that handles all permissions checks, we look for this uid and use 6900 // that rather than the Activity Manager's own uid. The effect is that 6901 // we do the check against the caller's permissions even though it looks 6902 // to the content provider like the Activity Manager itself is making 6903 // the request. 6904 sCallerIdentity.set(new Identity( 6905 Binder.getCallingPid(), Binder.getCallingUid())); 6906 try { 6907 pfd = cph.provider.openFile(uri, "r"); 6908 } catch (FileNotFoundException e) { 6909 // do nothing; pfd will be returned null 6910 } finally { 6911 // Ensure that whatever happens, we clean up the identity state 6912 sCallerIdentity.remove(); 6913 } 6914 6915 // We've got the fd now, so we're done with the provider. 6916 removeContentProviderExternalUnchecked(name, null); 6917 } else { 6918 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6919 } 6920 return pfd; 6921 } 6922 6923 // Actually is sleeping or shutting down or whatever else in the future 6924 // is an inactive state. 6925 public boolean isSleeping() { 6926 return mSleeping || mShuttingDown; 6927 } 6928 6929 public void goingToSleep() { 6930 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6931 != PackageManager.PERMISSION_GRANTED) { 6932 throw new SecurityException("Requires permission " 6933 + android.Manifest.permission.DEVICE_POWER); 6934 } 6935 6936 synchronized(this) { 6937 mWentToSleep = true; 6938 updateEventDispatchingLocked(); 6939 6940 if (!mSleeping) { 6941 mSleeping = true; 6942 mMainStack.stopIfSleepingLocked(); 6943 6944 // Initialize the wake times of all processes. 6945 checkExcessivePowerUsageLocked(false); 6946 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6947 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6948 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6949 } 6950 } 6951 } 6952 6953 public boolean shutdown(int timeout) { 6954 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6955 != PackageManager.PERMISSION_GRANTED) { 6956 throw new SecurityException("Requires permission " 6957 + android.Manifest.permission.SHUTDOWN); 6958 } 6959 6960 boolean timedout = false; 6961 6962 synchronized(this) { 6963 mShuttingDown = true; 6964 updateEventDispatchingLocked(); 6965 6966 if (mMainStack.mResumedActivity != null) { 6967 mMainStack.stopIfSleepingLocked(); 6968 final long endTime = System.currentTimeMillis() + timeout; 6969 while (mMainStack.mResumedActivity != null 6970 || mMainStack.mPausingActivity != null) { 6971 long delay = endTime - System.currentTimeMillis(); 6972 if (delay <= 0) { 6973 Slog.w(TAG, "Activity manager shutdown timed out"); 6974 timedout = true; 6975 break; 6976 } 6977 try { 6978 this.wait(); 6979 } catch (InterruptedException e) { 6980 } 6981 } 6982 } 6983 } 6984 6985 mUsageStatsService.shutdown(); 6986 mBatteryStatsService.shutdown(); 6987 6988 return timedout; 6989 } 6990 6991 public final void activitySlept(IBinder token) { 6992 if (localLOGV) Slog.v( 6993 TAG, "Activity slept: token=" + token); 6994 6995 ActivityRecord r = null; 6996 6997 final long origId = Binder.clearCallingIdentity(); 6998 6999 synchronized (this) { 7000 r = mMainStack.isInStackLocked(token); 7001 if (r != null) { 7002 mMainStack.activitySleptLocked(r); 7003 } 7004 } 7005 7006 Binder.restoreCallingIdentity(origId); 7007 } 7008 7009 private void comeOutOfSleepIfNeededLocked() { 7010 if (!mWentToSleep && !mLockScreenShown) { 7011 if (mSleeping) { 7012 mSleeping = false; 7013 mMainStack.awakeFromSleepingLocked(); 7014 mMainStack.resumeTopActivityLocked(null); 7015 } 7016 } 7017 } 7018 7019 public void wakingUp() { 7020 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7021 != PackageManager.PERMISSION_GRANTED) { 7022 throw new SecurityException("Requires permission " 7023 + android.Manifest.permission.DEVICE_POWER); 7024 } 7025 7026 synchronized(this) { 7027 mWentToSleep = false; 7028 updateEventDispatchingLocked(); 7029 comeOutOfSleepIfNeededLocked(); 7030 } 7031 } 7032 7033 private void updateEventDispatchingLocked() { 7034 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7035 } 7036 7037 public void setLockScreenShown(boolean shown) { 7038 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7039 != PackageManager.PERMISSION_GRANTED) { 7040 throw new SecurityException("Requires permission " 7041 + android.Manifest.permission.DEVICE_POWER); 7042 } 7043 7044 synchronized(this) { 7045 mLockScreenShown = shown; 7046 comeOutOfSleepIfNeededLocked(); 7047 } 7048 } 7049 7050 public void stopAppSwitches() { 7051 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7052 != PackageManager.PERMISSION_GRANTED) { 7053 throw new SecurityException("Requires permission " 7054 + android.Manifest.permission.STOP_APP_SWITCHES); 7055 } 7056 7057 synchronized(this) { 7058 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7059 + APP_SWITCH_DELAY_TIME; 7060 mDidAppSwitch = false; 7061 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7062 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7063 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7064 } 7065 } 7066 7067 public void resumeAppSwitches() { 7068 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7069 != PackageManager.PERMISSION_GRANTED) { 7070 throw new SecurityException("Requires permission " 7071 + android.Manifest.permission.STOP_APP_SWITCHES); 7072 } 7073 7074 synchronized(this) { 7075 // Note that we don't execute any pending app switches... we will 7076 // let those wait until either the timeout, or the next start 7077 // activity request. 7078 mAppSwitchesAllowedTime = 0; 7079 } 7080 } 7081 7082 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7083 String name) { 7084 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7085 return true; 7086 } 7087 7088 final int perm = checkComponentPermission( 7089 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7090 callingUid, -1, true); 7091 if (perm == PackageManager.PERMISSION_GRANTED) { 7092 return true; 7093 } 7094 7095 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7096 return false; 7097 } 7098 7099 public void setDebugApp(String packageName, boolean waitForDebugger, 7100 boolean persistent) { 7101 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7102 "setDebugApp()"); 7103 7104 // Note that this is not really thread safe if there are multiple 7105 // callers into it at the same time, but that's not a situation we 7106 // care about. 7107 if (persistent) { 7108 final ContentResolver resolver = mContext.getContentResolver(); 7109 Settings.System.putString( 7110 resolver, Settings.System.DEBUG_APP, 7111 packageName); 7112 Settings.System.putInt( 7113 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7114 waitForDebugger ? 1 : 0); 7115 } 7116 7117 synchronized (this) { 7118 if (!persistent) { 7119 mOrigDebugApp = mDebugApp; 7120 mOrigWaitForDebugger = mWaitForDebugger; 7121 } 7122 mDebugApp = packageName; 7123 mWaitForDebugger = waitForDebugger; 7124 mDebugTransient = !persistent; 7125 if (packageName != null) { 7126 final long origId = Binder.clearCallingIdentity(); 7127 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7128 Binder.restoreCallingIdentity(origId); 7129 } 7130 } 7131 } 7132 7133 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7134 synchronized (this) { 7135 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7136 if (!isDebuggable) { 7137 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7138 throw new SecurityException("Process not debuggable: " + app.packageName); 7139 } 7140 } 7141 7142 mOpenGlTraceApp = processName; 7143 } 7144 } 7145 7146 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7147 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7148 synchronized (this) { 7149 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7150 if (!isDebuggable) { 7151 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7152 throw new SecurityException("Process not debuggable: " + app.packageName); 7153 } 7154 } 7155 mProfileApp = processName; 7156 mProfileFile = profileFile; 7157 if (mProfileFd != null) { 7158 try { 7159 mProfileFd.close(); 7160 } catch (IOException e) { 7161 } 7162 mProfileFd = null; 7163 } 7164 mProfileFd = profileFd; 7165 mProfileType = 0; 7166 mAutoStopProfiler = autoStopProfiler; 7167 } 7168 } 7169 7170 public void setAlwaysFinish(boolean enabled) { 7171 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7172 "setAlwaysFinish()"); 7173 7174 Settings.System.putInt( 7175 mContext.getContentResolver(), 7176 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7177 7178 synchronized (this) { 7179 mAlwaysFinishActivities = enabled; 7180 } 7181 } 7182 7183 public void setActivityController(IActivityController controller) { 7184 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7185 "setActivityController()"); 7186 synchronized (this) { 7187 mController = controller; 7188 } 7189 } 7190 7191 public boolean isUserAMonkey() { 7192 // For now the fact that there is a controller implies 7193 // we have a monkey. 7194 synchronized (this) { 7195 return mController != null; 7196 } 7197 } 7198 7199 public void registerProcessObserver(IProcessObserver observer) { 7200 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7201 "registerProcessObserver()"); 7202 synchronized (this) { 7203 mProcessObservers.register(observer); 7204 } 7205 } 7206 7207 public void unregisterProcessObserver(IProcessObserver observer) { 7208 synchronized (this) { 7209 mProcessObservers.unregister(observer); 7210 } 7211 } 7212 7213 public void setImmersive(IBinder token, boolean immersive) { 7214 synchronized(this) { 7215 ActivityRecord r = mMainStack.isInStackLocked(token); 7216 if (r == null) { 7217 throw new IllegalArgumentException(); 7218 } 7219 r.immersive = immersive; 7220 } 7221 } 7222 7223 public boolean isImmersive(IBinder token) { 7224 synchronized (this) { 7225 ActivityRecord r = mMainStack.isInStackLocked(token); 7226 if (r == null) { 7227 throw new IllegalArgumentException(); 7228 } 7229 return r.immersive; 7230 } 7231 } 7232 7233 public boolean isTopActivityImmersive() { 7234 enforceNotIsolatedCaller("startActivity"); 7235 synchronized (this) { 7236 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7237 return (r != null) ? r.immersive : false; 7238 } 7239 } 7240 7241 public final void enterSafeMode() { 7242 synchronized(this) { 7243 // It only makes sense to do this before the system is ready 7244 // and started launching other packages. 7245 if (!mSystemReady) { 7246 try { 7247 AppGlobals.getPackageManager().enterSafeMode(); 7248 } catch (RemoteException e) { 7249 } 7250 } 7251 } 7252 } 7253 7254 public final void showSafeModeOverlay() { 7255 View v = LayoutInflater.from(mContext).inflate( 7256 com.android.internal.R.layout.safe_mode, null); 7257 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7258 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7259 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7260 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7261 lp.gravity = Gravity.BOTTOM | Gravity.START; 7262 lp.format = v.getBackground().getOpacity(); 7263 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7264 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7265 ((WindowManager)mContext.getSystemService( 7266 Context.WINDOW_SERVICE)).addView(v, lp); 7267 } 7268 7269 public void noteWakeupAlarm(IIntentSender sender) { 7270 if (!(sender instanceof PendingIntentRecord)) { 7271 return; 7272 } 7273 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7274 synchronized (stats) { 7275 if (mBatteryStatsService.isOnBattery()) { 7276 mBatteryStatsService.enforceCallingPermission(); 7277 PendingIntentRecord rec = (PendingIntentRecord)sender; 7278 int MY_UID = Binder.getCallingUid(); 7279 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7280 BatteryStatsImpl.Uid.Pkg pkg = 7281 stats.getPackageStatsLocked(uid, rec.key.packageName); 7282 pkg.incWakeupsLocked(); 7283 } 7284 } 7285 } 7286 7287 public boolean killPids(int[] pids, String pReason, boolean secure) { 7288 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7289 throw new SecurityException("killPids only available to the system"); 7290 } 7291 String reason = (pReason == null) ? "Unknown" : pReason; 7292 // XXX Note: don't acquire main activity lock here, because the window 7293 // manager calls in with its locks held. 7294 7295 boolean killed = false; 7296 synchronized (mPidsSelfLocked) { 7297 int[] types = new int[pids.length]; 7298 int worstType = 0; 7299 for (int i=0; i<pids.length; i++) { 7300 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7301 if (proc != null) { 7302 int type = proc.setAdj; 7303 types[i] = type; 7304 if (type > worstType) { 7305 worstType = type; 7306 } 7307 } 7308 } 7309 7310 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7311 // then constrain it so we will kill all hidden procs. 7312 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7313 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7314 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7315 } 7316 7317 // If this is not a secure call, don't let it kill processes that 7318 // are important. 7319 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7320 worstType = ProcessList.SERVICE_ADJ; 7321 } 7322 7323 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7324 for (int i=0; i<pids.length; i++) { 7325 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7326 if (proc == null) { 7327 continue; 7328 } 7329 int adj = proc.setAdj; 7330 if (adj >= worstType && !proc.killedBackground) { 7331 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7332 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7333 proc.processName, adj, reason); 7334 killed = true; 7335 proc.killedBackground = true; 7336 Process.killProcessQuiet(pids[i]); 7337 } 7338 } 7339 } 7340 return killed; 7341 } 7342 7343 @Override 7344 public boolean killProcessesBelowForeground(String reason) { 7345 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7346 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7347 } 7348 7349 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7350 } 7351 7352 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7353 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7354 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7355 } 7356 7357 boolean killed = false; 7358 synchronized (mPidsSelfLocked) { 7359 final int size = mPidsSelfLocked.size(); 7360 for (int i = 0; i < size; i++) { 7361 final int pid = mPidsSelfLocked.keyAt(i); 7362 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7363 if (proc == null) continue; 7364 7365 final int adj = proc.setAdj; 7366 if (adj > belowAdj && !proc.killedBackground) { 7367 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7368 EventLog.writeEvent( 7369 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7370 killed = true; 7371 proc.killedBackground = true; 7372 Process.killProcessQuiet(pid); 7373 } 7374 } 7375 } 7376 return killed; 7377 } 7378 7379 public final void startRunning(String pkg, String cls, String action, 7380 String data) { 7381 synchronized(this) { 7382 if (mStartRunning) { 7383 return; 7384 } 7385 mStartRunning = true; 7386 mTopComponent = pkg != null && cls != null 7387 ? new ComponentName(pkg, cls) : null; 7388 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7389 mTopData = data; 7390 if (!mSystemReady) { 7391 return; 7392 } 7393 } 7394 7395 systemReady(null); 7396 } 7397 7398 private void retrieveSettings() { 7399 final ContentResolver resolver = mContext.getContentResolver(); 7400 String debugApp = Settings.System.getString( 7401 resolver, Settings.System.DEBUG_APP); 7402 boolean waitForDebugger = Settings.System.getInt( 7403 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7404 boolean alwaysFinishActivities = Settings.System.getInt( 7405 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7406 7407 Configuration configuration = new Configuration(); 7408 Settings.System.getConfiguration(resolver, configuration); 7409 7410 synchronized (this) { 7411 mDebugApp = mOrigDebugApp = debugApp; 7412 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7413 mAlwaysFinishActivities = alwaysFinishActivities; 7414 // This happens before any activities are started, so we can 7415 // change mConfiguration in-place. 7416 updateConfigurationLocked(configuration, null, false, true); 7417 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7418 } 7419 } 7420 7421 public boolean testIsSystemReady() { 7422 // no need to synchronize(this) just to read & return the value 7423 return mSystemReady; 7424 } 7425 7426 private static File getCalledPreBootReceiversFile() { 7427 File dataDir = Environment.getDataDirectory(); 7428 File systemDir = new File(dataDir, "system"); 7429 File fname = new File(systemDir, "called_pre_boots.dat"); 7430 return fname; 7431 } 7432 7433 static final int LAST_DONE_VERSION = 10000; 7434 7435 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7436 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7437 File file = getCalledPreBootReceiversFile(); 7438 FileInputStream fis = null; 7439 try { 7440 fis = new FileInputStream(file); 7441 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7442 int fvers = dis.readInt(); 7443 if (fvers == LAST_DONE_VERSION) { 7444 String vers = dis.readUTF(); 7445 String codename = dis.readUTF(); 7446 String build = dis.readUTF(); 7447 if (android.os.Build.VERSION.RELEASE.equals(vers) 7448 && android.os.Build.VERSION.CODENAME.equals(codename) 7449 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7450 int num = dis.readInt(); 7451 while (num > 0) { 7452 num--; 7453 String pkg = dis.readUTF(); 7454 String cls = dis.readUTF(); 7455 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7456 } 7457 } 7458 } 7459 } catch (FileNotFoundException e) { 7460 } catch (IOException e) { 7461 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7462 } finally { 7463 if (fis != null) { 7464 try { 7465 fis.close(); 7466 } catch (IOException e) { 7467 } 7468 } 7469 } 7470 return lastDoneReceivers; 7471 } 7472 7473 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7474 File file = getCalledPreBootReceiversFile(); 7475 FileOutputStream fos = null; 7476 DataOutputStream dos = null; 7477 try { 7478 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7479 fos = new FileOutputStream(file); 7480 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7481 dos.writeInt(LAST_DONE_VERSION); 7482 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7483 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7484 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7485 dos.writeInt(list.size()); 7486 for (int i=0; i<list.size(); i++) { 7487 dos.writeUTF(list.get(i).getPackageName()); 7488 dos.writeUTF(list.get(i).getClassName()); 7489 } 7490 } catch (IOException e) { 7491 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7492 file.delete(); 7493 } finally { 7494 FileUtils.sync(fos); 7495 if (dos != null) { 7496 try { 7497 dos.close(); 7498 } catch (IOException e) { 7499 // TODO Auto-generated catch block 7500 e.printStackTrace(); 7501 } 7502 } 7503 } 7504 } 7505 7506 public void systemReady(final Runnable goingCallback) { 7507 synchronized(this) { 7508 if (mSystemReady) { 7509 if (goingCallback != null) goingCallback.run(); 7510 return; 7511 } 7512 7513 // Check to see if there are any update receivers to run. 7514 if (!mDidUpdate) { 7515 if (mWaitingUpdate) { 7516 return; 7517 } 7518 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7519 List<ResolveInfo> ris = null; 7520 try { 7521 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7522 intent, null, 0, 0); 7523 } catch (RemoteException e) { 7524 } 7525 if (ris != null) { 7526 for (int i=ris.size()-1; i>=0; i--) { 7527 if ((ris.get(i).activityInfo.applicationInfo.flags 7528 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7529 ris.remove(i); 7530 } 7531 } 7532 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7533 7534 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7535 7536 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7537 for (int i=0; i<ris.size(); i++) { 7538 ActivityInfo ai = ris.get(i).activityInfo; 7539 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7540 if (lastDoneReceivers.contains(comp)) { 7541 ris.remove(i); 7542 i--; 7543 } 7544 } 7545 7546 for (int i=0; i<ris.size(); i++) { 7547 ActivityInfo ai = ris.get(i).activityInfo; 7548 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7549 doneReceivers.add(comp); 7550 intent.setComponent(comp); 7551 IIntentReceiver finisher = null; 7552 if (i == ris.size()-1) { 7553 finisher = new IIntentReceiver.Stub() { 7554 public void performReceive(Intent intent, int resultCode, 7555 String data, Bundle extras, boolean ordered, 7556 boolean sticky) { 7557 // The raw IIntentReceiver interface is called 7558 // with the AM lock held, so redispatch to 7559 // execute our code without the lock. 7560 mHandler.post(new Runnable() { 7561 public void run() { 7562 synchronized (ActivityManagerService.this) { 7563 mDidUpdate = true; 7564 } 7565 writeLastDonePreBootReceivers(doneReceivers); 7566 showBootMessage(mContext.getText( 7567 R.string.android_upgrading_complete), 7568 false); 7569 systemReady(goingCallback); 7570 } 7571 }); 7572 } 7573 }; 7574 } 7575 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7576 /* TODO: Send this to all users */ 7577 broadcastIntentLocked(null, null, intent, null, finisher, 7578 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7579 0 /* UserId zero */); 7580 if (finisher != null) { 7581 mWaitingUpdate = true; 7582 } 7583 } 7584 } 7585 if (mWaitingUpdate) { 7586 return; 7587 } 7588 mDidUpdate = true; 7589 } 7590 7591 mSystemReady = true; 7592 if (!mStartRunning) { 7593 return; 7594 } 7595 } 7596 7597 ArrayList<ProcessRecord> procsToKill = null; 7598 synchronized(mPidsSelfLocked) { 7599 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7600 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7601 if (!isAllowedWhileBooting(proc.info)){ 7602 if (procsToKill == null) { 7603 procsToKill = new ArrayList<ProcessRecord>(); 7604 } 7605 procsToKill.add(proc); 7606 } 7607 } 7608 } 7609 7610 synchronized(this) { 7611 if (procsToKill != null) { 7612 for (int i=procsToKill.size()-1; i>=0; i--) { 7613 ProcessRecord proc = procsToKill.get(i); 7614 Slog.i(TAG, "Removing system update proc: " + proc); 7615 removeProcessLocked(proc, true, false, "system update done"); 7616 } 7617 } 7618 7619 // Now that we have cleaned up any update processes, we 7620 // are ready to start launching real processes and know that 7621 // we won't trample on them any more. 7622 mProcessesReady = true; 7623 } 7624 7625 Slog.i(TAG, "System now ready"); 7626 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7627 SystemClock.uptimeMillis()); 7628 7629 synchronized(this) { 7630 // Make sure we have no pre-ready processes sitting around. 7631 7632 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7633 ResolveInfo ri = mContext.getPackageManager() 7634 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7635 STOCK_PM_FLAGS); 7636 CharSequence errorMsg = null; 7637 if (ri != null) { 7638 ActivityInfo ai = ri.activityInfo; 7639 ApplicationInfo app = ai.applicationInfo; 7640 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7641 mTopAction = Intent.ACTION_FACTORY_TEST; 7642 mTopData = null; 7643 mTopComponent = new ComponentName(app.packageName, 7644 ai.name); 7645 } else { 7646 errorMsg = mContext.getResources().getText( 7647 com.android.internal.R.string.factorytest_not_system); 7648 } 7649 } else { 7650 errorMsg = mContext.getResources().getText( 7651 com.android.internal.R.string.factorytest_no_action); 7652 } 7653 if (errorMsg != null) { 7654 mTopAction = null; 7655 mTopData = null; 7656 mTopComponent = null; 7657 Message msg = Message.obtain(); 7658 msg.what = SHOW_FACTORY_ERROR_MSG; 7659 msg.getData().putCharSequence("msg", errorMsg); 7660 mHandler.sendMessage(msg); 7661 } 7662 } 7663 } 7664 7665 retrieveSettings(); 7666 7667 if (goingCallback != null) goingCallback.run(); 7668 7669 synchronized (this) { 7670 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7671 try { 7672 List apps = AppGlobals.getPackageManager(). 7673 getPersistentApplications(STOCK_PM_FLAGS); 7674 if (apps != null) { 7675 int N = apps.size(); 7676 int i; 7677 for (i=0; i<N; i++) { 7678 ApplicationInfo info 7679 = (ApplicationInfo)apps.get(i); 7680 if (info != null && 7681 !info.packageName.equals("android")) { 7682 addAppLocked(info, false); 7683 } 7684 } 7685 } 7686 } catch (RemoteException ex) { 7687 // pm is in same process, this will never happen. 7688 } 7689 } 7690 7691 // Start up initial activity. 7692 mBooting = true; 7693 7694 try { 7695 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7696 Message msg = Message.obtain(); 7697 msg.what = SHOW_UID_ERROR_MSG; 7698 mHandler.sendMessage(msg); 7699 } 7700 } catch (RemoteException e) { 7701 } 7702 7703 mMainStack.resumeTopActivityLocked(null); 7704 } 7705 } 7706 7707 private boolean makeAppCrashingLocked(ProcessRecord app, 7708 String shortMsg, String longMsg, String stackTrace) { 7709 app.crashing = true; 7710 app.crashingReport = generateProcessError(app, 7711 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7712 startAppProblemLocked(app); 7713 app.stopFreezingAllLocked(); 7714 return handleAppCrashLocked(app); 7715 } 7716 7717 private void makeAppNotRespondingLocked(ProcessRecord app, 7718 String activity, String shortMsg, String longMsg) { 7719 app.notResponding = true; 7720 app.notRespondingReport = generateProcessError(app, 7721 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7722 activity, shortMsg, longMsg, null); 7723 startAppProblemLocked(app); 7724 app.stopFreezingAllLocked(); 7725 } 7726 7727 /** 7728 * Generate a process error record, suitable for attachment to a ProcessRecord. 7729 * 7730 * @param app The ProcessRecord in which the error occurred. 7731 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7732 * ActivityManager.AppErrorStateInfo 7733 * @param activity The activity associated with the crash, if known. 7734 * @param shortMsg Short message describing the crash. 7735 * @param longMsg Long message describing the crash. 7736 * @param stackTrace Full crash stack trace, may be null. 7737 * 7738 * @return Returns a fully-formed AppErrorStateInfo record. 7739 */ 7740 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7741 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7742 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7743 7744 report.condition = condition; 7745 report.processName = app.processName; 7746 report.pid = app.pid; 7747 report.uid = app.info.uid; 7748 report.tag = activity; 7749 report.shortMsg = shortMsg; 7750 report.longMsg = longMsg; 7751 report.stackTrace = stackTrace; 7752 7753 return report; 7754 } 7755 7756 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7757 synchronized (this) { 7758 app.crashing = false; 7759 app.crashingReport = null; 7760 app.notResponding = false; 7761 app.notRespondingReport = null; 7762 if (app.anrDialog == fromDialog) { 7763 app.anrDialog = null; 7764 } 7765 if (app.waitDialog == fromDialog) { 7766 app.waitDialog = null; 7767 } 7768 if (app.pid > 0 && app.pid != MY_PID) { 7769 handleAppCrashLocked(app); 7770 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7771 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7772 app.processName, app.setAdj, "user's request after error"); 7773 Process.killProcessQuiet(app.pid); 7774 } 7775 } 7776 } 7777 7778 private boolean handleAppCrashLocked(ProcessRecord app) { 7779 if (mHeadless) { 7780 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7781 return false; 7782 } 7783 long now = SystemClock.uptimeMillis(); 7784 7785 Long crashTime; 7786 if (!app.isolated) { 7787 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7788 } else { 7789 crashTime = null; 7790 } 7791 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7792 // This process loses! 7793 Slog.w(TAG, "Process " + app.info.processName 7794 + " has crashed too many times: killing!"); 7795 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7796 app.info.processName, app.uid); 7797 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7798 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7799 if (r.app == app) { 7800 Slog.w(TAG, " Force finishing activity " 7801 + r.intent.getComponent().flattenToShortString()); 7802 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7803 } 7804 } 7805 if (!app.persistent) { 7806 // We don't want to start this process again until the user 7807 // explicitly does so... but for persistent process, we really 7808 // need to keep it running. If a persistent process is actually 7809 // repeatedly crashing, then badness for everyone. 7810 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7811 app.info.processName); 7812 if (!app.isolated) { 7813 // XXX We don't have a way to mark isolated processes 7814 // as bad, since they don't have a peristent identity. 7815 mBadProcesses.put(app.info.processName, app.uid, now); 7816 mProcessCrashTimes.remove(app.info.processName, app.uid); 7817 } 7818 app.bad = true; 7819 app.removed = true; 7820 // Don't let services in this process be restarted and potentially 7821 // annoy the user repeatedly. Unless it is persistent, since those 7822 // processes run critical code. 7823 removeProcessLocked(app, false, false, "crash"); 7824 mMainStack.resumeTopActivityLocked(null); 7825 return false; 7826 } 7827 mMainStack.resumeTopActivityLocked(null); 7828 } else { 7829 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7830 if (r != null && r.app == app) { 7831 // If the top running activity is from this crashing 7832 // process, then terminate it to avoid getting in a loop. 7833 Slog.w(TAG, " Force finishing activity " 7834 + r.intent.getComponent().flattenToShortString()); 7835 int index = mMainStack.indexOfActivityLocked(r); 7836 r.stack.finishActivityLocked(r, index, 7837 Activity.RESULT_CANCELED, null, "crashed"); 7838 // Also terminate any activities below it that aren't yet 7839 // stopped, to avoid a situation where one will get 7840 // re-start our crashing activity once it gets resumed again. 7841 index--; 7842 if (index >= 0) { 7843 r = (ActivityRecord)mMainStack.mHistory.get(index); 7844 if (r.state == ActivityState.RESUMED 7845 || r.state == ActivityState.PAUSING 7846 || r.state == ActivityState.PAUSED) { 7847 if (!r.isHomeActivity || mHomeProcess != r.app) { 7848 Slog.w(TAG, " Force finishing activity " 7849 + r.intent.getComponent().flattenToShortString()); 7850 r.stack.finishActivityLocked(r, index, 7851 Activity.RESULT_CANCELED, null, "crashed"); 7852 } 7853 } 7854 } 7855 } 7856 } 7857 7858 // Bump up the crash count of any services currently running in the proc. 7859 if (app.services.size() != 0) { 7860 // Any services running in the application need to be placed 7861 // back in the pending list. 7862 Iterator<ServiceRecord> it = app.services.iterator(); 7863 while (it.hasNext()) { 7864 ServiceRecord sr = it.next(); 7865 sr.crashCount++; 7866 } 7867 } 7868 7869 // If the crashing process is what we consider to be the "home process" and it has been 7870 // replaced by a third-party app, clear the package preferred activities from packages 7871 // with a home activity running in the process to prevent a repeatedly crashing app 7872 // from blocking the user to manually clear the list. 7873 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7874 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7875 Iterator it = mHomeProcess.activities.iterator(); 7876 while (it.hasNext()) { 7877 ActivityRecord r = (ActivityRecord)it.next(); 7878 if (r.isHomeActivity) { 7879 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7880 try { 7881 ActivityThread.getPackageManager() 7882 .clearPackagePreferredActivities(r.packageName); 7883 } catch (RemoteException c) { 7884 // pm is in same process, this will never happen. 7885 } 7886 } 7887 } 7888 } 7889 7890 if (!app.isolated) { 7891 // XXX Can't keep track of crash times for isolated processes, 7892 // because they don't have a perisistent identity. 7893 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7894 } 7895 7896 return true; 7897 } 7898 7899 void startAppProblemLocked(ProcessRecord app) { 7900 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7901 mContext, app.info.packageName, app.info.flags); 7902 skipCurrentReceiverLocked(app); 7903 } 7904 7905 void skipCurrentReceiverLocked(ProcessRecord app) { 7906 for (BroadcastQueue queue : mBroadcastQueues) { 7907 queue.skipCurrentReceiverLocked(app); 7908 } 7909 } 7910 7911 /** 7912 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7913 * The application process will exit immediately after this call returns. 7914 * @param app object of the crashing app, null for the system server 7915 * @param crashInfo describing the exception 7916 */ 7917 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7918 ProcessRecord r = findAppProcess(app, "Crash"); 7919 final String processName = app == null ? "system_server" 7920 : (r == null ? "unknown" : r.processName); 7921 7922 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7923 processName, 7924 r == null ? -1 : r.info.flags, 7925 crashInfo.exceptionClassName, 7926 crashInfo.exceptionMessage, 7927 crashInfo.throwFileName, 7928 crashInfo.throwLineNumber); 7929 7930 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7931 7932 crashApplication(r, crashInfo); 7933 } 7934 7935 public void handleApplicationStrictModeViolation( 7936 IBinder app, 7937 int violationMask, 7938 StrictMode.ViolationInfo info) { 7939 ProcessRecord r = findAppProcess(app, "StrictMode"); 7940 if (r == null) { 7941 return; 7942 } 7943 7944 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7945 Integer stackFingerprint = info.hashCode(); 7946 boolean logIt = true; 7947 synchronized (mAlreadyLoggedViolatedStacks) { 7948 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7949 logIt = false; 7950 // TODO: sub-sample into EventLog for these, with 7951 // the info.durationMillis? Then we'd get 7952 // the relative pain numbers, without logging all 7953 // the stack traces repeatedly. We'd want to do 7954 // likewise in the client code, which also does 7955 // dup suppression, before the Binder call. 7956 } else { 7957 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7958 mAlreadyLoggedViolatedStacks.clear(); 7959 } 7960 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7961 } 7962 } 7963 if (logIt) { 7964 logStrictModeViolationToDropBox(r, info); 7965 } 7966 } 7967 7968 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7969 AppErrorResult result = new AppErrorResult(); 7970 synchronized (this) { 7971 final long origId = Binder.clearCallingIdentity(); 7972 7973 Message msg = Message.obtain(); 7974 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7975 HashMap<String, Object> data = new HashMap<String, Object>(); 7976 data.put("result", result); 7977 data.put("app", r); 7978 data.put("violationMask", violationMask); 7979 data.put("info", info); 7980 msg.obj = data; 7981 mHandler.sendMessage(msg); 7982 7983 Binder.restoreCallingIdentity(origId); 7984 } 7985 int res = result.get(); 7986 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7987 } 7988 } 7989 7990 // Depending on the policy in effect, there could be a bunch of 7991 // these in quick succession so we try to batch these together to 7992 // minimize disk writes, number of dropbox entries, and maximize 7993 // compression, by having more fewer, larger records. 7994 private void logStrictModeViolationToDropBox( 7995 ProcessRecord process, 7996 StrictMode.ViolationInfo info) { 7997 if (info == null) { 7998 return; 7999 } 8000 final boolean isSystemApp = process == null || 8001 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8002 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8003 final String processName = process == null ? "unknown" : process.processName; 8004 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8005 final DropBoxManager dbox = (DropBoxManager) 8006 mContext.getSystemService(Context.DROPBOX_SERVICE); 8007 8008 // Exit early if the dropbox isn't configured to accept this report type. 8009 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8010 8011 boolean bufferWasEmpty; 8012 boolean needsFlush; 8013 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8014 synchronized (sb) { 8015 bufferWasEmpty = sb.length() == 0; 8016 appendDropBoxProcessHeaders(process, processName, sb); 8017 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8018 sb.append("System-App: ").append(isSystemApp).append("\n"); 8019 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8020 if (info.violationNumThisLoop != 0) { 8021 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8022 } 8023 if (info.numAnimationsRunning != 0) { 8024 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8025 } 8026 if (info.broadcastIntentAction != null) { 8027 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8028 } 8029 if (info.durationMillis != -1) { 8030 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8031 } 8032 if (info.numInstances != -1) { 8033 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8034 } 8035 if (info.tags != null) { 8036 for (String tag : info.tags) { 8037 sb.append("Span-Tag: ").append(tag).append("\n"); 8038 } 8039 } 8040 sb.append("\n"); 8041 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8042 sb.append(info.crashInfo.stackTrace); 8043 } 8044 sb.append("\n"); 8045 8046 // Only buffer up to ~64k. Various logging bits truncate 8047 // things at 128k. 8048 needsFlush = (sb.length() > 64 * 1024); 8049 } 8050 8051 // Flush immediately if the buffer's grown too large, or this 8052 // is a non-system app. Non-system apps are isolated with a 8053 // different tag & policy and not batched. 8054 // 8055 // Batching is useful during internal testing with 8056 // StrictMode settings turned up high. Without batching, 8057 // thousands of separate files could be created on boot. 8058 if (!isSystemApp || needsFlush) { 8059 new Thread("Error dump: " + dropboxTag) { 8060 @Override 8061 public void run() { 8062 String report; 8063 synchronized (sb) { 8064 report = sb.toString(); 8065 sb.delete(0, sb.length()); 8066 sb.trimToSize(); 8067 } 8068 if (report.length() != 0) { 8069 dbox.addText(dropboxTag, report); 8070 } 8071 } 8072 }.start(); 8073 return; 8074 } 8075 8076 // System app batching: 8077 if (!bufferWasEmpty) { 8078 // An existing dropbox-writing thread is outstanding, so 8079 // we don't need to start it up. The existing thread will 8080 // catch the buffer appends we just did. 8081 return; 8082 } 8083 8084 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8085 // (After this point, we shouldn't access AMS internal data structures.) 8086 new Thread("Error dump: " + dropboxTag) { 8087 @Override 8088 public void run() { 8089 // 5 second sleep to let stacks arrive and be batched together 8090 try { 8091 Thread.sleep(5000); // 5 seconds 8092 } catch (InterruptedException e) {} 8093 8094 String errorReport; 8095 synchronized (mStrictModeBuffer) { 8096 errorReport = mStrictModeBuffer.toString(); 8097 if (errorReport.length() == 0) { 8098 return; 8099 } 8100 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8101 mStrictModeBuffer.trimToSize(); 8102 } 8103 dbox.addText(dropboxTag, errorReport); 8104 } 8105 }.start(); 8106 } 8107 8108 /** 8109 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8110 * @param app object of the crashing app, null for the system server 8111 * @param tag reported by the caller 8112 * @param crashInfo describing the context of the error 8113 * @return true if the process should exit immediately (WTF is fatal) 8114 */ 8115 public boolean handleApplicationWtf(IBinder app, String tag, 8116 ApplicationErrorReport.CrashInfo crashInfo) { 8117 ProcessRecord r = findAppProcess(app, "WTF"); 8118 final String processName = app == null ? "system_server" 8119 : (r == null ? "unknown" : r.processName); 8120 8121 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8122 processName, 8123 r == null ? -1 : r.info.flags, 8124 tag, crashInfo.exceptionMessage); 8125 8126 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8127 8128 if (r != null && r.pid != Process.myPid() && 8129 Settings.Secure.getInt(mContext.getContentResolver(), 8130 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8131 crashApplication(r, crashInfo); 8132 return true; 8133 } else { 8134 return false; 8135 } 8136 } 8137 8138 /** 8139 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8140 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8141 */ 8142 private ProcessRecord findAppProcess(IBinder app, String reason) { 8143 if (app == null) { 8144 return null; 8145 } 8146 8147 synchronized (this) { 8148 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8149 final int NA = apps.size(); 8150 for (int ia=0; ia<NA; ia++) { 8151 ProcessRecord p = apps.valueAt(ia); 8152 if (p.thread != null && p.thread.asBinder() == app) { 8153 return p; 8154 } 8155 } 8156 } 8157 8158 Slog.w(TAG, "Can't find mystery application for " + reason 8159 + " from pid=" + Binder.getCallingPid() 8160 + " uid=" + Binder.getCallingUid() + ": " + app); 8161 return null; 8162 } 8163 } 8164 8165 /** 8166 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8167 * to append various headers to the dropbox log text. 8168 */ 8169 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8170 StringBuilder sb) { 8171 // Watchdog thread ends up invoking this function (with 8172 // a null ProcessRecord) to add the stack file to dropbox. 8173 // Do not acquire a lock on this (am) in such cases, as it 8174 // could cause a potential deadlock, if and when watchdog 8175 // is invoked due to unavailability of lock on am and it 8176 // would prevent watchdog from killing system_server. 8177 if (process == null) { 8178 sb.append("Process: ").append(processName).append("\n"); 8179 return; 8180 } 8181 // Note: ProcessRecord 'process' is guarded by the service 8182 // instance. (notably process.pkgList, which could otherwise change 8183 // concurrently during execution of this method) 8184 synchronized (this) { 8185 sb.append("Process: ").append(processName).append("\n"); 8186 int flags = process.info.flags; 8187 IPackageManager pm = AppGlobals.getPackageManager(); 8188 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8189 for (String pkg : process.pkgList) { 8190 sb.append("Package: ").append(pkg); 8191 try { 8192 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8193 if (pi != null) { 8194 sb.append(" v").append(pi.versionCode); 8195 if (pi.versionName != null) { 8196 sb.append(" (").append(pi.versionName).append(")"); 8197 } 8198 } 8199 } catch (RemoteException e) { 8200 Slog.e(TAG, "Error getting package info: " + pkg, e); 8201 } 8202 sb.append("\n"); 8203 } 8204 } 8205 } 8206 8207 private static String processClass(ProcessRecord process) { 8208 if (process == null || process.pid == MY_PID) { 8209 return "system_server"; 8210 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8211 return "system_app"; 8212 } else { 8213 return "data_app"; 8214 } 8215 } 8216 8217 /** 8218 * Write a description of an error (crash, WTF, ANR) to the drop box. 8219 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8220 * @param process which caused the error, null means the system server 8221 * @param activity which triggered the error, null if unknown 8222 * @param parent activity related to the error, null if unknown 8223 * @param subject line related to the error, null if absent 8224 * @param report in long form describing the error, null if absent 8225 * @param logFile to include in the report, null if none 8226 * @param crashInfo giving an application stack trace, null if absent 8227 */ 8228 public void addErrorToDropBox(String eventType, 8229 ProcessRecord process, String processName, ActivityRecord activity, 8230 ActivityRecord parent, String subject, 8231 final String report, final File logFile, 8232 final ApplicationErrorReport.CrashInfo crashInfo) { 8233 // NOTE -- this must never acquire the ActivityManagerService lock, 8234 // otherwise the watchdog may be prevented from resetting the system. 8235 8236 final String dropboxTag = processClass(process) + "_" + eventType; 8237 final DropBoxManager dbox = (DropBoxManager) 8238 mContext.getSystemService(Context.DROPBOX_SERVICE); 8239 8240 // Exit early if the dropbox isn't configured to accept this report type. 8241 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8242 8243 final StringBuilder sb = new StringBuilder(1024); 8244 appendDropBoxProcessHeaders(process, processName, sb); 8245 if (activity != null) { 8246 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8247 } 8248 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8249 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8250 } 8251 if (parent != null && parent != activity) { 8252 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8253 } 8254 if (subject != null) { 8255 sb.append("Subject: ").append(subject).append("\n"); 8256 } 8257 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8258 if (Debug.isDebuggerConnected()) { 8259 sb.append("Debugger: Connected\n"); 8260 } 8261 sb.append("\n"); 8262 8263 // Do the rest in a worker thread to avoid blocking the caller on I/O 8264 // (After this point, we shouldn't access AMS internal data structures.) 8265 Thread worker = new Thread("Error dump: " + dropboxTag) { 8266 @Override 8267 public void run() { 8268 if (report != null) { 8269 sb.append(report); 8270 } 8271 if (logFile != null) { 8272 try { 8273 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8274 } catch (IOException e) { 8275 Slog.e(TAG, "Error reading " + logFile, e); 8276 } 8277 } 8278 if (crashInfo != null && crashInfo.stackTrace != null) { 8279 sb.append(crashInfo.stackTrace); 8280 } 8281 8282 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8283 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8284 if (lines > 0) { 8285 sb.append("\n"); 8286 8287 // Merge several logcat streams, and take the last N lines 8288 InputStreamReader input = null; 8289 try { 8290 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8291 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8292 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8293 8294 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8295 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8296 input = new InputStreamReader(logcat.getInputStream()); 8297 8298 int num; 8299 char[] buf = new char[8192]; 8300 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8301 } catch (IOException e) { 8302 Slog.e(TAG, "Error running logcat", e); 8303 } finally { 8304 if (input != null) try { input.close(); } catch (IOException e) {} 8305 } 8306 } 8307 8308 dbox.addText(dropboxTag, sb.toString()); 8309 } 8310 }; 8311 8312 if (process == null) { 8313 // If process is null, we are being called from some internal code 8314 // and may be about to die -- run this synchronously. 8315 worker.run(); 8316 } else { 8317 worker.start(); 8318 } 8319 } 8320 8321 /** 8322 * Bring up the "unexpected error" dialog box for a crashing app. 8323 * Deal with edge cases (intercepts from instrumented applications, 8324 * ActivityController, error intent receivers, that sort of thing). 8325 * @param r the application crashing 8326 * @param crashInfo describing the failure 8327 */ 8328 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8329 long timeMillis = System.currentTimeMillis(); 8330 String shortMsg = crashInfo.exceptionClassName; 8331 String longMsg = crashInfo.exceptionMessage; 8332 String stackTrace = crashInfo.stackTrace; 8333 if (shortMsg != null && longMsg != null) { 8334 longMsg = shortMsg + ": " + longMsg; 8335 } else if (shortMsg != null) { 8336 longMsg = shortMsg; 8337 } 8338 8339 AppErrorResult result = new AppErrorResult(); 8340 synchronized (this) { 8341 if (mController != null) { 8342 try { 8343 String name = r != null ? r.processName : null; 8344 int pid = r != null ? r.pid : Binder.getCallingPid(); 8345 if (!mController.appCrashed(name, pid, 8346 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8347 Slog.w(TAG, "Force-killing crashed app " + name 8348 + " at watcher's request"); 8349 Process.killProcess(pid); 8350 return; 8351 } 8352 } catch (RemoteException e) { 8353 mController = null; 8354 } 8355 } 8356 8357 final long origId = Binder.clearCallingIdentity(); 8358 8359 // If this process is running instrumentation, finish it. 8360 if (r != null && r.instrumentationClass != null) { 8361 Slog.w(TAG, "Error in app " + r.processName 8362 + " running instrumentation " + r.instrumentationClass + ":"); 8363 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8364 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8365 Bundle info = new Bundle(); 8366 info.putString("shortMsg", shortMsg); 8367 info.putString("longMsg", longMsg); 8368 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8369 Binder.restoreCallingIdentity(origId); 8370 return; 8371 } 8372 8373 // If we can't identify the process or it's already exceeded its crash quota, 8374 // quit right away without showing a crash dialog. 8375 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8376 Binder.restoreCallingIdentity(origId); 8377 return; 8378 } 8379 8380 Message msg = Message.obtain(); 8381 msg.what = SHOW_ERROR_MSG; 8382 HashMap data = new HashMap(); 8383 data.put("result", result); 8384 data.put("app", r); 8385 msg.obj = data; 8386 mHandler.sendMessage(msg); 8387 8388 Binder.restoreCallingIdentity(origId); 8389 } 8390 8391 int res = result.get(); 8392 8393 Intent appErrorIntent = null; 8394 synchronized (this) { 8395 if (r != null && !r.isolated) { 8396 // XXX Can't keep track of crash time for isolated processes, 8397 // since they don't have a persistent identity. 8398 mProcessCrashTimes.put(r.info.processName, r.uid, 8399 SystemClock.uptimeMillis()); 8400 } 8401 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8402 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8403 } 8404 } 8405 8406 if (appErrorIntent != null) { 8407 try { 8408 mContext.startActivity(appErrorIntent); 8409 } catch (ActivityNotFoundException e) { 8410 Slog.w(TAG, "bug report receiver dissappeared", e); 8411 } 8412 } 8413 } 8414 8415 Intent createAppErrorIntentLocked(ProcessRecord r, 8416 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8417 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8418 if (report == null) { 8419 return null; 8420 } 8421 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8422 result.setComponent(r.errorReportReceiver); 8423 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8424 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8425 return result; 8426 } 8427 8428 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8429 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8430 if (r.errorReportReceiver == null) { 8431 return null; 8432 } 8433 8434 if (!r.crashing && !r.notResponding) { 8435 return null; 8436 } 8437 8438 ApplicationErrorReport report = new ApplicationErrorReport(); 8439 report.packageName = r.info.packageName; 8440 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8441 report.processName = r.processName; 8442 report.time = timeMillis; 8443 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8444 8445 if (r.crashing) { 8446 report.type = ApplicationErrorReport.TYPE_CRASH; 8447 report.crashInfo = crashInfo; 8448 } else if (r.notResponding) { 8449 report.type = ApplicationErrorReport.TYPE_ANR; 8450 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8451 8452 report.anrInfo.activity = r.notRespondingReport.tag; 8453 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8454 report.anrInfo.info = r.notRespondingReport.longMsg; 8455 } 8456 8457 return report; 8458 } 8459 8460 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8461 enforceNotIsolatedCaller("getProcessesInErrorState"); 8462 // assume our apps are happy - lazy create the list 8463 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8464 8465 final boolean allUsers = ActivityManager.checkUidPermission( 8466 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8467 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8468 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8469 8470 synchronized (this) { 8471 8472 // iterate across all processes 8473 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8474 ProcessRecord app = mLruProcesses.get(i); 8475 if (!allUsers && app.userId != userId) { 8476 continue; 8477 } 8478 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8479 // This one's in trouble, so we'll generate a report for it 8480 // crashes are higher priority (in case there's a crash *and* an anr) 8481 ActivityManager.ProcessErrorStateInfo report = null; 8482 if (app.crashing) { 8483 report = app.crashingReport; 8484 } else if (app.notResponding) { 8485 report = app.notRespondingReport; 8486 } 8487 8488 if (report != null) { 8489 if (errList == null) { 8490 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8491 } 8492 errList.add(report); 8493 } else { 8494 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8495 " crashing = " + app.crashing + 8496 " notResponding = " + app.notResponding); 8497 } 8498 } 8499 } 8500 } 8501 8502 return errList; 8503 } 8504 8505 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8506 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8507 if (currApp != null) { 8508 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8509 } 8510 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8511 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8512 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8513 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8514 if (currApp != null) { 8515 currApp.lru = 0; 8516 } 8517 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8518 } else if (adj >= ProcessList.SERVICE_ADJ) { 8519 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8520 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8521 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8522 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8523 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8524 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8525 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8526 } else { 8527 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8528 } 8529 } 8530 8531 private void fillInProcMemInfo(ProcessRecord app, 8532 ActivityManager.RunningAppProcessInfo outInfo) { 8533 outInfo.pid = app.pid; 8534 outInfo.uid = app.info.uid; 8535 if (mHeavyWeightProcess == app) { 8536 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8537 } 8538 if (app.persistent) { 8539 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8540 } 8541 if (app.hasActivities) { 8542 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8543 } 8544 outInfo.lastTrimLevel = app.trimMemoryLevel; 8545 int adj = app.curAdj; 8546 outInfo.importance = oomAdjToImportance(adj, outInfo); 8547 outInfo.importanceReasonCode = app.adjTypeCode; 8548 } 8549 8550 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8551 enforceNotIsolatedCaller("getRunningAppProcesses"); 8552 // Lazy instantiation of list 8553 List<ActivityManager.RunningAppProcessInfo> runList = null; 8554 final boolean allUsers = ActivityManager.checkUidPermission( 8555 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8556 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8557 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8558 synchronized (this) { 8559 // Iterate across all processes 8560 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8561 ProcessRecord app = mLruProcesses.get(i); 8562 if (!allUsers && app.userId != userId) { 8563 continue; 8564 } 8565 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8566 // Generate process state info for running application 8567 ActivityManager.RunningAppProcessInfo currApp = 8568 new ActivityManager.RunningAppProcessInfo(app.processName, 8569 app.pid, app.getPackageList()); 8570 fillInProcMemInfo(app, currApp); 8571 if (app.adjSource instanceof ProcessRecord) { 8572 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8573 currApp.importanceReasonImportance = oomAdjToImportance( 8574 app.adjSourceOom, null); 8575 } else if (app.adjSource instanceof ActivityRecord) { 8576 ActivityRecord r = (ActivityRecord)app.adjSource; 8577 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8578 } 8579 if (app.adjTarget instanceof ComponentName) { 8580 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8581 } 8582 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8583 // + " lru=" + currApp.lru); 8584 if (runList == null) { 8585 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8586 } 8587 runList.add(currApp); 8588 } 8589 } 8590 } 8591 return runList; 8592 } 8593 8594 public List<ApplicationInfo> getRunningExternalApplications() { 8595 enforceNotIsolatedCaller("getRunningExternalApplications"); 8596 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8597 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8598 if (runningApps != null && runningApps.size() > 0) { 8599 Set<String> extList = new HashSet<String>(); 8600 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8601 if (app.pkgList != null) { 8602 for (String pkg : app.pkgList) { 8603 extList.add(pkg); 8604 } 8605 } 8606 } 8607 IPackageManager pm = AppGlobals.getPackageManager(); 8608 for (String pkg : extList) { 8609 try { 8610 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8611 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8612 retList.add(info); 8613 } 8614 } catch (RemoteException e) { 8615 } 8616 } 8617 } 8618 return retList; 8619 } 8620 8621 @Override 8622 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8623 enforceNotIsolatedCaller("getMyMemoryState"); 8624 synchronized (this) { 8625 ProcessRecord proc; 8626 synchronized (mPidsSelfLocked) { 8627 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8628 } 8629 fillInProcMemInfo(proc, outInfo); 8630 } 8631 } 8632 8633 @Override 8634 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8635 if (checkCallingPermission(android.Manifest.permission.DUMP) 8636 != PackageManager.PERMISSION_GRANTED) { 8637 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8638 + Binder.getCallingPid() 8639 + ", uid=" + Binder.getCallingUid() 8640 + " without permission " 8641 + android.Manifest.permission.DUMP); 8642 return; 8643 } 8644 8645 boolean dumpAll = false; 8646 boolean dumpClient = false; 8647 String dumpPackage = null; 8648 8649 int opti = 0; 8650 while (opti < args.length) { 8651 String opt = args[opti]; 8652 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8653 break; 8654 } 8655 opti++; 8656 if ("-a".equals(opt)) { 8657 dumpAll = true; 8658 } else if ("-c".equals(opt)) { 8659 dumpClient = true; 8660 } else if ("-h".equals(opt)) { 8661 pw.println("Activity manager dump options:"); 8662 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8663 pw.println(" cmd may be one of:"); 8664 pw.println(" a[ctivities]: activity stack state"); 8665 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8666 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8667 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8668 pw.println(" o[om]: out of memory management"); 8669 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8670 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8671 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8672 pw.println(" service [COMP_SPEC]: service client-side state"); 8673 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8674 pw.println(" all: dump all activities"); 8675 pw.println(" top: dump the top activity"); 8676 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8677 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8678 pw.println(" a partial substring in a component name, a"); 8679 pw.println(" hex object identifier."); 8680 pw.println(" -a: include all available server state."); 8681 pw.println(" -c: include client state."); 8682 return; 8683 } else { 8684 pw.println("Unknown argument: " + opt + "; use -h for help"); 8685 } 8686 } 8687 8688 long origId = Binder.clearCallingIdentity(); 8689 boolean more = false; 8690 // Is the caller requesting to dump a particular piece of data? 8691 if (opti < args.length) { 8692 String cmd = args[opti]; 8693 opti++; 8694 if ("activities".equals(cmd) || "a".equals(cmd)) { 8695 synchronized (this) { 8696 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8697 } 8698 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8699 String[] newArgs; 8700 String name; 8701 if (opti >= args.length) { 8702 name = null; 8703 newArgs = EMPTY_STRING_ARRAY; 8704 } else { 8705 name = args[opti]; 8706 opti++; 8707 newArgs = new String[args.length - opti]; 8708 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8709 args.length - opti); 8710 } 8711 synchronized (this) { 8712 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8713 } 8714 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8715 String[] newArgs; 8716 String name; 8717 if (opti >= args.length) { 8718 name = null; 8719 newArgs = EMPTY_STRING_ARRAY; 8720 } else { 8721 name = args[opti]; 8722 opti++; 8723 newArgs = new String[args.length - opti]; 8724 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8725 args.length - opti); 8726 } 8727 synchronized (this) { 8728 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8729 } 8730 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8731 String[] newArgs; 8732 String name; 8733 if (opti >= args.length) { 8734 name = null; 8735 newArgs = EMPTY_STRING_ARRAY; 8736 } else { 8737 name = args[opti]; 8738 opti++; 8739 newArgs = new String[args.length - opti]; 8740 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8741 args.length - opti); 8742 } 8743 synchronized (this) { 8744 dumpProcessesLocked(fd, pw, args, opti, true, name); 8745 } 8746 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8747 synchronized (this) { 8748 dumpOomLocked(fd, pw, args, opti, true); 8749 } 8750 } else if ("provider".equals(cmd)) { 8751 String[] newArgs; 8752 String name; 8753 if (opti >= args.length) { 8754 name = null; 8755 newArgs = EMPTY_STRING_ARRAY; 8756 } else { 8757 name = args[opti]; 8758 opti++; 8759 newArgs = new String[args.length - opti]; 8760 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8761 } 8762 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8763 pw.println("No providers match: " + name); 8764 pw.println("Use -h for help."); 8765 } 8766 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8767 synchronized (this) { 8768 dumpProvidersLocked(fd, pw, args, opti, true, null); 8769 } 8770 } else if ("service".equals(cmd)) { 8771 String[] newArgs; 8772 String name; 8773 if (opti >= args.length) { 8774 name = null; 8775 newArgs = EMPTY_STRING_ARRAY; 8776 } else { 8777 name = args[opti]; 8778 opti++; 8779 newArgs = new String[args.length - opti]; 8780 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8781 args.length - opti); 8782 } 8783 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8784 pw.println("No services match: " + name); 8785 pw.println("Use -h for help."); 8786 } 8787 } else if ("package".equals(cmd)) { 8788 String[] newArgs; 8789 if (opti >= args.length) { 8790 pw.println("package: no package name specified"); 8791 pw.println("Use -h for help."); 8792 } else { 8793 dumpPackage = args[opti]; 8794 opti++; 8795 newArgs = new String[args.length - opti]; 8796 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8797 args.length - opti); 8798 args = newArgs; 8799 opti = 0; 8800 more = true; 8801 } 8802 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8803 synchronized (this) { 8804 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8805 } 8806 } else { 8807 // Dumping a single activity? 8808 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8809 pw.println("Bad activity command, or no activities match: " + cmd); 8810 pw.println("Use -h for help."); 8811 } 8812 } 8813 if (!more) { 8814 Binder.restoreCallingIdentity(origId); 8815 return; 8816 } 8817 } 8818 8819 // No piece of data specified, dump everything. 8820 synchronized (this) { 8821 boolean needSep; 8822 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8823 if (needSep) { 8824 pw.println(" "); 8825 } 8826 if (dumpAll) { 8827 pw.println("-------------------------------------------------------------------------------"); 8828 } 8829 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8830 if (needSep) { 8831 pw.println(" "); 8832 } 8833 if (dumpAll) { 8834 pw.println("-------------------------------------------------------------------------------"); 8835 } 8836 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8837 if (needSep) { 8838 pw.println(" "); 8839 } 8840 if (dumpAll) { 8841 pw.println("-------------------------------------------------------------------------------"); 8842 } 8843 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8844 if (needSep) { 8845 pw.println(" "); 8846 } 8847 if (dumpAll) { 8848 pw.println("-------------------------------------------------------------------------------"); 8849 } 8850 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8851 if (needSep) { 8852 pw.println(" "); 8853 } 8854 if (dumpAll) { 8855 pw.println("-------------------------------------------------------------------------------"); 8856 } 8857 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8858 } 8859 Binder.restoreCallingIdentity(origId); 8860 } 8861 8862 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8863 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8864 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8865 pw.println(" Main stack:"); 8866 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8867 dumpPackage); 8868 pw.println(" "); 8869 pw.println(" Running activities (most recent first):"); 8870 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8871 dumpPackage); 8872 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8873 pw.println(" "); 8874 pw.println(" Activities waiting for another to become visible:"); 8875 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8876 !dumpAll, false, dumpPackage); 8877 } 8878 if (mMainStack.mStoppingActivities.size() > 0) { 8879 pw.println(" "); 8880 pw.println(" Activities waiting to stop:"); 8881 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8882 !dumpAll, false, dumpPackage); 8883 } 8884 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8885 pw.println(" "); 8886 pw.println(" Activities waiting to sleep:"); 8887 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8888 !dumpAll, false, dumpPackage); 8889 } 8890 if (mMainStack.mFinishingActivities.size() > 0) { 8891 pw.println(" "); 8892 pw.println(" Activities waiting to finish:"); 8893 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8894 !dumpAll, false, dumpPackage); 8895 } 8896 8897 pw.println(" "); 8898 if (mMainStack.mPausingActivity != null) { 8899 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8900 } 8901 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8902 pw.println(" mFocusedActivity: " + mFocusedActivity); 8903 if (dumpAll) { 8904 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8905 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8906 pw.println(" mDismissKeyguardOnNextActivity: " 8907 + mMainStack.mDismissKeyguardOnNextActivity); 8908 } 8909 8910 if (mRecentTasks.size() > 0) { 8911 pw.println(); 8912 pw.println(" Recent tasks:"); 8913 8914 final int N = mRecentTasks.size(); 8915 for (int i=0; i<N; i++) { 8916 TaskRecord tr = mRecentTasks.get(i); 8917 if (dumpPackage != null) { 8918 if (tr.realActivity == null || 8919 !dumpPackage.equals(tr.realActivity)) { 8920 continue; 8921 } 8922 } 8923 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8924 pw.println(tr); 8925 if (dumpAll) { 8926 mRecentTasks.get(i).dump(pw, " "); 8927 } 8928 } 8929 } 8930 8931 if (dumpAll) { 8932 pw.println(" "); 8933 pw.println(" mCurTask: " + mCurTask); 8934 } 8935 8936 return true; 8937 } 8938 8939 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8940 int opti, boolean dumpAll, String dumpPackage) { 8941 boolean needSep = false; 8942 int numPers = 0; 8943 8944 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8945 8946 if (dumpAll) { 8947 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8948 final int NA = procs.size(); 8949 for (int ia=0; ia<NA; ia++) { 8950 ProcessRecord r = procs.valueAt(ia); 8951 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8952 continue; 8953 } 8954 if (!needSep) { 8955 pw.println(" All known processes:"); 8956 needSep = true; 8957 } 8958 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8959 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8960 pw.print(" "); pw.println(r); 8961 r.dump(pw, " "); 8962 if (r.persistent) { 8963 numPers++; 8964 } 8965 } 8966 } 8967 } 8968 8969 if (mIsolatedProcesses.size() > 0) { 8970 if (needSep) pw.println(" "); 8971 needSep = true; 8972 pw.println(" Isolated process list (sorted by uid):"); 8973 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8974 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8975 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8976 continue; 8977 } 8978 pw.println(String.format("%sIsolated #%2d: %s", 8979 " ", i, r.toString())); 8980 } 8981 } 8982 8983 if (mLruProcesses.size() > 0) { 8984 if (needSep) pw.println(" "); 8985 needSep = true; 8986 pw.println(" Process LRU list (sorted by oom_adj):"); 8987 dumpProcessOomList(pw, this, mLruProcesses, " ", 8988 "Proc", "PERS", false, dumpPackage); 8989 needSep = true; 8990 } 8991 8992 if (dumpAll) { 8993 synchronized (mPidsSelfLocked) { 8994 boolean printed = false; 8995 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8996 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8997 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8998 continue; 8999 } 9000 if (!printed) { 9001 if (needSep) pw.println(" "); 9002 needSep = true; 9003 pw.println(" PID mappings:"); 9004 printed = true; 9005 } 9006 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9007 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9008 } 9009 } 9010 } 9011 9012 if (mForegroundProcesses.size() > 0) { 9013 synchronized (mPidsSelfLocked) { 9014 boolean printed = false; 9015 for (int i=0; i<mForegroundProcesses.size(); i++) { 9016 ProcessRecord r = mPidsSelfLocked.get( 9017 mForegroundProcesses.valueAt(i).pid); 9018 if (dumpPackage != null && (r == null 9019 || !dumpPackage.equals(r.info.packageName))) { 9020 continue; 9021 } 9022 if (!printed) { 9023 if (needSep) pw.println(" "); 9024 needSep = true; 9025 pw.println(" Foreground Processes:"); 9026 printed = true; 9027 } 9028 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9029 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9030 } 9031 } 9032 } 9033 9034 if (mPersistentStartingProcesses.size() > 0) { 9035 if (needSep) pw.println(" "); 9036 needSep = true; 9037 pw.println(" Persisent processes that are starting:"); 9038 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9039 "Starting Norm", "Restarting PERS", dumpPackage); 9040 } 9041 9042 if (mRemovedProcesses.size() > 0) { 9043 if (needSep) pw.println(" "); 9044 needSep = true; 9045 pw.println(" Processes that are being removed:"); 9046 dumpProcessList(pw, this, mRemovedProcesses, " ", 9047 "Removed Norm", "Removed PERS", dumpPackage); 9048 } 9049 9050 if (mProcessesOnHold.size() > 0) { 9051 if (needSep) pw.println(" "); 9052 needSep = true; 9053 pw.println(" Processes that are on old until the system is ready:"); 9054 dumpProcessList(pw, this, mProcessesOnHold, " ", 9055 "OnHold Norm", "OnHold PERS", dumpPackage); 9056 } 9057 9058 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9059 9060 if (mProcessCrashTimes.getMap().size() > 0) { 9061 boolean printed = false; 9062 long now = SystemClock.uptimeMillis(); 9063 for (Map.Entry<String, SparseArray<Long>> procs 9064 : mProcessCrashTimes.getMap().entrySet()) { 9065 String pname = procs.getKey(); 9066 SparseArray<Long> uids = procs.getValue(); 9067 final int N = uids.size(); 9068 for (int i=0; i<N; i++) { 9069 int puid = uids.keyAt(i); 9070 ProcessRecord r = mProcessNames.get(pname, puid); 9071 if (dumpPackage != null && (r == null 9072 || !dumpPackage.equals(r.info.packageName))) { 9073 continue; 9074 } 9075 if (!printed) { 9076 if (needSep) pw.println(" "); 9077 needSep = true; 9078 pw.println(" Time since processes crashed:"); 9079 printed = true; 9080 } 9081 pw.print(" Process "); pw.print(pname); 9082 pw.print(" uid "); pw.print(puid); 9083 pw.print(": last crashed "); 9084 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9085 pw.println(" ago"); 9086 } 9087 } 9088 } 9089 9090 if (mBadProcesses.getMap().size() > 0) { 9091 boolean printed = false; 9092 for (Map.Entry<String, SparseArray<Long>> procs 9093 : mBadProcesses.getMap().entrySet()) { 9094 String pname = procs.getKey(); 9095 SparseArray<Long> uids = procs.getValue(); 9096 final int N = uids.size(); 9097 for (int i=0; i<N; i++) { 9098 int puid = uids.keyAt(i); 9099 ProcessRecord r = mProcessNames.get(pname, puid); 9100 if (dumpPackage != null && (r == null 9101 || !dumpPackage.equals(r.info.packageName))) { 9102 continue; 9103 } 9104 if (!printed) { 9105 if (needSep) pw.println(" "); 9106 needSep = true; 9107 pw.println(" Bad processes:"); 9108 } 9109 pw.print(" Bad process "); pw.print(pname); 9110 pw.print(" uid "); pw.print(puid); 9111 pw.print(": crashed at time "); 9112 pw.println(uids.valueAt(i)); 9113 } 9114 } 9115 } 9116 9117 pw.println(); 9118 pw.println(" mStartedUsers:"); 9119 for (int i=0; i<mStartedUsers.size(); i++) { 9120 UserStartedState uss = mStartedUsers.valueAt(i); 9121 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9122 pw.println(":"); 9123 uss.dump(" ", pw); 9124 } 9125 pw.println(" mHomeProcess: " + mHomeProcess); 9126 pw.println(" mPreviousProcess: " + mPreviousProcess); 9127 if (dumpAll) { 9128 StringBuilder sb = new StringBuilder(128); 9129 sb.append(" mPreviousProcessVisibleTime: "); 9130 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9131 pw.println(sb); 9132 } 9133 if (mHeavyWeightProcess != null) { 9134 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9135 } 9136 pw.println(" mConfiguration: " + mConfiguration); 9137 if (dumpAll) { 9138 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9139 if (mCompatModePackages.getPackages().size() > 0) { 9140 boolean printed = false; 9141 for (Map.Entry<String, Integer> entry 9142 : mCompatModePackages.getPackages().entrySet()) { 9143 String pkg = entry.getKey(); 9144 int mode = entry.getValue(); 9145 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9146 continue; 9147 } 9148 if (!printed) { 9149 pw.println(" mScreenCompatPackages:"); 9150 printed = true; 9151 } 9152 pw.print(" "); pw.print(pkg); pw.print(": "); 9153 pw.print(mode); pw.println(); 9154 } 9155 } 9156 } 9157 if (mSleeping || mWentToSleep || mLockScreenShown) { 9158 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9159 + " mLockScreenShown " + mLockScreenShown); 9160 } 9161 if (mShuttingDown) { 9162 pw.println(" mShuttingDown=" + mShuttingDown); 9163 } 9164 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9165 || mOrigWaitForDebugger) { 9166 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9167 + " mDebugTransient=" + mDebugTransient 9168 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9169 } 9170 if (mOpenGlTraceApp != null) { 9171 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9172 } 9173 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9174 || mProfileFd != null) { 9175 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9176 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9177 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9178 + mAutoStopProfiler); 9179 } 9180 if (mAlwaysFinishActivities || mController != null) { 9181 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9182 + " mController=" + mController); 9183 } 9184 if (dumpAll) { 9185 pw.println(" Total persistent processes: " + numPers); 9186 pw.println(" mStartRunning=" + mStartRunning 9187 + " mProcessesReady=" + mProcessesReady 9188 + " mSystemReady=" + mSystemReady); 9189 pw.println(" mBooting=" + mBooting 9190 + " mBooted=" + mBooted 9191 + " mFactoryTest=" + mFactoryTest); 9192 pw.print(" mLastPowerCheckRealtime="); 9193 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9194 pw.println(""); 9195 pw.print(" mLastPowerCheckUptime="); 9196 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9197 pw.println(""); 9198 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9199 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9200 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9201 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9202 + " mNumHiddenProcs=" + mNumHiddenProcs 9203 + " mNumServiceProcs=" + mNumServiceProcs 9204 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9205 } 9206 9207 return true; 9208 } 9209 9210 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9211 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9212 if (mProcessesToGc.size() > 0) { 9213 boolean printed = false; 9214 long now = SystemClock.uptimeMillis(); 9215 for (int i=0; i<mProcessesToGc.size(); i++) { 9216 ProcessRecord proc = mProcessesToGc.get(i); 9217 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9218 continue; 9219 } 9220 if (!printed) { 9221 if (needSep) pw.println(" "); 9222 needSep = true; 9223 pw.println(" Processes that are waiting to GC:"); 9224 printed = true; 9225 } 9226 pw.print(" Process "); pw.println(proc); 9227 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9228 pw.print(", last gced="); 9229 pw.print(now-proc.lastRequestedGc); 9230 pw.print(" ms ago, last lowMem="); 9231 pw.print(now-proc.lastLowMemory); 9232 pw.println(" ms ago"); 9233 9234 } 9235 } 9236 return needSep; 9237 } 9238 9239 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9240 int opti, boolean dumpAll) { 9241 boolean needSep = false; 9242 9243 if (mLruProcesses.size() > 0) { 9244 if (needSep) pw.println(" "); 9245 needSep = true; 9246 pw.println(" OOM levels:"); 9247 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9248 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9249 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9250 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9251 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9252 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9253 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9254 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9255 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9256 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9257 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9258 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9259 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9260 9261 if (needSep) pw.println(" "); 9262 needSep = true; 9263 pw.println(" Process OOM control:"); 9264 dumpProcessOomList(pw, this, mLruProcesses, " ", 9265 "Proc", "PERS", true, null); 9266 needSep = true; 9267 } 9268 9269 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9270 9271 pw.println(); 9272 pw.println(" mHomeProcess: " + mHomeProcess); 9273 pw.println(" mPreviousProcess: " + mPreviousProcess); 9274 if (mHeavyWeightProcess != null) { 9275 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9276 } 9277 9278 return true; 9279 } 9280 9281 /** 9282 * There are three ways to call this: 9283 * - no provider specified: dump all the providers 9284 * - a flattened component name that matched an existing provider was specified as the 9285 * first arg: dump that one provider 9286 * - the first arg isn't the flattened component name of an existing provider: 9287 * dump all providers whose component contains the first arg as a substring 9288 */ 9289 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9290 int opti, boolean dumpAll) { 9291 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9292 } 9293 9294 static class ItemMatcher { 9295 ArrayList<ComponentName> components; 9296 ArrayList<String> strings; 9297 ArrayList<Integer> objects; 9298 boolean all; 9299 9300 ItemMatcher() { 9301 all = true; 9302 } 9303 9304 void build(String name) { 9305 ComponentName componentName = ComponentName.unflattenFromString(name); 9306 if (componentName != null) { 9307 if (components == null) { 9308 components = new ArrayList<ComponentName>(); 9309 } 9310 components.add(componentName); 9311 all = false; 9312 } else { 9313 int objectId = 0; 9314 // Not a '/' separated full component name; maybe an object ID? 9315 try { 9316 objectId = Integer.parseInt(name, 16); 9317 if (objects == null) { 9318 objects = new ArrayList<Integer>(); 9319 } 9320 objects.add(objectId); 9321 all = false; 9322 } catch (RuntimeException e) { 9323 // Not an integer; just do string match. 9324 if (strings == null) { 9325 strings = new ArrayList<String>(); 9326 } 9327 strings.add(name); 9328 all = false; 9329 } 9330 } 9331 } 9332 9333 int build(String[] args, int opti) { 9334 for (; opti<args.length; opti++) { 9335 String name = args[opti]; 9336 if ("--".equals(name)) { 9337 return opti+1; 9338 } 9339 build(name); 9340 } 9341 return opti; 9342 } 9343 9344 boolean match(Object object, ComponentName comp) { 9345 if (all) { 9346 return true; 9347 } 9348 if (components != null) { 9349 for (int i=0; i<components.size(); i++) { 9350 if (components.get(i).equals(comp)) { 9351 return true; 9352 } 9353 } 9354 } 9355 if (objects != null) { 9356 for (int i=0; i<objects.size(); i++) { 9357 if (System.identityHashCode(object) == objects.get(i)) { 9358 return true; 9359 } 9360 } 9361 } 9362 if (strings != null) { 9363 String flat = comp.flattenToString(); 9364 for (int i=0; i<strings.size(); i++) { 9365 if (flat.contains(strings.get(i))) { 9366 return true; 9367 } 9368 } 9369 } 9370 return false; 9371 } 9372 } 9373 9374 /** 9375 * There are three things that cmd can be: 9376 * - a flattened component name that matches an existing activity 9377 * - the cmd arg isn't the flattened component name of an existing activity: 9378 * dump all activity whose component contains the cmd as a substring 9379 * - A hex number of the ActivityRecord object instance. 9380 */ 9381 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9382 int opti, boolean dumpAll) { 9383 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9384 9385 if ("all".equals(name)) { 9386 synchronized (this) { 9387 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9388 activities.add(r1); 9389 } 9390 } 9391 } else if ("top".equals(name)) { 9392 synchronized (this) { 9393 final int N = mMainStack.mHistory.size(); 9394 if (N > 0) { 9395 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9396 } 9397 } 9398 } else { 9399 ItemMatcher matcher = new ItemMatcher(); 9400 matcher.build(name); 9401 9402 synchronized (this) { 9403 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9404 if (matcher.match(r1, r1.intent.getComponent())) { 9405 activities.add(r1); 9406 } 9407 } 9408 } 9409 } 9410 9411 if (activities.size() <= 0) { 9412 return false; 9413 } 9414 9415 String[] newArgs = new String[args.length - opti]; 9416 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9417 9418 TaskRecord lastTask = null; 9419 boolean needSep = false; 9420 for (int i=activities.size()-1; i>=0; i--) { 9421 ActivityRecord r = (ActivityRecord)activities.get(i); 9422 if (needSep) { 9423 pw.println(); 9424 } 9425 needSep = true; 9426 synchronized (this) { 9427 if (lastTask != r.task) { 9428 lastTask = r.task; 9429 pw.print("TASK "); pw.print(lastTask.affinity); 9430 pw.print(" id="); pw.println(lastTask.taskId); 9431 if (dumpAll) { 9432 lastTask.dump(pw, " "); 9433 } 9434 } 9435 } 9436 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9437 } 9438 return true; 9439 } 9440 9441 /** 9442 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9443 * there is a thread associated with the activity. 9444 */ 9445 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9446 final ActivityRecord r, String[] args, boolean dumpAll) { 9447 String innerPrefix = prefix + " "; 9448 synchronized (this) { 9449 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9450 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9451 pw.print(" pid="); 9452 if (r.app != null) pw.println(r.app.pid); 9453 else pw.println("(not running)"); 9454 if (dumpAll) { 9455 r.dump(pw, innerPrefix); 9456 } 9457 } 9458 if (r.app != null && r.app.thread != null) { 9459 // flush anything that is already in the PrintWriter since the thread is going 9460 // to write to the file descriptor directly 9461 pw.flush(); 9462 try { 9463 TransferPipe tp = new TransferPipe(); 9464 try { 9465 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9466 r.appToken, innerPrefix, args); 9467 tp.go(fd); 9468 } finally { 9469 tp.kill(); 9470 } 9471 } catch (IOException e) { 9472 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9473 } catch (RemoteException e) { 9474 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9475 } 9476 } 9477 } 9478 9479 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9480 int opti, boolean dumpAll, String dumpPackage) { 9481 boolean needSep = false; 9482 boolean onlyHistory = false; 9483 9484 if ("history".equals(dumpPackage)) { 9485 onlyHistory = true; 9486 dumpPackage = null; 9487 } 9488 9489 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9490 if (!onlyHistory && dumpAll) { 9491 if (mRegisteredReceivers.size() > 0) { 9492 boolean printed = false; 9493 Iterator it = mRegisteredReceivers.values().iterator(); 9494 while (it.hasNext()) { 9495 ReceiverList r = (ReceiverList)it.next(); 9496 if (dumpPackage != null && (r.app == null || 9497 !dumpPackage.equals(r.app.info.packageName))) { 9498 continue; 9499 } 9500 if (!printed) { 9501 pw.println(" Registered Receivers:"); 9502 needSep = true; 9503 printed = true; 9504 } 9505 pw.print(" * "); pw.println(r); 9506 r.dump(pw, " "); 9507 } 9508 } 9509 9510 if (mReceiverResolver.dump(pw, needSep ? 9511 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9512 " ", dumpPackage, false)) { 9513 needSep = true; 9514 } 9515 } 9516 9517 for (BroadcastQueue q : mBroadcastQueues) { 9518 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9519 } 9520 9521 needSep = true; 9522 9523 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9524 if (needSep) { 9525 pw.println(); 9526 } 9527 needSep = true; 9528 pw.println(" Sticky broadcasts:"); 9529 StringBuilder sb = new StringBuilder(128); 9530 for (Map.Entry<String, ArrayList<Intent>> ent 9531 : mStickyBroadcasts.entrySet()) { 9532 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9533 if (dumpAll) { 9534 pw.println(":"); 9535 ArrayList<Intent> intents = ent.getValue(); 9536 final int N = intents.size(); 9537 for (int i=0; i<N; i++) { 9538 sb.setLength(0); 9539 sb.append(" Intent: "); 9540 intents.get(i).toShortString(sb, false, true, false, false); 9541 pw.println(sb.toString()); 9542 Bundle bundle = intents.get(i).getExtras(); 9543 if (bundle != null) { 9544 pw.print(" "); 9545 pw.println(bundle.toString()); 9546 } 9547 } 9548 } else { 9549 pw.println(""); 9550 } 9551 } 9552 needSep = true; 9553 } 9554 9555 if (!onlyHistory && dumpAll) { 9556 pw.println(); 9557 for (BroadcastQueue queue : mBroadcastQueues) { 9558 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9559 + queue.mBroadcastsScheduled); 9560 } 9561 pw.println(" mHandler:"); 9562 mHandler.dump(new PrintWriterPrinter(pw), " "); 9563 needSep = true; 9564 } 9565 9566 return needSep; 9567 } 9568 9569 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9570 int opti, boolean dumpAll, String dumpPackage) { 9571 boolean needSep = true; 9572 9573 ItemMatcher matcher = new ItemMatcher(); 9574 matcher.build(args, opti); 9575 9576 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9577 9578 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9579 9580 if (mLaunchingProviders.size() > 0) { 9581 boolean printed = false; 9582 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9583 ContentProviderRecord r = mLaunchingProviders.get(i); 9584 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9585 continue; 9586 } 9587 if (!printed) { 9588 if (needSep) pw.println(" "); 9589 needSep = true; 9590 pw.println(" Launching content providers:"); 9591 printed = true; 9592 } 9593 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9594 pw.println(r); 9595 } 9596 } 9597 9598 if (mGrantedUriPermissions.size() > 0) { 9599 if (needSep) pw.println(); 9600 needSep = true; 9601 pw.println("Granted Uri Permissions:"); 9602 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9603 int uid = mGrantedUriPermissions.keyAt(i); 9604 HashMap<Uri, UriPermission> perms 9605 = mGrantedUriPermissions.valueAt(i); 9606 pw.print(" * UID "); pw.print(uid); 9607 pw.println(" holds:"); 9608 for (UriPermission perm : perms.values()) { 9609 pw.print(" "); pw.println(perm); 9610 if (dumpAll) { 9611 perm.dump(pw, " "); 9612 } 9613 } 9614 } 9615 needSep = true; 9616 } 9617 9618 return needSep; 9619 } 9620 9621 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9622 int opti, boolean dumpAll, String dumpPackage) { 9623 boolean needSep = false; 9624 9625 if (mIntentSenderRecords.size() > 0) { 9626 boolean printed = false; 9627 Iterator<WeakReference<PendingIntentRecord>> it 9628 = mIntentSenderRecords.values().iterator(); 9629 while (it.hasNext()) { 9630 WeakReference<PendingIntentRecord> ref = it.next(); 9631 PendingIntentRecord rec = ref != null ? ref.get(): null; 9632 if (dumpPackage != null && (rec == null 9633 || !dumpPackage.equals(rec.key.packageName))) { 9634 continue; 9635 } 9636 if (!printed) { 9637 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9638 printed = true; 9639 } 9640 needSep = true; 9641 if (rec != null) { 9642 pw.print(" * "); pw.println(rec); 9643 if (dumpAll) { 9644 rec.dump(pw, " "); 9645 } 9646 } else { 9647 pw.print(" * "); pw.println(ref); 9648 } 9649 } 9650 } 9651 9652 return needSep; 9653 } 9654 9655 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9656 String prefix, String label, boolean complete, boolean brief, boolean client, 9657 String dumpPackage) { 9658 TaskRecord lastTask = null; 9659 boolean needNL = false; 9660 final String innerPrefix = prefix + " "; 9661 final String[] args = new String[0]; 9662 for (int i=list.size()-1; i>=0; i--) { 9663 final ActivityRecord r = (ActivityRecord)list.get(i); 9664 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9665 continue; 9666 } 9667 final boolean full = !brief && (complete || !r.isInHistory()); 9668 if (needNL) { 9669 pw.println(" "); 9670 needNL = false; 9671 } 9672 if (lastTask != r.task) { 9673 lastTask = r.task; 9674 pw.print(prefix); 9675 pw.print(full ? "* " : " "); 9676 pw.println(lastTask); 9677 if (full) { 9678 lastTask.dump(pw, prefix + " "); 9679 } else if (complete) { 9680 // Complete + brief == give a summary. Isn't that obvious?!? 9681 if (lastTask.intent != null) { 9682 pw.print(prefix); pw.print(" "); 9683 pw.println(lastTask.intent.toInsecureStringWithClip()); 9684 } 9685 } 9686 } 9687 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9688 pw.print(" #"); pw.print(i); pw.print(": "); 9689 pw.println(r); 9690 if (full) { 9691 r.dump(pw, innerPrefix); 9692 } else if (complete) { 9693 // Complete + brief == give a summary. Isn't that obvious?!? 9694 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9695 if (r.app != null) { 9696 pw.print(innerPrefix); pw.println(r.app); 9697 } 9698 } 9699 if (client && r.app != null && r.app.thread != null) { 9700 // flush anything that is already in the PrintWriter since the thread is going 9701 // to write to the file descriptor directly 9702 pw.flush(); 9703 try { 9704 TransferPipe tp = new TransferPipe(); 9705 try { 9706 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9707 r.appToken, innerPrefix, args); 9708 // Short timeout, since blocking here can 9709 // deadlock with the application. 9710 tp.go(fd, 2000); 9711 } finally { 9712 tp.kill(); 9713 } 9714 } catch (IOException e) { 9715 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9716 } catch (RemoteException e) { 9717 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9718 } 9719 needNL = true; 9720 } 9721 } 9722 } 9723 9724 private static String buildOomTag(String prefix, String space, int val, int base) { 9725 if (val == base) { 9726 if (space == null) return prefix; 9727 return prefix + " "; 9728 } 9729 return prefix + "+" + Integer.toString(val-base); 9730 } 9731 9732 private static final int dumpProcessList(PrintWriter pw, 9733 ActivityManagerService service, List list, 9734 String prefix, String normalLabel, String persistentLabel, 9735 String dumpPackage) { 9736 int numPers = 0; 9737 final int N = list.size()-1; 9738 for (int i=N; i>=0; i--) { 9739 ProcessRecord r = (ProcessRecord)list.get(i); 9740 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9741 continue; 9742 } 9743 pw.println(String.format("%s%s #%2d: %s", 9744 prefix, (r.persistent ? persistentLabel : normalLabel), 9745 i, r.toString())); 9746 if (r.persistent) { 9747 numPers++; 9748 } 9749 } 9750 return numPers; 9751 } 9752 9753 private static final boolean dumpProcessOomList(PrintWriter pw, 9754 ActivityManagerService service, List<ProcessRecord> origList, 9755 String prefix, String normalLabel, String persistentLabel, 9756 boolean inclDetails, String dumpPackage) { 9757 9758 ArrayList<Pair<ProcessRecord, Integer>> list 9759 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9760 for (int i=0; i<origList.size(); i++) { 9761 ProcessRecord r = origList.get(i); 9762 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9763 continue; 9764 } 9765 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9766 } 9767 9768 if (list.size() <= 0) { 9769 return false; 9770 } 9771 9772 Comparator<Pair<ProcessRecord, Integer>> comparator 9773 = new Comparator<Pair<ProcessRecord, Integer>>() { 9774 @Override 9775 public int compare(Pair<ProcessRecord, Integer> object1, 9776 Pair<ProcessRecord, Integer> object2) { 9777 if (object1.first.setAdj != object2.first.setAdj) { 9778 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9779 } 9780 if (object1.second.intValue() != object2.second.intValue()) { 9781 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9782 } 9783 return 0; 9784 } 9785 }; 9786 9787 Collections.sort(list, comparator); 9788 9789 final long curRealtime = SystemClock.elapsedRealtime(); 9790 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9791 final long curUptime = SystemClock.uptimeMillis(); 9792 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9793 9794 for (int i=list.size()-1; i>=0; i--) { 9795 ProcessRecord r = list.get(i).first; 9796 String oomAdj; 9797 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9798 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9799 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9800 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9801 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9802 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9803 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9804 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9805 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9806 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9807 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9808 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9809 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9810 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9811 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9812 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9813 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9814 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9815 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9816 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9817 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9818 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9819 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9820 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9821 } else { 9822 oomAdj = Integer.toString(r.setAdj); 9823 } 9824 String schedGroup; 9825 switch (r.setSchedGroup) { 9826 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9827 schedGroup = "B"; 9828 break; 9829 case Process.THREAD_GROUP_DEFAULT: 9830 schedGroup = "F"; 9831 break; 9832 default: 9833 schedGroup = Integer.toString(r.setSchedGroup); 9834 break; 9835 } 9836 String foreground; 9837 if (r.foregroundActivities) { 9838 foreground = "A"; 9839 } else if (r.foregroundServices) { 9840 foreground = "S"; 9841 } else { 9842 foreground = " "; 9843 } 9844 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9845 prefix, (r.persistent ? persistentLabel : normalLabel), 9846 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9847 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9848 if (r.adjSource != null || r.adjTarget != null) { 9849 pw.print(prefix); 9850 pw.print(" "); 9851 if (r.adjTarget instanceof ComponentName) { 9852 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9853 } else if (r.adjTarget != null) { 9854 pw.print(r.adjTarget.toString()); 9855 } else { 9856 pw.print("{null}"); 9857 } 9858 pw.print("<="); 9859 if (r.adjSource instanceof ProcessRecord) { 9860 pw.print("Proc{"); 9861 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9862 pw.println("}"); 9863 } else if (r.adjSource != null) { 9864 pw.println(r.adjSource.toString()); 9865 } else { 9866 pw.println("{null}"); 9867 } 9868 } 9869 if (inclDetails) { 9870 pw.print(prefix); 9871 pw.print(" "); 9872 pw.print("oom: max="); pw.print(r.maxAdj); 9873 pw.print(" hidden="); pw.print(r.hiddenAdj); 9874 pw.print(" empty="); pw.print(r.emptyAdj); 9875 pw.print(" curRaw="); pw.print(r.curRawAdj); 9876 pw.print(" setRaw="); pw.print(r.setRawAdj); 9877 pw.print(" cur="); pw.print(r.curAdj); 9878 pw.print(" set="); pw.println(r.setAdj); 9879 pw.print(prefix); 9880 pw.print(" "); 9881 pw.print("keeping="); pw.print(r.keeping); 9882 pw.print(" hidden="); pw.print(r.hidden); 9883 pw.print(" empty="); pw.print(r.empty); 9884 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9885 9886 if (!r.keeping) { 9887 if (r.lastWakeTime != 0) { 9888 long wtime; 9889 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9890 synchronized (stats) { 9891 wtime = stats.getProcessWakeTime(r.info.uid, 9892 r.pid, curRealtime); 9893 } 9894 long timeUsed = wtime - r.lastWakeTime; 9895 pw.print(prefix); 9896 pw.print(" "); 9897 pw.print("keep awake over "); 9898 TimeUtils.formatDuration(realtimeSince, pw); 9899 pw.print(" used "); 9900 TimeUtils.formatDuration(timeUsed, pw); 9901 pw.print(" ("); 9902 pw.print((timeUsed*100)/realtimeSince); 9903 pw.println("%)"); 9904 } 9905 if (r.lastCpuTime != 0) { 9906 long timeUsed = r.curCpuTime - r.lastCpuTime; 9907 pw.print(prefix); 9908 pw.print(" "); 9909 pw.print("run cpu over "); 9910 TimeUtils.formatDuration(uptimeSince, pw); 9911 pw.print(" used "); 9912 TimeUtils.formatDuration(timeUsed, pw); 9913 pw.print(" ("); 9914 pw.print((timeUsed*100)/uptimeSince); 9915 pw.println("%)"); 9916 } 9917 } 9918 } 9919 } 9920 return true; 9921 } 9922 9923 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9924 ArrayList<ProcessRecord> procs; 9925 synchronized (this) { 9926 if (args != null && args.length > start 9927 && args[start].charAt(0) != '-') { 9928 procs = new ArrayList<ProcessRecord>(); 9929 int pid = -1; 9930 try { 9931 pid = Integer.parseInt(args[start]); 9932 } catch (NumberFormatException e) { 9933 9934 } 9935 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9936 ProcessRecord proc = mLruProcesses.get(i); 9937 if (proc.pid == pid) { 9938 procs.add(proc); 9939 } else if (proc.processName.equals(args[start])) { 9940 procs.add(proc); 9941 } 9942 } 9943 if (procs.size() <= 0) { 9944 pw.println("No process found for: " + args[start]); 9945 return null; 9946 } 9947 } else { 9948 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9949 } 9950 } 9951 return procs; 9952 } 9953 9954 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9955 PrintWriter pw, String[] args) { 9956 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9957 if (procs == null) { 9958 return; 9959 } 9960 9961 long uptime = SystemClock.uptimeMillis(); 9962 long realtime = SystemClock.elapsedRealtime(); 9963 pw.println("Applications Graphics Acceleration Info:"); 9964 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9965 9966 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9967 ProcessRecord r = procs.get(i); 9968 if (r.thread != null) { 9969 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9970 pw.flush(); 9971 try { 9972 TransferPipe tp = new TransferPipe(); 9973 try { 9974 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9975 tp.go(fd); 9976 } finally { 9977 tp.kill(); 9978 } 9979 } catch (IOException e) { 9980 pw.println("Failure while dumping the app: " + r); 9981 pw.flush(); 9982 } catch (RemoteException e) { 9983 pw.println("Got a RemoteException while dumping the app " + r); 9984 pw.flush(); 9985 } 9986 } 9987 } 9988 } 9989 9990 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9991 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9992 if (procs == null) { 9993 return; 9994 } 9995 9996 pw.println("Applications Database Info:"); 9997 9998 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9999 ProcessRecord r = procs.get(i); 10000 if (r.thread != null) { 10001 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10002 pw.flush(); 10003 try { 10004 TransferPipe tp = new TransferPipe(); 10005 try { 10006 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10007 tp.go(fd); 10008 } finally { 10009 tp.kill(); 10010 } 10011 } catch (IOException e) { 10012 pw.println("Failure while dumping the app: " + r); 10013 pw.flush(); 10014 } catch (RemoteException e) { 10015 pw.println("Got a RemoteException while dumping the app " + r); 10016 pw.flush(); 10017 } 10018 } 10019 } 10020 } 10021 10022 final static class MemItem { 10023 final String label; 10024 final String shortLabel; 10025 final long pss; 10026 final int id; 10027 ArrayList<MemItem> subitems; 10028 10029 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10030 label = _label; 10031 shortLabel = _shortLabel; 10032 pss = _pss; 10033 id = _id; 10034 } 10035 } 10036 10037 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10038 boolean sort) { 10039 if (sort) { 10040 Collections.sort(items, new Comparator<MemItem>() { 10041 @Override 10042 public int compare(MemItem lhs, MemItem rhs) { 10043 if (lhs.pss < rhs.pss) { 10044 return 1; 10045 } else if (lhs.pss > rhs.pss) { 10046 return -1; 10047 } 10048 return 0; 10049 } 10050 }); 10051 } 10052 10053 for (int i=0; i<items.size(); i++) { 10054 MemItem mi = items.get(i); 10055 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10056 if (mi.subitems != null) { 10057 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10058 } 10059 } 10060 } 10061 10062 // These are in KB. 10063 static final long[] DUMP_MEM_BUCKETS = new long[] { 10064 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10065 120*1024, 160*1024, 200*1024, 10066 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10067 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10068 }; 10069 10070 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10071 boolean stackLike) { 10072 int start = label.lastIndexOf('.'); 10073 if (start >= 0) start++; 10074 else start = 0; 10075 int end = label.length(); 10076 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10077 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10078 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10079 out.append(bucket); 10080 out.append(stackLike ? "MB." : "MB "); 10081 out.append(label, start, end); 10082 return; 10083 } 10084 } 10085 out.append(memKB/1024); 10086 out.append(stackLike ? "MB." : "MB "); 10087 out.append(label, start, end); 10088 } 10089 10090 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10091 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10092 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10093 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10094 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10095 }; 10096 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10097 "System", "Persistent", "Foreground", 10098 "Visible", "Perceptible", "Heavy Weight", 10099 "Backup", "A Services", "Home", "Previous", 10100 "B Services", "Background" 10101 }; 10102 10103 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10104 PrintWriter pw, String prefix, String[] args, boolean brief, 10105 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10106 boolean dumpAll = false; 10107 boolean oomOnly = false; 10108 10109 int opti = 0; 10110 while (opti < args.length) { 10111 String opt = args[opti]; 10112 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10113 break; 10114 } 10115 opti++; 10116 if ("-a".equals(opt)) { 10117 dumpAll = true; 10118 } else if ("--oom".equals(opt)) { 10119 oomOnly = true; 10120 } else if ("-h".equals(opt)) { 10121 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10122 pw.println(" -a: include all available information for each process."); 10123 pw.println(" --oom: only show processes organized by oom adj."); 10124 pw.println("If [process] is specified it can be the name or "); 10125 pw.println("pid of a specific process to dump."); 10126 return; 10127 } else { 10128 pw.println("Unknown argument: " + opt + "; use -h for help"); 10129 } 10130 } 10131 10132 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10133 if (procs == null) { 10134 return; 10135 } 10136 10137 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10138 long uptime = SystemClock.uptimeMillis(); 10139 long realtime = SystemClock.elapsedRealtime(); 10140 10141 if (procs.size() == 1 || isCheckinRequest) { 10142 dumpAll = true; 10143 } 10144 10145 if (isCheckinRequest) { 10146 // short checkin version 10147 pw.println(uptime + "," + realtime); 10148 pw.flush(); 10149 } else { 10150 pw.println("Applications Memory Usage (kB):"); 10151 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10152 } 10153 10154 String[] innerArgs = new String[args.length-opti]; 10155 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10156 10157 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10158 long nativePss=0, dalvikPss=0, otherPss=0; 10159 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10160 10161 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10162 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10163 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10164 10165 long totalPss = 0; 10166 10167 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10168 ProcessRecord r = procs.get(i); 10169 if (r.thread != null) { 10170 if (!isCheckinRequest && dumpAll) { 10171 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10172 pw.flush(); 10173 } 10174 Debug.MemoryInfo mi = null; 10175 if (dumpAll) { 10176 try { 10177 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10178 } catch (RemoteException e) { 10179 if (!isCheckinRequest) { 10180 pw.println("Got RemoteException!"); 10181 pw.flush(); 10182 } 10183 } 10184 } else { 10185 mi = new Debug.MemoryInfo(); 10186 Debug.getMemoryInfo(r.pid, mi); 10187 } 10188 10189 if (!isCheckinRequest && mi != null) { 10190 long myTotalPss = mi.getTotalPss(); 10191 totalPss += myTotalPss; 10192 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10193 r.processName, myTotalPss, 0); 10194 procMems.add(pssItem); 10195 10196 nativePss += mi.nativePss; 10197 dalvikPss += mi.dalvikPss; 10198 otherPss += mi.otherPss; 10199 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10200 long mem = mi.getOtherPss(j); 10201 miscPss[j] += mem; 10202 otherPss -= mem; 10203 } 10204 10205 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10206 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10207 || oomIndex == (oomPss.length-1)) { 10208 oomPss[oomIndex] += myTotalPss; 10209 if (oomProcs[oomIndex] == null) { 10210 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10211 } 10212 oomProcs[oomIndex].add(pssItem); 10213 break; 10214 } 10215 } 10216 } 10217 } 10218 } 10219 10220 if (!isCheckinRequest && procs.size() > 1) { 10221 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10222 10223 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10224 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10225 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10226 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10227 String label = Debug.MemoryInfo.getOtherLabel(j); 10228 catMems.add(new MemItem(label, label, miscPss[j], j)); 10229 } 10230 10231 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10232 for (int j=0; j<oomPss.length; j++) { 10233 if (oomPss[j] != 0) { 10234 String label = DUMP_MEM_OOM_LABEL[j]; 10235 MemItem item = new MemItem(label, label, oomPss[j], 10236 DUMP_MEM_OOM_ADJ[j]); 10237 item.subitems = oomProcs[j]; 10238 oomMems.add(item); 10239 } 10240 } 10241 10242 if (outTag != null || outStack != null) { 10243 if (outTag != null) { 10244 appendMemBucket(outTag, totalPss, "total", false); 10245 } 10246 if (outStack != null) { 10247 appendMemBucket(outStack, totalPss, "total", true); 10248 } 10249 boolean firstLine = true; 10250 for (int i=0; i<oomMems.size(); i++) { 10251 MemItem miCat = oomMems.get(i); 10252 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10253 continue; 10254 } 10255 if (miCat.id < ProcessList.SERVICE_ADJ 10256 || miCat.id == ProcessList.HOME_APP_ADJ 10257 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10258 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10259 outTag.append(" / "); 10260 } 10261 if (outStack != null) { 10262 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10263 if (firstLine) { 10264 outStack.append(":"); 10265 firstLine = false; 10266 } 10267 outStack.append("\n\t at "); 10268 } else { 10269 outStack.append("$"); 10270 } 10271 } 10272 for (int j=0; j<miCat.subitems.size(); j++) { 10273 MemItem mi = miCat.subitems.get(j); 10274 if (j > 0) { 10275 if (outTag != null) { 10276 outTag.append(" "); 10277 } 10278 if (outStack != null) { 10279 outStack.append("$"); 10280 } 10281 } 10282 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10283 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10284 } 10285 if (outStack != null) { 10286 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10287 } 10288 } 10289 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10290 outStack.append("("); 10291 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10292 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10293 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10294 outStack.append(":"); 10295 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10296 } 10297 } 10298 outStack.append(")"); 10299 } 10300 } 10301 } 10302 } 10303 10304 if (!brief && !oomOnly) { 10305 pw.println(); 10306 pw.println("Total PSS by process:"); 10307 dumpMemItems(pw, " ", procMems, true); 10308 pw.println(); 10309 } 10310 pw.println("Total PSS by OOM adjustment:"); 10311 dumpMemItems(pw, " ", oomMems, false); 10312 if (!oomOnly) { 10313 PrintWriter out = categoryPw != null ? categoryPw : pw; 10314 out.println(); 10315 out.println("Total PSS by category:"); 10316 dumpMemItems(out, " ", catMems, true); 10317 } 10318 pw.println(); 10319 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10320 final int[] SINGLE_LONG_FORMAT = new int[] { 10321 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10322 }; 10323 long[] longOut = new long[1]; 10324 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10325 SINGLE_LONG_FORMAT, null, longOut, null); 10326 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10327 longOut[0] = 0; 10328 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10329 SINGLE_LONG_FORMAT, null, longOut, null); 10330 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10331 longOut[0] = 0; 10332 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10333 SINGLE_LONG_FORMAT, null, longOut, null); 10334 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10335 longOut[0] = 0; 10336 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10337 SINGLE_LONG_FORMAT, null, longOut, null); 10338 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10339 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10340 pw.print(shared); pw.println(" kB"); 10341 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10342 pw.print(voltile); pw.println(" kB volatile"); 10343 } 10344 } 10345 10346 /** 10347 * Searches array of arguments for the specified string 10348 * @param args array of argument strings 10349 * @param value value to search for 10350 * @return true if the value is contained in the array 10351 */ 10352 private static boolean scanArgs(String[] args, String value) { 10353 if (args != null) { 10354 for (String arg : args) { 10355 if (value.equals(arg)) { 10356 return true; 10357 } 10358 } 10359 } 10360 return false; 10361 } 10362 10363 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10364 ContentProviderRecord cpr, boolean always) { 10365 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10366 10367 if (!inLaunching || always) { 10368 synchronized (cpr) { 10369 cpr.launchingApp = null; 10370 cpr.notifyAll(); 10371 } 10372 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10373 String names[] = cpr.info.authority.split(";"); 10374 for (int j = 0; j < names.length; j++) { 10375 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10376 } 10377 } 10378 10379 for (int i=0; i<cpr.connections.size(); i++) { 10380 ContentProviderConnection conn = cpr.connections.get(i); 10381 if (conn.waiting) { 10382 // If this connection is waiting for the provider, then we don't 10383 // need to mess with its process unless we are always removing 10384 // or for some reason the provider is not currently launching. 10385 if (inLaunching && !always) { 10386 continue; 10387 } 10388 } 10389 ProcessRecord capp = conn.client; 10390 conn.dead = true; 10391 if (conn.stableCount > 0) { 10392 if (!capp.persistent && capp.thread != null 10393 && capp.pid != 0 10394 && capp.pid != MY_PID) { 10395 Slog.i(TAG, "Kill " + capp.processName 10396 + " (pid " + capp.pid + "): provider " + cpr.info.name 10397 + " in dying process " + (proc != null ? proc.processName : "??")); 10398 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10399 capp.processName, capp.setAdj, "dying provider " 10400 + cpr.name.toShortString()); 10401 Process.killProcessQuiet(capp.pid); 10402 } 10403 } else if (capp.thread != null && conn.provider.provider != null) { 10404 try { 10405 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10406 } catch (RemoteException e) { 10407 } 10408 // In the protocol here, we don't expect the client to correctly 10409 // clean up this connection, we'll just remove it. 10410 cpr.connections.remove(i); 10411 conn.client.conProviders.remove(conn); 10412 } 10413 } 10414 10415 if (inLaunching && always) { 10416 mLaunchingProviders.remove(cpr); 10417 } 10418 return inLaunching; 10419 } 10420 10421 /** 10422 * Main code for cleaning up a process when it has gone away. This is 10423 * called both as a result of the process dying, or directly when stopping 10424 * a process when running in single process mode. 10425 */ 10426 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10427 boolean restarting, boolean allowRestart, int index) { 10428 if (index >= 0) { 10429 mLruProcesses.remove(index); 10430 } 10431 10432 mProcessesToGc.remove(app); 10433 10434 // Dismiss any open dialogs. 10435 if (app.crashDialog != null) { 10436 app.crashDialog.dismiss(); 10437 app.crashDialog = null; 10438 } 10439 if (app.anrDialog != null) { 10440 app.anrDialog.dismiss(); 10441 app.anrDialog = null; 10442 } 10443 if (app.waitDialog != null) { 10444 app.waitDialog.dismiss(); 10445 app.waitDialog = null; 10446 } 10447 10448 app.crashing = false; 10449 app.notResponding = false; 10450 10451 app.resetPackageList(); 10452 app.unlinkDeathRecipient(); 10453 app.thread = null; 10454 app.forcingToForeground = null; 10455 app.foregroundServices = false; 10456 app.foregroundActivities = false; 10457 app.hasShownUi = false; 10458 app.hasAboveClient = false; 10459 10460 mServices.killServicesLocked(app, allowRestart); 10461 10462 boolean restart = false; 10463 10464 // Remove published content providers. 10465 if (!app.pubProviders.isEmpty()) { 10466 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10467 while (it.hasNext()) { 10468 ContentProviderRecord cpr = it.next(); 10469 10470 final boolean always = app.bad || !allowRestart; 10471 if (removeDyingProviderLocked(app, cpr, always) || always) { 10472 // We left the provider in the launching list, need to 10473 // restart it. 10474 restart = true; 10475 } 10476 10477 cpr.provider = null; 10478 cpr.proc = null; 10479 } 10480 app.pubProviders.clear(); 10481 } 10482 10483 // Take care of any launching providers waiting for this process. 10484 if (checkAppInLaunchingProvidersLocked(app, false)) { 10485 restart = true; 10486 } 10487 10488 // Unregister from connected content providers. 10489 if (!app.conProviders.isEmpty()) { 10490 for (int i=0; i<app.conProviders.size(); i++) { 10491 ContentProviderConnection conn = app.conProviders.get(i); 10492 conn.provider.connections.remove(conn); 10493 } 10494 app.conProviders.clear(); 10495 } 10496 10497 // At this point there may be remaining entries in mLaunchingProviders 10498 // where we were the only one waiting, so they are no longer of use. 10499 // Look for these and clean up if found. 10500 // XXX Commented out for now. Trying to figure out a way to reproduce 10501 // the actual situation to identify what is actually going on. 10502 if (false) { 10503 for (int i=0; i<mLaunchingProviders.size(); i++) { 10504 ContentProviderRecord cpr = (ContentProviderRecord) 10505 mLaunchingProviders.get(i); 10506 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10507 synchronized (cpr) { 10508 cpr.launchingApp = null; 10509 cpr.notifyAll(); 10510 } 10511 } 10512 } 10513 } 10514 10515 skipCurrentReceiverLocked(app); 10516 10517 // Unregister any receivers. 10518 if (app.receivers.size() > 0) { 10519 Iterator<ReceiverList> it = app.receivers.iterator(); 10520 while (it.hasNext()) { 10521 removeReceiverLocked(it.next()); 10522 } 10523 app.receivers.clear(); 10524 } 10525 10526 // If the app is undergoing backup, tell the backup manager about it 10527 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10528 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10529 try { 10530 IBackupManager bm = IBackupManager.Stub.asInterface( 10531 ServiceManager.getService(Context.BACKUP_SERVICE)); 10532 bm.agentDisconnected(app.info.packageName); 10533 } catch (RemoteException e) { 10534 // can't happen; backup manager is local 10535 } 10536 } 10537 10538 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10539 ProcessChangeItem item = mPendingProcessChanges.get(i); 10540 if (item.pid == app.pid) { 10541 mPendingProcessChanges.remove(i); 10542 mAvailProcessChanges.add(item); 10543 } 10544 } 10545 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10546 10547 // If the caller is restarting this app, then leave it in its 10548 // current lists and let the caller take care of it. 10549 if (restarting) { 10550 return; 10551 } 10552 10553 if (!app.persistent || app.isolated) { 10554 if (DEBUG_PROCESSES) Slog.v(TAG, 10555 "Removing non-persistent process during cleanup: " + app); 10556 mProcessNames.remove(app.processName, app.uid); 10557 mIsolatedProcesses.remove(app.uid); 10558 if (mHeavyWeightProcess == app) { 10559 mHeavyWeightProcess = null; 10560 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10561 } 10562 } else if (!app.removed) { 10563 // This app is persistent, so we need to keep its record around. 10564 // If it is not already on the pending app list, add it there 10565 // and start a new process for it. 10566 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10567 mPersistentStartingProcesses.add(app); 10568 restart = true; 10569 } 10570 } 10571 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10572 "Clean-up removing on hold: " + app); 10573 mProcessesOnHold.remove(app); 10574 10575 if (app == mHomeProcess) { 10576 mHomeProcess = null; 10577 } 10578 if (app == mPreviousProcess) { 10579 mPreviousProcess = null; 10580 } 10581 10582 if (restart && !app.isolated) { 10583 // We have components that still need to be running in the 10584 // process, so re-launch it. 10585 mProcessNames.put(app.processName, app.uid, app); 10586 startProcessLocked(app, "restart", app.processName); 10587 } else if (app.pid > 0 && app.pid != MY_PID) { 10588 // Goodbye! 10589 synchronized (mPidsSelfLocked) { 10590 mPidsSelfLocked.remove(app.pid); 10591 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10592 } 10593 app.setPid(0); 10594 } 10595 } 10596 10597 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10598 // Look through the content providers we are waiting to have launched, 10599 // and if any run in this process then either schedule a restart of 10600 // the process or kill the client waiting for it if this process has 10601 // gone bad. 10602 int NL = mLaunchingProviders.size(); 10603 boolean restart = false; 10604 for (int i=0; i<NL; i++) { 10605 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10606 if (cpr.launchingApp == app) { 10607 if (!alwaysBad && !app.bad) { 10608 restart = true; 10609 } else { 10610 removeDyingProviderLocked(app, cpr, true); 10611 NL = mLaunchingProviders.size(); 10612 } 10613 } 10614 } 10615 return restart; 10616 } 10617 10618 // ========================================================= 10619 // SERVICES 10620 // ========================================================= 10621 10622 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10623 int flags) { 10624 enforceNotIsolatedCaller("getServices"); 10625 synchronized (this) { 10626 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10627 } 10628 } 10629 10630 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10631 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10632 synchronized (this) { 10633 return mServices.getRunningServiceControlPanelLocked(name); 10634 } 10635 } 10636 10637 public ComponentName startService(IApplicationThread caller, Intent service, 10638 String resolvedType, int userId) { 10639 enforceNotIsolatedCaller("startService"); 10640 // Refuse possible leaked file descriptors 10641 if (service != null && service.hasFileDescriptors() == true) { 10642 throw new IllegalArgumentException("File descriptors passed in Intent"); 10643 } 10644 10645 if (DEBUG_SERVICE) 10646 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10647 synchronized(this) { 10648 final int callingPid = Binder.getCallingPid(); 10649 final int callingUid = Binder.getCallingUid(); 10650 checkValidCaller(callingUid, userId); 10651 final long origId = Binder.clearCallingIdentity(); 10652 ComponentName res = mServices.startServiceLocked(caller, service, 10653 resolvedType, callingPid, callingUid, userId); 10654 Binder.restoreCallingIdentity(origId); 10655 return res; 10656 } 10657 } 10658 10659 ComponentName startServiceInPackage(int uid, 10660 Intent service, String resolvedType) { 10661 synchronized(this) { 10662 if (DEBUG_SERVICE) 10663 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10664 final long origId = Binder.clearCallingIdentity(); 10665 ComponentName res = mServices.startServiceLocked(null, service, 10666 resolvedType, -1, uid, UserHandle.getUserId(uid)); 10667 Binder.restoreCallingIdentity(origId); 10668 return res; 10669 } 10670 } 10671 10672 public int stopService(IApplicationThread caller, Intent service, 10673 String resolvedType, int userId) { 10674 enforceNotIsolatedCaller("stopService"); 10675 // Refuse possible leaked file descriptors 10676 if (service != null && service.hasFileDescriptors() == true) { 10677 throw new IllegalArgumentException("File descriptors passed in Intent"); 10678 } 10679 10680 checkValidCaller(Binder.getCallingUid(), userId); 10681 10682 synchronized(this) { 10683 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10684 } 10685 } 10686 10687 public IBinder peekService(Intent service, String resolvedType) { 10688 enforceNotIsolatedCaller("peekService"); 10689 // Refuse possible leaked file descriptors 10690 if (service != null && service.hasFileDescriptors() == true) { 10691 throw new IllegalArgumentException("File descriptors passed in Intent"); 10692 } 10693 synchronized(this) { 10694 return mServices.peekServiceLocked(service, resolvedType); 10695 } 10696 } 10697 10698 public boolean stopServiceToken(ComponentName className, IBinder token, 10699 int startId) { 10700 synchronized(this) { 10701 return mServices.stopServiceTokenLocked(className, token, startId); 10702 } 10703 } 10704 10705 public void setServiceForeground(ComponentName className, IBinder token, 10706 int id, Notification notification, boolean removeNotification) { 10707 synchronized(this) { 10708 mServices.setServiceForegroundLocked(className, token, id, notification, 10709 removeNotification); 10710 } 10711 } 10712 10713 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10714 String className, int flags) { 10715 boolean result = false; 10716 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10717 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10718 if (ActivityManager.checkUidPermission( 10719 android.Manifest.permission.INTERACT_ACROSS_USERS, 10720 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10721 ComponentName comp = new ComponentName(aInfo.packageName, className); 10722 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10723 + " requests FLAG_SINGLE_USER, but app does not hold " 10724 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10725 Slog.w(TAG, msg); 10726 throw new SecurityException(msg); 10727 } 10728 result = true; 10729 } 10730 } else if (componentProcessName == aInfo.packageName) { 10731 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10732 } else if ("system".equals(componentProcessName)) { 10733 result = true; 10734 } 10735 if (DEBUG_MU) { 10736 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10737 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10738 } 10739 return result; 10740 } 10741 10742 public int bindService(IApplicationThread caller, IBinder token, 10743 Intent service, String resolvedType, 10744 IServiceConnection connection, int flags, int userId) { 10745 enforceNotIsolatedCaller("bindService"); 10746 // Refuse possible leaked file descriptors 10747 if (service != null && service.hasFileDescriptors() == true) { 10748 throw new IllegalArgumentException("File descriptors passed in Intent"); 10749 } 10750 10751 if (userId != UserHandle.getCallingUserId()) { 10752 // Requesting a different user, make sure that they have permission 10753 if (checkComponentPermission( 10754 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10755 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 10756 == PackageManager.PERMISSION_GRANTED) { 10757 // Translate to the current user id, if caller wasn't aware 10758 if (userId == UserHandle.USER_CURRENT) { 10759 userId = mCurrentUserId; 10760 } 10761 } else { 10762 String msg = "Permission Denial: Request to bindService as user " + userId 10763 + " but is calling from user " + UserHandle.getCallingUserId() 10764 + "; this requires " 10765 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 10766 Slog.w(TAG, msg); 10767 throw new SecurityException(msg); 10768 } 10769 } 10770 10771 synchronized(this) { 10772 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10773 connection, flags, userId); 10774 } 10775 } 10776 10777 public boolean unbindService(IServiceConnection connection) { 10778 synchronized (this) { 10779 return mServices.unbindServiceLocked(connection); 10780 } 10781 } 10782 10783 public void publishService(IBinder token, Intent intent, IBinder service) { 10784 // Refuse possible leaked file descriptors 10785 if (intent != null && intent.hasFileDescriptors() == true) { 10786 throw new IllegalArgumentException("File descriptors passed in Intent"); 10787 } 10788 10789 synchronized(this) { 10790 if (!(token instanceof ServiceRecord)) { 10791 throw new IllegalArgumentException("Invalid service token"); 10792 } 10793 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10794 } 10795 } 10796 10797 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10798 // Refuse possible leaked file descriptors 10799 if (intent != null && intent.hasFileDescriptors() == true) { 10800 throw new IllegalArgumentException("File descriptors passed in Intent"); 10801 } 10802 10803 synchronized(this) { 10804 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10805 } 10806 } 10807 10808 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10809 synchronized(this) { 10810 if (!(token instanceof ServiceRecord)) { 10811 throw new IllegalArgumentException("Invalid service token"); 10812 } 10813 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10814 } 10815 } 10816 10817 // ========================================================= 10818 // BACKUP AND RESTORE 10819 // ========================================================= 10820 10821 // Cause the target app to be launched if necessary and its backup agent 10822 // instantiated. The backup agent will invoke backupAgentCreated() on the 10823 // activity manager to announce its creation. 10824 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10825 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10826 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10827 10828 synchronized(this) { 10829 // !!! TODO: currently no check here that we're already bound 10830 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10831 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10832 synchronized (stats) { 10833 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10834 } 10835 10836 // Backup agent is now in use, its package can't be stopped. 10837 try { 10838 AppGlobals.getPackageManager().setPackageStoppedState( 10839 app.packageName, false, UserHandle.getUserId(app.uid)); 10840 } catch (RemoteException e) { 10841 } catch (IllegalArgumentException e) { 10842 Slog.w(TAG, "Failed trying to unstop package " 10843 + app.packageName + ": " + e); 10844 } 10845 10846 BackupRecord r = new BackupRecord(ss, app, backupMode); 10847 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10848 ? new ComponentName(app.packageName, app.backupAgentName) 10849 : new ComponentName("android", "FullBackupAgent"); 10850 // startProcessLocked() returns existing proc's record if it's already running 10851 ProcessRecord proc = startProcessLocked(app.processName, app, 10852 false, 0, "backup", hostingName, false, false); 10853 if (proc == null) { 10854 Slog.e(TAG, "Unable to start backup agent process " + r); 10855 return false; 10856 } 10857 10858 r.app = proc; 10859 mBackupTarget = r; 10860 mBackupAppName = app.packageName; 10861 10862 // Try not to kill the process during backup 10863 updateOomAdjLocked(proc); 10864 10865 // If the process is already attached, schedule the creation of the backup agent now. 10866 // If it is not yet live, this will be done when it attaches to the framework. 10867 if (proc.thread != null) { 10868 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10869 try { 10870 proc.thread.scheduleCreateBackupAgent(app, 10871 compatibilityInfoForPackageLocked(app), backupMode); 10872 } catch (RemoteException e) { 10873 // Will time out on the backup manager side 10874 } 10875 } else { 10876 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10877 } 10878 // Invariants: at this point, the target app process exists and the application 10879 // is either already running or in the process of coming up. mBackupTarget and 10880 // mBackupAppName describe the app, so that when it binds back to the AM we 10881 // know that it's scheduled for a backup-agent operation. 10882 } 10883 10884 return true; 10885 } 10886 10887 // A backup agent has just come up 10888 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10889 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10890 + " = " + agent); 10891 10892 synchronized(this) { 10893 if (!agentPackageName.equals(mBackupAppName)) { 10894 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10895 return; 10896 } 10897 } 10898 10899 long oldIdent = Binder.clearCallingIdentity(); 10900 try { 10901 IBackupManager bm = IBackupManager.Stub.asInterface( 10902 ServiceManager.getService(Context.BACKUP_SERVICE)); 10903 bm.agentConnected(agentPackageName, agent); 10904 } catch (RemoteException e) { 10905 // can't happen; the backup manager service is local 10906 } catch (Exception e) { 10907 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10908 e.printStackTrace(); 10909 } finally { 10910 Binder.restoreCallingIdentity(oldIdent); 10911 } 10912 } 10913 10914 // done with this agent 10915 public void unbindBackupAgent(ApplicationInfo appInfo) { 10916 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10917 if (appInfo == null) { 10918 Slog.w(TAG, "unbind backup agent for null app"); 10919 return; 10920 } 10921 10922 synchronized(this) { 10923 if (mBackupAppName == null) { 10924 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10925 return; 10926 } 10927 10928 if (!mBackupAppName.equals(appInfo.packageName)) { 10929 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10930 return; 10931 } 10932 10933 ProcessRecord proc = mBackupTarget.app; 10934 mBackupTarget = null; 10935 mBackupAppName = null; 10936 10937 // Not backing this app up any more; reset its OOM adjustment 10938 updateOomAdjLocked(proc); 10939 10940 // If the app crashed during backup, 'thread' will be null here 10941 if (proc.thread != null) { 10942 try { 10943 proc.thread.scheduleDestroyBackupAgent(appInfo, 10944 compatibilityInfoForPackageLocked(appInfo)); 10945 } catch (Exception e) { 10946 Slog.e(TAG, "Exception when unbinding backup agent:"); 10947 e.printStackTrace(); 10948 } 10949 } 10950 } 10951 } 10952 // ========================================================= 10953 // BROADCASTS 10954 // ========================================================= 10955 10956 private final List getStickiesLocked(String action, IntentFilter filter, 10957 List cur) { 10958 final ContentResolver resolver = mContext.getContentResolver(); 10959 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10960 if (list == null) { 10961 return cur; 10962 } 10963 int N = list.size(); 10964 for (int i=0; i<N; i++) { 10965 Intent intent = list.get(i); 10966 if (filter.match(resolver, intent, true, TAG) >= 0) { 10967 if (cur == null) { 10968 cur = new ArrayList<Intent>(); 10969 } 10970 cur.add(intent); 10971 } 10972 } 10973 return cur; 10974 } 10975 10976 boolean isPendingBroadcastProcessLocked(int pid) { 10977 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10978 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10979 } 10980 10981 void skipPendingBroadcastLocked(int pid) { 10982 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10983 for (BroadcastQueue queue : mBroadcastQueues) { 10984 queue.skipPendingBroadcastLocked(pid); 10985 } 10986 } 10987 10988 // The app just attached; send any pending broadcasts that it should receive 10989 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10990 boolean didSomething = false; 10991 for (BroadcastQueue queue : mBroadcastQueues) { 10992 didSomething |= queue.sendPendingBroadcastsLocked(app); 10993 } 10994 return didSomething; 10995 } 10996 10997 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10998 IIntentReceiver receiver, IntentFilter filter, String permission) { 10999 enforceNotIsolatedCaller("registerReceiver"); 11000 int callingUid; 11001 synchronized(this) { 11002 ProcessRecord callerApp = null; 11003 if (caller != null) { 11004 callerApp = getRecordForAppLocked(caller); 11005 if (callerApp == null) { 11006 throw new SecurityException( 11007 "Unable to find app for caller " + caller 11008 + " (pid=" + Binder.getCallingPid() 11009 + ") when registering receiver " + receiver); 11010 } 11011 if (callerApp.info.uid != Process.SYSTEM_UID && 11012 !callerApp.pkgList.contains(callerPackage)) { 11013 throw new SecurityException("Given caller package " + callerPackage 11014 + " is not running in process " + callerApp); 11015 } 11016 callingUid = callerApp.info.uid; 11017 } else { 11018 callerPackage = null; 11019 callingUid = Binder.getCallingUid(); 11020 } 11021 11022 List allSticky = null; 11023 11024 // Look for any matching sticky broadcasts... 11025 Iterator actions = filter.actionsIterator(); 11026 if (actions != null) { 11027 while (actions.hasNext()) { 11028 String action = (String)actions.next(); 11029 allSticky = getStickiesLocked(action, filter, allSticky); 11030 } 11031 } else { 11032 allSticky = getStickiesLocked(null, filter, allSticky); 11033 } 11034 11035 // The first sticky in the list is returned directly back to 11036 // the client. 11037 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11038 11039 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11040 + ": " + sticky); 11041 11042 if (receiver == null) { 11043 return sticky; 11044 } 11045 11046 ReceiverList rl 11047 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11048 if (rl == null) { 11049 rl = new ReceiverList(this, callerApp, 11050 Binder.getCallingPid(), 11051 Binder.getCallingUid(), receiver); 11052 if (rl.app != null) { 11053 rl.app.receivers.add(rl); 11054 } else { 11055 try { 11056 receiver.asBinder().linkToDeath(rl, 0); 11057 } catch (RemoteException e) { 11058 return sticky; 11059 } 11060 rl.linkedToDeath = true; 11061 } 11062 mRegisteredReceivers.put(receiver.asBinder(), rl); 11063 } 11064 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11065 permission, callingUid); 11066 rl.add(bf); 11067 if (!bf.debugCheck()) { 11068 Slog.w(TAG, "==> For Dynamic broadast"); 11069 } 11070 mReceiverResolver.addFilter(bf); 11071 11072 // Enqueue broadcasts for all existing stickies that match 11073 // this filter. 11074 if (allSticky != null) { 11075 ArrayList receivers = new ArrayList(); 11076 receivers.add(bf); 11077 11078 int N = allSticky.size(); 11079 for (int i=0; i<N; i++) { 11080 Intent intent = (Intent)allSticky.get(i); 11081 BroadcastQueue queue = broadcastQueueForIntent(intent); 11082 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11083 null, -1, -1, null, receivers, null, 0, null, null, 11084 false, true, true, -1); 11085 queue.enqueueParallelBroadcastLocked(r); 11086 queue.scheduleBroadcastsLocked(); 11087 } 11088 } 11089 11090 return sticky; 11091 } 11092 } 11093 11094 public void unregisterReceiver(IIntentReceiver receiver) { 11095 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11096 11097 final long origId = Binder.clearCallingIdentity(); 11098 try { 11099 boolean doTrim = false; 11100 11101 synchronized(this) { 11102 ReceiverList rl 11103 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11104 if (rl != null) { 11105 if (rl.curBroadcast != null) { 11106 BroadcastRecord r = rl.curBroadcast; 11107 final boolean doNext = finishReceiverLocked( 11108 receiver.asBinder(), r.resultCode, r.resultData, 11109 r.resultExtras, r.resultAbort, true); 11110 if (doNext) { 11111 doTrim = true; 11112 r.queue.processNextBroadcast(false); 11113 } 11114 } 11115 11116 if (rl.app != null) { 11117 rl.app.receivers.remove(rl); 11118 } 11119 removeReceiverLocked(rl); 11120 if (rl.linkedToDeath) { 11121 rl.linkedToDeath = false; 11122 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11123 } 11124 } 11125 } 11126 11127 // If we actually concluded any broadcasts, we might now be able 11128 // to trim the recipients' apps from our working set 11129 if (doTrim) { 11130 trimApplications(); 11131 return; 11132 } 11133 11134 } finally { 11135 Binder.restoreCallingIdentity(origId); 11136 } 11137 } 11138 11139 void removeReceiverLocked(ReceiverList rl) { 11140 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11141 int N = rl.size(); 11142 for (int i=0; i<N; i++) { 11143 mReceiverResolver.removeFilter(rl.get(i)); 11144 } 11145 } 11146 11147 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11148 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11149 ProcessRecord r = mLruProcesses.get(i); 11150 if (r.thread != null) { 11151 try { 11152 r.thread.dispatchPackageBroadcast(cmd, packages); 11153 } catch (RemoteException ex) { 11154 } 11155 } 11156 } 11157 } 11158 11159 private final int broadcastIntentLocked(ProcessRecord callerApp, 11160 String callerPackage, Intent intent, String resolvedType, 11161 IIntentReceiver resultTo, int resultCode, String resultData, 11162 Bundle map, String requiredPermission, 11163 boolean ordered, boolean sticky, int callingPid, int callingUid, 11164 int userId) { 11165 intent = new Intent(intent); 11166 11167 // By default broadcasts do not go to stopped apps. 11168 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11169 11170 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11171 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11172 + " ordered=" + ordered + " userid=" + userId); 11173 if ((resultTo != null) && !ordered) { 11174 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11175 } 11176 11177 // If the caller is trying to send this broadcast to a different 11178 // user, verify that is allowed. 11179 if (UserHandle.getUserId(callingUid) != userId) { 11180 if (checkComponentPermission( 11181 android.Manifest.permission.INTERACT_ACROSS_USERS, 11182 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED 11183 && checkComponentPermission( 11184 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11185 callingPid, callingUid, -1, true) 11186 != PackageManager.PERMISSION_GRANTED) { 11187 String msg = "Permission Denial: " + intent.getAction() 11188 + " broadcast from " + callerPackage 11189 + " asks to send as user " + userId 11190 + " but is calling from user " + UserHandle.getUserId(callingUid) 11191 + "; this requires " 11192 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11193 Slog.w(TAG, msg); 11194 throw new SecurityException(msg); 11195 } else { 11196 if (userId == UserHandle.USER_CURRENT) { 11197 userId = mCurrentUserId; 11198 } 11199 } 11200 } 11201 11202 // Make sure that the user who is receiving this broadcast is started 11203 // If not, we will just skip it. 11204 if (mStartedUsers.get(userId) == null) { 11205 Slog.w(TAG, "Skipping broadcast of " + intent 11206 + ": user " + userId + " is stopped"); 11207 return ActivityManager.BROADCAST_SUCCESS; 11208 } 11209 11210 // Handle special intents: if this broadcast is from the package 11211 // manager about a package being removed, we need to remove all of 11212 // its activities from the history stack. 11213 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11214 intent.getAction()); 11215 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11216 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11217 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11218 || uidRemoved) { 11219 if (checkComponentPermission( 11220 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11221 callingPid, callingUid, -1, true) 11222 == PackageManager.PERMISSION_GRANTED) { 11223 if (uidRemoved) { 11224 final Bundle intentExtras = intent.getExtras(); 11225 final int uid = intentExtras != null 11226 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11227 if (uid >= 0) { 11228 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11229 synchronized (bs) { 11230 bs.removeUidStatsLocked(uid); 11231 } 11232 } 11233 } else { 11234 // If resources are unvailble just force stop all 11235 // those packages and flush the attribute cache as well. 11236 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11237 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11238 if (list != null && (list.length > 0)) { 11239 for (String pkg : list) { 11240 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11241 } 11242 sendPackageBroadcastLocked( 11243 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11244 } 11245 } else { 11246 Uri data = intent.getData(); 11247 String ssp; 11248 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11249 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11250 forceStopPackageLocked(ssp, 11251 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11252 false, userId); 11253 } 11254 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11255 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11256 new String[] {ssp}); 11257 } 11258 } 11259 } 11260 } 11261 } else { 11262 String msg = "Permission Denial: " + intent.getAction() 11263 + " broadcast from " + callerPackage + " (pid=" + callingPid 11264 + ", uid=" + callingUid + ")" 11265 + " requires " 11266 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11267 Slog.w(TAG, msg); 11268 throw new SecurityException(msg); 11269 } 11270 11271 // Special case for adding a package: by default turn on compatibility 11272 // mode. 11273 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11274 Uri data = intent.getData(); 11275 String ssp; 11276 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11277 mCompatModePackages.handlePackageAddedLocked(ssp, 11278 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11279 } 11280 } 11281 11282 /* 11283 * If this is the time zone changed action, queue up a message that will reset the timezone 11284 * of all currently running processes. This message will get queued up before the broadcast 11285 * happens. 11286 */ 11287 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11288 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11289 } 11290 11291 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11292 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11293 } 11294 11295 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11296 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11297 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11298 } 11299 11300 /* 11301 * Prevent non-system code (defined here to be non-persistent 11302 * processes) from sending protected broadcasts. 11303 */ 11304 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11305 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11306 callingUid == 0) { 11307 // Always okay. 11308 } else if (callerApp == null || !callerApp.persistent) { 11309 try { 11310 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11311 intent.getAction())) { 11312 String msg = "Permission Denial: not allowed to send broadcast " 11313 + intent.getAction() + " from pid=" 11314 + callingPid + ", uid=" + callingUid; 11315 Slog.w(TAG, msg); 11316 throw new SecurityException(msg); 11317 } 11318 } catch (RemoteException e) { 11319 Slog.w(TAG, "Remote exception", e); 11320 return ActivityManager.BROADCAST_SUCCESS; 11321 } 11322 } 11323 11324 // Add to the sticky list if requested. 11325 if (sticky) { 11326 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11327 callingPid, callingUid) 11328 != PackageManager.PERMISSION_GRANTED) { 11329 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11330 + callingPid + ", uid=" + callingUid 11331 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11332 Slog.w(TAG, msg); 11333 throw new SecurityException(msg); 11334 } 11335 if (requiredPermission != null) { 11336 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11337 + " and enforce permission " + requiredPermission); 11338 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11339 } 11340 if (intent.getComponent() != null) { 11341 throw new SecurityException( 11342 "Sticky broadcasts can't target a specific component"); 11343 } 11344 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11345 if (list == null) { 11346 list = new ArrayList<Intent>(); 11347 mStickyBroadcasts.put(intent.getAction(), list); 11348 } 11349 int N = list.size(); 11350 int i; 11351 for (i=0; i<N; i++) { 11352 if (intent.filterEquals(list.get(i))) { 11353 // This sticky already exists, replace it. 11354 list.set(i, new Intent(intent)); 11355 break; 11356 } 11357 } 11358 if (i >= N) { 11359 list.add(new Intent(intent)); 11360 } 11361 } 11362 11363 // Figure out who all will receive this broadcast. 11364 List receivers = null; 11365 List<BroadcastFilter> registeredReceivers = null; 11366 try { 11367 // Need to resolve the intent to interested receivers... 11368 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11369 == 0) { 11370 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11371 intent, resolvedType, STOCK_PM_FLAGS, userId); 11372 } 11373 if (intent.getComponent() == null) { 11374 registeredReceivers = mReceiverResolver.queryIntent(intent, 11375 resolvedType, false, userId); 11376 } 11377 } catch (RemoteException ex) { 11378 // pm is in same process, this will never happen. 11379 } 11380 11381 final boolean replacePending = 11382 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11383 11384 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11385 + " replacePending=" + replacePending); 11386 11387 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11388 if (!ordered && NR > 0) { 11389 // If we are not serializing this broadcast, then send the 11390 // registered receivers separately so they don't wait for the 11391 // components to be launched. 11392 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11393 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11394 callerPackage, callingPid, callingUid, requiredPermission, 11395 registeredReceivers, resultTo, resultCode, resultData, map, 11396 ordered, sticky, false, userId); 11397 if (DEBUG_BROADCAST) Slog.v( 11398 TAG, "Enqueueing parallel broadcast " + r); 11399 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11400 if (!replaced) { 11401 queue.enqueueParallelBroadcastLocked(r); 11402 queue.scheduleBroadcastsLocked(); 11403 } 11404 registeredReceivers = null; 11405 NR = 0; 11406 } 11407 11408 // Merge into one list. 11409 int ir = 0; 11410 if (receivers != null) { 11411 // A special case for PACKAGE_ADDED: do not allow the package 11412 // being added to see this broadcast. This prevents them from 11413 // using this as a back door to get run as soon as they are 11414 // installed. Maybe in the future we want to have a special install 11415 // broadcast or such for apps, but we'd like to deliberately make 11416 // this decision. 11417 String skipPackages[] = null; 11418 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11419 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11420 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11421 Uri data = intent.getData(); 11422 if (data != null) { 11423 String pkgName = data.getSchemeSpecificPart(); 11424 if (pkgName != null) { 11425 skipPackages = new String[] { pkgName }; 11426 } 11427 } 11428 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11429 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11430 } 11431 if (skipPackages != null && (skipPackages.length > 0)) { 11432 for (String skipPackage : skipPackages) { 11433 if (skipPackage != null) { 11434 int NT = receivers.size(); 11435 for (int it=0; it<NT; it++) { 11436 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11437 if (curt.activityInfo.packageName.equals(skipPackage)) { 11438 receivers.remove(it); 11439 it--; 11440 NT--; 11441 } 11442 } 11443 } 11444 } 11445 } 11446 11447 int NT = receivers != null ? receivers.size() : 0; 11448 int it = 0; 11449 ResolveInfo curt = null; 11450 BroadcastFilter curr = null; 11451 while (it < NT && ir < NR) { 11452 if (curt == null) { 11453 curt = (ResolveInfo)receivers.get(it); 11454 } 11455 if (curr == null) { 11456 curr = registeredReceivers.get(ir); 11457 } 11458 if (curr.getPriority() >= curt.priority) { 11459 // Insert this broadcast record into the final list. 11460 receivers.add(it, curr); 11461 ir++; 11462 curr = null; 11463 it++; 11464 NT++; 11465 } else { 11466 // Skip to the next ResolveInfo in the final list. 11467 it++; 11468 curt = null; 11469 } 11470 } 11471 } 11472 while (ir < NR) { 11473 if (receivers == null) { 11474 receivers = new ArrayList(); 11475 } 11476 receivers.add(registeredReceivers.get(ir)); 11477 ir++; 11478 } 11479 11480 if ((receivers != null && receivers.size() > 0) 11481 || resultTo != null) { 11482 BroadcastQueue queue = broadcastQueueForIntent(intent); 11483 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11484 callerPackage, callingPid, callingUid, requiredPermission, 11485 receivers, resultTo, resultCode, resultData, map, ordered, 11486 sticky, false, userId); 11487 if (DEBUG_BROADCAST) Slog.v( 11488 TAG, "Enqueueing ordered broadcast " + r 11489 + ": prev had " + queue.mOrderedBroadcasts.size()); 11490 if (DEBUG_BROADCAST) { 11491 int seq = r.intent.getIntExtra("seq", -1); 11492 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11493 } 11494 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11495 if (!replaced) { 11496 queue.enqueueOrderedBroadcastLocked(r); 11497 queue.scheduleBroadcastsLocked(); 11498 } 11499 } 11500 11501 return ActivityManager.BROADCAST_SUCCESS; 11502 } 11503 11504 final Intent verifyBroadcastLocked(Intent intent) { 11505 // Refuse possible leaked file descriptors 11506 if (intent != null && intent.hasFileDescriptors() == true) { 11507 throw new IllegalArgumentException("File descriptors passed in Intent"); 11508 } 11509 11510 int flags = intent.getFlags(); 11511 11512 if (!mProcessesReady) { 11513 // if the caller really truly claims to know what they're doing, go 11514 // ahead and allow the broadcast without launching any receivers 11515 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11516 intent = new Intent(intent); 11517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11518 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11519 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11520 + " before boot completion"); 11521 throw new IllegalStateException("Cannot broadcast before boot completed"); 11522 } 11523 } 11524 11525 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11526 throw new IllegalArgumentException( 11527 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11528 } 11529 11530 return intent; 11531 } 11532 11533 public final int broadcastIntent(IApplicationThread caller, 11534 Intent intent, String resolvedType, IIntentReceiver resultTo, 11535 int resultCode, String resultData, Bundle map, 11536 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11537 enforceNotIsolatedCaller("broadcastIntent"); 11538 synchronized(this) { 11539 intent = verifyBroadcastLocked(intent); 11540 11541 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11542 final int callingPid = Binder.getCallingPid(); 11543 final int callingUid = Binder.getCallingUid(); 11544 final long origId = Binder.clearCallingIdentity(); 11545 int res = broadcastIntentLocked(callerApp, 11546 callerApp != null ? callerApp.info.packageName : null, 11547 intent, resolvedType, resultTo, 11548 resultCode, resultData, map, requiredPermission, serialized, sticky, 11549 callingPid, callingUid, userId); 11550 Binder.restoreCallingIdentity(origId); 11551 return res; 11552 } 11553 } 11554 11555 int broadcastIntentInPackage(String packageName, int uid, 11556 Intent intent, String resolvedType, IIntentReceiver resultTo, 11557 int resultCode, String resultData, Bundle map, 11558 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11559 synchronized(this) { 11560 intent = verifyBroadcastLocked(intent); 11561 11562 final long origId = Binder.clearCallingIdentity(); 11563 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11564 resultTo, resultCode, resultData, map, requiredPermission, 11565 serialized, sticky, -1, uid, userId); 11566 Binder.restoreCallingIdentity(origId); 11567 return res; 11568 } 11569 } 11570 11571 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11572 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11573 // Refuse possible leaked file descriptors 11574 if (intent != null && intent.hasFileDescriptors() == true) { 11575 throw new IllegalArgumentException("File descriptors passed in Intent"); 11576 } 11577 11578 synchronized(this) { 11579 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11580 != PackageManager.PERMISSION_GRANTED) { 11581 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11582 + Binder.getCallingPid() 11583 + ", uid=" + Binder.getCallingUid() 11584 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11585 Slog.w(TAG, msg); 11586 throw new SecurityException(msg); 11587 } 11588 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11589 if (list != null) { 11590 int N = list.size(); 11591 int i; 11592 for (i=0; i<N; i++) { 11593 if (intent.filterEquals(list.get(i))) { 11594 list.remove(i); 11595 break; 11596 } 11597 } 11598 } 11599 } 11600 } 11601 11602 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11603 String resultData, Bundle resultExtras, boolean resultAbort, 11604 boolean explicit) { 11605 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11606 if (r == null) { 11607 Slog.w(TAG, "finishReceiver called but not found on queue"); 11608 return false; 11609 } 11610 11611 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11612 explicit); 11613 } 11614 11615 public void finishReceiver(IBinder who, int resultCode, String resultData, 11616 Bundle resultExtras, boolean resultAbort) { 11617 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11618 11619 // Refuse possible leaked file descriptors 11620 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11621 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11622 } 11623 11624 final long origId = Binder.clearCallingIdentity(); 11625 try { 11626 boolean doNext = false; 11627 BroadcastRecord r = null; 11628 11629 synchronized(this) { 11630 r = broadcastRecordForReceiverLocked(who); 11631 if (r != null) { 11632 doNext = r.queue.finishReceiverLocked(r, resultCode, 11633 resultData, resultExtras, resultAbort, true); 11634 } 11635 } 11636 11637 if (doNext) { 11638 r.queue.processNextBroadcast(false); 11639 } 11640 trimApplications(); 11641 } finally { 11642 Binder.restoreCallingIdentity(origId); 11643 } 11644 } 11645 11646 // ========================================================= 11647 // INSTRUMENTATION 11648 // ========================================================= 11649 11650 public boolean startInstrumentation(ComponentName className, 11651 String profileFile, int flags, Bundle arguments, 11652 IInstrumentationWatcher watcher) { 11653 enforceNotIsolatedCaller("startInstrumentation"); 11654 // Refuse possible leaked file descriptors 11655 if (arguments != null && arguments.hasFileDescriptors()) { 11656 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11657 } 11658 11659 synchronized(this) { 11660 InstrumentationInfo ii = null; 11661 ApplicationInfo ai = null; 11662 try { 11663 ii = mContext.getPackageManager().getInstrumentationInfo( 11664 className, STOCK_PM_FLAGS); 11665 ai = mContext.getPackageManager().getApplicationInfo( 11666 ii.targetPackage, STOCK_PM_FLAGS); 11667 } catch (PackageManager.NameNotFoundException e) { 11668 } 11669 if (ii == null) { 11670 reportStartInstrumentationFailure(watcher, className, 11671 "Unable to find instrumentation info for: " + className); 11672 return false; 11673 } 11674 if (ai == null) { 11675 reportStartInstrumentationFailure(watcher, className, 11676 "Unable to find instrumentation target package: " + ii.targetPackage); 11677 return false; 11678 } 11679 11680 int match = mContext.getPackageManager().checkSignatures( 11681 ii.targetPackage, ii.packageName); 11682 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11683 String msg = "Permission Denial: starting instrumentation " 11684 + className + " from pid=" 11685 + Binder.getCallingPid() 11686 + ", uid=" + Binder.getCallingPid() 11687 + " not allowed because package " + ii.packageName 11688 + " does not have a signature matching the target " 11689 + ii.targetPackage; 11690 reportStartInstrumentationFailure(watcher, className, msg); 11691 throw new SecurityException(msg); 11692 } 11693 11694 int userId = UserHandle.getCallingUserId(); 11695 final long origId = Binder.clearCallingIdentity(); 11696 // Instrumentation can kill and relaunch even persistent processes 11697 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11698 ProcessRecord app = addAppLocked(ai, false); 11699 app.instrumentationClass = className; 11700 app.instrumentationInfo = ai; 11701 app.instrumentationProfileFile = profileFile; 11702 app.instrumentationArguments = arguments; 11703 app.instrumentationWatcher = watcher; 11704 app.instrumentationResultClass = className; 11705 Binder.restoreCallingIdentity(origId); 11706 } 11707 11708 return true; 11709 } 11710 11711 /** 11712 * Report errors that occur while attempting to start Instrumentation. Always writes the 11713 * error to the logs, but if somebody is watching, send the report there too. This enables 11714 * the "am" command to report errors with more information. 11715 * 11716 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11717 * @param cn The component name of the instrumentation. 11718 * @param report The error report. 11719 */ 11720 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11721 ComponentName cn, String report) { 11722 Slog.w(TAG, report); 11723 try { 11724 if (watcher != null) { 11725 Bundle results = new Bundle(); 11726 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11727 results.putString("Error", report); 11728 watcher.instrumentationStatus(cn, -1, results); 11729 } 11730 } catch (RemoteException e) { 11731 Slog.w(TAG, e); 11732 } 11733 } 11734 11735 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11736 if (app.instrumentationWatcher != null) { 11737 try { 11738 // NOTE: IInstrumentationWatcher *must* be oneway here 11739 app.instrumentationWatcher.instrumentationFinished( 11740 app.instrumentationClass, 11741 resultCode, 11742 results); 11743 } catch (RemoteException e) { 11744 } 11745 } 11746 app.instrumentationWatcher = null; 11747 app.instrumentationClass = null; 11748 app.instrumentationInfo = null; 11749 app.instrumentationProfileFile = null; 11750 app.instrumentationArguments = null; 11751 11752 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 11753 } 11754 11755 public void finishInstrumentation(IApplicationThread target, 11756 int resultCode, Bundle results) { 11757 int userId = UserHandle.getCallingUserId(); 11758 // Refuse possible leaked file descriptors 11759 if (results != null && results.hasFileDescriptors()) { 11760 throw new IllegalArgumentException("File descriptors passed in Intent"); 11761 } 11762 11763 synchronized(this) { 11764 ProcessRecord app = getRecordForAppLocked(target); 11765 if (app == null) { 11766 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11767 return; 11768 } 11769 final long origId = Binder.clearCallingIdentity(); 11770 finishInstrumentationLocked(app, resultCode, results); 11771 Binder.restoreCallingIdentity(origId); 11772 } 11773 } 11774 11775 // ========================================================= 11776 // CONFIGURATION 11777 // ========================================================= 11778 11779 public ConfigurationInfo getDeviceConfigurationInfo() { 11780 ConfigurationInfo config = new ConfigurationInfo(); 11781 synchronized (this) { 11782 config.reqTouchScreen = mConfiguration.touchscreen; 11783 config.reqKeyboardType = mConfiguration.keyboard; 11784 config.reqNavigation = mConfiguration.navigation; 11785 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11786 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11787 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11788 } 11789 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11790 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11791 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11792 } 11793 config.reqGlEsVersion = GL_ES_VERSION; 11794 } 11795 return config; 11796 } 11797 11798 public Configuration getConfiguration() { 11799 Configuration ci; 11800 synchronized(this) { 11801 ci = new Configuration(mConfiguration); 11802 } 11803 return ci; 11804 } 11805 11806 public void updatePersistentConfiguration(Configuration values) { 11807 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11808 "updateConfiguration()"); 11809 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11810 "updateConfiguration()"); 11811 if (values == null) { 11812 throw new NullPointerException("Configuration must not be null"); 11813 } 11814 11815 synchronized(this) { 11816 final long origId = Binder.clearCallingIdentity(); 11817 updateConfigurationLocked(values, null, true, false); 11818 Binder.restoreCallingIdentity(origId); 11819 } 11820 } 11821 11822 public void updateConfiguration(Configuration values) { 11823 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11824 "updateConfiguration()"); 11825 11826 synchronized(this) { 11827 if (values == null && mWindowManager != null) { 11828 // sentinel: fetch the current configuration from the window manager 11829 values = mWindowManager.computeNewConfiguration(); 11830 } 11831 11832 if (mWindowManager != null) { 11833 mProcessList.applyDisplaySize(mWindowManager); 11834 } 11835 11836 final long origId = Binder.clearCallingIdentity(); 11837 if (values != null) { 11838 Settings.System.clearConfiguration(values); 11839 } 11840 updateConfigurationLocked(values, null, false, false); 11841 Binder.restoreCallingIdentity(origId); 11842 } 11843 } 11844 11845 /** 11846 * Do either or both things: (1) change the current configuration, and (2) 11847 * make sure the given activity is running with the (now) current 11848 * configuration. Returns true if the activity has been left running, or 11849 * false if <var>starting</var> is being destroyed to match the new 11850 * configuration. 11851 * @param persistent TODO 11852 */ 11853 boolean updateConfigurationLocked(Configuration values, 11854 ActivityRecord starting, boolean persistent, boolean initLocale) { 11855 // do nothing if we are headless 11856 if (mHeadless) return true; 11857 11858 int changes = 0; 11859 11860 boolean kept = true; 11861 11862 if (values != null) { 11863 Configuration newConfig = new Configuration(mConfiguration); 11864 changes = newConfig.updateFrom(values); 11865 if (changes != 0) { 11866 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11867 Slog.i(TAG, "Updating configuration to: " + values); 11868 } 11869 11870 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11871 11872 if (values.locale != null && !initLocale) { 11873 saveLocaleLocked(values.locale, 11874 !values.locale.equals(mConfiguration.locale), 11875 values.userSetLocale); 11876 } 11877 11878 mConfigurationSeq++; 11879 if (mConfigurationSeq <= 0) { 11880 mConfigurationSeq = 1; 11881 } 11882 newConfig.seq = mConfigurationSeq; 11883 mConfiguration = newConfig; 11884 Slog.i(TAG, "Config changed: " + newConfig); 11885 11886 final Configuration configCopy = new Configuration(mConfiguration); 11887 11888 // TODO: If our config changes, should we auto dismiss any currently 11889 // showing dialogs? 11890 mShowDialogs = shouldShowDialogs(newConfig); 11891 11892 AttributeCache ac = AttributeCache.instance(); 11893 if (ac != null) { 11894 ac.updateConfiguration(configCopy); 11895 } 11896 11897 // Make sure all resources in our process are updated 11898 // right now, so that anyone who is going to retrieve 11899 // resource values after we return will be sure to get 11900 // the new ones. This is especially important during 11901 // boot, where the first config change needs to guarantee 11902 // all resources have that config before following boot 11903 // code is executed. 11904 mSystemThread.applyConfigurationToResources(configCopy); 11905 11906 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11907 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11908 msg.obj = new Configuration(configCopy); 11909 mHandler.sendMessage(msg); 11910 } 11911 11912 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11913 ProcessRecord app = mLruProcesses.get(i); 11914 try { 11915 if (app.thread != null) { 11916 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11917 + app.processName + " new config " + mConfiguration); 11918 app.thread.scheduleConfigurationChanged(configCopy); 11919 } 11920 } catch (Exception e) { 11921 } 11922 } 11923 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11924 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11925 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11926 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11927 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11928 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11929 broadcastIntentLocked(null, null, 11930 new Intent(Intent.ACTION_LOCALE_CHANGED), 11931 null, null, 0, null, null, 11932 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11933 } 11934 } 11935 } 11936 11937 if (changes != 0 && starting == null) { 11938 // If the configuration changed, and the caller is not already 11939 // in the process of starting an activity, then find the top 11940 // activity to check if its configuration needs to change. 11941 starting = mMainStack.topRunningActivityLocked(null); 11942 } 11943 11944 if (starting != null) { 11945 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11946 // And we need to make sure at this point that all other activities 11947 // are made visible with the correct configuration. 11948 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11949 } 11950 11951 if (values != null && mWindowManager != null) { 11952 mWindowManager.setNewConfiguration(mConfiguration); 11953 } 11954 11955 return kept; 11956 } 11957 11958 /** 11959 * Decide based on the configuration whether we should shouw the ANR, 11960 * crash, etc dialogs. The idea is that if there is no affordnace to 11961 * press the on-screen buttons, we shouldn't show the dialog. 11962 * 11963 * A thought: SystemUI might also want to get told about this, the Power 11964 * dialog / global actions also might want different behaviors. 11965 */ 11966 private static final boolean shouldShowDialogs(Configuration config) { 11967 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11968 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11969 } 11970 11971 /** 11972 * Save the locale. You must be inside a synchronized (this) block. 11973 */ 11974 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11975 if(isDiff) { 11976 SystemProperties.set("user.language", l.getLanguage()); 11977 SystemProperties.set("user.region", l.getCountry()); 11978 } 11979 11980 if(isPersist) { 11981 SystemProperties.set("persist.sys.language", l.getLanguage()); 11982 SystemProperties.set("persist.sys.country", l.getCountry()); 11983 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11984 } 11985 } 11986 11987 @Override 11988 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11989 ActivityRecord srec = ActivityRecord.forToken(token); 11990 return srec != null && srec.task.affinity != null && 11991 srec.task.affinity.equals(destAffinity); 11992 } 11993 11994 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11995 Intent resultData) { 11996 ComponentName dest = destIntent.getComponent(); 11997 11998 synchronized (this) { 11999 ActivityRecord srec = ActivityRecord.forToken(token); 12000 if (srec == null) { 12001 return false; 12002 } 12003 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12004 final int start = history.indexOf(srec); 12005 if (start < 0) { 12006 // Current activity is not in history stack; do nothing. 12007 return false; 12008 } 12009 int finishTo = start - 1; 12010 ActivityRecord parent = null; 12011 boolean foundParentInTask = false; 12012 if (dest != null) { 12013 TaskRecord tr = srec.task; 12014 for (int i = start - 1; i >= 0; i--) { 12015 ActivityRecord r = history.get(i); 12016 if (tr != r.task) { 12017 // Couldn't find parent in the same task; stop at the one above this. 12018 // (Root of current task; in-app "home" behavior) 12019 // Always at least finish the current activity. 12020 finishTo = Math.min(start - 1, i + 1); 12021 parent = history.get(finishTo); 12022 break; 12023 } else if (r.info.packageName.equals(dest.getPackageName()) && 12024 r.info.name.equals(dest.getClassName())) { 12025 finishTo = i; 12026 parent = r; 12027 foundParentInTask = true; 12028 break; 12029 } 12030 } 12031 } 12032 12033 if (mController != null) { 12034 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12035 if (next != null) { 12036 // ask watcher if this is allowed 12037 boolean resumeOK = true; 12038 try { 12039 resumeOK = mController.activityResuming(next.packageName); 12040 } catch (RemoteException e) { 12041 mController = null; 12042 } 12043 12044 if (!resumeOK) { 12045 return false; 12046 } 12047 } 12048 } 12049 final long origId = Binder.clearCallingIdentity(); 12050 for (int i = start; i > finishTo; i--) { 12051 ActivityRecord r = history.get(i); 12052 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12053 "navigate-up"); 12054 // Only return the supplied result for the first activity finished 12055 resultCode = Activity.RESULT_CANCELED; 12056 resultData = null; 12057 } 12058 12059 if (parent != null && foundParentInTask) { 12060 final int parentLaunchMode = parent.info.launchMode; 12061 final int destIntentFlags = destIntent.getFlags(); 12062 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12063 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12064 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12065 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12066 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12067 } else { 12068 try { 12069 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12070 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12071 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12072 null, aInfo, parent.appToken, null, 12073 0, -1, parent.launchedFromUid, 0, null, true, null); 12074 foundParentInTask = res == ActivityManager.START_SUCCESS; 12075 } catch (RemoteException e) { 12076 foundParentInTask = false; 12077 } 12078 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12079 resultData, "navigate-up"); 12080 } 12081 } 12082 Binder.restoreCallingIdentity(origId); 12083 return foundParentInTask; 12084 } 12085 } 12086 12087 public int getLaunchedFromUid(IBinder activityToken) { 12088 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12089 if (srec == null) { 12090 return -1; 12091 } 12092 return srec.launchedFromUid; 12093 } 12094 12095 // ========================================================= 12096 // LIFETIME MANAGEMENT 12097 // ========================================================= 12098 12099 // Returns which broadcast queue the app is the current [or imminent] receiver 12100 // on, or 'null' if the app is not an active broadcast recipient. 12101 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12102 BroadcastRecord r = app.curReceiver; 12103 if (r != null) { 12104 return r.queue; 12105 } 12106 12107 // It's not the current receiver, but it might be starting up to become one 12108 synchronized (this) { 12109 for (BroadcastQueue queue : mBroadcastQueues) { 12110 r = queue.mPendingBroadcast; 12111 if (r != null && r.curApp == app) { 12112 // found it; report which queue it's in 12113 return queue; 12114 } 12115 } 12116 } 12117 12118 return null; 12119 } 12120 12121 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12122 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12123 if (mAdjSeq == app.adjSeq) { 12124 // This adjustment has already been computed. If we are calling 12125 // from the top, we may have already computed our adjustment with 12126 // an earlier hidden adjustment that isn't really for us... if 12127 // so, use the new hidden adjustment. 12128 if (!recursed && app.hidden) { 12129 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12130 app.hasActivities ? hiddenAdj : emptyAdj; 12131 } 12132 return app.curRawAdj; 12133 } 12134 12135 if (app.thread == null) { 12136 app.adjSeq = mAdjSeq; 12137 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12138 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12139 } 12140 12141 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12142 app.adjSource = null; 12143 app.adjTarget = null; 12144 app.empty = false; 12145 app.hidden = false; 12146 12147 final int activitiesSize = app.activities.size(); 12148 12149 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12150 // The max adjustment doesn't allow this app to be anything 12151 // below foreground, so it is not worth doing work for it. 12152 app.adjType = "fixed"; 12153 app.adjSeq = mAdjSeq; 12154 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12155 app.hasActivities = false; 12156 app.foregroundActivities = false; 12157 app.keeping = true; 12158 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12159 // System process can do UI, and when they do we want to have 12160 // them trim their memory after the user leaves the UI. To 12161 // facilitate this, here we need to determine whether or not it 12162 // is currently showing UI. 12163 app.systemNoUi = true; 12164 if (app == TOP_APP) { 12165 app.systemNoUi = false; 12166 app.hasActivities = true; 12167 } else if (activitiesSize > 0) { 12168 for (int j = 0; j < activitiesSize; j++) { 12169 final ActivityRecord r = app.activities.get(j); 12170 if (r.visible) { 12171 app.systemNoUi = false; 12172 } 12173 if (r.app == app) { 12174 app.hasActivities = true; 12175 } 12176 } 12177 } 12178 return (app.curAdj=app.maxAdj); 12179 } 12180 12181 app.keeping = false; 12182 app.systemNoUi = false; 12183 app.hasActivities = false; 12184 12185 // Determine the importance of the process, starting with most 12186 // important to least, and assign an appropriate OOM adjustment. 12187 int adj; 12188 int schedGroup; 12189 boolean foregroundActivities = false; 12190 boolean interesting = false; 12191 BroadcastQueue queue; 12192 if (app == TOP_APP) { 12193 // The last app on the list is the foreground app. 12194 adj = ProcessList.FOREGROUND_APP_ADJ; 12195 schedGroup = Process.THREAD_GROUP_DEFAULT; 12196 app.adjType = "top-activity"; 12197 foregroundActivities = true; 12198 interesting = true; 12199 app.hasActivities = true; 12200 } else if (app.instrumentationClass != null) { 12201 // Don't want to kill running instrumentation. 12202 adj = ProcessList.FOREGROUND_APP_ADJ; 12203 schedGroup = Process.THREAD_GROUP_DEFAULT; 12204 app.adjType = "instrumentation"; 12205 interesting = true; 12206 } else if ((queue = isReceivingBroadcast(app)) != null) { 12207 // An app that is currently receiving a broadcast also 12208 // counts as being in the foreground for OOM killer purposes. 12209 // It's placed in a sched group based on the nature of the 12210 // broadcast as reflected by which queue it's active in. 12211 adj = ProcessList.FOREGROUND_APP_ADJ; 12212 schedGroup = (queue == mFgBroadcastQueue) 12213 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12214 app.adjType = "broadcast"; 12215 } else if (app.executingServices.size() > 0) { 12216 // An app that is currently executing a service callback also 12217 // counts as being in the foreground. 12218 adj = ProcessList.FOREGROUND_APP_ADJ; 12219 schedGroup = Process.THREAD_GROUP_DEFAULT; 12220 app.adjType = "exec-service"; 12221 } else { 12222 // Assume process is hidden (has activities); we will correct 12223 // later if this is not the case. 12224 adj = hiddenAdj; 12225 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12226 app.hidden = true; 12227 app.adjType = "bg-activities"; 12228 } 12229 12230 boolean hasStoppingActivities = false; 12231 12232 // Examine all activities if not already foreground. 12233 if (!foregroundActivities && activitiesSize > 0) { 12234 for (int j = 0; j < activitiesSize; j++) { 12235 final ActivityRecord r = app.activities.get(j); 12236 if (r.visible) { 12237 // App has a visible activity; only upgrade adjustment. 12238 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12239 adj = ProcessList.VISIBLE_APP_ADJ; 12240 app.adjType = "visible"; 12241 } 12242 schedGroup = Process.THREAD_GROUP_DEFAULT; 12243 app.hidden = false; 12244 app.hasActivities = true; 12245 foregroundActivities = true; 12246 break; 12247 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12248 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12249 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12250 app.adjType = "pausing"; 12251 } 12252 app.hidden = false; 12253 foregroundActivities = true; 12254 } else if (r.state == ActivityState.STOPPING) { 12255 // We will apply the actual adjustment later, because 12256 // we want to allow this process to immediately go through 12257 // any memory trimming that is in effect. 12258 app.hidden = false; 12259 foregroundActivities = true; 12260 hasStoppingActivities = true; 12261 } 12262 if (r.app == app) { 12263 app.hasActivities = true; 12264 } 12265 } 12266 } 12267 12268 if (adj == hiddenAdj && !app.hasActivities) { 12269 // Whoops, this process is completely empty as far as we know 12270 // at this point. 12271 adj = emptyAdj; 12272 app.empty = true; 12273 app.adjType = "bg-empty"; 12274 } 12275 12276 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12277 if (app.foregroundServices) { 12278 // The user is aware of this app, so make it visible. 12279 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12280 app.hidden = false; 12281 app.adjType = "foreground-service"; 12282 schedGroup = Process.THREAD_GROUP_DEFAULT; 12283 } else if (app.forcingToForeground != null) { 12284 // The user is aware of this app, so make it visible. 12285 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12286 app.hidden = false; 12287 app.adjType = "force-foreground"; 12288 app.adjSource = app.forcingToForeground; 12289 schedGroup = Process.THREAD_GROUP_DEFAULT; 12290 } 12291 } 12292 12293 if (app.foregroundServices) { 12294 interesting = true; 12295 } 12296 12297 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12298 // We don't want to kill the current heavy-weight process. 12299 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12300 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12301 app.hidden = false; 12302 app.adjType = "heavy"; 12303 } 12304 12305 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12306 // This process is hosting what we currently consider to be the 12307 // home app, so we don't want to let it go into the background. 12308 adj = ProcessList.HOME_APP_ADJ; 12309 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12310 app.hidden = false; 12311 app.adjType = "home"; 12312 } 12313 12314 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12315 && app.activities.size() > 0) { 12316 // This was the previous process that showed UI to the user. 12317 // We want to try to keep it around more aggressively, to give 12318 // a good experience around switching between two apps. 12319 adj = ProcessList.PREVIOUS_APP_ADJ; 12320 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12321 app.hidden = false; 12322 app.adjType = "previous"; 12323 } 12324 12325 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12326 + " reason=" + app.adjType); 12327 12328 // By default, we use the computed adjustment. It may be changed if 12329 // there are applications dependent on our services or providers, but 12330 // this gives us a baseline and makes sure we don't get into an 12331 // infinite recursion. 12332 app.adjSeq = mAdjSeq; 12333 app.curRawAdj = app.nonStoppingAdj = adj; 12334 12335 if (mBackupTarget != null && app == mBackupTarget.app) { 12336 // If possible we want to avoid killing apps while they're being backed up 12337 if (adj > ProcessList.BACKUP_APP_ADJ) { 12338 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12339 adj = ProcessList.BACKUP_APP_ADJ; 12340 app.adjType = "backup"; 12341 app.hidden = false; 12342 } 12343 } 12344 12345 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12346 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12347 final long now = SystemClock.uptimeMillis(); 12348 // This process is more important if the top activity is 12349 // bound to the service. 12350 Iterator<ServiceRecord> jt = app.services.iterator(); 12351 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12352 ServiceRecord s = jt.next(); 12353 if (s.startRequested) { 12354 if (app.hasShownUi && app != mHomeProcess) { 12355 // If this process has shown some UI, let it immediately 12356 // go to the LRU list because it may be pretty heavy with 12357 // UI stuff. We'll tag it with a label just to help 12358 // debug and understand what is going on. 12359 if (adj > ProcessList.SERVICE_ADJ) { 12360 app.adjType = "started-bg-ui-services"; 12361 } 12362 } else { 12363 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12364 // This service has seen some activity within 12365 // recent memory, so we will keep its process ahead 12366 // of the background processes. 12367 if (adj > ProcessList.SERVICE_ADJ) { 12368 adj = ProcessList.SERVICE_ADJ; 12369 app.adjType = "started-services"; 12370 app.hidden = false; 12371 } 12372 } 12373 // If we have let the service slide into the background 12374 // state, still have some text describing what it is doing 12375 // even though the service no longer has an impact. 12376 if (adj > ProcessList.SERVICE_ADJ) { 12377 app.adjType = "started-bg-services"; 12378 } 12379 } 12380 // Don't kill this process because it is doing work; it 12381 // has said it is doing work. 12382 app.keeping = true; 12383 } 12384 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12385 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12386 Iterator<ArrayList<ConnectionRecord>> kt 12387 = s.connections.values().iterator(); 12388 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12389 ArrayList<ConnectionRecord> clist = kt.next(); 12390 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12391 // XXX should compute this based on the max of 12392 // all connected clients. 12393 ConnectionRecord cr = clist.get(i); 12394 if (cr.binding.client == app) { 12395 // Binding to ourself is not interesting. 12396 continue; 12397 } 12398 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12399 ProcessRecord client = cr.binding.client; 12400 int clientAdj = adj; 12401 int myHiddenAdj = hiddenAdj; 12402 if (myHiddenAdj > client.hiddenAdj) { 12403 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12404 myHiddenAdj = client.hiddenAdj; 12405 } else { 12406 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12407 } 12408 } 12409 int myEmptyAdj = emptyAdj; 12410 if (myEmptyAdj > client.emptyAdj) { 12411 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12412 myEmptyAdj = client.emptyAdj; 12413 } else { 12414 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12415 } 12416 } 12417 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12418 myEmptyAdj, TOP_APP, true, doingAll); 12419 String adjType = null; 12420 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12421 // Not doing bind OOM management, so treat 12422 // this guy more like a started service. 12423 if (app.hasShownUi && app != mHomeProcess) { 12424 // If this process has shown some UI, let it immediately 12425 // go to the LRU list because it may be pretty heavy with 12426 // UI stuff. We'll tag it with a label just to help 12427 // debug and understand what is going on. 12428 if (adj > clientAdj) { 12429 adjType = "bound-bg-ui-services"; 12430 } 12431 app.hidden = false; 12432 clientAdj = adj; 12433 } else { 12434 if (now >= (s.lastActivity 12435 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12436 // This service has not seen activity within 12437 // recent memory, so allow it to drop to the 12438 // LRU list if there is no other reason to keep 12439 // it around. We'll also tag it with a label just 12440 // to help debug and undertand what is going on. 12441 if (adj > clientAdj) { 12442 adjType = "bound-bg-services"; 12443 } 12444 clientAdj = adj; 12445 } 12446 } 12447 } 12448 if (adj > clientAdj) { 12449 // If this process has recently shown UI, and 12450 // the process that is binding to it is less 12451 // important than being visible, then we don't 12452 // care about the binding as much as we care 12453 // about letting this process get into the LRU 12454 // list to be killed and restarted if needed for 12455 // memory. 12456 if (app.hasShownUi && app != mHomeProcess 12457 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12458 adjType = "bound-bg-ui-services"; 12459 } else { 12460 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12461 |Context.BIND_IMPORTANT)) != 0) { 12462 adj = clientAdj; 12463 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12464 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12465 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12466 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12467 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12468 adj = clientAdj; 12469 } else { 12470 app.pendingUiClean = true; 12471 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12472 adj = ProcessList.VISIBLE_APP_ADJ; 12473 } 12474 } 12475 if (!client.hidden) { 12476 app.hidden = false; 12477 } 12478 if (client.keeping) { 12479 app.keeping = true; 12480 } 12481 adjType = "service"; 12482 } 12483 } 12484 if (adjType != null) { 12485 app.adjType = adjType; 12486 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12487 .REASON_SERVICE_IN_USE; 12488 app.adjSource = cr.binding.client; 12489 app.adjSourceOom = clientAdj; 12490 app.adjTarget = s.name; 12491 } 12492 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12493 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12494 schedGroup = Process.THREAD_GROUP_DEFAULT; 12495 } 12496 } 12497 } 12498 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12499 ActivityRecord a = cr.activity; 12500 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12501 (a.visible || a.state == ActivityState.RESUMED 12502 || a.state == ActivityState.PAUSING)) { 12503 adj = ProcessList.FOREGROUND_APP_ADJ; 12504 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12505 schedGroup = Process.THREAD_GROUP_DEFAULT; 12506 } 12507 app.hidden = false; 12508 app.adjType = "service"; 12509 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12510 .REASON_SERVICE_IN_USE; 12511 app.adjSource = a; 12512 app.adjSourceOom = adj; 12513 app.adjTarget = s.name; 12514 } 12515 } 12516 } 12517 } 12518 } 12519 } 12520 12521 // Finally, if this process has active services running in it, we 12522 // would like to avoid killing it unless it would prevent the current 12523 // application from running. By default we put the process in 12524 // with the rest of the background processes; as we scan through 12525 // its services we may bump it up from there. 12526 if (adj > hiddenAdj) { 12527 adj = hiddenAdj; 12528 app.hidden = false; 12529 app.adjType = "bg-services"; 12530 } 12531 } 12532 12533 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12534 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12535 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12536 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12537 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12538 ContentProviderRecord cpr = jt.next(); 12539 for (int i = cpr.connections.size()-1; 12540 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12541 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12542 i--) { 12543 ContentProviderConnection conn = cpr.connections.get(i); 12544 ProcessRecord client = conn.client; 12545 if (client == app) { 12546 // Being our own client is not interesting. 12547 continue; 12548 } 12549 int myHiddenAdj = hiddenAdj; 12550 if (myHiddenAdj > client.hiddenAdj) { 12551 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12552 myHiddenAdj = client.hiddenAdj; 12553 } else { 12554 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12555 } 12556 } 12557 int myEmptyAdj = emptyAdj; 12558 if (myEmptyAdj > client.emptyAdj) { 12559 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12560 myEmptyAdj = client.emptyAdj; 12561 } else { 12562 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12563 } 12564 } 12565 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12566 myEmptyAdj, TOP_APP, true, doingAll); 12567 if (adj > clientAdj) { 12568 if (app.hasShownUi && app != mHomeProcess 12569 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12570 app.adjType = "bg-ui-provider"; 12571 } else { 12572 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12573 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12574 app.adjType = "provider"; 12575 } 12576 if (!client.hidden) { 12577 app.hidden = false; 12578 } 12579 if (client.keeping) { 12580 app.keeping = true; 12581 } 12582 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12583 .REASON_PROVIDER_IN_USE; 12584 app.adjSource = client; 12585 app.adjSourceOom = clientAdj; 12586 app.adjTarget = cpr.name; 12587 } 12588 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12589 schedGroup = Process.THREAD_GROUP_DEFAULT; 12590 } 12591 } 12592 // If the provider has external (non-framework) process 12593 // dependencies, ensure that its adjustment is at least 12594 // FOREGROUND_APP_ADJ. 12595 if (cpr.hasExternalProcessHandles()) { 12596 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12597 adj = ProcessList.FOREGROUND_APP_ADJ; 12598 schedGroup = Process.THREAD_GROUP_DEFAULT; 12599 app.hidden = false; 12600 app.keeping = true; 12601 app.adjType = "provider"; 12602 app.adjTarget = cpr.name; 12603 } 12604 } 12605 } 12606 } 12607 12608 if (adj == ProcessList.SERVICE_ADJ) { 12609 if (doingAll) { 12610 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12611 mNewNumServiceProcs++; 12612 } 12613 if (app.serviceb) { 12614 adj = ProcessList.SERVICE_B_ADJ; 12615 } 12616 } else { 12617 app.serviceb = false; 12618 } 12619 12620 app.nonStoppingAdj = adj; 12621 12622 if (hasStoppingActivities) { 12623 // Only upgrade adjustment. 12624 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12625 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12626 app.adjType = "stopping"; 12627 } 12628 } 12629 12630 app.curRawAdj = adj; 12631 12632 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12633 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12634 if (adj > app.maxAdj) { 12635 adj = app.maxAdj; 12636 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12637 schedGroup = Process.THREAD_GROUP_DEFAULT; 12638 } 12639 } 12640 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12641 app.keeping = true; 12642 } 12643 12644 if (app.hasAboveClient) { 12645 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12646 // then we need to drop its adjustment to be lower than the service's 12647 // in order to honor the request. We want to drop it by one adjustment 12648 // level... but there is special meaning applied to various levels so 12649 // we will skip some of them. 12650 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12651 // System process will not get dropped, ever 12652 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12653 adj = ProcessList.VISIBLE_APP_ADJ; 12654 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12655 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12656 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12657 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12658 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12659 adj++; 12660 } 12661 } 12662 12663 int importance = app.memImportance; 12664 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12665 app.curAdj = adj; 12666 app.curSchedGroup = schedGroup; 12667 if (!interesting) { 12668 // For this reporting, if there is not something explicitly 12669 // interesting in this process then we will push it to the 12670 // background importance. 12671 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12672 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12673 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12674 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12675 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12676 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12677 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12678 } else if (adj >= ProcessList.SERVICE_ADJ) { 12679 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12680 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12681 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12682 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12683 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12684 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12685 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12686 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12687 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12688 } else { 12689 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12690 } 12691 } 12692 12693 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12694 if (foregroundActivities != app.foregroundActivities) { 12695 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12696 } 12697 if (changes != 0) { 12698 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12699 app.memImportance = importance; 12700 app.foregroundActivities = foregroundActivities; 12701 int i = mPendingProcessChanges.size()-1; 12702 ProcessChangeItem item = null; 12703 while (i >= 0) { 12704 item = mPendingProcessChanges.get(i); 12705 if (item.pid == app.pid) { 12706 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12707 break; 12708 } 12709 i--; 12710 } 12711 if (i < 0) { 12712 // No existing item in pending changes; need a new one. 12713 final int NA = mAvailProcessChanges.size(); 12714 if (NA > 0) { 12715 item = mAvailProcessChanges.remove(NA-1); 12716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12717 } else { 12718 item = new ProcessChangeItem(); 12719 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12720 } 12721 item.changes = 0; 12722 item.pid = app.pid; 12723 item.uid = app.info.uid; 12724 if (mPendingProcessChanges.size() == 0) { 12725 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12726 "*** Enqueueing dispatch processes changed!"); 12727 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12728 } 12729 mPendingProcessChanges.add(item); 12730 } 12731 item.changes |= changes; 12732 item.importance = importance; 12733 item.foregroundActivities = foregroundActivities; 12734 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12735 + Integer.toHexString(System.identityHashCode(item)) 12736 + " " + app.toShortString() + ": changes=" + item.changes 12737 + " importance=" + item.importance 12738 + " foreground=" + item.foregroundActivities 12739 + " type=" + app.adjType + " source=" + app.adjSource 12740 + " target=" + app.adjTarget); 12741 } 12742 12743 return app.curRawAdj; 12744 } 12745 12746 /** 12747 * Ask a given process to GC right now. 12748 */ 12749 final void performAppGcLocked(ProcessRecord app) { 12750 try { 12751 app.lastRequestedGc = SystemClock.uptimeMillis(); 12752 if (app.thread != null) { 12753 if (app.reportLowMemory) { 12754 app.reportLowMemory = false; 12755 app.thread.scheduleLowMemory(); 12756 } else { 12757 app.thread.processInBackground(); 12758 } 12759 } 12760 } catch (Exception e) { 12761 // whatever. 12762 } 12763 } 12764 12765 /** 12766 * Returns true if things are idle enough to perform GCs. 12767 */ 12768 private final boolean canGcNowLocked() { 12769 boolean processingBroadcasts = false; 12770 for (BroadcastQueue q : mBroadcastQueues) { 12771 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12772 processingBroadcasts = true; 12773 } 12774 } 12775 return !processingBroadcasts 12776 && (mSleeping || (mMainStack.mResumedActivity != null && 12777 mMainStack.mResumedActivity.idle)); 12778 } 12779 12780 /** 12781 * Perform GCs on all processes that are waiting for it, but only 12782 * if things are idle. 12783 */ 12784 final void performAppGcsLocked() { 12785 final int N = mProcessesToGc.size(); 12786 if (N <= 0) { 12787 return; 12788 } 12789 if (canGcNowLocked()) { 12790 while (mProcessesToGc.size() > 0) { 12791 ProcessRecord proc = mProcessesToGc.remove(0); 12792 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12793 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12794 <= SystemClock.uptimeMillis()) { 12795 // To avoid spamming the system, we will GC processes one 12796 // at a time, waiting a few seconds between each. 12797 performAppGcLocked(proc); 12798 scheduleAppGcsLocked(); 12799 return; 12800 } else { 12801 // It hasn't been long enough since we last GCed this 12802 // process... put it in the list to wait for its time. 12803 addProcessToGcListLocked(proc); 12804 break; 12805 } 12806 } 12807 } 12808 12809 scheduleAppGcsLocked(); 12810 } 12811 } 12812 12813 /** 12814 * If all looks good, perform GCs on all processes waiting for them. 12815 */ 12816 final void performAppGcsIfAppropriateLocked() { 12817 if (canGcNowLocked()) { 12818 performAppGcsLocked(); 12819 return; 12820 } 12821 // Still not idle, wait some more. 12822 scheduleAppGcsLocked(); 12823 } 12824 12825 /** 12826 * Schedule the execution of all pending app GCs. 12827 */ 12828 final void scheduleAppGcsLocked() { 12829 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12830 12831 if (mProcessesToGc.size() > 0) { 12832 // Schedule a GC for the time to the next process. 12833 ProcessRecord proc = mProcessesToGc.get(0); 12834 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12835 12836 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12837 long now = SystemClock.uptimeMillis(); 12838 if (when < (now+GC_TIMEOUT)) { 12839 when = now + GC_TIMEOUT; 12840 } 12841 mHandler.sendMessageAtTime(msg, when); 12842 } 12843 } 12844 12845 /** 12846 * Add a process to the array of processes waiting to be GCed. Keeps the 12847 * list in sorted order by the last GC time. The process can't already be 12848 * on the list. 12849 */ 12850 final void addProcessToGcListLocked(ProcessRecord proc) { 12851 boolean added = false; 12852 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12853 if (mProcessesToGc.get(i).lastRequestedGc < 12854 proc.lastRequestedGc) { 12855 added = true; 12856 mProcessesToGc.add(i+1, proc); 12857 break; 12858 } 12859 } 12860 if (!added) { 12861 mProcessesToGc.add(0, proc); 12862 } 12863 } 12864 12865 /** 12866 * Set up to ask a process to GC itself. This will either do it 12867 * immediately, or put it on the list of processes to gc the next 12868 * time things are idle. 12869 */ 12870 final void scheduleAppGcLocked(ProcessRecord app) { 12871 long now = SystemClock.uptimeMillis(); 12872 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12873 return; 12874 } 12875 if (!mProcessesToGc.contains(app)) { 12876 addProcessToGcListLocked(app); 12877 scheduleAppGcsLocked(); 12878 } 12879 } 12880 12881 final void checkExcessivePowerUsageLocked(boolean doKills) { 12882 updateCpuStatsNow(); 12883 12884 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12885 boolean doWakeKills = doKills; 12886 boolean doCpuKills = doKills; 12887 if (mLastPowerCheckRealtime == 0) { 12888 doWakeKills = false; 12889 } 12890 if (mLastPowerCheckUptime == 0) { 12891 doCpuKills = false; 12892 } 12893 if (stats.isScreenOn()) { 12894 doWakeKills = false; 12895 } 12896 final long curRealtime = SystemClock.elapsedRealtime(); 12897 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12898 final long curUptime = SystemClock.uptimeMillis(); 12899 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12900 mLastPowerCheckRealtime = curRealtime; 12901 mLastPowerCheckUptime = curUptime; 12902 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12903 doWakeKills = false; 12904 } 12905 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12906 doCpuKills = false; 12907 } 12908 int i = mLruProcesses.size(); 12909 while (i > 0) { 12910 i--; 12911 ProcessRecord app = mLruProcesses.get(i); 12912 if (!app.keeping) { 12913 long wtime; 12914 synchronized (stats) { 12915 wtime = stats.getProcessWakeTime(app.info.uid, 12916 app.pid, curRealtime); 12917 } 12918 long wtimeUsed = wtime - app.lastWakeTime; 12919 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12920 if (DEBUG_POWER) { 12921 StringBuilder sb = new StringBuilder(128); 12922 sb.append("Wake for "); 12923 app.toShortString(sb); 12924 sb.append(": over "); 12925 TimeUtils.formatDuration(realtimeSince, sb); 12926 sb.append(" used "); 12927 TimeUtils.formatDuration(wtimeUsed, sb); 12928 sb.append(" ("); 12929 sb.append((wtimeUsed*100)/realtimeSince); 12930 sb.append("%)"); 12931 Slog.i(TAG, sb.toString()); 12932 sb.setLength(0); 12933 sb.append("CPU for "); 12934 app.toShortString(sb); 12935 sb.append(": over "); 12936 TimeUtils.formatDuration(uptimeSince, sb); 12937 sb.append(" used "); 12938 TimeUtils.formatDuration(cputimeUsed, sb); 12939 sb.append(" ("); 12940 sb.append((cputimeUsed*100)/uptimeSince); 12941 sb.append("%)"); 12942 Slog.i(TAG, sb.toString()); 12943 } 12944 // If a process has held a wake lock for more 12945 // than 50% of the time during this period, 12946 // that sounds bad. Kill! 12947 if (doWakeKills && realtimeSince > 0 12948 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12949 synchronized (stats) { 12950 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12951 realtimeSince, wtimeUsed); 12952 } 12953 Slog.w(TAG, "Excessive wake lock in " + app.processName 12954 + " (pid " + app.pid + "): held " + wtimeUsed 12955 + " during " + realtimeSince); 12956 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12957 app.processName, app.setAdj, "excessive wake lock"); 12958 Process.killProcessQuiet(app.pid); 12959 } else if (doCpuKills && uptimeSince > 0 12960 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12961 synchronized (stats) { 12962 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12963 uptimeSince, cputimeUsed); 12964 } 12965 Slog.w(TAG, "Excessive CPU in " + app.processName 12966 + " (pid " + app.pid + "): used " + cputimeUsed 12967 + " during " + uptimeSince); 12968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12969 app.processName, app.setAdj, "excessive cpu"); 12970 Process.killProcessQuiet(app.pid); 12971 } else { 12972 app.lastWakeTime = wtime; 12973 app.lastCpuTime = app.curCpuTime; 12974 } 12975 } 12976 } 12977 } 12978 12979 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12980 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12981 app.hiddenAdj = hiddenAdj; 12982 app.emptyAdj = emptyAdj; 12983 12984 if (app.thread == null) { 12985 return false; 12986 } 12987 12988 final boolean wasKeeping = app.keeping; 12989 12990 boolean success = true; 12991 12992 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12993 12994 if (app.curRawAdj != app.setRawAdj) { 12995 if (wasKeeping && !app.keeping) { 12996 // This app is no longer something we want to keep. Note 12997 // its current wake lock time to later know to kill it if 12998 // it is not behaving well. 12999 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13000 synchronized (stats) { 13001 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13002 app.pid, SystemClock.elapsedRealtime()); 13003 } 13004 app.lastCpuTime = app.curCpuTime; 13005 } 13006 13007 app.setRawAdj = app.curRawAdj; 13008 } 13009 13010 if (app.curAdj != app.setAdj) { 13011 if (Process.setOomAdj(app.pid, app.curAdj)) { 13012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13013 TAG, "Set " + app.pid + " " + app.processName + 13014 " adj " + app.curAdj + ": " + app.adjType); 13015 app.setAdj = app.curAdj; 13016 } else { 13017 success = false; 13018 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13019 } 13020 } 13021 if (app.setSchedGroup != app.curSchedGroup) { 13022 app.setSchedGroup = app.curSchedGroup; 13023 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13024 "Setting process group of " + app.processName 13025 + " to " + app.curSchedGroup); 13026 if (app.waitingToKill != null && 13027 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13028 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13029 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13030 app.processName, app.setAdj, app.waitingToKill); 13031 app.killedBackground = true; 13032 Process.killProcessQuiet(app.pid); 13033 success = false; 13034 } else { 13035 if (true) { 13036 long oldId = Binder.clearCallingIdentity(); 13037 try { 13038 Process.setProcessGroup(app.pid, app.curSchedGroup); 13039 } catch (Exception e) { 13040 Slog.w(TAG, "Failed setting process group of " + app.pid 13041 + " to " + app.curSchedGroup); 13042 e.printStackTrace(); 13043 } finally { 13044 Binder.restoreCallingIdentity(oldId); 13045 } 13046 } else { 13047 if (app.thread != null) { 13048 try { 13049 app.thread.setSchedulingGroup(app.curSchedGroup); 13050 } catch (RemoteException e) { 13051 } 13052 } 13053 } 13054 } 13055 } 13056 return success; 13057 } 13058 13059 private final ActivityRecord resumedAppLocked() { 13060 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13061 if (resumedActivity == null || resumedActivity.app == null) { 13062 resumedActivity = mMainStack.mPausingActivity; 13063 if (resumedActivity == null || resumedActivity.app == null) { 13064 resumedActivity = mMainStack.topRunningActivityLocked(null); 13065 } 13066 } 13067 return resumedActivity; 13068 } 13069 13070 final boolean updateOomAdjLocked(ProcessRecord app) { 13071 final ActivityRecord TOP_ACT = resumedAppLocked(); 13072 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13073 int curAdj = app.curAdj; 13074 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13075 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13076 13077 mAdjSeq++; 13078 13079 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13080 TOP_APP, false); 13081 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13082 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13083 if (nowHidden != wasHidden) { 13084 // Changed to/from hidden state, so apps after it in the LRU 13085 // list may also be changed. 13086 updateOomAdjLocked(); 13087 } 13088 return success; 13089 } 13090 13091 final void updateOomAdjLocked() { 13092 final ActivityRecord TOP_ACT = resumedAppLocked(); 13093 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13094 13095 if (false) { 13096 RuntimeException e = new RuntimeException(); 13097 e.fillInStackTrace(); 13098 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13099 } 13100 13101 mAdjSeq++; 13102 mNewNumServiceProcs = 0; 13103 13104 // Let's determine how many processes we have running vs. 13105 // how many slots we have for background processes; we may want 13106 // to put multiple processes in a slot of there are enough of 13107 // them. 13108 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13109 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13110 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13111 if (emptyFactor < 1) emptyFactor = 1; 13112 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13113 if (hiddenFactor < 1) hiddenFactor = 1; 13114 int stepHidden = 0; 13115 int stepEmpty = 0; 13116 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13117 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13118 int numHidden = 0; 13119 int numEmpty = 0; 13120 int numTrimming = 0; 13121 13122 mNumNonHiddenProcs = 0; 13123 mNumHiddenProcs = 0; 13124 13125 // First update the OOM adjustment for each of the 13126 // application processes based on their current state. 13127 int i = mLruProcesses.size(); 13128 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13129 int nextHiddenAdj = curHiddenAdj+1; 13130 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13131 int nextEmptyAdj = curEmptyAdj+2; 13132 while (i > 0) { 13133 i--; 13134 ProcessRecord app = mLruProcesses.get(i); 13135 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13136 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13137 if (!app.killedBackground) { 13138 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13139 // This process was assigned as a hidden process... step the 13140 // hidden level. 13141 mNumHiddenProcs++; 13142 if (curHiddenAdj != nextHiddenAdj) { 13143 stepHidden++; 13144 if (stepHidden >= hiddenFactor) { 13145 stepHidden = 0; 13146 curHiddenAdj = nextHiddenAdj; 13147 nextHiddenAdj += 2; 13148 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13149 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13150 } 13151 } 13152 } 13153 numHidden++; 13154 if (numHidden > hiddenProcessLimit) { 13155 Slog.i(TAG, "No longer want " + app.processName 13156 + " (pid " + app.pid + "): hidden #" + numHidden); 13157 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13158 app.processName, app.setAdj, "too many background"); 13159 app.killedBackground = true; 13160 Process.killProcessQuiet(app.pid); 13161 } 13162 } else { 13163 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13164 // This process was assigned as an empty process... step the 13165 // empty level. 13166 if (curEmptyAdj != nextEmptyAdj) { 13167 stepEmpty++; 13168 if (stepEmpty >= emptyFactor) { 13169 stepEmpty = 0; 13170 curEmptyAdj = nextEmptyAdj; 13171 nextEmptyAdj += 2; 13172 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13173 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13174 } 13175 } 13176 } 13177 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13178 mNumNonHiddenProcs++; 13179 } 13180 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13181 numEmpty++; 13182 if (numEmpty > emptyProcessLimit) { 13183 Slog.i(TAG, "No longer want " + app.processName 13184 + " (pid " + app.pid + "): empty #" + numEmpty); 13185 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13186 app.processName, app.setAdj, "too many background"); 13187 app.killedBackground = true; 13188 Process.killProcessQuiet(app.pid); 13189 } 13190 } 13191 } 13192 if (app.isolated && app.services.size() <= 0) { 13193 // If this is an isolated process, and there are no 13194 // services running in it, then the process is no longer 13195 // needed. We agressively kill these because we can by 13196 // definition not re-use the same process again, and it is 13197 // good to avoid having whatever code was running in them 13198 // left sitting around after no longer needed. 13199 Slog.i(TAG, "Isolated process " + app.processName 13200 + " (pid " + app.pid + ") no longer needed"); 13201 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13202 app.processName, app.setAdj, "isolated not needed"); 13203 app.killedBackground = true; 13204 Process.killProcessQuiet(app.pid); 13205 } 13206 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13207 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13208 && !app.killedBackground) { 13209 numTrimming++; 13210 } 13211 } 13212 } 13213 13214 mNumServiceProcs = mNewNumServiceProcs; 13215 13216 // Now determine the memory trimming level of background processes. 13217 // Unfortunately we need to start at the back of the list to do this 13218 // properly. We only do this if the number of background apps we 13219 // are managing to keep around is less than half the maximum we desire; 13220 // if we are keeping a good number around, we'll let them use whatever 13221 // memory they want. 13222 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13223 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13224 final int numHiddenAndEmpty = numHidden + numEmpty; 13225 final int N = mLruProcesses.size(); 13226 int factor = numTrimming/3; 13227 int minFactor = 2; 13228 if (mHomeProcess != null) minFactor++; 13229 if (mPreviousProcess != null) minFactor++; 13230 if (factor < minFactor) factor = minFactor; 13231 int step = 0; 13232 int fgTrimLevel; 13233 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13234 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13235 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13236 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13237 } else { 13238 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13239 } 13240 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13241 for (i=0; i<N; i++) { 13242 ProcessRecord app = mLruProcesses.get(i); 13243 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13244 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13245 && !app.killedBackground) { 13246 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13247 try { 13248 app.thread.scheduleTrimMemory(curLevel); 13249 } catch (RemoteException e) { 13250 } 13251 if (false) { 13252 // For now we won't do this; our memory trimming seems 13253 // to be good enough at this point that destroying 13254 // activities causes more harm than good. 13255 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13256 && app != mHomeProcess && app != mPreviousProcess) { 13257 // Need to do this on its own message because the stack may not 13258 // be in a consistent state at this point. 13259 // For these apps we will also finish their activities 13260 // to help them free memory. 13261 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13262 } 13263 } 13264 } 13265 app.trimMemoryLevel = curLevel; 13266 step++; 13267 if (step >= factor) { 13268 step = 0; 13269 switch (curLevel) { 13270 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13271 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13272 break; 13273 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13274 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13275 break; 13276 } 13277 } 13278 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13279 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13280 && app.thread != null) { 13281 try { 13282 app.thread.scheduleTrimMemory( 13283 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13284 } catch (RemoteException e) { 13285 } 13286 } 13287 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13288 } else { 13289 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13290 && app.pendingUiClean) { 13291 // If this application is now in the background and it 13292 // had done UI, then give it the special trim level to 13293 // have it free UI resources. 13294 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13295 if (app.trimMemoryLevel < level && app.thread != null) { 13296 try { 13297 app.thread.scheduleTrimMemory(level); 13298 } catch (RemoteException e) { 13299 } 13300 } 13301 app.pendingUiClean = false; 13302 } 13303 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13304 try { 13305 app.thread.scheduleTrimMemory(fgTrimLevel); 13306 } catch (RemoteException e) { 13307 } 13308 } 13309 app.trimMemoryLevel = fgTrimLevel; 13310 } 13311 } 13312 } else { 13313 final int N = mLruProcesses.size(); 13314 for (i=0; i<N; i++) { 13315 ProcessRecord app = mLruProcesses.get(i); 13316 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13317 && app.pendingUiClean) { 13318 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13319 && app.thread != null) { 13320 try { 13321 app.thread.scheduleTrimMemory( 13322 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13323 } catch (RemoteException e) { 13324 } 13325 } 13326 app.pendingUiClean = false; 13327 } 13328 app.trimMemoryLevel = 0; 13329 } 13330 } 13331 13332 if (mAlwaysFinishActivities) { 13333 // Need to do this on its own message because the stack may not 13334 // be in a consistent state at this point. 13335 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13336 } 13337 } 13338 13339 final void trimApplications() { 13340 synchronized (this) { 13341 int i; 13342 13343 // First remove any unused application processes whose package 13344 // has been removed. 13345 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13346 final ProcessRecord app = mRemovedProcesses.get(i); 13347 if (app.activities.size() == 0 13348 && app.curReceiver == null && app.services.size() == 0) { 13349 Slog.i( 13350 TAG, "Exiting empty application process " 13351 + app.processName + " (" 13352 + (app.thread != null ? app.thread.asBinder() : null) 13353 + ")\n"); 13354 if (app.pid > 0 && app.pid != MY_PID) { 13355 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13356 app.processName, app.setAdj, "empty"); 13357 Process.killProcessQuiet(app.pid); 13358 } else { 13359 try { 13360 app.thread.scheduleExit(); 13361 } catch (Exception e) { 13362 // Ignore exceptions. 13363 } 13364 } 13365 cleanUpApplicationRecordLocked(app, false, true, -1); 13366 mRemovedProcesses.remove(i); 13367 13368 if (app.persistent) { 13369 if (app.persistent) { 13370 addAppLocked(app.info, false); 13371 } 13372 } 13373 } 13374 } 13375 13376 // Now update the oom adj for all processes. 13377 updateOomAdjLocked(); 13378 } 13379 } 13380 13381 /** This method sends the specified signal to each of the persistent apps */ 13382 public void signalPersistentProcesses(int sig) throws RemoteException { 13383 if (sig != Process.SIGNAL_USR1) { 13384 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13385 } 13386 13387 synchronized (this) { 13388 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13389 != PackageManager.PERMISSION_GRANTED) { 13390 throw new SecurityException("Requires permission " 13391 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13392 } 13393 13394 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13395 ProcessRecord r = mLruProcesses.get(i); 13396 if (r.thread != null && r.persistent) { 13397 Process.sendSignal(r.pid, sig); 13398 } 13399 } 13400 } 13401 } 13402 13403 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13404 if (proc == null || proc == mProfileProc) { 13405 proc = mProfileProc; 13406 path = mProfileFile; 13407 profileType = mProfileType; 13408 clearProfilerLocked(); 13409 } 13410 if (proc == null) { 13411 return; 13412 } 13413 try { 13414 proc.thread.profilerControl(false, path, null, profileType); 13415 } catch (RemoteException e) { 13416 throw new IllegalStateException("Process disappeared"); 13417 } 13418 } 13419 13420 private void clearProfilerLocked() { 13421 if (mProfileFd != null) { 13422 try { 13423 mProfileFd.close(); 13424 } catch (IOException e) { 13425 } 13426 } 13427 mProfileApp = null; 13428 mProfileProc = null; 13429 mProfileFile = null; 13430 mProfileType = 0; 13431 mAutoStopProfiler = false; 13432 } 13433 13434 public boolean profileControl(String process, boolean start, 13435 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13436 13437 try { 13438 synchronized (this) { 13439 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13440 // its own permission. 13441 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13442 != PackageManager.PERMISSION_GRANTED) { 13443 throw new SecurityException("Requires permission " 13444 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13445 } 13446 13447 if (start && fd == null) { 13448 throw new IllegalArgumentException("null fd"); 13449 } 13450 13451 ProcessRecord proc = null; 13452 if (process != null) { 13453 try { 13454 int pid = Integer.parseInt(process); 13455 synchronized (mPidsSelfLocked) { 13456 proc = mPidsSelfLocked.get(pid); 13457 } 13458 } catch (NumberFormatException e) { 13459 } 13460 13461 if (proc == null) { 13462 HashMap<String, SparseArray<ProcessRecord>> all 13463 = mProcessNames.getMap(); 13464 SparseArray<ProcessRecord> procs = all.get(process); 13465 if (procs != null && procs.size() > 0) { 13466 proc = procs.valueAt(0); 13467 } 13468 } 13469 } 13470 13471 if (start && (proc == null || proc.thread == null)) { 13472 throw new IllegalArgumentException("Unknown process: " + process); 13473 } 13474 13475 if (start) { 13476 stopProfilerLocked(null, null, 0); 13477 setProfileApp(proc.info, proc.processName, path, fd, false); 13478 mProfileProc = proc; 13479 mProfileType = profileType; 13480 try { 13481 fd = fd.dup(); 13482 } catch (IOException e) { 13483 fd = null; 13484 } 13485 proc.thread.profilerControl(start, path, fd, profileType); 13486 fd = null; 13487 mProfileFd = null; 13488 } else { 13489 stopProfilerLocked(proc, path, profileType); 13490 if (fd != null) { 13491 try { 13492 fd.close(); 13493 } catch (IOException e) { 13494 } 13495 } 13496 } 13497 13498 return true; 13499 } 13500 } catch (RemoteException e) { 13501 throw new IllegalStateException("Process disappeared"); 13502 } finally { 13503 if (fd != null) { 13504 try { 13505 fd.close(); 13506 } catch (IOException e) { 13507 } 13508 } 13509 } 13510 } 13511 13512 public boolean dumpHeap(String process, boolean managed, 13513 String path, ParcelFileDescriptor fd) throws RemoteException { 13514 13515 try { 13516 synchronized (this) { 13517 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13518 // its own permission (same as profileControl). 13519 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13520 != PackageManager.PERMISSION_GRANTED) { 13521 throw new SecurityException("Requires permission " 13522 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13523 } 13524 13525 if (fd == null) { 13526 throw new IllegalArgumentException("null fd"); 13527 } 13528 13529 ProcessRecord proc = null; 13530 try { 13531 int pid = Integer.parseInt(process); 13532 synchronized (mPidsSelfLocked) { 13533 proc = mPidsSelfLocked.get(pid); 13534 } 13535 } catch (NumberFormatException e) { 13536 } 13537 13538 if (proc == null) { 13539 HashMap<String, SparseArray<ProcessRecord>> all 13540 = mProcessNames.getMap(); 13541 SparseArray<ProcessRecord> procs = all.get(process); 13542 if (procs != null && procs.size() > 0) { 13543 proc = procs.valueAt(0); 13544 } 13545 } 13546 13547 if (proc == null || proc.thread == null) { 13548 throw new IllegalArgumentException("Unknown process: " + process); 13549 } 13550 13551 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13552 if (!isDebuggable) { 13553 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13554 throw new SecurityException("Process not debuggable: " + proc); 13555 } 13556 } 13557 13558 proc.thread.dumpHeap(managed, path, fd); 13559 fd = null; 13560 return true; 13561 } 13562 } catch (RemoteException e) { 13563 throw new IllegalStateException("Process disappeared"); 13564 } finally { 13565 if (fd != null) { 13566 try { 13567 fd.close(); 13568 } catch (IOException e) { 13569 } 13570 } 13571 } 13572 } 13573 13574 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13575 public void monitor() { 13576 synchronized (this) { } 13577 } 13578 13579 void onCoreSettingsChange(Bundle settings) { 13580 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13581 ProcessRecord processRecord = mLruProcesses.get(i); 13582 try { 13583 if (processRecord.thread != null) { 13584 processRecord.thread.setCoreSettings(settings); 13585 } 13586 } catch (RemoteException re) { 13587 /* ignore */ 13588 } 13589 } 13590 } 13591 13592 // Multi-user methods 13593 13594 @Override 13595 public boolean switchUser(int userId) { 13596 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13597 != PackageManager.PERMISSION_GRANTED) { 13598 String msg = "Permission Denial: switchUser() from pid=" 13599 + Binder.getCallingPid() 13600 + ", uid=" + Binder.getCallingUid() 13601 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13602 Slog.w(TAG, msg); 13603 throw new SecurityException(msg); 13604 } 13605 synchronized (this) { 13606 if (mCurrentUserId == userId) { 13607 return true; 13608 } 13609 13610 // If the user we are switching to is not currently started, then 13611 // we need to start it now. 13612 if (mStartedUsers.get(userId) == null) { 13613 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13614 } 13615 13616 mCurrentUserId = userId; 13617 boolean haveActivities = mMainStack.switchUser(userId); 13618 if (!haveActivities) { 13619 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13620 } 13621 } 13622 13623 long ident = Binder.clearCallingIdentity(); 13624 try { 13625 // Inform of user switch 13626 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13627 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13628 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13629 } finally { 13630 Binder.restoreCallingIdentity(ident); 13631 } 13632 13633 return true; 13634 } 13635 13636 void finishUserSwitch(UserStartedState uss) { 13637 synchronized (this) { 13638 if (uss.mState == UserStartedState.STATE_BOOTING 13639 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13640 uss.mState = UserStartedState.STATE_RUNNING; 13641 broadcastIntentLocked(null, null, 13642 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 13643 null, null, 0, null, null, 13644 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13645 false, false, MY_PID, Process.SYSTEM_UID, uss.mHandle.getIdentifier()); 13646 } 13647 } 13648 } 13649 13650 @Override 13651 public int stopUser(final int userId, final IStopUserCallback callback) { 13652 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13653 != PackageManager.PERMISSION_GRANTED) { 13654 String msg = "Permission Denial: switchUser() from pid=" 13655 + Binder.getCallingPid() 13656 + ", uid=" + Binder.getCallingUid() 13657 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13658 Slog.w(TAG, msg); 13659 throw new SecurityException(msg); 13660 } 13661 if (userId <= 0) { 13662 throw new IllegalArgumentException("Can't stop primary user " + userId); 13663 } 13664 synchronized (this) { 13665 if (mCurrentUserId == userId) { 13666 return ActivityManager.USER_OP_IS_CURRENT; 13667 } 13668 13669 final UserStartedState uss = mStartedUsers.get(userId); 13670 if (uss == null) { 13671 // User is not started, nothing to do... but we do need to 13672 // callback if requested. 13673 if (callback != null) { 13674 mHandler.post(new Runnable() { 13675 @Override 13676 public void run() { 13677 try { 13678 callback.userStopped(userId); 13679 } catch (RemoteException e) { 13680 } 13681 } 13682 }); 13683 } 13684 return ActivityManager.USER_OP_SUCCESS; 13685 } 13686 13687 if (callback != null) { 13688 uss.mStopCallbacks.add(callback); 13689 } 13690 13691 if (uss.mState != UserStartedState.STATE_STOPPING) { 13692 uss.mState = UserStartedState.STATE_STOPPING; 13693 13694 long ident = Binder.clearCallingIdentity(); 13695 try { 13696 // Inform of user switch 13697 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13698 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13699 @Override 13700 public void performReceive(Intent intent, int resultCode, String data, 13701 Bundle extras, boolean ordered, boolean sticky) { 13702 finishUserStop(uss); 13703 } 13704 }; 13705 broadcastIntentLocked(null, null, intent, 13706 null, resultReceiver, 0, null, null, null, 13707 true, false, MY_PID, Process.SYSTEM_UID, userId); 13708 } finally { 13709 Binder.restoreCallingIdentity(ident); 13710 } 13711 } 13712 } 13713 13714 return ActivityManager.USER_OP_SUCCESS; 13715 } 13716 13717 void finishUserStop(UserStartedState uss) { 13718 final int userId = uss.mHandle.getIdentifier(); 13719 boolean stopped; 13720 ArrayList<IStopUserCallback> callbacks; 13721 synchronized (this) { 13722 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 13723 if (uss.mState != UserStartedState.STATE_STOPPING 13724 || mStartedUsers.get(userId) != uss) { 13725 stopped = false; 13726 } else { 13727 stopped = true; 13728 // User can no longer run. 13729 mStartedUsers.remove(userId); 13730 13731 // Clean up all state and processes associated with the user. 13732 // Kill all the processes for the user. 13733 forceStopUserLocked(userId); 13734 } 13735 } 13736 13737 for (int i=0; i<callbacks.size(); i++) { 13738 try { 13739 if (stopped) callbacks.get(i).userStopped(userId); 13740 else callbacks.get(i).userStopAborted(userId); 13741 } catch (RemoteException e) { 13742 } 13743 } 13744 } 13745 13746 @Override 13747 public UserInfo getCurrentUser() { 13748 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13749 != PackageManager.PERMISSION_GRANTED) { 13750 String msg = "Permission Denial: getCurrentUser() from pid=" 13751 + Binder.getCallingPid() 13752 + ", uid=" + Binder.getCallingUid() 13753 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13754 Slog.w(TAG, msg); 13755 throw new SecurityException(msg); 13756 } 13757 synchronized (this) { 13758 return getUserManager().getUserInfo(mCurrentUserId); 13759 } 13760 } 13761 13762 private boolean userExists(int userId) { 13763 UserInfo user = getUserManager().getUserInfo(userId); 13764 return user != null; 13765 } 13766 13767 UserManager getUserManager() { 13768 if (mUserManager == null) { 13769 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13770 } 13771 return mUserManager; 13772 } 13773 13774 private void checkValidCaller(int uid, int userId) { 13775 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13776 13777 throw new SecurityException("Caller uid=" + uid 13778 + " is not privileged to communicate with user=" + userId); 13779 } 13780 13781 private int applyUserId(int uid, int userId) { 13782 return UserHandle.getUid(userId, uid); 13783 } 13784 13785 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13786 if (info == null) return null; 13787 ApplicationInfo newInfo = new ApplicationInfo(info); 13788 newInfo.uid = applyUserId(info.uid, userId); 13789 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13790 + info.packageName; 13791 return newInfo; 13792 } 13793 13794 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13795 if (aInfo == null 13796 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13797 return aInfo; 13798 } 13799 13800 ActivityInfo info = new ActivityInfo(aInfo); 13801 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13802 return info; 13803 } 13804} 13805