ActivityManagerService.java revision 258848d2ae04f447ff1c18023fa76b139fcc0862
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.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IThumbnailReceiver; 51import android.app.Instrumentation; 52import android.app.Notification; 53import android.app.NotificationManager; 54import android.app.PendingIntent; 55import android.app.Service; 56import android.app.backup.IBackupManager; 57import android.content.ActivityNotFoundException; 58import android.content.BroadcastReceiver; 59import android.content.ClipData; 60import android.content.ComponentCallbacks2; 61import android.content.ComponentName; 62import android.content.ContentProvider; 63import android.content.ContentResolver; 64import android.content.Context; 65import android.content.DialogInterface; 66import android.content.IContentProvider; 67import android.content.IIntentReceiver; 68import android.content.IIntentSender; 69import android.content.Intent; 70import android.content.IntentFilter; 71import android.content.IntentSender; 72import android.content.pm.ActivityInfo; 73import android.content.pm.ApplicationInfo; 74import android.content.pm.ConfigurationInfo; 75import android.content.pm.IPackageDataObserver; 76import android.content.pm.IPackageManager; 77import android.content.pm.InstrumentationInfo; 78import android.content.pm.PackageInfo; 79import android.content.pm.PackageManager; 80import android.content.pm.UserInfo; 81import android.content.pm.PackageManager.NameNotFoundException; 82import android.content.pm.PathPermission; 83import android.content.pm.ProviderInfo; 84import android.content.pm.ResolveInfo; 85import android.content.pm.ServiceInfo; 86import android.content.res.CompatibilityInfo; 87import android.content.res.Configuration; 88import android.graphics.Bitmap; 89import android.net.Proxy; 90import android.net.ProxyProperties; 91import android.net.Uri; 92import android.os.Binder; 93import android.os.Build; 94import android.os.Bundle; 95import android.os.Debug; 96import android.os.DropBoxManager; 97import android.os.Environment; 98import android.os.FileObserver; 99import android.os.FileUtils; 100import android.os.Handler; 101import android.os.IBinder; 102import android.os.IPermissionController; 103import android.os.Looper; 104import android.os.Message; 105import android.os.Parcel; 106import android.os.ParcelFileDescriptor; 107import android.os.Process; 108import android.os.RemoteCallbackList; 109import android.os.RemoteException; 110import android.os.ServiceManager; 111import android.os.StrictMode; 112import android.os.SystemClock; 113import android.os.SystemProperties; 114import android.os.UserId; 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.Collection; 149import java.util.Collections; 150import java.util.Comparator; 151import java.util.HashMap; 152import java.util.HashSet; 153import java.util.Iterator; 154import java.util.List; 155import java.util.Locale; 156import java.util.Map; 157import java.util.Map.Entry; 158import java.util.Set; 159import java.util.concurrent.atomic.AtomicBoolean; 160import java.util.concurrent.atomic.AtomicLong; 161 162public final class ActivityManagerService extends ActivityManagerNative 163 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 164 private static final String USER_DATA_DIR = "/data/user/"; 165 static final String TAG = "ActivityManager"; 166 static final String TAG_MU = "ActivityManagerServiceMU"; 167 static final boolean DEBUG = false; 168 static final boolean localLOGV = DEBUG; 169 static final boolean DEBUG_SWITCH = localLOGV || false; 170 static final boolean DEBUG_TASKS = localLOGV || false; 171 static final boolean DEBUG_PAUSE = localLOGV || false; 172 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 173 static final boolean DEBUG_TRANSITION = localLOGV || false; 174 static final boolean DEBUG_BROADCAST = localLOGV || false; 175 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 177 static final boolean DEBUG_SERVICE = localLOGV || false; 178 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 179 static final boolean DEBUG_VISBILITY = localLOGV || false; 180 static final boolean DEBUG_PROCESSES = localLOGV || false; 181 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 182 static final boolean DEBUG_PROVIDER = localLOGV || false; 183 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 184 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 185 static final boolean DEBUG_RESULTS = localLOGV || false; 186 static final boolean DEBUG_BACKUP = localLOGV || false; 187 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 188 static final boolean DEBUG_POWER = localLOGV || false; 189 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 190 static final boolean DEBUG_MU = localLOGV || false; 191 static final boolean VALIDATE_TOKENS = false; 192 static final boolean SHOW_ACTIVITY_START_TIME = true; 193 194 // Control over CPU and battery monitoring. 195 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 196 static final boolean MONITOR_CPU_USAGE = true; 197 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 198 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 199 static final boolean MONITOR_THREAD_CPU_USAGE = false; 200 201 // The flags that are set for all calls we make to the package manager. 202 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 203 204 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 205 206 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 207 208 // Maximum number of recent tasks that we can remember. 209 static final int MAX_RECENT_TASKS = 20; 210 211 // Amount of time after a call to stopAppSwitches() during which we will 212 // prevent further untrusted switches from happening. 213 static final long APP_SWITCH_DELAY_TIME = 5*1000; 214 215 // How long we wait for a launched process to attach to the activity manager 216 // before we decide it's never going to come up for real. 217 static final int PROC_START_TIMEOUT = 10*1000; 218 219 // How long we wait for a launched process to attach to the activity manager 220 // before we decide it's never going to come up for real, when the process was 221 // started with a wrapper for instrumentation (such as Valgrind) because it 222 // could take much longer than usual. 223 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 224 225 // How long to wait after going idle before forcing apps to GC. 226 static final int GC_TIMEOUT = 5*1000; 227 228 // The minimum amount of time between successive GC requests for a process. 229 static final int GC_MIN_INTERVAL = 60*1000; 230 231 // The rate at which we check for apps using excessive power -- 15 mins. 232 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 233 234 // The minimum sample duration we will allow before deciding we have 235 // enough data on wake locks to start killing things. 236 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 237 238 // The minimum sample duration we will allow before deciding we have 239 // enough data on CPU usage to start killing things. 240 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 241 242 // How long we allow a receiver to run before giving up on it. 243 static final int BROADCAST_FG_TIMEOUT = 10*1000; 244 static final int BROADCAST_BG_TIMEOUT = 60*1000; 245 246 // How long we wait until we timeout on key dispatching. 247 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 248 249 // How long we wait until we timeout on key dispatching during instrumentation. 250 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 251 252 static final int MY_PID = Process.myPid(); 253 254 static final String[] EMPTY_STRING_ARRAY = new String[0]; 255 256 public ActivityStack mMainStack; 257 258 private final boolean mHeadless; 259 260 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 261 // default actuion automatically. Important for devices without direct input 262 // devices. 263 private boolean mShowDialogs = true; 264 265 /** 266 * Description of a request to start a new activity, which has been held 267 * due to app switches being disabled. 268 */ 269 static class PendingActivityLaunch { 270 ActivityRecord r; 271 ActivityRecord sourceRecord; 272 int startFlags; 273 } 274 275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 276 = new ArrayList<PendingActivityLaunch>(); 277 278 279 BroadcastQueue mFgBroadcastQueue; 280 BroadcastQueue mBgBroadcastQueue; 281 // Convenient for easy iteration over the queues. Foreground is first 282 // so that dispatch of foreground broadcasts gets precedence. 283 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 284 285 BroadcastQueue broadcastQueueForIntent(Intent intent) { 286 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 287 if (DEBUG_BACKGROUND_BROADCAST) { 288 Slog.i(TAG, "Broadcast intent " + intent + " on " 289 + (isFg ? "foreground" : "background") 290 + " queue"); 291 } 292 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 293 } 294 295 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 296 for (BroadcastQueue queue : mBroadcastQueues) { 297 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 298 if (r != null) { 299 return r; 300 } 301 } 302 return null; 303 } 304 305 /** 306 * Activity we have told the window manager to have key focus. 307 */ 308 ActivityRecord mFocusedActivity = null; 309 /** 310 * List of intents that were used to start the most recent tasks. 311 */ 312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 313 314 /** 315 * Process management. 316 */ 317 final ProcessList mProcessList = new ProcessList(); 318 319 /** 320 * All of the applications we currently have running organized by name. 321 * The keys are strings of the application package name (as 322 * returned by the package manager), and the keys are ApplicationRecord 323 * objects. 324 */ 325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 326 327 /** 328 * The currently running isolated processes. 329 */ 330 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 331 332 /** 333 * Counter for assigning isolated process uids, to avoid frequently reusing the 334 * same ones. 335 */ 336 int mNextIsolatedProcessUid = 0; 337 338 /** 339 * The currently running heavy-weight process, if any. 340 */ 341 ProcessRecord mHeavyWeightProcess = null; 342 343 /** 344 * The last time that various processes have crashed. 345 */ 346 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 347 348 /** 349 * Set of applications that we consider to be bad, and will reject 350 * incoming broadcasts from (which the user has no control over). 351 * Processes are added to this set when they have crashed twice within 352 * a minimum amount of time; they are removed from it when they are 353 * later restarted (hopefully due to some user action). The value is the 354 * time it was added to the list. 355 */ 356 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 357 358 /** 359 * All of the processes we currently have running organized by pid. 360 * The keys are the pid running the application. 361 * 362 * <p>NOTE: This object is protected by its own lock, NOT the global 363 * activity manager lock! 364 */ 365 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 366 367 /** 368 * All of the processes that have been forced to be foreground. The key 369 * is the pid of the caller who requested it (we hold a death 370 * link on it). 371 */ 372 abstract class ForegroundToken implements IBinder.DeathRecipient { 373 int pid; 374 IBinder token; 375 } 376 final SparseArray<ForegroundToken> mForegroundProcesses 377 = new SparseArray<ForegroundToken>(); 378 379 /** 380 * List of records for processes that someone had tried to start before the 381 * system was ready. We don't start them at that point, but ensure they 382 * are started by the time booting is complete. 383 */ 384 final ArrayList<ProcessRecord> mProcessesOnHold 385 = new ArrayList<ProcessRecord>(); 386 387 /** 388 * List of persistent applications that are in the process 389 * of being started. 390 */ 391 final ArrayList<ProcessRecord> mPersistentStartingProcesses 392 = new ArrayList<ProcessRecord>(); 393 394 /** 395 * Processes that are being forcibly torn down. 396 */ 397 final ArrayList<ProcessRecord> mRemovedProcesses 398 = new ArrayList<ProcessRecord>(); 399 400 /** 401 * List of running applications, sorted by recent usage. 402 * The first entry in the list is the least recently used. 403 * It contains ApplicationRecord objects. This list does NOT include 404 * any persistent application records (since we never want to exit them). 405 */ 406 final ArrayList<ProcessRecord> mLruProcesses 407 = new ArrayList<ProcessRecord>(); 408 409 /** 410 * List of processes that should gc as soon as things are idle. 411 */ 412 final ArrayList<ProcessRecord> mProcessesToGc 413 = new ArrayList<ProcessRecord>(); 414 415 /** 416 * This is the process holding what we currently consider to be 417 * the "home" activity. 418 */ 419 ProcessRecord mHomeProcess; 420 421 /** 422 * This is the process holding the activity the user last visited that 423 * is in a different process from the one they are currently in. 424 */ 425 ProcessRecord mPreviousProcess; 426 427 /** 428 * The time at which the previous process was last visible. 429 */ 430 long mPreviousProcessVisibleTime; 431 432 /** 433 * Packages that the user has asked to have run in screen size 434 * compatibility mode instead of filling the screen. 435 */ 436 final CompatModePackages mCompatModePackages; 437 438 /** 439 * Set of PendingResultRecord objects that are currently active. 440 */ 441 final HashSet mPendingResultRecords = new HashSet(); 442 443 /** 444 * Set of IntentSenderRecord objects that are currently active. 445 */ 446 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 447 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 448 449 /** 450 * Fingerprints (hashCode()) of stack traces that we've 451 * already logged DropBox entries for. Guarded by itself. If 452 * something (rogue user app) forces this over 453 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 454 */ 455 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 456 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 457 458 /** 459 * Strict Mode background batched logging state. 460 * 461 * The string buffer is guarded by itself, and its lock is also 462 * used to determine if another batched write is already 463 * in-flight. 464 */ 465 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 466 467 /** 468 * Keeps track of all IIntentReceivers that have been registered for 469 * broadcasts. Hash keys are the receiver IBinder, hash value is 470 * a ReceiverList. 471 */ 472 final HashMap mRegisteredReceivers = new HashMap(); 473 474 /** 475 * Resolver for broadcast intents to registered receivers. 476 * Holds BroadcastFilter (subclass of IntentFilter). 477 */ 478 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 479 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 480 @Override 481 protected boolean allowFilterResult( 482 BroadcastFilter filter, List<BroadcastFilter> dest) { 483 IBinder target = filter.receiverList.receiver.asBinder(); 484 for (int i=dest.size()-1; i>=0; i--) { 485 if (dest.get(i).receiverList.receiver.asBinder() == target) { 486 return false; 487 } 488 } 489 return true; 490 } 491 492 @Override 493 protected BroadcastFilter[] newArray(int size) { 494 return new BroadcastFilter[size]; 495 } 496 497 @Override 498 protected String packageForFilter(BroadcastFilter filter) { 499 return filter.packageName; 500 } 501 }; 502 503 /** 504 * State of all active sticky broadcasts. Keys are the action of the 505 * sticky Intent, values are an ArrayList of all broadcasted intents with 506 * that action (which should usually be one). 507 */ 508 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 509 new HashMap<String, ArrayList<Intent>>(); 510 511 final ActiveServices mServices; 512 513 /** 514 * Backup/restore process management 515 */ 516 String mBackupAppName = null; 517 BackupRecord mBackupTarget = null; 518 519 /** 520 * List of PendingThumbnailsRecord objects of clients who are still 521 * waiting to receive all of the thumbnails for a task. 522 */ 523 final ArrayList mPendingThumbnails = new ArrayList(); 524 525 /** 526 * List of HistoryRecord objects that have been finished and must 527 * still report back to a pending thumbnail receiver. 528 */ 529 final ArrayList mCancelledThumbnails = new ArrayList(); 530 531 final ProviderMap mProviderMap = new ProviderMap(); 532 533 /** 534 * List of content providers who have clients waiting for them. The 535 * application is currently being launched and the provider will be 536 * removed from this list once it is published. 537 */ 538 final ArrayList<ContentProviderRecord> mLaunchingProviders 539 = new ArrayList<ContentProviderRecord>(); 540 541 /** 542 * Global set of specific Uri permissions that have been granted. 543 */ 544 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 545 = new SparseArray<HashMap<Uri, UriPermission>>(); 546 547 CoreSettingsObserver mCoreSettingsObserver; 548 549 /** 550 * Thread-local storage used to carry caller permissions over through 551 * indirect content-provider access. 552 * @see #ActivityManagerService.openContentUri() 553 */ 554 private class Identity { 555 public int pid; 556 public int uid; 557 558 Identity(int _pid, int _uid) { 559 pid = _pid; 560 uid = _uid; 561 } 562 } 563 564 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 565 566 /** 567 * All information we have collected about the runtime performance of 568 * any user id that can impact battery performance. 569 */ 570 final BatteryStatsService mBatteryStatsService; 571 572 /** 573 * information about component usage 574 */ 575 final UsageStatsService mUsageStatsService; 576 577 /** 578 * Current configuration information. HistoryRecord objects are given 579 * a reference to this object to indicate which configuration they are 580 * currently running in, so this object must be kept immutable. 581 */ 582 Configuration mConfiguration = new Configuration(); 583 584 /** 585 * Current sequencing integer of the configuration, for skipping old 586 * configurations. 587 */ 588 int mConfigurationSeq = 0; 589 590 /** 591 * Hardware-reported OpenGLES version. 592 */ 593 final int GL_ES_VERSION; 594 595 /** 596 * List of initialization arguments to pass to all processes when binding applications to them. 597 * For example, references to the commonly used services. 598 */ 599 HashMap<String, IBinder> mAppBindArgs; 600 601 /** 602 * Temporary to avoid allocations. Protected by main lock. 603 */ 604 final StringBuilder mStringBuilder = new StringBuilder(256); 605 606 /** 607 * Used to control how we initialize the service. 608 */ 609 boolean mStartRunning = false; 610 ComponentName mTopComponent; 611 String mTopAction; 612 String mTopData; 613 boolean mProcessesReady = false; 614 boolean mSystemReady = false; 615 boolean mBooting = false; 616 boolean mWaitingUpdate = false; 617 boolean mDidUpdate = false; 618 boolean mOnBattery = false; 619 boolean mLaunchWarningShown = false; 620 621 Context mContext; 622 623 int mFactoryTest; 624 625 boolean mCheckedForSetup; 626 627 /** 628 * The time at which we will allow normal application switches again, 629 * after a call to {@link #stopAppSwitches()}. 630 */ 631 long mAppSwitchesAllowedTime; 632 633 /** 634 * This is set to true after the first switch after mAppSwitchesAllowedTime 635 * is set; any switches after that will clear the time. 636 */ 637 boolean mDidAppSwitch; 638 639 /** 640 * Last time (in realtime) at which we checked for power usage. 641 */ 642 long mLastPowerCheckRealtime; 643 644 /** 645 * Last time (in uptime) at which we checked for power usage. 646 */ 647 long mLastPowerCheckUptime; 648 649 /** 650 * Set while we are wanting to sleep, to prevent any 651 * activities from being started/resumed. 652 */ 653 boolean mSleeping = false; 654 655 /** 656 * State of external calls telling us if the device is asleep. 657 */ 658 boolean mWentToSleep = false; 659 660 /** 661 * State of external call telling us if the lock screen is shown. 662 */ 663 boolean mLockScreenShown = false; 664 665 /** 666 * Set if we are shutting down the system, similar to sleeping. 667 */ 668 boolean mShuttingDown = false; 669 670 /** 671 * Task identifier that activities are currently being started 672 * in. Incremented each time a new task is created. 673 * todo: Replace this with a TokenSpace class that generates non-repeating 674 * integers that won't wrap. 675 */ 676 int mCurTask = 1; 677 678 /** 679 * Current sequence id for oom_adj computation traversal. 680 */ 681 int mAdjSeq = 0; 682 683 /** 684 * Current sequence id for process LRU updating. 685 */ 686 int mLruSeq = 0; 687 688 /** 689 * Keep track of the number of service processes we last found, to 690 * determine on the next iteration which should be B services. 691 */ 692 int mNumServiceProcs = 0; 693 int mNewNumServiceProcs = 0; 694 695 /** 696 * System monitoring: number of processes that died since the last 697 * N procs were started. 698 */ 699 int[] mProcDeaths = new int[20]; 700 701 /** 702 * This is set if we had to do a delayed dexopt of an app before launching 703 * it, to increasing the ANR timeouts in that case. 704 */ 705 boolean mDidDexOpt; 706 707 String mDebugApp = null; 708 boolean mWaitForDebugger = false; 709 boolean mDebugTransient = false; 710 String mOrigDebugApp = null; 711 boolean mOrigWaitForDebugger = false; 712 boolean mAlwaysFinishActivities = false; 713 IActivityController mController = null; 714 String mProfileApp = null; 715 ProcessRecord mProfileProc = null; 716 String mProfileFile; 717 ParcelFileDescriptor mProfileFd; 718 int mProfileType = 0; 719 boolean mAutoStopProfiler = false; 720 String mOpenGlTraceApp = null; 721 722 static class ProcessChangeItem { 723 static final int CHANGE_ACTIVITIES = 1<<0; 724 static final int CHANGE_IMPORTANCE= 1<<1; 725 int changes; 726 int uid; 727 int pid; 728 int importance; 729 boolean foregroundActivities; 730 } 731 732 final RemoteCallbackList<IProcessObserver> mProcessObservers 733 = new RemoteCallbackList<IProcessObserver>(); 734 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 735 736 final ArrayList<ProcessChangeItem> mPendingProcessChanges 737 = new ArrayList<ProcessChangeItem>(); 738 final ArrayList<ProcessChangeItem> mAvailProcessChanges 739 = new ArrayList<ProcessChangeItem>(); 740 741 /** 742 * Callback of last caller to {@link #requestPss}. 743 */ 744 Runnable mRequestPssCallback; 745 746 /** 747 * Remaining processes for which we are waiting results from the last 748 * call to {@link #requestPss}. 749 */ 750 final ArrayList<ProcessRecord> mRequestPssList 751 = new ArrayList<ProcessRecord>(); 752 753 /** 754 * Runtime statistics collection thread. This object's lock is used to 755 * protect all related state. 756 */ 757 final Thread mProcessStatsThread; 758 759 /** 760 * Used to collect process stats when showing not responding dialog. 761 * Protected by mProcessStatsThread. 762 */ 763 final ProcessStats mProcessStats = new ProcessStats( 764 MONITOR_THREAD_CPU_USAGE); 765 final AtomicLong mLastCpuTime = new AtomicLong(0); 766 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 767 768 long mLastWriteTime = 0; 769 770 /** 771 * Set to true after the system has finished booting. 772 */ 773 boolean mBooted = false; 774 775 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 776 int mProcessLimitOverride = -1; 777 778 WindowManagerService mWindowManager; 779 780 static ActivityManagerService mSelf; 781 static ActivityThread mSystemThread; 782 783 private int mCurrentUserId; 784 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 785 private UserManager mUserManager; 786 787 private final class AppDeathRecipient implements IBinder.DeathRecipient { 788 final ProcessRecord mApp; 789 final int mPid; 790 final IApplicationThread mAppThread; 791 792 AppDeathRecipient(ProcessRecord app, int pid, 793 IApplicationThread thread) { 794 if (localLOGV) Slog.v( 795 TAG, "New death recipient " + this 796 + " for thread " + thread.asBinder()); 797 mApp = app; 798 mPid = pid; 799 mAppThread = thread; 800 } 801 802 public void binderDied() { 803 if (localLOGV) Slog.v( 804 TAG, "Death received in " + this 805 + " for thread " + mAppThread.asBinder()); 806 synchronized(ActivityManagerService.this) { 807 appDiedLocked(mApp, mPid, mAppThread); 808 } 809 } 810 } 811 812 static final int SHOW_ERROR_MSG = 1; 813 static final int SHOW_NOT_RESPONDING_MSG = 2; 814 static final int SHOW_FACTORY_ERROR_MSG = 3; 815 static final int UPDATE_CONFIGURATION_MSG = 4; 816 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 817 static final int WAIT_FOR_DEBUGGER_MSG = 6; 818 static final int SERVICE_TIMEOUT_MSG = 12; 819 static final int UPDATE_TIME_ZONE = 13; 820 static final int SHOW_UID_ERROR_MSG = 14; 821 static final int IM_FEELING_LUCKY_MSG = 15; 822 static final int PROC_START_TIMEOUT_MSG = 20; 823 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 824 static final int KILL_APPLICATION_MSG = 22; 825 static final int FINALIZE_PENDING_INTENT_MSG = 23; 826 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 827 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 828 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 829 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 830 static final int CLEAR_DNS_CACHE = 28; 831 static final int UPDATE_HTTP_PROXY = 29; 832 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 833 static final int DISPATCH_PROCESSES_CHANGED = 31; 834 static final int DISPATCH_PROCESS_DIED = 32; 835 static final int REPORT_MEM_USAGE = 33; 836 837 static final int FIRST_ACTIVITY_STACK_MSG = 100; 838 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 839 static final int FIRST_COMPAT_MODE_MSG = 300; 840 841 AlertDialog mUidAlert; 842 CompatModeDialog mCompatModeDialog; 843 long mLastMemUsageReportTime = 0; 844 845 final Handler mHandler = new Handler() { 846 //public Handler() { 847 // if (localLOGV) Slog.v(TAG, "Handler started!"); 848 //} 849 850 public void handleMessage(Message msg) { 851 switch (msg.what) { 852 case SHOW_ERROR_MSG: { 853 HashMap data = (HashMap) msg.obj; 854 synchronized (ActivityManagerService.this) { 855 ProcessRecord proc = (ProcessRecord)data.get("app"); 856 if (proc != null && proc.crashDialog != null) { 857 Slog.e(TAG, "App already has crash dialog: " + proc); 858 return; 859 } 860 AppErrorResult res = (AppErrorResult) data.get("result"); 861 if (mShowDialogs && !mSleeping && !mShuttingDown) { 862 Dialog d = new AppErrorDialog(mContext, res, proc); 863 d.show(); 864 proc.crashDialog = d; 865 } else { 866 // The device is asleep, so just pretend that the user 867 // saw a crash dialog and hit "force quit". 868 res.set(0); 869 } 870 } 871 872 ensureBootCompleted(); 873 } break; 874 case SHOW_NOT_RESPONDING_MSG: { 875 synchronized (ActivityManagerService.this) { 876 HashMap data = (HashMap) msg.obj; 877 ProcessRecord proc = (ProcessRecord)data.get("app"); 878 if (proc != null && proc.anrDialog != null) { 879 Slog.e(TAG, "App already has anr dialog: " + proc); 880 return; 881 } 882 883 Intent intent = new Intent("android.intent.action.ANR"); 884 if (!mProcessesReady) { 885 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 886 | Intent.FLAG_RECEIVER_FOREGROUND); 887 } 888 broadcastIntentLocked(null, null, intent, 889 null, null, 0, null, null, null, 890 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 891 892 if (mShowDialogs) { 893 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 894 mContext, proc, (ActivityRecord)data.get("activity")); 895 d.show(); 896 proc.anrDialog = d; 897 } else { 898 // Just kill the app if there is no dialog to be shown. 899 killAppAtUsersRequest(proc, null); 900 } 901 } 902 903 ensureBootCompleted(); 904 } break; 905 case SHOW_STRICT_MODE_VIOLATION_MSG: { 906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 907 synchronized (ActivityManagerService.this) { 908 ProcessRecord proc = (ProcessRecord) data.get("app"); 909 if (proc == null) { 910 Slog.e(TAG, "App not found when showing strict mode dialog."); 911 break; 912 } 913 if (proc.crashDialog != null) { 914 Slog.e(TAG, "App already has strict mode dialog: " + proc); 915 return; 916 } 917 AppErrorResult res = (AppErrorResult) data.get("result"); 918 if (mShowDialogs && !mSleeping && !mShuttingDown) { 919 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 920 d.show(); 921 proc.crashDialog = d; 922 } else { 923 // The device is asleep, so just pretend that the user 924 // saw a crash dialog and hit "force quit". 925 res.set(0); 926 } 927 } 928 ensureBootCompleted(); 929 } break; 930 case SHOW_FACTORY_ERROR_MSG: { 931 Dialog d = new FactoryErrorDialog( 932 mContext, msg.getData().getCharSequence("msg")); 933 d.show(); 934 ensureBootCompleted(); 935 } break; 936 case UPDATE_CONFIGURATION_MSG: { 937 final ContentResolver resolver = mContext.getContentResolver(); 938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 939 } break; 940 case GC_BACKGROUND_PROCESSES_MSG: { 941 synchronized (ActivityManagerService.this) { 942 performAppGcsIfAppropriateLocked(); 943 } 944 } break; 945 case WAIT_FOR_DEBUGGER_MSG: { 946 synchronized (ActivityManagerService.this) { 947 ProcessRecord app = (ProcessRecord)msg.obj; 948 if (msg.arg1 != 0) { 949 if (!app.waitedForDebugger) { 950 Dialog d = new AppWaitingForDebuggerDialog( 951 ActivityManagerService.this, 952 mContext, app); 953 app.waitDialog = d; 954 app.waitedForDebugger = true; 955 d.show(); 956 } 957 } else { 958 if (app.waitDialog != null) { 959 app.waitDialog.dismiss(); 960 app.waitDialog = null; 961 } 962 } 963 } 964 } break; 965 case SERVICE_TIMEOUT_MSG: { 966 if (mDidDexOpt) { 967 mDidDexOpt = false; 968 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 969 nmsg.obj = msg.obj; 970 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 971 return; 972 } 973 mServices.serviceTimeout((ProcessRecord)msg.obj); 974 } break; 975 case UPDATE_TIME_ZONE: { 976 synchronized (ActivityManagerService.this) { 977 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 978 ProcessRecord r = mLruProcesses.get(i); 979 if (r.thread != null) { 980 try { 981 r.thread.updateTimeZone(); 982 } catch (RemoteException ex) { 983 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 984 } 985 } 986 } 987 } 988 } break; 989 case CLEAR_DNS_CACHE: { 990 synchronized (ActivityManagerService.this) { 991 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 992 ProcessRecord r = mLruProcesses.get(i); 993 if (r.thread != null) { 994 try { 995 r.thread.clearDnsCache(); 996 } catch (RemoteException ex) { 997 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 998 } 999 } 1000 } 1001 } 1002 } break; 1003 case UPDATE_HTTP_PROXY: { 1004 ProxyProperties proxy = (ProxyProperties)msg.obj; 1005 String host = ""; 1006 String port = ""; 1007 String exclList = ""; 1008 if (proxy != null) { 1009 host = proxy.getHost(); 1010 port = Integer.toString(proxy.getPort()); 1011 exclList = proxy.getExclusionList(); 1012 } 1013 synchronized (ActivityManagerService.this) { 1014 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1015 ProcessRecord r = mLruProcesses.get(i); 1016 if (r.thread != null) { 1017 try { 1018 r.thread.setHttpProxy(host, port, exclList); 1019 } catch (RemoteException ex) { 1020 Slog.w(TAG, "Failed to update http proxy for: " + 1021 r.info.processName); 1022 } 1023 } 1024 } 1025 } 1026 } break; 1027 case SHOW_UID_ERROR_MSG: { 1028 String title = "System UIDs Inconsistent"; 1029 String text = "UIDs on the system are inconsistent, you need to wipe your" 1030 + " data partition or your device will be unstable."; 1031 Log.e(TAG, title + ": " + text); 1032 if (mShowDialogs) { 1033 // XXX This is a temporary dialog, no need to localize. 1034 AlertDialog d = new BaseErrorDialog(mContext); 1035 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1036 d.setCancelable(false); 1037 d.setTitle(title); 1038 d.setMessage(text); 1039 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1040 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1041 mUidAlert = d; 1042 d.show(); 1043 } 1044 } break; 1045 case IM_FEELING_LUCKY_MSG: { 1046 if (mUidAlert != null) { 1047 mUidAlert.dismiss(); 1048 mUidAlert = null; 1049 } 1050 } break; 1051 case PROC_START_TIMEOUT_MSG: { 1052 if (mDidDexOpt) { 1053 mDidDexOpt = false; 1054 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1055 nmsg.obj = msg.obj; 1056 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1057 return; 1058 } 1059 ProcessRecord app = (ProcessRecord)msg.obj; 1060 synchronized (ActivityManagerService.this) { 1061 processStartTimedOutLocked(app); 1062 } 1063 } break; 1064 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1065 synchronized (ActivityManagerService.this) { 1066 doPendingActivityLaunchesLocked(true); 1067 } 1068 } break; 1069 case KILL_APPLICATION_MSG: { 1070 synchronized (ActivityManagerService.this) { 1071 int uid = msg.arg1; 1072 boolean restart = (msg.arg2 == 1); 1073 String pkg = (String) msg.obj; 1074 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1075 UserId.getUserId(uid)); 1076 } 1077 } break; 1078 case FINALIZE_PENDING_INTENT_MSG: { 1079 ((PendingIntentRecord)msg.obj).completeFinalize(); 1080 } break; 1081 case POST_HEAVY_NOTIFICATION_MSG: { 1082 INotificationManager inm = NotificationManager.getService(); 1083 if (inm == null) { 1084 return; 1085 } 1086 1087 ActivityRecord root = (ActivityRecord)msg.obj; 1088 ProcessRecord process = root.app; 1089 if (process == null) { 1090 return; 1091 } 1092 1093 try { 1094 Context context = mContext.createPackageContext(process.info.packageName, 0); 1095 String text = mContext.getString(R.string.heavy_weight_notification, 1096 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1097 Notification notification = new Notification(); 1098 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1099 notification.when = 0; 1100 notification.flags = Notification.FLAG_ONGOING_EVENT; 1101 notification.tickerText = text; 1102 notification.defaults = 0; // please be quiet 1103 notification.sound = null; 1104 notification.vibrate = null; 1105 notification.setLatestEventInfo(context, text, 1106 mContext.getText(R.string.heavy_weight_notification_detail), 1107 PendingIntent.getActivity(mContext, 0, root.intent, 1108 PendingIntent.FLAG_CANCEL_CURRENT)); 1109 1110 try { 1111 int[] outId = new int[1]; 1112 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1113 notification, outId); 1114 } catch (RuntimeException e) { 1115 Slog.w(ActivityManagerService.TAG, 1116 "Error showing notification for heavy-weight app", e); 1117 } catch (RemoteException e) { 1118 } 1119 } catch (NameNotFoundException e) { 1120 Slog.w(TAG, "Unable to create context for heavy notification", e); 1121 } 1122 } break; 1123 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1124 INotificationManager inm = NotificationManager.getService(); 1125 if (inm == null) { 1126 return; 1127 } 1128 try { 1129 inm.cancelNotification("android", 1130 R.string.heavy_weight_notification); 1131 } catch (RuntimeException e) { 1132 Slog.w(ActivityManagerService.TAG, 1133 "Error canceling notification for service", e); 1134 } catch (RemoteException e) { 1135 } 1136 } break; 1137 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1138 synchronized (ActivityManagerService.this) { 1139 checkExcessivePowerUsageLocked(true); 1140 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1141 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1142 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1143 } 1144 } break; 1145 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 ActivityRecord ar = (ActivityRecord)msg.obj; 1148 if (mCompatModeDialog != null) { 1149 if (mCompatModeDialog.mAppInfo.packageName.equals( 1150 ar.info.applicationInfo.packageName)) { 1151 return; 1152 } 1153 mCompatModeDialog.dismiss(); 1154 mCompatModeDialog = null; 1155 } 1156 if (ar != null && false) { 1157 if (mCompatModePackages.getPackageAskCompatModeLocked( 1158 ar.packageName)) { 1159 int mode = mCompatModePackages.computeCompatModeLocked( 1160 ar.info.applicationInfo); 1161 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1162 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1163 mCompatModeDialog = new CompatModeDialog( 1164 ActivityManagerService.this, mContext, 1165 ar.info.applicationInfo); 1166 mCompatModeDialog.show(); 1167 } 1168 } 1169 } 1170 } 1171 break; 1172 } 1173 case DISPATCH_PROCESSES_CHANGED: { 1174 dispatchProcessesChanged(); 1175 break; 1176 } 1177 case DISPATCH_PROCESS_DIED: { 1178 final int pid = msg.arg1; 1179 final int uid = msg.arg2; 1180 dispatchProcessDied(pid, uid); 1181 break; 1182 } 1183 case REPORT_MEM_USAGE: { 1184 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1185 if (!isDebuggable) { 1186 return; 1187 } 1188 synchronized (ActivityManagerService.this) { 1189 long now = SystemClock.uptimeMillis(); 1190 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1191 // Don't report more than every 5 minutes to somewhat 1192 // avoid spamming. 1193 return; 1194 } 1195 mLastMemUsageReportTime = now; 1196 } 1197 Thread thread = new Thread() { 1198 @Override public void run() { 1199 StringBuilder dropBuilder = new StringBuilder(1024); 1200 StringBuilder logBuilder = new StringBuilder(1024); 1201 StringWriter oomSw = new StringWriter(); 1202 PrintWriter oomPw = new PrintWriter(oomSw); 1203 StringWriter catSw = new StringWriter(); 1204 PrintWriter catPw = new PrintWriter(catSw); 1205 String[] emptyArgs = new String[] { }; 1206 StringBuilder tag = new StringBuilder(128); 1207 StringBuilder stack = new StringBuilder(128); 1208 tag.append("Low on memory -- "); 1209 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1210 tag, stack); 1211 dropBuilder.append(stack); 1212 dropBuilder.append('\n'); 1213 dropBuilder.append('\n'); 1214 String oomString = oomSw.toString(); 1215 dropBuilder.append(oomString); 1216 dropBuilder.append('\n'); 1217 logBuilder.append(oomString); 1218 try { 1219 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1220 "procrank", }); 1221 final InputStreamReader converter = new InputStreamReader( 1222 proc.getInputStream()); 1223 BufferedReader in = new BufferedReader(converter); 1224 String line; 1225 while (true) { 1226 line = in.readLine(); 1227 if (line == null) { 1228 break; 1229 } 1230 if (line.length() > 0) { 1231 logBuilder.append(line); 1232 logBuilder.append('\n'); 1233 } 1234 dropBuilder.append(line); 1235 dropBuilder.append('\n'); 1236 } 1237 converter.close(); 1238 } catch (IOException e) { 1239 } 1240 synchronized (ActivityManagerService.this) { 1241 catPw.println(); 1242 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1243 catPw.println(); 1244 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1245 false, false, null); 1246 catPw.println(); 1247 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1248 } 1249 dropBuilder.append(catSw.toString()); 1250 addErrorToDropBox("lowmem", null, "system_server", null, 1251 null, tag.toString(), dropBuilder.toString(), null, null); 1252 Slog.i(TAG, logBuilder.toString()); 1253 synchronized (ActivityManagerService.this) { 1254 long now = SystemClock.uptimeMillis(); 1255 if (mLastMemUsageReportTime < now) { 1256 mLastMemUsageReportTime = now; 1257 } 1258 } 1259 } 1260 }; 1261 thread.start(); 1262 break; 1263 } 1264 } 1265 } 1266 }; 1267 1268 public static void setSystemProcess() { 1269 try { 1270 ActivityManagerService m = mSelf; 1271 1272 ServiceManager.addService("activity", m, true); 1273 ServiceManager.addService("meminfo", new MemBinder(m)); 1274 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1275 ServiceManager.addService("dbinfo", new DbBinder(m)); 1276 if (MONITOR_CPU_USAGE) { 1277 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1278 } 1279 ServiceManager.addService("permission", new PermissionController(m)); 1280 1281 ApplicationInfo info = 1282 mSelf.mContext.getPackageManager().getApplicationInfo( 1283 "android", STOCK_PM_FLAGS); 1284 mSystemThread.installSystemApplicationInfo(info); 1285 1286 synchronized (mSelf) { 1287 ProcessRecord app = mSelf.newProcessRecordLocked( 1288 mSystemThread.getApplicationThread(), info, 1289 info.processName, false); 1290 app.persistent = true; 1291 app.pid = MY_PID; 1292 app.maxAdj = ProcessList.SYSTEM_ADJ; 1293 mSelf.mProcessNames.put(app.processName, app.uid, app); 1294 synchronized (mSelf.mPidsSelfLocked) { 1295 mSelf.mPidsSelfLocked.put(app.pid, app); 1296 } 1297 mSelf.updateLruProcessLocked(app, true, true); 1298 } 1299 } catch (PackageManager.NameNotFoundException e) { 1300 throw new RuntimeException( 1301 "Unable to find android system package", e); 1302 } 1303 } 1304 1305 public void setWindowManager(WindowManagerService wm) { 1306 mWindowManager = wm; 1307 } 1308 1309 public static final Context main(int factoryTest) { 1310 AThread thr = new AThread(); 1311 thr.start(); 1312 1313 synchronized (thr) { 1314 while (thr.mService == null) { 1315 try { 1316 thr.wait(); 1317 } catch (InterruptedException e) { 1318 } 1319 } 1320 } 1321 1322 ActivityManagerService m = thr.mService; 1323 mSelf = m; 1324 ActivityThread at = ActivityThread.systemMain(); 1325 mSystemThread = at; 1326 Context context = at.getSystemContext(); 1327 context.setTheme(android.R.style.Theme_Holo); 1328 m.mContext = context; 1329 m.mFactoryTest = factoryTest; 1330 m.mMainStack = new ActivityStack(m, context, true); 1331 1332 m.mBatteryStatsService.publish(context); 1333 m.mUsageStatsService.publish(context); 1334 1335 synchronized (thr) { 1336 thr.mReady = true; 1337 thr.notifyAll(); 1338 } 1339 1340 m.startRunning(null, null, null, null); 1341 1342 return context; 1343 } 1344 1345 public static ActivityManagerService self() { 1346 return mSelf; 1347 } 1348 1349 static class AThread extends Thread { 1350 ActivityManagerService mService; 1351 boolean mReady = false; 1352 1353 public AThread() { 1354 super("ActivityManager"); 1355 } 1356 1357 public void run() { 1358 Looper.prepare(); 1359 1360 android.os.Process.setThreadPriority( 1361 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1362 android.os.Process.setCanSelfBackground(false); 1363 1364 ActivityManagerService m = new ActivityManagerService(); 1365 1366 synchronized (this) { 1367 mService = m; 1368 notifyAll(); 1369 } 1370 1371 synchronized (this) { 1372 while (!mReady) { 1373 try { 1374 wait(); 1375 } catch (InterruptedException e) { 1376 } 1377 } 1378 } 1379 1380 // For debug builds, log event loop stalls to dropbox for analysis. 1381 if (StrictMode.conditionallyEnableDebugLogging()) { 1382 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1383 } 1384 1385 Looper.loop(); 1386 } 1387 } 1388 1389 static class MemBinder extends Binder { 1390 ActivityManagerService mActivityManagerService; 1391 MemBinder(ActivityManagerService activityManagerService) { 1392 mActivityManagerService = activityManagerService; 1393 } 1394 1395 @Override 1396 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1397 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1398 != PackageManager.PERMISSION_GRANTED) { 1399 pw.println("Permission Denial: can't dump meminfo from from pid=" 1400 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1401 + " without permission " + android.Manifest.permission.DUMP); 1402 return; 1403 } 1404 1405 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1406 false, null, null, null); 1407 } 1408 } 1409 1410 static class GraphicsBinder extends Binder { 1411 ActivityManagerService mActivityManagerService; 1412 GraphicsBinder(ActivityManagerService activityManagerService) { 1413 mActivityManagerService = activityManagerService; 1414 } 1415 1416 @Override 1417 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1418 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1419 != PackageManager.PERMISSION_GRANTED) { 1420 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1421 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1422 + " without permission " + android.Manifest.permission.DUMP); 1423 return; 1424 } 1425 1426 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1427 } 1428 } 1429 1430 static class DbBinder extends Binder { 1431 ActivityManagerService mActivityManagerService; 1432 DbBinder(ActivityManagerService activityManagerService) { 1433 mActivityManagerService = activityManagerService; 1434 } 1435 1436 @Override 1437 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1438 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1439 != PackageManager.PERMISSION_GRANTED) { 1440 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1441 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1442 + " without permission " + android.Manifest.permission.DUMP); 1443 return; 1444 } 1445 1446 mActivityManagerService.dumpDbInfo(fd, pw, args); 1447 } 1448 } 1449 1450 static class CpuBinder extends Binder { 1451 ActivityManagerService mActivityManagerService; 1452 CpuBinder(ActivityManagerService activityManagerService) { 1453 mActivityManagerService = activityManagerService; 1454 } 1455 1456 @Override 1457 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1458 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1459 != PackageManager.PERMISSION_GRANTED) { 1460 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1461 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1462 + " without permission " + android.Manifest.permission.DUMP); 1463 return; 1464 } 1465 1466 synchronized (mActivityManagerService.mProcessStatsThread) { 1467 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1468 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1469 SystemClock.uptimeMillis())); 1470 } 1471 } 1472 } 1473 1474 private ActivityManagerService() { 1475 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1476 1477 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1478 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1479 mBroadcastQueues[0] = mFgBroadcastQueue; 1480 mBroadcastQueues[1] = mBgBroadcastQueue; 1481 1482 mServices = new ActiveServices(this); 1483 1484 File dataDir = Environment.getDataDirectory(); 1485 File systemDir = new File(dataDir, "system"); 1486 systemDir.mkdirs(); 1487 mBatteryStatsService = new BatteryStatsService(new File( 1488 systemDir, "batterystats.bin").toString()); 1489 mBatteryStatsService.getActiveStatistics().readLocked(); 1490 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1491 mOnBattery = DEBUG_POWER ? true 1492 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1493 mBatteryStatsService.getActiveStatistics().setCallback(this); 1494 1495 mUsageStatsService = new UsageStatsService(new File( 1496 systemDir, "usagestats").toString()); 1497 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1498 1499 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1500 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1501 1502 mConfiguration.setToDefaults(); 1503 mConfiguration.locale = Locale.getDefault(); 1504 mConfigurationSeq = mConfiguration.seq = 1; 1505 mProcessStats.init(); 1506 1507 mCompatModePackages = new CompatModePackages(this, systemDir); 1508 1509 // Add ourself to the Watchdog monitors. 1510 Watchdog.getInstance().addMonitor(this); 1511 1512 mProcessStatsThread = new Thread("ProcessStats") { 1513 public void run() { 1514 while (true) { 1515 try { 1516 try { 1517 synchronized(this) { 1518 final long now = SystemClock.uptimeMillis(); 1519 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1520 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1521 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1522 // + ", write delay=" + nextWriteDelay); 1523 if (nextWriteDelay < nextCpuDelay) { 1524 nextCpuDelay = nextWriteDelay; 1525 } 1526 if (nextCpuDelay > 0) { 1527 mProcessStatsMutexFree.set(true); 1528 this.wait(nextCpuDelay); 1529 } 1530 } 1531 } catch (InterruptedException e) { 1532 } 1533 updateCpuStatsNow(); 1534 } catch (Exception e) { 1535 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1536 } 1537 } 1538 } 1539 }; 1540 mProcessStatsThread.start(); 1541 } 1542 1543 @Override 1544 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1545 throws RemoteException { 1546 if (code == SYSPROPS_TRANSACTION) { 1547 // We need to tell all apps about the system property change. 1548 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1549 synchronized(this) { 1550 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1551 final int NA = apps.size(); 1552 for (int ia=0; ia<NA; ia++) { 1553 ProcessRecord app = apps.valueAt(ia); 1554 if (app.thread != null) { 1555 procs.add(app.thread.asBinder()); 1556 } 1557 } 1558 } 1559 } 1560 1561 int N = procs.size(); 1562 for (int i=0; i<N; i++) { 1563 Parcel data2 = Parcel.obtain(); 1564 try { 1565 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1566 } catch (RemoteException e) { 1567 } 1568 data2.recycle(); 1569 } 1570 } 1571 try { 1572 return super.onTransact(code, data, reply, flags); 1573 } catch (RuntimeException e) { 1574 // The activity manager only throws security exceptions, so let's 1575 // log all others. 1576 if (!(e instanceof SecurityException)) { 1577 Slog.e(TAG, "Activity Manager Crash", e); 1578 } 1579 throw e; 1580 } 1581 } 1582 1583 void updateCpuStats() { 1584 final long now = SystemClock.uptimeMillis(); 1585 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1586 return; 1587 } 1588 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1589 synchronized (mProcessStatsThread) { 1590 mProcessStatsThread.notify(); 1591 } 1592 } 1593 } 1594 1595 void updateCpuStatsNow() { 1596 synchronized (mProcessStatsThread) { 1597 mProcessStatsMutexFree.set(false); 1598 final long now = SystemClock.uptimeMillis(); 1599 boolean haveNewCpuStats = false; 1600 1601 if (MONITOR_CPU_USAGE && 1602 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1603 mLastCpuTime.set(now); 1604 haveNewCpuStats = true; 1605 mProcessStats.update(); 1606 //Slog.i(TAG, mProcessStats.printCurrentState()); 1607 //Slog.i(TAG, "Total CPU usage: " 1608 // + mProcessStats.getTotalCpuPercent() + "%"); 1609 1610 // Slog the cpu usage if the property is set. 1611 if ("true".equals(SystemProperties.get("events.cpu"))) { 1612 int user = mProcessStats.getLastUserTime(); 1613 int system = mProcessStats.getLastSystemTime(); 1614 int iowait = mProcessStats.getLastIoWaitTime(); 1615 int irq = mProcessStats.getLastIrqTime(); 1616 int softIrq = mProcessStats.getLastSoftIrqTime(); 1617 int idle = mProcessStats.getLastIdleTime(); 1618 1619 int total = user + system + iowait + irq + softIrq + idle; 1620 if (total == 0) total = 1; 1621 1622 EventLog.writeEvent(EventLogTags.CPU, 1623 ((user+system+iowait+irq+softIrq) * 100) / total, 1624 (user * 100) / total, 1625 (system * 100) / total, 1626 (iowait * 100) / total, 1627 (irq * 100) / total, 1628 (softIrq * 100) / total); 1629 } 1630 } 1631 1632 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1633 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1634 synchronized(bstats) { 1635 synchronized(mPidsSelfLocked) { 1636 if (haveNewCpuStats) { 1637 if (mOnBattery) { 1638 int perc = bstats.startAddingCpuLocked(); 1639 int totalUTime = 0; 1640 int totalSTime = 0; 1641 final int N = mProcessStats.countStats(); 1642 for (int i=0; i<N; i++) { 1643 ProcessStats.Stats st = mProcessStats.getStats(i); 1644 if (!st.working) { 1645 continue; 1646 } 1647 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1648 int otherUTime = (st.rel_utime*perc)/100; 1649 int otherSTime = (st.rel_stime*perc)/100; 1650 totalUTime += otherUTime; 1651 totalSTime += otherSTime; 1652 if (pr != null) { 1653 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1654 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1655 st.rel_stime-otherSTime); 1656 ps.addSpeedStepTimes(cpuSpeedTimes); 1657 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1658 } else { 1659 BatteryStatsImpl.Uid.Proc ps = 1660 bstats.getProcessStatsLocked(st.name, st.pid); 1661 if (ps != null) { 1662 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1663 st.rel_stime-otherSTime); 1664 ps.addSpeedStepTimes(cpuSpeedTimes); 1665 } 1666 } 1667 } 1668 bstats.finishAddingCpuLocked(perc, totalUTime, 1669 totalSTime, cpuSpeedTimes); 1670 } 1671 } 1672 } 1673 1674 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1675 mLastWriteTime = now; 1676 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1677 } 1678 } 1679 } 1680 } 1681 1682 @Override 1683 public void batteryNeedsCpuUpdate() { 1684 updateCpuStatsNow(); 1685 } 1686 1687 @Override 1688 public void batteryPowerChanged(boolean onBattery) { 1689 // When plugging in, update the CPU stats first before changing 1690 // the plug state. 1691 updateCpuStatsNow(); 1692 synchronized (this) { 1693 synchronized(mPidsSelfLocked) { 1694 mOnBattery = DEBUG_POWER ? true : onBattery; 1695 } 1696 } 1697 } 1698 1699 /** 1700 * Initialize the application bind args. These are passed to each 1701 * process when the bindApplication() IPC is sent to the process. They're 1702 * lazily setup to make sure the services are running when they're asked for. 1703 */ 1704 private HashMap<String, IBinder> getCommonServicesLocked() { 1705 if (mAppBindArgs == null) { 1706 mAppBindArgs = new HashMap<String, IBinder>(); 1707 1708 // Setup the application init args 1709 mAppBindArgs.put("package", ServiceManager.getService("package")); 1710 mAppBindArgs.put("window", ServiceManager.getService("window")); 1711 mAppBindArgs.put(Context.ALARM_SERVICE, 1712 ServiceManager.getService(Context.ALARM_SERVICE)); 1713 } 1714 return mAppBindArgs; 1715 } 1716 1717 final void setFocusedActivityLocked(ActivityRecord r) { 1718 if (mFocusedActivity != r) { 1719 mFocusedActivity = r; 1720 if (r != null) { 1721 mWindowManager.setFocusedApp(r.appToken, true); 1722 } 1723 } 1724 } 1725 1726 private final void updateLruProcessInternalLocked(ProcessRecord app, 1727 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1728 // put it on the LRU to keep track of when it should be exited. 1729 int lrui = mLruProcesses.indexOf(app); 1730 if (lrui >= 0) mLruProcesses.remove(lrui); 1731 1732 int i = mLruProcesses.size()-1; 1733 int skipTop = 0; 1734 1735 app.lruSeq = mLruSeq; 1736 1737 // compute the new weight for this process. 1738 if (updateActivityTime) { 1739 app.lastActivityTime = SystemClock.uptimeMillis(); 1740 } 1741 if (app.activities.size() > 0) { 1742 // If this process has activities, we more strongly want to keep 1743 // it around. 1744 app.lruWeight = app.lastActivityTime; 1745 } else if (app.pubProviders.size() > 0) { 1746 // If this process contains content providers, we want to keep 1747 // it a little more strongly. 1748 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1749 // Also don't let it kick out the first few "real" hidden processes. 1750 skipTop = ProcessList.MIN_HIDDEN_APPS; 1751 } else { 1752 // If this process doesn't have activities, we less strongly 1753 // want to keep it around, and generally want to avoid getting 1754 // in front of any very recently used activities. 1755 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1756 // Also don't let it kick out the first few "real" hidden processes. 1757 skipTop = ProcessList.MIN_HIDDEN_APPS; 1758 } 1759 1760 while (i >= 0) { 1761 ProcessRecord p = mLruProcesses.get(i); 1762 // If this app shouldn't be in front of the first N background 1763 // apps, then skip over that many that are currently hidden. 1764 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1765 skipTop--; 1766 } 1767 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1768 mLruProcesses.add(i+1, app); 1769 break; 1770 } 1771 i--; 1772 } 1773 if (i < 0) { 1774 mLruProcesses.add(0, app); 1775 } 1776 1777 // If the app is currently using a content provider or service, 1778 // bump those processes as well. 1779 if (app.connections.size() > 0) { 1780 for (ConnectionRecord cr : app.connections) { 1781 if (cr.binding != null && cr.binding.service != null 1782 && cr.binding.service.app != null 1783 && cr.binding.service.app.lruSeq != mLruSeq) { 1784 updateLruProcessInternalLocked(cr.binding.service.app, false, 1785 updateActivityTime, i+1); 1786 } 1787 } 1788 } 1789 for (int j=app.conProviders.size()-1; j>=0; j--) { 1790 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1791 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1792 updateLruProcessInternalLocked(cpr.proc, false, 1793 updateActivityTime, i+1); 1794 } 1795 } 1796 1797 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1798 if (oomAdj) { 1799 updateOomAdjLocked(); 1800 } 1801 } 1802 1803 final void updateLruProcessLocked(ProcessRecord app, 1804 boolean oomAdj, boolean updateActivityTime) { 1805 mLruSeq++; 1806 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1807 } 1808 1809 final ProcessRecord getProcessRecordLocked( 1810 String processName, int uid) { 1811 if (uid == Process.SYSTEM_UID) { 1812 // The system gets to run in any process. If there are multiple 1813 // processes with the same uid, just pick the first (this 1814 // should never happen). 1815 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1816 processName); 1817 if (procs == null) return null; 1818 final int N = procs.size(); 1819 for (int i = 0; i < N; i++) { 1820 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1821 } 1822 } 1823 ProcessRecord proc = mProcessNames.get(processName, uid); 1824 return proc; 1825 } 1826 1827 void ensurePackageDexOpt(String packageName) { 1828 IPackageManager pm = AppGlobals.getPackageManager(); 1829 try { 1830 if (pm.performDexOpt(packageName)) { 1831 mDidDexOpt = true; 1832 } 1833 } catch (RemoteException e) { 1834 } 1835 } 1836 1837 boolean isNextTransitionForward() { 1838 int transit = mWindowManager.getPendingAppTransition(); 1839 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1840 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1841 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1842 } 1843 1844 final ProcessRecord startProcessLocked(String processName, 1845 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1846 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1847 boolean isolated) { 1848 ProcessRecord app; 1849 if (!isolated) { 1850 app = getProcessRecordLocked(processName, info.uid); 1851 } else { 1852 // If this is an isolated process, it can't re-use an existing process. 1853 app = null; 1854 } 1855 // We don't have to do anything more if: 1856 // (1) There is an existing application record; and 1857 // (2) The caller doesn't think it is dead, OR there is no thread 1858 // object attached to it so we know it couldn't have crashed; and 1859 // (3) There is a pid assigned to it, so it is either starting or 1860 // already running. 1861 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1862 + " app=" + app + " knownToBeDead=" + knownToBeDead 1863 + " thread=" + (app != null ? app.thread : null) 1864 + " pid=" + (app != null ? app.pid : -1)); 1865 if (app != null && app.pid > 0) { 1866 if (!knownToBeDead || app.thread == null) { 1867 // We already have the app running, or are waiting for it to 1868 // come up (we have a pid but not yet its thread), so keep it. 1869 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1870 // If this is a new package in the process, add the package to the list 1871 app.addPackage(info.packageName); 1872 return app; 1873 } else { 1874 // An application record is attached to a previous process, 1875 // clean it up now. 1876 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1877 handleAppDiedLocked(app, true, true); 1878 } 1879 } 1880 1881 String hostingNameStr = hostingName != null 1882 ? hostingName.flattenToShortString() : null; 1883 1884 if (!isolated) { 1885 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1886 // If we are in the background, then check to see if this process 1887 // is bad. If so, we will just silently fail. 1888 if (mBadProcesses.get(info.processName, info.uid) != null) { 1889 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1890 + "/" + info.processName); 1891 return null; 1892 } 1893 } else { 1894 // When the user is explicitly starting a process, then clear its 1895 // crash count so that we won't make it bad until they see at 1896 // least one crash dialog again, and make the process good again 1897 // if it had been bad. 1898 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1899 + "/" + info.processName); 1900 mProcessCrashTimes.remove(info.processName, info.uid); 1901 if (mBadProcesses.get(info.processName, info.uid) != null) { 1902 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1903 info.processName); 1904 mBadProcesses.remove(info.processName, info.uid); 1905 if (app != null) { 1906 app.bad = false; 1907 } 1908 } 1909 } 1910 } 1911 1912 if (app == null) { 1913 app = newProcessRecordLocked(null, info, processName, isolated); 1914 if (app == null) { 1915 Slog.w(TAG, "Failed making new process record for " 1916 + processName + "/" + info.uid + " isolated=" + isolated); 1917 return null; 1918 } 1919 mProcessNames.put(processName, app.uid, app); 1920 if (isolated) { 1921 mIsolatedProcesses.put(app.uid, app); 1922 } 1923 } else { 1924 // If this is a new package in the process, add the package to the list 1925 app.addPackage(info.packageName); 1926 } 1927 1928 // If the system is not ready yet, then hold off on starting this 1929 // process until it is. 1930 if (!mProcessesReady 1931 && !isAllowedWhileBooting(info) 1932 && !allowWhileBooting) { 1933 if (!mProcessesOnHold.contains(app)) { 1934 mProcessesOnHold.add(app); 1935 } 1936 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1937 return app; 1938 } 1939 1940 startProcessLocked(app, hostingType, hostingNameStr); 1941 return (app.pid != 0) ? app : null; 1942 } 1943 1944 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1945 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1946 } 1947 1948 private final void startProcessLocked(ProcessRecord app, 1949 String hostingType, String hostingNameStr) { 1950 if (app.pid > 0 && app.pid != MY_PID) { 1951 synchronized (mPidsSelfLocked) { 1952 mPidsSelfLocked.remove(app.pid); 1953 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1954 } 1955 app.pid = 0; 1956 } 1957 1958 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1959 "startProcessLocked removing on hold: " + app); 1960 mProcessesOnHold.remove(app); 1961 1962 updateCpuStats(); 1963 1964 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1965 mProcDeaths[0] = 0; 1966 1967 try { 1968 int uid = app.uid; 1969 1970 int[] gids = null; 1971 if (!app.isolated) { 1972 try { 1973 gids = mContext.getPackageManager().getPackageGids( 1974 app.info.packageName); 1975 } catch (PackageManager.NameNotFoundException e) { 1976 Slog.w(TAG, "Unable to retrieve gids", e); 1977 } 1978 } 1979 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1980 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1981 && mTopComponent != null 1982 && app.processName.equals(mTopComponent.getPackageName())) { 1983 uid = 0; 1984 } 1985 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1986 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1987 uid = 0; 1988 } 1989 } 1990 int debugFlags = 0; 1991 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1992 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1993 // Also turn on CheckJNI for debuggable apps. It's quite 1994 // awkward to turn on otherwise. 1995 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1996 } 1997 // Run the app in safe mode if its manifest requests so or the 1998 // system is booted in safe mode. 1999 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2000 Zygote.systemInSafeMode == true) { 2001 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2002 } 2003 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2004 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2005 } 2006 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2007 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2008 } 2009 if ("1".equals(SystemProperties.get("debug.assert"))) { 2010 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2011 } 2012 2013 // Start the process. It will either succeed and return a result containing 2014 // the PID of the new process, or else throw a RuntimeException. 2015 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2016 app.processName, uid, uid, gids, debugFlags, 2017 app.info.targetSdkVersion, null, null); 2018 2019 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2020 synchronized (bs) { 2021 if (bs.isOnBattery()) { 2022 app.batteryStats.incStartsLocked(); 2023 } 2024 } 2025 2026 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2027 app.processName, hostingType, 2028 hostingNameStr != null ? hostingNameStr : ""); 2029 2030 if (app.persistent) { 2031 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2032 } 2033 2034 StringBuilder buf = mStringBuilder; 2035 buf.setLength(0); 2036 buf.append("Start proc "); 2037 buf.append(app.processName); 2038 buf.append(" for "); 2039 buf.append(hostingType); 2040 if (hostingNameStr != null) { 2041 buf.append(" "); 2042 buf.append(hostingNameStr); 2043 } 2044 buf.append(": pid="); 2045 buf.append(startResult.pid); 2046 buf.append(" uid="); 2047 buf.append(uid); 2048 buf.append(" gids={"); 2049 if (gids != null) { 2050 for (int gi=0; gi<gids.length; gi++) { 2051 if (gi != 0) buf.append(", "); 2052 buf.append(gids[gi]); 2053 2054 } 2055 } 2056 buf.append("}"); 2057 Slog.i(TAG, buf.toString()); 2058 app.pid = startResult.pid; 2059 app.usingWrapper = startResult.usingWrapper; 2060 app.removed = false; 2061 synchronized (mPidsSelfLocked) { 2062 this.mPidsSelfLocked.put(startResult.pid, app); 2063 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2064 msg.obj = app; 2065 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2066 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2067 } 2068 } catch (RuntimeException e) { 2069 // XXX do better error recovery. 2070 app.pid = 0; 2071 Slog.e(TAG, "Failure starting process " + app.processName, e); 2072 } 2073 } 2074 2075 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2076 if (resumed) { 2077 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2078 } else { 2079 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2080 } 2081 } 2082 2083 boolean startHomeActivityLocked(int userId) { 2084 if (mHeadless) { 2085 // Added because none of the other calls to ensureBootCompleted seem to fire 2086 // when running headless. 2087 ensureBootCompleted(); 2088 return false; 2089 } 2090 2091 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2092 && mTopAction == null) { 2093 // We are running in factory test mode, but unable to find 2094 // the factory test app, so just sit around displaying the 2095 // error message and don't try to start anything. 2096 return false; 2097 } 2098 Intent intent = new Intent( 2099 mTopAction, 2100 mTopData != null ? Uri.parse(mTopData) : null); 2101 intent.setComponent(mTopComponent); 2102 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2103 intent.addCategory(Intent.CATEGORY_HOME); 2104 } 2105 ActivityInfo aInfo = 2106 intent.resolveActivityInfo(mContext.getPackageManager(), 2107 STOCK_PM_FLAGS); 2108 if (aInfo != null) { 2109 intent.setComponent(new ComponentName( 2110 aInfo.applicationInfo.packageName, aInfo.name)); 2111 // Don't do this if the home app is currently being 2112 // instrumented. 2113 aInfo = new ActivityInfo(aInfo); 2114 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2115 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2116 aInfo.applicationInfo.uid); 2117 if (app == null || app.instrumentationClass == null) { 2118 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2119 mMainStack.startActivityLocked(null, intent, null, aInfo, 2120 null, null, 0, 0, 0, 0, null, false, null); 2121 } 2122 } 2123 2124 return true; 2125 } 2126 2127 /** 2128 * Starts the "new version setup screen" if appropriate. 2129 */ 2130 void startSetupActivityLocked() { 2131 // Only do this once per boot. 2132 if (mCheckedForSetup) { 2133 return; 2134 } 2135 2136 // We will show this screen if the current one is a different 2137 // version than the last one shown, and we are not running in 2138 // low-level factory test mode. 2139 final ContentResolver resolver = mContext.getContentResolver(); 2140 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2141 Settings.Secure.getInt(resolver, 2142 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2143 mCheckedForSetup = true; 2144 2145 // See if we should be showing the platform update setup UI. 2146 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2147 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2148 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2149 2150 // We don't allow third party apps to replace this. 2151 ResolveInfo ri = null; 2152 for (int i=0; ris != null && i<ris.size(); i++) { 2153 if ((ris.get(i).activityInfo.applicationInfo.flags 2154 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2155 ri = ris.get(i); 2156 break; 2157 } 2158 } 2159 2160 if (ri != null) { 2161 String vers = ri.activityInfo.metaData != null 2162 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2163 : null; 2164 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2165 vers = ri.activityInfo.applicationInfo.metaData.getString( 2166 Intent.METADATA_SETUP_VERSION); 2167 } 2168 String lastVers = Settings.Secure.getString( 2169 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2170 if (vers != null && !vers.equals(lastVers)) { 2171 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2172 intent.setComponent(new ComponentName( 2173 ri.activityInfo.packageName, ri.activityInfo.name)); 2174 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2175 null, null, 0, 0, 0, 0, null, false, null); 2176 } 2177 } 2178 } 2179 } 2180 2181 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2182 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2183 } 2184 2185 void enforceNotIsolatedCaller(String caller) { 2186 if (UserId.isIsolated(Binder.getCallingUid())) { 2187 throw new SecurityException("Isolated process not allowed to call " + caller); 2188 } 2189 } 2190 2191 public int getFrontActivityScreenCompatMode() { 2192 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2193 synchronized (this) { 2194 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2195 } 2196 } 2197 2198 public void setFrontActivityScreenCompatMode(int mode) { 2199 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2200 "setFrontActivityScreenCompatMode"); 2201 synchronized (this) { 2202 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2203 } 2204 } 2205 2206 public int getPackageScreenCompatMode(String packageName) { 2207 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2208 synchronized (this) { 2209 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2210 } 2211 } 2212 2213 public void setPackageScreenCompatMode(String packageName, int mode) { 2214 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2215 "setPackageScreenCompatMode"); 2216 synchronized (this) { 2217 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2218 } 2219 } 2220 2221 public boolean getPackageAskScreenCompat(String packageName) { 2222 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2223 synchronized (this) { 2224 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2225 } 2226 } 2227 2228 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2229 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2230 "setPackageAskScreenCompat"); 2231 synchronized (this) { 2232 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2233 } 2234 } 2235 2236 void reportResumedActivityLocked(ActivityRecord r) { 2237 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2238 updateUsageStats(r, true); 2239 } 2240 2241 private void dispatchProcessesChanged() { 2242 int N; 2243 synchronized (this) { 2244 N = mPendingProcessChanges.size(); 2245 if (mActiveProcessChanges.length < N) { 2246 mActiveProcessChanges = new ProcessChangeItem[N]; 2247 } 2248 mPendingProcessChanges.toArray(mActiveProcessChanges); 2249 mAvailProcessChanges.addAll(mPendingProcessChanges); 2250 mPendingProcessChanges.clear(); 2251 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2252 } 2253 int i = mProcessObservers.beginBroadcast(); 2254 while (i > 0) { 2255 i--; 2256 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2257 if (observer != null) { 2258 try { 2259 for (int j=0; j<N; j++) { 2260 ProcessChangeItem item = mActiveProcessChanges[j]; 2261 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2262 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2263 + item.pid + " uid=" + item.uid + ": " 2264 + item.foregroundActivities); 2265 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2266 item.foregroundActivities); 2267 } 2268 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2270 + item.pid + " uid=" + item.uid + ": " + item.importance); 2271 observer.onImportanceChanged(item.pid, item.uid, 2272 item.importance); 2273 } 2274 } 2275 } catch (RemoteException e) { 2276 } 2277 } 2278 } 2279 mProcessObservers.finishBroadcast(); 2280 } 2281 2282 private void dispatchProcessDied(int pid, int uid) { 2283 int i = mProcessObservers.beginBroadcast(); 2284 while (i > 0) { 2285 i--; 2286 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2287 if (observer != null) { 2288 try { 2289 observer.onProcessDied(pid, uid); 2290 } catch (RemoteException e) { 2291 } 2292 } 2293 } 2294 mProcessObservers.finishBroadcast(); 2295 } 2296 2297 final void doPendingActivityLaunchesLocked(boolean doResume) { 2298 final int N = mPendingActivityLaunches.size(); 2299 if (N <= 0) { 2300 return; 2301 } 2302 for (int i=0; i<N; i++) { 2303 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2304 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2305 pal.startFlags, doResume && i == (N-1), null); 2306 } 2307 mPendingActivityLaunches.clear(); 2308 } 2309 2310 public final int startActivity(IApplicationThread caller, 2311 Intent intent, String resolvedType, IBinder resultTo, 2312 String resultWho, int requestCode, int startFlags, 2313 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2314 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2315 startFlags, profileFile, profileFd, options, UserId.getCallingUserId()); 2316 } 2317 2318 public final int startActivityAsUser(IApplicationThread caller, 2319 Intent intent, String resolvedType, IBinder resultTo, 2320 String resultWho, int requestCode, int startFlags, 2321 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2322 enforceNotIsolatedCaller("startActivity"); 2323 if (userId != UserId.getCallingUserId()) { 2324 // Requesting a different user, make sure that they have the permission 2325 if (checkComponentPermission( 2326 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2327 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2328 == PackageManager.PERMISSION_GRANTED) { 2329 // Translate to the current user id, if caller wasn't aware 2330 if (userId == UserId.USER_CURRENT) { 2331 userId = mCurrentUserId; 2332 } 2333 } else { 2334 String msg = "Permission Denial: " 2335 + "Request to startActivity as user " + userId 2336 + " but is calling from user " + UserId.getCallingUserId() 2337 + "; this requires " 2338 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2339 Slog.w(TAG, msg); 2340 throw new SecurityException(msg); 2341 } 2342 } else { 2343 if (intent.getCategories() != null 2344 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2345 // Requesting home, set the identity to the current user 2346 // HACK! 2347 userId = mCurrentUserId; 2348 } else { 2349 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2350 // the current user's userId 2351 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2352 userId = 0; 2353 } else { 2354 userId = Binder.getOrigCallingUser(); 2355 } 2356 } 2357 } 2358 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2359 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2360 null, null, options, userId); 2361 } 2362 2363 public final WaitResult startActivityAndWait(IApplicationThread caller, 2364 Intent intent, String resolvedType, IBinder resultTo, 2365 String resultWho, int requestCode, int startFlags, String profileFile, 2366 ParcelFileDescriptor profileFd, Bundle options) { 2367 enforceNotIsolatedCaller("startActivityAndWait"); 2368 WaitResult res = new WaitResult(); 2369 int userId = Binder.getOrigCallingUser(); 2370 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2371 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2372 res, null, options, userId); 2373 return res; 2374 } 2375 2376 public final int startActivityWithConfig(IApplicationThread caller, 2377 Intent intent, String resolvedType, IBinder resultTo, 2378 String resultWho, int requestCode, int startFlags, Configuration config, 2379 Bundle options) { 2380 enforceNotIsolatedCaller("startActivityWithConfig"); 2381 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2382 resultTo, resultWho, requestCode, startFlags, 2383 null, null, null, config, options, Binder.getOrigCallingUser()); 2384 return ret; 2385 } 2386 2387 public int startActivityIntentSender(IApplicationThread caller, 2388 IntentSender intent, Intent fillInIntent, String resolvedType, 2389 IBinder resultTo, String resultWho, int requestCode, 2390 int flagsMask, int flagsValues, Bundle options) { 2391 enforceNotIsolatedCaller("startActivityIntentSender"); 2392 // Refuse possible leaked file descriptors 2393 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2394 throw new IllegalArgumentException("File descriptors passed in Intent"); 2395 } 2396 2397 IIntentSender sender = intent.getTarget(); 2398 if (!(sender instanceof PendingIntentRecord)) { 2399 throw new IllegalArgumentException("Bad PendingIntent object"); 2400 } 2401 2402 PendingIntentRecord pir = (PendingIntentRecord)sender; 2403 2404 synchronized (this) { 2405 // If this is coming from the currently resumed activity, it is 2406 // effectively saying that app switches are allowed at this point. 2407 if (mMainStack.mResumedActivity != null 2408 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2409 Binder.getCallingUid()) { 2410 mAppSwitchesAllowedTime = 0; 2411 } 2412 } 2413 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2414 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2415 return ret; 2416 } 2417 2418 public boolean startNextMatchingActivity(IBinder callingActivity, 2419 Intent intent, Bundle options) { 2420 // Refuse possible leaked file descriptors 2421 if (intent != null && intent.hasFileDescriptors() == true) { 2422 throw new IllegalArgumentException("File descriptors passed in Intent"); 2423 } 2424 2425 synchronized (this) { 2426 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2427 if (r == null) { 2428 ActivityOptions.abort(options); 2429 return false; 2430 } 2431 if (r.app == null || r.app.thread == null) { 2432 // The caller is not running... d'oh! 2433 ActivityOptions.abort(options); 2434 return false; 2435 } 2436 intent = new Intent(intent); 2437 // The caller is not allowed to change the data. 2438 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2439 // And we are resetting to find the next component... 2440 intent.setComponent(null); 2441 2442 ActivityInfo aInfo = null; 2443 try { 2444 List<ResolveInfo> resolves = 2445 AppGlobals.getPackageManager().queryIntentActivities( 2446 intent, r.resolvedType, 2447 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2448 UserId.getCallingUserId()); 2449 2450 // Look for the original activity in the list... 2451 final int N = resolves != null ? resolves.size() : 0; 2452 for (int i=0; i<N; i++) { 2453 ResolveInfo rInfo = resolves.get(i); 2454 if (rInfo.activityInfo.packageName.equals(r.packageName) 2455 && rInfo.activityInfo.name.equals(r.info.name)) { 2456 // We found the current one... the next matching is 2457 // after it. 2458 i++; 2459 if (i<N) { 2460 aInfo = resolves.get(i).activityInfo; 2461 } 2462 break; 2463 } 2464 } 2465 } catch (RemoteException e) { 2466 } 2467 2468 if (aInfo == null) { 2469 // Nobody who is next! 2470 ActivityOptions.abort(options); 2471 return false; 2472 } 2473 2474 intent.setComponent(new ComponentName( 2475 aInfo.applicationInfo.packageName, aInfo.name)); 2476 intent.setFlags(intent.getFlags()&~( 2477 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2478 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2479 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2480 Intent.FLAG_ACTIVITY_NEW_TASK)); 2481 2482 // Okay now we need to start the new activity, replacing the 2483 // currently running activity. This is a little tricky because 2484 // we want to start the new one as if the current one is finished, 2485 // but not finish the current one first so that there is no flicker. 2486 // And thus... 2487 final boolean wasFinishing = r.finishing; 2488 r.finishing = true; 2489 2490 // Propagate reply information over to the new activity. 2491 final ActivityRecord resultTo = r.resultTo; 2492 final String resultWho = r.resultWho; 2493 final int requestCode = r.requestCode; 2494 r.resultTo = null; 2495 if (resultTo != null) { 2496 resultTo.removeResultsLocked(r, resultWho, requestCode); 2497 } 2498 2499 final long origId = Binder.clearCallingIdentity(); 2500 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2501 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2502 resultWho, requestCode, -1, r.launchedFromUid, 0, 2503 options, false, null); 2504 Binder.restoreCallingIdentity(origId); 2505 2506 r.finishing = wasFinishing; 2507 if (res != ActivityManager.START_SUCCESS) { 2508 return false; 2509 } 2510 return true; 2511 } 2512 } 2513 2514 public final int startActivityInPackage(int uid, 2515 Intent intent, String resolvedType, IBinder resultTo, 2516 String resultWho, int requestCode, int startFlags, Bundle options) { 2517 2518 // This is so super not safe, that only the system (or okay root) 2519 // can do it. 2520 int userId = Binder.getOrigCallingUser(); 2521 final int callingUid = Binder.getCallingUid(); 2522 if (callingUid != 0 && callingUid != Process.myUid()) { 2523 throw new SecurityException( 2524 "startActivityInPackage only available to the system"); 2525 } 2526 2527 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2528 resultTo, resultWho, requestCode, startFlags, 2529 null, null, null, null, options, userId); 2530 return ret; 2531 } 2532 2533 public final int startActivities(IApplicationThread caller, 2534 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2535 enforceNotIsolatedCaller("startActivities"); 2536 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2537 options, Binder.getOrigCallingUser()); 2538 return ret; 2539 } 2540 2541 public final int startActivitiesInPackage(int uid, 2542 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2543 Bundle options) { 2544 2545 // This is so super not safe, that only the system (or okay root) 2546 // can do it. 2547 final int callingUid = Binder.getCallingUid(); 2548 if (callingUid != 0 && callingUid != Process.myUid()) { 2549 throw new SecurityException( 2550 "startActivityInPackage only available to the system"); 2551 } 2552 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2553 options, UserId.getUserId(uid)); 2554 return ret; 2555 } 2556 2557 final void addRecentTaskLocked(TaskRecord task) { 2558 int N = mRecentTasks.size(); 2559 // Quick case: check if the top-most recent task is the same. 2560 if (N > 0 && mRecentTasks.get(0) == task) { 2561 return; 2562 } 2563 // Remove any existing entries that are the same kind of task. 2564 for (int i=0; i<N; i++) { 2565 TaskRecord tr = mRecentTasks.get(i); 2566 if (task.userId == tr.userId 2567 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2568 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2569 mRecentTasks.remove(i); 2570 i--; 2571 N--; 2572 if (task.intent == null) { 2573 // If the new recent task we are adding is not fully 2574 // specified, then replace it with the existing recent task. 2575 task = tr; 2576 } 2577 } 2578 } 2579 if (N >= MAX_RECENT_TASKS) { 2580 mRecentTasks.remove(N-1); 2581 } 2582 mRecentTasks.add(0, task); 2583 } 2584 2585 public void setRequestedOrientation(IBinder token, 2586 int requestedOrientation) { 2587 synchronized (this) { 2588 ActivityRecord r = mMainStack.isInStackLocked(token); 2589 if (r == null) { 2590 return; 2591 } 2592 final long origId = Binder.clearCallingIdentity(); 2593 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2594 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2595 mConfiguration, 2596 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2597 if (config != null) { 2598 r.frozenBeforeDestroy = true; 2599 if (!updateConfigurationLocked(config, r, false, false)) { 2600 mMainStack.resumeTopActivityLocked(null); 2601 } 2602 } 2603 Binder.restoreCallingIdentity(origId); 2604 } 2605 } 2606 2607 public int getRequestedOrientation(IBinder token) { 2608 synchronized (this) { 2609 ActivityRecord r = mMainStack.isInStackLocked(token); 2610 if (r == null) { 2611 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2612 } 2613 return mWindowManager.getAppOrientation(r.appToken); 2614 } 2615 } 2616 2617 /** 2618 * This is the internal entry point for handling Activity.finish(). 2619 * 2620 * @param token The Binder token referencing the Activity we want to finish. 2621 * @param resultCode Result code, if any, from this Activity. 2622 * @param resultData Result data (Intent), if any, from this Activity. 2623 * 2624 * @return Returns true if the activity successfully finished, or false if it is still running. 2625 */ 2626 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2627 // Refuse possible leaked file descriptors 2628 if (resultData != null && resultData.hasFileDescriptors() == true) { 2629 throw new IllegalArgumentException("File descriptors passed in Intent"); 2630 } 2631 2632 synchronized(this) { 2633 if (mController != null) { 2634 // Find the first activity that is not finishing. 2635 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2636 if (next != null) { 2637 // ask watcher if this is allowed 2638 boolean resumeOK = true; 2639 try { 2640 resumeOK = mController.activityResuming(next.packageName); 2641 } catch (RemoteException e) { 2642 mController = null; 2643 } 2644 2645 if (!resumeOK) { 2646 return false; 2647 } 2648 } 2649 } 2650 final long origId = Binder.clearCallingIdentity(); 2651 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2652 resultData, "app-request"); 2653 Binder.restoreCallingIdentity(origId); 2654 return res; 2655 } 2656 } 2657 2658 public final void finishHeavyWeightApp() { 2659 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2660 != PackageManager.PERMISSION_GRANTED) { 2661 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2662 + Binder.getCallingPid() 2663 + ", uid=" + Binder.getCallingUid() 2664 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2665 Slog.w(TAG, msg); 2666 throw new SecurityException(msg); 2667 } 2668 2669 synchronized(this) { 2670 if (mHeavyWeightProcess == null) { 2671 return; 2672 } 2673 2674 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2675 mHeavyWeightProcess.activities); 2676 for (int i=0; i<activities.size(); i++) { 2677 ActivityRecord r = activities.get(i); 2678 if (!r.finishing) { 2679 int index = mMainStack.indexOfTokenLocked(r.appToken); 2680 if (index >= 0) { 2681 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2682 null, "finish-heavy"); 2683 } 2684 } 2685 } 2686 2687 mHeavyWeightProcess = null; 2688 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2689 } 2690 } 2691 2692 public void crashApplication(int uid, int initialPid, String packageName, 2693 String message) { 2694 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2695 != PackageManager.PERMISSION_GRANTED) { 2696 String msg = "Permission Denial: crashApplication() from pid=" 2697 + Binder.getCallingPid() 2698 + ", uid=" + Binder.getCallingUid() 2699 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2700 Slog.w(TAG, msg); 2701 throw new SecurityException(msg); 2702 } 2703 2704 synchronized(this) { 2705 ProcessRecord proc = null; 2706 2707 // Figure out which process to kill. We don't trust that initialPid 2708 // still has any relation to current pids, so must scan through the 2709 // list. 2710 synchronized (mPidsSelfLocked) { 2711 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2712 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2713 if (p.uid != uid) { 2714 continue; 2715 } 2716 if (p.pid == initialPid) { 2717 proc = p; 2718 break; 2719 } 2720 for (String str : p.pkgList) { 2721 if (str.equals(packageName)) { 2722 proc = p; 2723 } 2724 } 2725 } 2726 } 2727 2728 if (proc == null) { 2729 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2730 + " initialPid=" + initialPid 2731 + " packageName=" + packageName); 2732 return; 2733 } 2734 2735 if (proc.thread != null) { 2736 if (proc.pid == Process.myPid()) { 2737 Log.w(TAG, "crashApplication: trying to crash self!"); 2738 return; 2739 } 2740 long ident = Binder.clearCallingIdentity(); 2741 try { 2742 proc.thread.scheduleCrash(message); 2743 } catch (RemoteException e) { 2744 } 2745 Binder.restoreCallingIdentity(ident); 2746 } 2747 } 2748 } 2749 2750 public final void finishSubActivity(IBinder token, String resultWho, 2751 int requestCode) { 2752 synchronized(this) { 2753 final long origId = Binder.clearCallingIdentity(); 2754 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2755 Binder.restoreCallingIdentity(origId); 2756 } 2757 } 2758 2759 public boolean finishActivityAffinity(IBinder token) { 2760 synchronized(this) { 2761 final long origId = Binder.clearCallingIdentity(); 2762 boolean res = mMainStack.finishActivityAffinityLocked(token); 2763 Binder.restoreCallingIdentity(origId); 2764 return res; 2765 } 2766 } 2767 2768 public boolean willActivityBeVisible(IBinder token) { 2769 synchronized(this) { 2770 int i; 2771 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2772 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2773 if (r.appToken == token) { 2774 return true; 2775 } 2776 if (r.fullscreen && !r.finishing) { 2777 return false; 2778 } 2779 } 2780 return true; 2781 } 2782 } 2783 2784 public void overridePendingTransition(IBinder token, String packageName, 2785 int enterAnim, int exitAnim) { 2786 synchronized(this) { 2787 ActivityRecord self = mMainStack.isInStackLocked(token); 2788 if (self == null) { 2789 return; 2790 } 2791 2792 final long origId = Binder.clearCallingIdentity(); 2793 2794 if (self.state == ActivityState.RESUMED 2795 || self.state == ActivityState.PAUSING) { 2796 mWindowManager.overridePendingAppTransition(packageName, 2797 enterAnim, exitAnim, null); 2798 } 2799 2800 Binder.restoreCallingIdentity(origId); 2801 } 2802 } 2803 2804 /** 2805 * Main function for removing an existing process from the activity manager 2806 * as a result of that process going away. Clears out all connections 2807 * to the process. 2808 */ 2809 private final void handleAppDiedLocked(ProcessRecord app, 2810 boolean restarting, boolean allowRestart) { 2811 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2812 if (!restarting) { 2813 mLruProcesses.remove(app); 2814 } 2815 2816 if (mProfileProc == app) { 2817 clearProfilerLocked(); 2818 } 2819 2820 // Just in case... 2821 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2822 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2823 mMainStack.mPausingActivity = null; 2824 } 2825 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2826 mMainStack.mLastPausedActivity = null; 2827 } 2828 2829 // Remove this application's activities from active lists. 2830 mMainStack.removeHistoryRecordsForAppLocked(app); 2831 2832 boolean atTop = true; 2833 boolean hasVisibleActivities = false; 2834 2835 // Clean out the history list. 2836 int i = mMainStack.mHistory.size(); 2837 if (localLOGV) Slog.v( 2838 TAG, "Removing app " + app + " from history with " + i + " entries"); 2839 while (i > 0) { 2840 i--; 2841 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2842 if (localLOGV) Slog.v( 2843 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2844 if (r.app == app) { 2845 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2846 if (ActivityStack.DEBUG_ADD_REMOVE) { 2847 RuntimeException here = new RuntimeException("here"); 2848 here.fillInStackTrace(); 2849 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2850 + ": haveState=" + r.haveState 2851 + " stateNotNeeded=" + r.stateNotNeeded 2852 + " finishing=" + r.finishing 2853 + " state=" + r.state, here); 2854 } 2855 if (!r.finishing) { 2856 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2857 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2858 System.identityHashCode(r), 2859 r.task.taskId, r.shortComponentName, 2860 "proc died without state saved"); 2861 } 2862 mMainStack.removeActivityFromHistoryLocked(r); 2863 2864 } else { 2865 // We have the current state for this activity, so 2866 // it can be restarted later when needed. 2867 if (localLOGV) Slog.v( 2868 TAG, "Keeping entry, setting app to null"); 2869 if (r.visible) { 2870 hasVisibleActivities = true; 2871 } 2872 r.app = null; 2873 r.nowVisible = false; 2874 if (!r.haveState) { 2875 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2876 "App died, clearing saved state of " + r); 2877 r.icicle = null; 2878 } 2879 } 2880 2881 r.stack.cleanUpActivityLocked(r, true, true); 2882 } 2883 atTop = false; 2884 } 2885 2886 app.activities.clear(); 2887 2888 if (app.instrumentationClass != null) { 2889 Slog.w(TAG, "Crash of app " + app.processName 2890 + " running instrumentation " + app.instrumentationClass); 2891 Bundle info = new Bundle(); 2892 info.putString("shortMsg", "Process crashed."); 2893 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2894 } 2895 2896 if (!restarting) { 2897 if (!mMainStack.resumeTopActivityLocked(null)) { 2898 // If there was nothing to resume, and we are not already 2899 // restarting this process, but there is a visible activity that 2900 // is hosted by the process... then make sure all visible 2901 // activities are running, taking care of restarting this 2902 // process. 2903 if (hasVisibleActivities) { 2904 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2905 } 2906 } 2907 } 2908 } 2909 2910 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2911 IBinder threadBinder = thread.asBinder(); 2912 // Find the application record. 2913 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2914 ProcessRecord rec = mLruProcesses.get(i); 2915 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2916 return i; 2917 } 2918 } 2919 return -1; 2920 } 2921 2922 final ProcessRecord getRecordForAppLocked( 2923 IApplicationThread thread) { 2924 if (thread == null) { 2925 return null; 2926 } 2927 2928 int appIndex = getLRURecordIndexForAppLocked(thread); 2929 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2930 } 2931 2932 final void appDiedLocked(ProcessRecord app, int pid, 2933 IApplicationThread thread) { 2934 2935 mProcDeaths[0]++; 2936 2937 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2938 synchronized (stats) { 2939 stats.noteProcessDiedLocked(app.info.uid, pid); 2940 } 2941 2942 // Clean up already done if the process has been re-started. 2943 if (app.pid == pid && app.thread != null && 2944 app.thread.asBinder() == thread.asBinder()) { 2945 if (!app.killedBackground) { 2946 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2947 + ") has died."); 2948 } 2949 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2950 if (localLOGV) Slog.v( 2951 TAG, "Dying app: " + app + ", pid: " + pid 2952 + ", thread: " + thread.asBinder()); 2953 boolean doLowMem = app.instrumentationClass == null; 2954 handleAppDiedLocked(app, false, true); 2955 2956 if (doLowMem) { 2957 // If there are no longer any background processes running, 2958 // and the app that died was not running instrumentation, 2959 // then tell everyone we are now low on memory. 2960 boolean haveBg = false; 2961 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2962 ProcessRecord rec = mLruProcesses.get(i); 2963 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2964 haveBg = true; 2965 break; 2966 } 2967 } 2968 2969 if (!haveBg) { 2970 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2971 long now = SystemClock.uptimeMillis(); 2972 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2973 ProcessRecord rec = mLruProcesses.get(i); 2974 if (rec != app && rec.thread != null && 2975 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2976 // The low memory report is overriding any current 2977 // state for a GC request. Make sure to do 2978 // heavy/important/visible/foreground processes first. 2979 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2980 rec.lastRequestedGc = 0; 2981 } else { 2982 rec.lastRequestedGc = rec.lastLowMemory; 2983 } 2984 rec.reportLowMemory = true; 2985 rec.lastLowMemory = now; 2986 mProcessesToGc.remove(rec); 2987 addProcessToGcListLocked(rec); 2988 } 2989 } 2990 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 2991 scheduleAppGcsLocked(); 2992 } 2993 } 2994 } else if (app.pid != pid) { 2995 // A new process has already been started. 2996 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2997 + ") has died and restarted (pid " + app.pid + ")."); 2998 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2999 } else if (DEBUG_PROCESSES) { 3000 Slog.d(TAG, "Received spurious death notification for thread " 3001 + thread.asBinder()); 3002 } 3003 } 3004 3005 /** 3006 * If a stack trace dump file is configured, dump process stack traces. 3007 * @param clearTraces causes the dump file to be erased prior to the new 3008 * traces being written, if true; when false, the new traces will be 3009 * appended to any existing file content. 3010 * @param firstPids of dalvik VM processes to dump stack traces for first 3011 * @param lastPids of dalvik VM processes to dump stack traces for last 3012 * @param nativeProcs optional list of native process names to dump stack crawls 3013 * @return file containing stack traces, or null if no dump file is configured 3014 */ 3015 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3016 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3017 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3018 if (tracesPath == null || tracesPath.length() == 0) { 3019 return null; 3020 } 3021 3022 File tracesFile = new File(tracesPath); 3023 try { 3024 File tracesDir = tracesFile.getParentFile(); 3025 if (!tracesDir.exists()) tracesFile.mkdirs(); 3026 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3027 3028 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3029 tracesFile.createNewFile(); 3030 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3031 } catch (IOException e) { 3032 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3033 return null; 3034 } 3035 3036 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3037 return tracesFile; 3038 } 3039 3040 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3041 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3042 // Use a FileObserver to detect when traces finish writing. 3043 // The order of traces is considered important to maintain for legibility. 3044 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3045 public synchronized void onEvent(int event, String path) { notify(); } 3046 }; 3047 3048 try { 3049 observer.startWatching(); 3050 3051 // First collect all of the stacks of the most important pids. 3052 if (firstPids != null) { 3053 try { 3054 int num = firstPids.size(); 3055 for (int i = 0; i < num; i++) { 3056 synchronized (observer) { 3057 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3058 observer.wait(200); // Wait for write-close, give up after 200msec 3059 } 3060 } 3061 } catch (InterruptedException e) { 3062 Log.wtf(TAG, e); 3063 } 3064 } 3065 3066 // Next measure CPU usage. 3067 if (processStats != null) { 3068 processStats.init(); 3069 System.gc(); 3070 processStats.update(); 3071 try { 3072 synchronized (processStats) { 3073 processStats.wait(500); // measure over 1/2 second. 3074 } 3075 } catch (InterruptedException e) { 3076 } 3077 processStats.update(); 3078 3079 // We'll take the stack crawls of just the top apps using CPU. 3080 final int N = processStats.countWorkingStats(); 3081 int numProcs = 0; 3082 for (int i=0; i<N && numProcs<5; i++) { 3083 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3084 if (lastPids.indexOfKey(stats.pid) >= 0) { 3085 numProcs++; 3086 try { 3087 synchronized (observer) { 3088 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3089 observer.wait(200); // Wait for write-close, give up after 200msec 3090 } 3091 } catch (InterruptedException e) { 3092 Log.wtf(TAG, e); 3093 } 3094 3095 } 3096 } 3097 } 3098 3099 } finally { 3100 observer.stopWatching(); 3101 } 3102 3103 if (nativeProcs != null) { 3104 int[] pids = Process.getPidsForCommands(nativeProcs); 3105 if (pids != null) { 3106 for (int pid : pids) { 3107 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3108 } 3109 } 3110 } 3111 } 3112 3113 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3114 if (true || IS_USER_BUILD) { 3115 return; 3116 } 3117 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3118 if (tracesPath == null || tracesPath.length() == 0) { 3119 return; 3120 } 3121 3122 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3123 StrictMode.allowThreadDiskWrites(); 3124 try { 3125 final File tracesFile = new File(tracesPath); 3126 final File tracesDir = tracesFile.getParentFile(); 3127 final File tracesTmp = new File(tracesDir, "__tmp__"); 3128 try { 3129 if (!tracesDir.exists()) tracesFile.mkdirs(); 3130 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3131 3132 if (tracesFile.exists()) { 3133 tracesTmp.delete(); 3134 tracesFile.renameTo(tracesTmp); 3135 } 3136 StringBuilder sb = new StringBuilder(); 3137 Time tobj = new Time(); 3138 tobj.set(System.currentTimeMillis()); 3139 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3140 sb.append(": "); 3141 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3142 sb.append(" since "); 3143 sb.append(msg); 3144 FileOutputStream fos = new FileOutputStream(tracesFile); 3145 fos.write(sb.toString().getBytes()); 3146 if (app == null) { 3147 fos.write("\n*** No application process!".getBytes()); 3148 } 3149 fos.close(); 3150 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3151 } catch (IOException e) { 3152 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3153 return; 3154 } 3155 3156 if (app != null) { 3157 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3158 firstPids.add(app.pid); 3159 dumpStackTraces(tracesPath, firstPids, null, null, null); 3160 } 3161 3162 File lastTracesFile = null; 3163 File curTracesFile = null; 3164 for (int i=9; i>=0; i--) { 3165 String name = String.format("slow%02d.txt", i); 3166 curTracesFile = new File(tracesDir, name); 3167 if (curTracesFile.exists()) { 3168 if (lastTracesFile != null) { 3169 curTracesFile.renameTo(lastTracesFile); 3170 } else { 3171 curTracesFile.delete(); 3172 } 3173 } 3174 lastTracesFile = curTracesFile; 3175 } 3176 tracesFile.renameTo(curTracesFile); 3177 if (tracesTmp.exists()) { 3178 tracesTmp.renameTo(tracesFile); 3179 } 3180 } finally { 3181 StrictMode.setThreadPolicy(oldPolicy); 3182 } 3183 } 3184 3185 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3186 ActivityRecord parent, final String annotation) { 3187 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3188 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3189 3190 if (mController != null) { 3191 try { 3192 // 0 == continue, -1 = kill process immediately 3193 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3194 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3195 } catch (RemoteException e) { 3196 mController = null; 3197 } 3198 } 3199 3200 long anrTime = SystemClock.uptimeMillis(); 3201 if (MONITOR_CPU_USAGE) { 3202 updateCpuStatsNow(); 3203 } 3204 3205 synchronized (this) { 3206 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3207 if (mShuttingDown) { 3208 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3209 return; 3210 } else if (app.notResponding) { 3211 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3212 return; 3213 } else if (app.crashing) { 3214 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3215 return; 3216 } 3217 3218 // In case we come through here for the same app before completing 3219 // this one, mark as anring now so we will bail out. 3220 app.notResponding = true; 3221 3222 // Log the ANR to the event log. 3223 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3224 annotation); 3225 3226 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3227 firstPids.add(app.pid); 3228 3229 int parentPid = app.pid; 3230 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3231 if (parentPid != app.pid) firstPids.add(parentPid); 3232 3233 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3234 3235 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3236 ProcessRecord r = mLruProcesses.get(i); 3237 if (r != null && r.thread != null) { 3238 int pid = r.pid; 3239 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3240 if (r.persistent) { 3241 firstPids.add(pid); 3242 } else { 3243 lastPids.put(pid, Boolean.TRUE); 3244 } 3245 } 3246 } 3247 } 3248 } 3249 3250 // Log the ANR to the main log. 3251 StringBuilder info = new StringBuilder(); 3252 info.setLength(0); 3253 info.append("ANR in ").append(app.processName); 3254 if (activity != null && activity.shortComponentName != null) { 3255 info.append(" (").append(activity.shortComponentName).append(")"); 3256 } 3257 info.append("\n"); 3258 if (annotation != null) { 3259 info.append("Reason: ").append(annotation).append("\n"); 3260 } 3261 if (parent != null && parent != activity) { 3262 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3263 } 3264 3265 final ProcessStats processStats = new ProcessStats(true); 3266 3267 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3268 3269 String cpuInfo = null; 3270 if (MONITOR_CPU_USAGE) { 3271 updateCpuStatsNow(); 3272 synchronized (mProcessStatsThread) { 3273 cpuInfo = mProcessStats.printCurrentState(anrTime); 3274 } 3275 info.append(processStats.printCurrentLoad()); 3276 info.append(cpuInfo); 3277 } 3278 3279 info.append(processStats.printCurrentState(anrTime)); 3280 3281 Slog.e(TAG, info.toString()); 3282 if (tracesFile == null) { 3283 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3284 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3285 } 3286 3287 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3288 cpuInfo, tracesFile, null); 3289 3290 if (mController != null) { 3291 try { 3292 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3293 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3294 if (res != 0) { 3295 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3296 return; 3297 } 3298 } catch (RemoteException e) { 3299 mController = null; 3300 } 3301 } 3302 3303 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3304 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3305 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3306 3307 synchronized (this) { 3308 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3309 Slog.w(TAG, "Killing " + app + ": background ANR"); 3310 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3311 app.processName, app.setAdj, "background ANR"); 3312 Process.killProcessQuiet(app.pid); 3313 return; 3314 } 3315 3316 // Set the app's notResponding state, and look up the errorReportReceiver 3317 makeAppNotRespondingLocked(app, 3318 activity != null ? activity.shortComponentName : null, 3319 annotation != null ? "ANR " + annotation : "ANR", 3320 info.toString()); 3321 3322 // Bring up the infamous App Not Responding dialog 3323 Message msg = Message.obtain(); 3324 HashMap map = new HashMap(); 3325 msg.what = SHOW_NOT_RESPONDING_MSG; 3326 msg.obj = map; 3327 map.put("app", app); 3328 if (activity != null) { 3329 map.put("activity", activity); 3330 } 3331 3332 mHandler.sendMessage(msg); 3333 } 3334 } 3335 3336 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3337 if (!mLaunchWarningShown) { 3338 mLaunchWarningShown = true; 3339 mHandler.post(new Runnable() { 3340 @Override 3341 public void run() { 3342 synchronized (ActivityManagerService.this) { 3343 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3344 d.show(); 3345 mHandler.postDelayed(new Runnable() { 3346 @Override 3347 public void run() { 3348 synchronized (ActivityManagerService.this) { 3349 d.dismiss(); 3350 mLaunchWarningShown = false; 3351 } 3352 } 3353 }, 4000); 3354 } 3355 } 3356 }); 3357 } 3358 } 3359 3360 public boolean clearApplicationUserData(final String packageName, 3361 final IPackageDataObserver observer, final int userId) { 3362 enforceNotIsolatedCaller("clearApplicationUserData"); 3363 int uid = Binder.getCallingUid(); 3364 int pid = Binder.getCallingPid(); 3365 long callingId = Binder.clearCallingIdentity(); 3366 try { 3367 IPackageManager pm = AppGlobals.getPackageManager(); 3368 int pkgUid = -1; 3369 synchronized(this) { 3370 try { 3371 pkgUid = pm.getPackageUid(packageName, userId); 3372 } catch (RemoteException e) { 3373 } 3374 if (pkgUid == -1) { 3375 Slog.w(TAG, "Invalid packageName:" + packageName); 3376 return false; 3377 } 3378 if (uid == pkgUid || checkComponentPermission( 3379 android.Manifest.permission.CLEAR_APP_USER_DATA, 3380 pid, uid, -1, true) 3381 == PackageManager.PERMISSION_GRANTED) { 3382 forceStopPackageLocked(packageName, pkgUid); 3383 } else { 3384 throw new SecurityException(pid+" does not have permission:"+ 3385 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3386 "for process:"+packageName); 3387 } 3388 } 3389 3390 try { 3391 //clear application user data 3392 pm.clearApplicationUserData(packageName, observer, userId); 3393 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3394 Uri.fromParts("package", packageName, null)); 3395 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3396 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3397 null, null, 0, null, null, null, false, false, userId); 3398 } catch (RemoteException e) { 3399 } 3400 } finally { 3401 Binder.restoreCallingIdentity(callingId); 3402 } 3403 return true; 3404 } 3405 3406 public void killBackgroundProcesses(final String packageName) { 3407 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3408 != PackageManager.PERMISSION_GRANTED && 3409 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3410 != PackageManager.PERMISSION_GRANTED) { 3411 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3412 + Binder.getCallingPid() 3413 + ", uid=" + Binder.getCallingUid() 3414 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3415 Slog.w(TAG, msg); 3416 throw new SecurityException(msg); 3417 } 3418 3419 int userId = UserId.getCallingUserId(); 3420 long callingId = Binder.clearCallingIdentity(); 3421 try { 3422 IPackageManager pm = AppGlobals.getPackageManager(); 3423 int pkgUid = -1; 3424 synchronized(this) { 3425 try { 3426 pkgUid = pm.getPackageUid(packageName, userId); 3427 } catch (RemoteException e) { 3428 } 3429 if (pkgUid == -1) { 3430 Slog.w(TAG, "Invalid packageName: " + packageName); 3431 return; 3432 } 3433 killPackageProcessesLocked(packageName, pkgUid, 3434 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3435 } 3436 } finally { 3437 Binder.restoreCallingIdentity(callingId); 3438 } 3439 } 3440 3441 public void killAllBackgroundProcesses() { 3442 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3443 != PackageManager.PERMISSION_GRANTED) { 3444 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3445 + Binder.getCallingPid() 3446 + ", uid=" + Binder.getCallingUid() 3447 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3448 Slog.w(TAG, msg); 3449 throw new SecurityException(msg); 3450 } 3451 3452 long callingId = Binder.clearCallingIdentity(); 3453 try { 3454 synchronized(this) { 3455 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3456 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3457 final int NA = apps.size(); 3458 for (int ia=0; ia<NA; ia++) { 3459 ProcessRecord app = apps.valueAt(ia); 3460 if (app.persistent) { 3461 // we don't kill persistent processes 3462 continue; 3463 } 3464 if (app.removed) { 3465 procs.add(app); 3466 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3467 app.removed = true; 3468 procs.add(app); 3469 } 3470 } 3471 } 3472 3473 int N = procs.size(); 3474 for (int i=0; i<N; i++) { 3475 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3476 } 3477 } 3478 } finally { 3479 Binder.restoreCallingIdentity(callingId); 3480 } 3481 } 3482 3483 public void forceStopPackage(final String packageName) { 3484 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3485 != PackageManager.PERMISSION_GRANTED) { 3486 String msg = "Permission Denial: forceStopPackage() from pid=" 3487 + Binder.getCallingPid() 3488 + ", uid=" + Binder.getCallingUid() 3489 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3490 Slog.w(TAG, msg); 3491 throw new SecurityException(msg); 3492 } 3493 final int userId = UserId.getCallingUserId(); 3494 long callingId = Binder.clearCallingIdentity(); 3495 try { 3496 IPackageManager pm = AppGlobals.getPackageManager(); 3497 int pkgUid = -1; 3498 synchronized(this) { 3499 try { 3500 pkgUid = pm.getPackageUid(packageName, userId); 3501 } catch (RemoteException e) { 3502 } 3503 if (pkgUid == -1) { 3504 Slog.w(TAG, "Invalid packageName: " + packageName); 3505 return; 3506 } 3507 forceStopPackageLocked(packageName, pkgUid); 3508 try { 3509 pm.setPackageStoppedState(packageName, true, userId); 3510 } catch (RemoteException e) { 3511 } catch (IllegalArgumentException e) { 3512 Slog.w(TAG, "Failed trying to unstop package " 3513 + packageName + ": " + e); 3514 } 3515 } 3516 } finally { 3517 Binder.restoreCallingIdentity(callingId); 3518 } 3519 } 3520 3521 /* 3522 * The pkg name and uid have to be specified. 3523 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3524 */ 3525 public void killApplicationWithUid(String pkg, int uid) { 3526 if (pkg == null) { 3527 return; 3528 } 3529 // Make sure the uid is valid. 3530 if (uid < 0) { 3531 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3532 return; 3533 } 3534 int callerUid = Binder.getCallingUid(); 3535 // Only the system server can kill an application 3536 if (callerUid == Process.SYSTEM_UID) { 3537 // Post an aysnc message to kill the application 3538 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3539 msg.arg1 = uid; 3540 msg.arg2 = 0; 3541 msg.obj = pkg; 3542 mHandler.sendMessage(msg); 3543 } else { 3544 throw new SecurityException(callerUid + " cannot kill pkg: " + 3545 pkg); 3546 } 3547 } 3548 3549 public void closeSystemDialogs(String reason) { 3550 enforceNotIsolatedCaller("closeSystemDialogs"); 3551 3552 final int uid = Binder.getCallingUid(); 3553 final long origId = Binder.clearCallingIdentity(); 3554 synchronized (this) { 3555 closeSystemDialogsLocked(uid, reason); 3556 } 3557 Binder.restoreCallingIdentity(origId); 3558 } 3559 3560 void closeSystemDialogsLocked(int callingUid, String reason) { 3561 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3562 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3563 if (reason != null) { 3564 intent.putExtra("reason", reason); 3565 } 3566 mWindowManager.closeSystemDialogs(reason); 3567 3568 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3569 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3570 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3571 r.stack.finishActivityLocked(r, i, 3572 Activity.RESULT_CANCELED, null, "close-sys"); 3573 } 3574 } 3575 3576 broadcastIntentLocked(null, null, intent, null, 3577 null, 0, null, null, null, false, false, -1, 3578 callingUid, 0 /* TODO: Verify */); 3579 } 3580 3581 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3582 throws RemoteException { 3583 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3584 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3585 for (int i=pids.length-1; i>=0; i--) { 3586 infos[i] = new Debug.MemoryInfo(); 3587 Debug.getMemoryInfo(pids[i], infos[i]); 3588 } 3589 return infos; 3590 } 3591 3592 public long[] getProcessPss(int[] pids) throws RemoteException { 3593 enforceNotIsolatedCaller("getProcessPss"); 3594 long[] pss = new long[pids.length]; 3595 for (int i=pids.length-1; i>=0; i--) { 3596 pss[i] = Debug.getPss(pids[i]); 3597 } 3598 return pss; 3599 } 3600 3601 public void killApplicationProcess(String processName, int uid) { 3602 if (processName == null) { 3603 return; 3604 } 3605 3606 int callerUid = Binder.getCallingUid(); 3607 // Only the system server can kill an application 3608 if (callerUid == Process.SYSTEM_UID) { 3609 synchronized (this) { 3610 ProcessRecord app = getProcessRecordLocked(processName, uid); 3611 if (app != null && app.thread != null) { 3612 try { 3613 app.thread.scheduleSuicide(); 3614 } catch (RemoteException e) { 3615 // If the other end already died, then our work here is done. 3616 } 3617 } else { 3618 Slog.w(TAG, "Process/uid not found attempting kill of " 3619 + processName + " / " + uid); 3620 } 3621 } 3622 } else { 3623 throw new SecurityException(callerUid + " cannot kill app process: " + 3624 processName); 3625 } 3626 } 3627 3628 private void forceStopPackageLocked(final String packageName, int uid) { 3629 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3630 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3631 Uri.fromParts("package", packageName, null)); 3632 if (!mProcessesReady) { 3633 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3634 } 3635 intent.putExtra(Intent.EXTRA_UID, uid); 3636 broadcastIntentLocked(null, null, intent, 3637 null, null, 0, null, null, null, 3638 false, false, 3639 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3640 } 3641 3642 private final boolean killPackageProcessesLocked(String packageName, int uid, 3643 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3644 boolean evenPersistent, String reason) { 3645 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3646 3647 // Remove all processes this package may have touched: all with the 3648 // same UID (except for the system or root user), and all whose name 3649 // matches the package name. 3650 final String procNamePrefix = packageName + ":"; 3651 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3652 final int NA = apps.size(); 3653 for (int ia=0; ia<NA; ia++) { 3654 ProcessRecord app = apps.valueAt(ia); 3655 if (app.persistent && !evenPersistent) { 3656 // we don't kill persistent processes 3657 continue; 3658 } 3659 if (app.removed) { 3660 if (doit) { 3661 procs.add(app); 3662 } 3663 // If uid is specified and the uid and process name match 3664 // Or, the uid is not specified and the process name matches 3665 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3666 || ((app.processName.equals(packageName) 3667 || app.processName.startsWith(procNamePrefix)) 3668 && uid < 0))) { 3669 if (app.setAdj >= minOomAdj) { 3670 if (!doit) { 3671 return true; 3672 } 3673 app.removed = true; 3674 procs.add(app); 3675 } 3676 } 3677 } 3678 } 3679 3680 int N = procs.size(); 3681 for (int i=0; i<N; i++) { 3682 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3683 } 3684 return N > 0; 3685 } 3686 3687 private final boolean forceStopPackageLocked(String name, int uid, 3688 boolean callerWillRestart, boolean purgeCache, boolean doit, 3689 boolean evenPersistent, int userId) { 3690 int i; 3691 int N; 3692 3693 if (uid < 0) { 3694 try { 3695 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3696 } catch (RemoteException e) { 3697 } 3698 } 3699 3700 if (doit) { 3701 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3702 3703 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3704 while (badApps.hasNext()) { 3705 SparseArray<Long> ba = badApps.next(); 3706 if (ba.get(uid) != null) { 3707 badApps.remove(); 3708 } 3709 } 3710 } 3711 3712 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3713 callerWillRestart, false, doit, evenPersistent, "force stop"); 3714 3715 TaskRecord lastTask = null; 3716 for (i=0; i<mMainStack.mHistory.size(); i++) { 3717 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3718 final boolean samePackage = r.packageName.equals(name); 3719 if (r.userId == userId 3720 && (samePackage || r.task == lastTask) 3721 && (r.app == null || evenPersistent || !r.app.persistent)) { 3722 if (!doit) { 3723 if (r.finishing) { 3724 // If this activity is just finishing, then it is not 3725 // interesting as far as something to stop. 3726 continue; 3727 } 3728 return true; 3729 } 3730 didSomething = true; 3731 Slog.i(TAG, " Force finishing activity " + r); 3732 if (samePackage) { 3733 if (r.app != null) { 3734 r.app.removed = true; 3735 } 3736 r.app = null; 3737 } 3738 lastTask = r.task; 3739 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3740 null, "force-stop", true)) { 3741 i--; 3742 } 3743 } 3744 } 3745 3746 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3747 if (!doit) { 3748 return true; 3749 } 3750 didSomething = true; 3751 } 3752 3753 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3754 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3755 if (provider.info.packageName.equals(name) 3756 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3757 if (!doit) { 3758 return true; 3759 } 3760 didSomething = true; 3761 providers.add(provider); 3762 } 3763 } 3764 3765 N = providers.size(); 3766 for (i=0; i<N; i++) { 3767 removeDyingProviderLocked(null, providers.get(i), true); 3768 } 3769 3770 if (doit) { 3771 if (purgeCache) { 3772 AttributeCache ac = AttributeCache.instance(); 3773 if (ac != null) { 3774 ac.removePackage(name); 3775 } 3776 } 3777 if (mBooted) { 3778 mMainStack.resumeTopActivityLocked(null); 3779 mMainStack.scheduleIdleLocked(); 3780 } 3781 } 3782 3783 return didSomething; 3784 } 3785 3786 private final boolean removeProcessLocked(ProcessRecord app, 3787 boolean callerWillRestart, boolean allowRestart, String reason) { 3788 final String name = app.processName; 3789 final int uid = app.uid; 3790 if (DEBUG_PROCESSES) Slog.d( 3791 TAG, "Force removing proc " + app.toShortString() + " (" + name 3792 + "/" + uid + ")"); 3793 3794 mProcessNames.remove(name, uid); 3795 mIsolatedProcesses.remove(app.uid); 3796 if (mHeavyWeightProcess == app) { 3797 mHeavyWeightProcess = null; 3798 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3799 } 3800 boolean needRestart = false; 3801 if (app.pid > 0 && app.pid != MY_PID) { 3802 int pid = app.pid; 3803 synchronized (mPidsSelfLocked) { 3804 mPidsSelfLocked.remove(pid); 3805 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3806 } 3807 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3808 handleAppDiedLocked(app, true, allowRestart); 3809 mLruProcesses.remove(app); 3810 Process.killProcessQuiet(pid); 3811 3812 if (app.persistent && !app.isolated) { 3813 if (!callerWillRestart) { 3814 addAppLocked(app.info, false); 3815 } else { 3816 needRestart = true; 3817 } 3818 } 3819 } else { 3820 mRemovedProcesses.add(app); 3821 } 3822 3823 return needRestart; 3824 } 3825 3826 private final void processStartTimedOutLocked(ProcessRecord app) { 3827 final int pid = app.pid; 3828 boolean gone = false; 3829 synchronized (mPidsSelfLocked) { 3830 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3831 if (knownApp != null && knownApp.thread == null) { 3832 mPidsSelfLocked.remove(pid); 3833 gone = true; 3834 } 3835 } 3836 3837 if (gone) { 3838 Slog.w(TAG, "Process " + app + " failed to attach"); 3839 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3840 app.processName); 3841 mProcessNames.remove(app.processName, app.uid); 3842 mIsolatedProcesses.remove(app.uid); 3843 if (mHeavyWeightProcess == app) { 3844 mHeavyWeightProcess = null; 3845 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3846 } 3847 // Take care of any launching providers waiting for this process. 3848 checkAppInLaunchingProvidersLocked(app, true); 3849 // Take care of any services that are waiting for the process. 3850 mServices.processStartTimedOutLocked(app); 3851 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3852 app.processName, app.setAdj, "start timeout"); 3853 Process.killProcessQuiet(pid); 3854 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3855 Slog.w(TAG, "Unattached app died before backup, skipping"); 3856 try { 3857 IBackupManager bm = IBackupManager.Stub.asInterface( 3858 ServiceManager.getService(Context.BACKUP_SERVICE)); 3859 bm.agentDisconnected(app.info.packageName); 3860 } catch (RemoteException e) { 3861 // Can't happen; the backup manager is local 3862 } 3863 } 3864 if (isPendingBroadcastProcessLocked(pid)) { 3865 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3866 skipPendingBroadcastLocked(pid); 3867 } 3868 } else { 3869 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3870 } 3871 } 3872 3873 private final boolean attachApplicationLocked(IApplicationThread thread, 3874 int pid) { 3875 3876 // Find the application record that is being attached... either via 3877 // the pid if we are running in multiple processes, or just pull the 3878 // next app record if we are emulating process with anonymous threads. 3879 ProcessRecord app; 3880 if (pid != MY_PID && pid >= 0) { 3881 synchronized (mPidsSelfLocked) { 3882 app = mPidsSelfLocked.get(pid); 3883 } 3884 } else { 3885 app = null; 3886 } 3887 3888 if (app == null) { 3889 Slog.w(TAG, "No pending application record for pid " + pid 3890 + " (IApplicationThread " + thread + "); dropping process"); 3891 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3892 if (pid > 0 && pid != MY_PID) { 3893 Process.killProcessQuiet(pid); 3894 } else { 3895 try { 3896 thread.scheduleExit(); 3897 } catch (Exception e) { 3898 // Ignore exceptions. 3899 } 3900 } 3901 return false; 3902 } 3903 3904 // If this application record is still attached to a previous 3905 // process, clean it up now. 3906 if (app.thread != null) { 3907 handleAppDiedLocked(app, true, true); 3908 } 3909 3910 // Tell the process all about itself. 3911 3912 if (localLOGV) Slog.v( 3913 TAG, "Binding process pid " + pid + " to record " + app); 3914 3915 String processName = app.processName; 3916 try { 3917 AppDeathRecipient adr = new AppDeathRecipient( 3918 app, pid, thread); 3919 thread.asBinder().linkToDeath(adr, 0); 3920 app.deathRecipient = adr; 3921 } catch (RemoteException e) { 3922 app.resetPackageList(); 3923 startProcessLocked(app, "link fail", processName); 3924 return false; 3925 } 3926 3927 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3928 3929 app.thread = thread; 3930 app.curAdj = app.setAdj = -100; 3931 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3932 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3933 app.forcingToForeground = null; 3934 app.foregroundServices = false; 3935 app.hasShownUi = false; 3936 app.debugging = false; 3937 3938 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3939 3940 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3941 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3942 3943 if (!normalMode) { 3944 Slog.i(TAG, "Launching preboot mode app: " + app); 3945 } 3946 3947 if (localLOGV) Slog.v( 3948 TAG, "New app record " + app 3949 + " thread=" + thread.asBinder() + " pid=" + pid); 3950 try { 3951 int testMode = IApplicationThread.DEBUG_OFF; 3952 if (mDebugApp != null && mDebugApp.equals(processName)) { 3953 testMode = mWaitForDebugger 3954 ? IApplicationThread.DEBUG_WAIT 3955 : IApplicationThread.DEBUG_ON; 3956 app.debugging = true; 3957 if (mDebugTransient) { 3958 mDebugApp = mOrigDebugApp; 3959 mWaitForDebugger = mOrigWaitForDebugger; 3960 } 3961 } 3962 String profileFile = app.instrumentationProfileFile; 3963 ParcelFileDescriptor profileFd = null; 3964 boolean profileAutoStop = false; 3965 if (mProfileApp != null && mProfileApp.equals(processName)) { 3966 mProfileProc = app; 3967 profileFile = mProfileFile; 3968 profileFd = mProfileFd; 3969 profileAutoStop = mAutoStopProfiler; 3970 } 3971 boolean enableOpenGlTrace = false; 3972 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3973 enableOpenGlTrace = true; 3974 mOpenGlTraceApp = null; 3975 } 3976 3977 // If the app is being launched for restore or full backup, set it up specially 3978 boolean isRestrictedBackupMode = false; 3979 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3980 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3981 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3982 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3983 } 3984 3985 ensurePackageDexOpt(app.instrumentationInfo != null 3986 ? app.instrumentationInfo.packageName 3987 : app.info.packageName); 3988 if (app.instrumentationClass != null) { 3989 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3990 } 3991 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3992 + processName + " with config " + mConfiguration); 3993 ApplicationInfo appInfo = app.instrumentationInfo != null 3994 ? app.instrumentationInfo : app.info; 3995 app.compat = compatibilityInfoForPackageLocked(appInfo); 3996 if (profileFd != null) { 3997 profileFd = profileFd.dup(); 3998 } 3999 thread.bindApplication(processName, appInfo, providers, 4000 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4001 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4002 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4003 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4004 mCoreSettingsObserver.getCoreSettingsLocked()); 4005 updateLruProcessLocked(app, false, true); 4006 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4007 } catch (Exception e) { 4008 // todo: Yikes! What should we do? For now we will try to 4009 // start another process, but that could easily get us in 4010 // an infinite loop of restarting processes... 4011 Slog.w(TAG, "Exception thrown during bind!", e); 4012 4013 app.resetPackageList(); 4014 app.unlinkDeathRecipient(); 4015 startProcessLocked(app, "bind fail", processName); 4016 return false; 4017 } 4018 4019 // Remove this record from the list of starting applications. 4020 mPersistentStartingProcesses.remove(app); 4021 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4022 "Attach application locked removing on hold: " + app); 4023 mProcessesOnHold.remove(app); 4024 4025 boolean badApp = false; 4026 boolean didSomething = false; 4027 4028 // See if the top visible activity is waiting to run in this process... 4029 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4030 if (hr != null && normalMode) { 4031 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4032 && processName.equals(hr.processName)) { 4033 try { 4034 if (mHeadless) { 4035 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4036 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4037 didSomething = true; 4038 } 4039 } catch (Exception e) { 4040 Slog.w(TAG, "Exception in new application when starting activity " 4041 + hr.intent.getComponent().flattenToShortString(), e); 4042 badApp = true; 4043 } 4044 } else { 4045 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4046 } 4047 } 4048 4049 // Find any services that should be running in this process... 4050 if (!badApp) { 4051 try { 4052 didSomething |= mServices.attachApplicationLocked(app, processName); 4053 } catch (Exception e) { 4054 badApp = true; 4055 } 4056 } 4057 4058 // Check if a next-broadcast receiver is in this process... 4059 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4060 try { 4061 didSomething = sendPendingBroadcastsLocked(app); 4062 } catch (Exception e) { 4063 // If the app died trying to launch the receiver we declare it 'bad' 4064 badApp = true; 4065 } 4066 } 4067 4068 // Check whether the next backup agent is in this process... 4069 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4070 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4071 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4072 try { 4073 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4074 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4075 mBackupTarget.backupMode); 4076 } catch (Exception e) { 4077 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4078 e.printStackTrace(); 4079 } 4080 } 4081 4082 if (badApp) { 4083 // todo: Also need to kill application to deal with all 4084 // kinds of exceptions. 4085 handleAppDiedLocked(app, false, true); 4086 return false; 4087 } 4088 4089 if (!didSomething) { 4090 updateOomAdjLocked(); 4091 } 4092 4093 return true; 4094 } 4095 4096 public final void attachApplication(IApplicationThread thread) { 4097 synchronized (this) { 4098 int callingPid = Binder.getCallingPid(); 4099 final long origId = Binder.clearCallingIdentity(); 4100 attachApplicationLocked(thread, callingPid); 4101 Binder.restoreCallingIdentity(origId); 4102 } 4103 } 4104 4105 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4106 final long origId = Binder.clearCallingIdentity(); 4107 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4108 if (stopProfiling) { 4109 synchronized (this) { 4110 if (mProfileProc == r.app) { 4111 if (mProfileFd != null) { 4112 try { 4113 mProfileFd.close(); 4114 } catch (IOException e) { 4115 } 4116 clearProfilerLocked(); 4117 } 4118 } 4119 } 4120 } 4121 Binder.restoreCallingIdentity(origId); 4122 } 4123 4124 void enableScreenAfterBoot() { 4125 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4126 SystemClock.uptimeMillis()); 4127 mWindowManager.enableScreenAfterBoot(); 4128 4129 synchronized (this) { 4130 updateEventDispatchingLocked(); 4131 } 4132 } 4133 4134 public void showBootMessage(final CharSequence msg, final boolean always) { 4135 enforceNotIsolatedCaller("showBootMessage"); 4136 mWindowManager.showBootMessage(msg, always); 4137 } 4138 4139 public void dismissKeyguardOnNextActivity() { 4140 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4141 final long token = Binder.clearCallingIdentity(); 4142 try { 4143 synchronized (this) { 4144 if (mLockScreenShown) { 4145 mLockScreenShown = false; 4146 comeOutOfSleepIfNeededLocked(); 4147 } 4148 mMainStack.dismissKeyguardOnNextActivityLocked(); 4149 } 4150 } finally { 4151 Binder.restoreCallingIdentity(token); 4152 } 4153 } 4154 4155 final void finishBooting() { 4156 IntentFilter pkgFilter = new IntentFilter(); 4157 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4158 pkgFilter.addDataScheme("package"); 4159 mContext.registerReceiver(new BroadcastReceiver() { 4160 @Override 4161 public void onReceive(Context context, Intent intent) { 4162 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4163 if (pkgs != null) { 4164 for (String pkg : pkgs) { 4165 synchronized (ActivityManagerService.this) { 4166 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4167 setResultCode(Activity.RESULT_OK); 4168 return; 4169 } 4170 } 4171 } 4172 } 4173 } 4174 }, pkgFilter); 4175 4176 IntentFilter userFilter = new IntentFilter(); 4177 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4178 mContext.registerReceiver(new BroadcastReceiver() { 4179 @Override 4180 public void onReceive(Context context, Intent intent) { 4181 onUserRemoved(intent); 4182 } 4183 }, userFilter); 4184 4185 synchronized (this) { 4186 // Ensure that any processes we had put on hold are now started 4187 // up. 4188 final int NP = mProcessesOnHold.size(); 4189 if (NP > 0) { 4190 ArrayList<ProcessRecord> procs = 4191 new ArrayList<ProcessRecord>(mProcessesOnHold); 4192 for (int ip=0; ip<NP; ip++) { 4193 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4194 + procs.get(ip)); 4195 startProcessLocked(procs.get(ip), "on-hold", null); 4196 } 4197 } 4198 4199 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4200 // Start looking for apps that are abusing wake locks. 4201 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4202 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4203 // Tell anyone interested that we are done booting! 4204 SystemProperties.set("sys.boot_completed", "1"); 4205 SystemProperties.set("dev.bootcomplete", "1"); 4206 List<UserInfo> users = getUserManager().getUsers(); 4207 for (UserInfo user : users) { 4208 broadcastIntentLocked(null, null, 4209 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4210 null, null, 0, null, null, 4211 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4212 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4213 } 4214 } 4215 } 4216 } 4217 4218 final void ensureBootCompleted() { 4219 boolean booting; 4220 boolean enableScreen; 4221 synchronized (this) { 4222 booting = mBooting; 4223 mBooting = false; 4224 enableScreen = !mBooted; 4225 mBooted = true; 4226 } 4227 4228 if (booting) { 4229 finishBooting(); 4230 } 4231 4232 if (enableScreen) { 4233 enableScreenAfterBoot(); 4234 } 4235 } 4236 4237 public final void activityPaused(IBinder token) { 4238 final long origId = Binder.clearCallingIdentity(); 4239 mMainStack.activityPaused(token, false); 4240 Binder.restoreCallingIdentity(origId); 4241 } 4242 4243 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4244 CharSequence description) { 4245 if (localLOGV) Slog.v( 4246 TAG, "Activity stopped: token=" + token); 4247 4248 // Refuse possible leaked file descriptors 4249 if (icicle != null && icicle.hasFileDescriptors()) { 4250 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4251 } 4252 4253 ActivityRecord r = null; 4254 4255 final long origId = Binder.clearCallingIdentity(); 4256 4257 synchronized (this) { 4258 r = mMainStack.isInStackLocked(token); 4259 if (r != null) { 4260 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4261 } 4262 } 4263 4264 if (r != null) { 4265 sendPendingThumbnail(r, null, null, null, false); 4266 } 4267 4268 trimApplications(); 4269 4270 Binder.restoreCallingIdentity(origId); 4271 } 4272 4273 public final void activityDestroyed(IBinder token) { 4274 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4275 mMainStack.activityDestroyed(token); 4276 } 4277 4278 public String getCallingPackage(IBinder token) { 4279 synchronized (this) { 4280 ActivityRecord r = getCallingRecordLocked(token); 4281 return r != null && r.app != null ? r.info.packageName : null; 4282 } 4283 } 4284 4285 public ComponentName getCallingActivity(IBinder token) { 4286 synchronized (this) { 4287 ActivityRecord r = getCallingRecordLocked(token); 4288 return r != null ? r.intent.getComponent() : null; 4289 } 4290 } 4291 4292 private ActivityRecord getCallingRecordLocked(IBinder token) { 4293 ActivityRecord r = mMainStack.isInStackLocked(token); 4294 if (r == null) { 4295 return null; 4296 } 4297 return r.resultTo; 4298 } 4299 4300 public ComponentName getActivityClassForToken(IBinder token) { 4301 synchronized(this) { 4302 ActivityRecord r = mMainStack.isInStackLocked(token); 4303 if (r == null) { 4304 return null; 4305 } 4306 return r.intent.getComponent(); 4307 } 4308 } 4309 4310 public String getPackageForToken(IBinder token) { 4311 synchronized(this) { 4312 ActivityRecord r = mMainStack.isInStackLocked(token); 4313 if (r == null) { 4314 return null; 4315 } 4316 return r.packageName; 4317 } 4318 } 4319 4320 public IIntentSender getIntentSender(int type, 4321 String packageName, IBinder token, String resultWho, 4322 int requestCode, Intent[] intents, String[] resolvedTypes, 4323 int flags, Bundle options) { 4324 enforceNotIsolatedCaller("getIntentSender"); 4325 // Refuse possible leaked file descriptors 4326 if (intents != null) { 4327 if (intents.length < 1) { 4328 throw new IllegalArgumentException("Intents array length must be >= 1"); 4329 } 4330 for (int i=0; i<intents.length; i++) { 4331 Intent intent = intents[i]; 4332 if (intent != null) { 4333 if (intent.hasFileDescriptors()) { 4334 throw new IllegalArgumentException("File descriptors passed in Intent"); 4335 } 4336 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4337 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4338 throw new IllegalArgumentException( 4339 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4340 } 4341 intents[i] = new Intent(intent); 4342 } 4343 } 4344 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4345 throw new IllegalArgumentException( 4346 "Intent array length does not match resolvedTypes length"); 4347 } 4348 } 4349 if (options != null) { 4350 if (options.hasFileDescriptors()) { 4351 throw new IllegalArgumentException("File descriptors passed in options"); 4352 } 4353 } 4354 4355 synchronized(this) { 4356 int callingUid = Binder.getCallingUid(); 4357 try { 4358 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4359 int uid = AppGlobals.getPackageManager() 4360 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4361 if (!UserId.isSameApp(callingUid, uid)) { 4362 String msg = "Permission Denial: getIntentSender() from pid=" 4363 + Binder.getCallingPid() 4364 + ", uid=" + Binder.getCallingUid() 4365 + ", (need uid=" + uid + ")" 4366 + " is not allowed to send as package " + packageName; 4367 Slog.w(TAG, msg); 4368 throw new SecurityException(msg); 4369 } 4370 } 4371 4372 if (DEBUG_MU) 4373 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4374 + Binder.getOrigCallingUid()); 4375 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4376 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4377 4378 } catch (RemoteException e) { 4379 throw new SecurityException(e); 4380 } 4381 } 4382 } 4383 4384 IIntentSender getIntentSenderLocked(int type, 4385 String packageName, int callingUid, IBinder token, String resultWho, 4386 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4387 Bundle options) { 4388 if (DEBUG_MU) 4389 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4390 ActivityRecord activity = null; 4391 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4392 activity = mMainStack.isInStackLocked(token); 4393 if (activity == null) { 4394 return null; 4395 } 4396 if (activity.finishing) { 4397 return null; 4398 } 4399 } 4400 4401 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4402 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4403 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4404 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4405 |PendingIntent.FLAG_UPDATE_CURRENT); 4406 4407 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4408 type, packageName, activity, resultWho, 4409 requestCode, intents, resolvedTypes, flags, options); 4410 WeakReference<PendingIntentRecord> ref; 4411 ref = mIntentSenderRecords.get(key); 4412 PendingIntentRecord rec = ref != null ? ref.get() : null; 4413 if (rec != null) { 4414 if (!cancelCurrent) { 4415 if (updateCurrent) { 4416 if (rec.key.requestIntent != null) { 4417 rec.key.requestIntent.replaceExtras(intents != null ? 4418 intents[intents.length - 1] : null); 4419 } 4420 if (intents != null) { 4421 intents[intents.length-1] = rec.key.requestIntent; 4422 rec.key.allIntents = intents; 4423 rec.key.allResolvedTypes = resolvedTypes; 4424 } else { 4425 rec.key.allIntents = null; 4426 rec.key.allResolvedTypes = null; 4427 } 4428 } 4429 return rec; 4430 } 4431 rec.canceled = true; 4432 mIntentSenderRecords.remove(key); 4433 } 4434 if (noCreate) { 4435 return rec; 4436 } 4437 rec = new PendingIntentRecord(this, key, callingUid); 4438 mIntentSenderRecords.put(key, rec.ref); 4439 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4440 if (activity.pendingResults == null) { 4441 activity.pendingResults 4442 = new HashSet<WeakReference<PendingIntentRecord>>(); 4443 } 4444 activity.pendingResults.add(rec.ref); 4445 } 4446 return rec; 4447 } 4448 4449 public void cancelIntentSender(IIntentSender sender) { 4450 if (!(sender instanceof PendingIntentRecord)) { 4451 return; 4452 } 4453 synchronized(this) { 4454 PendingIntentRecord rec = (PendingIntentRecord)sender; 4455 try { 4456 int uid = AppGlobals.getPackageManager() 4457 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4458 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4459 String msg = "Permission Denial: cancelIntentSender() from pid=" 4460 + Binder.getCallingPid() 4461 + ", uid=" + Binder.getCallingUid() 4462 + " is not allowed to cancel packges " 4463 + rec.key.packageName; 4464 Slog.w(TAG, msg); 4465 throw new SecurityException(msg); 4466 } 4467 } catch (RemoteException e) { 4468 throw new SecurityException(e); 4469 } 4470 cancelIntentSenderLocked(rec, true); 4471 } 4472 } 4473 4474 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4475 rec.canceled = true; 4476 mIntentSenderRecords.remove(rec.key); 4477 if (cleanActivity && rec.key.activity != null) { 4478 rec.key.activity.pendingResults.remove(rec.ref); 4479 } 4480 } 4481 4482 public String getPackageForIntentSender(IIntentSender pendingResult) { 4483 if (!(pendingResult instanceof PendingIntentRecord)) { 4484 return null; 4485 } 4486 try { 4487 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4488 return res.key.packageName; 4489 } catch (ClassCastException e) { 4490 } 4491 return null; 4492 } 4493 4494 public int getUidForIntentSender(IIntentSender sender) { 4495 if (sender instanceof PendingIntentRecord) { 4496 try { 4497 PendingIntentRecord res = (PendingIntentRecord)sender; 4498 return res.uid; 4499 } catch (ClassCastException e) { 4500 } 4501 } 4502 return -1; 4503 } 4504 4505 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4506 if (!(pendingResult instanceof PendingIntentRecord)) { 4507 return false; 4508 } 4509 try { 4510 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4511 if (res.key.allIntents == null) { 4512 return false; 4513 } 4514 for (int i=0; i<res.key.allIntents.length; i++) { 4515 Intent intent = res.key.allIntents[i]; 4516 if (intent.getPackage() != null && intent.getComponent() != null) { 4517 return false; 4518 } 4519 } 4520 return true; 4521 } catch (ClassCastException e) { 4522 } 4523 return false; 4524 } 4525 4526 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4527 if (!(pendingResult instanceof PendingIntentRecord)) { 4528 return false; 4529 } 4530 try { 4531 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4532 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4533 return true; 4534 } 4535 return false; 4536 } catch (ClassCastException e) { 4537 } 4538 return false; 4539 } 4540 4541 public void setProcessLimit(int max) { 4542 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4543 "setProcessLimit()"); 4544 synchronized (this) { 4545 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4546 mProcessLimitOverride = max; 4547 } 4548 trimApplications(); 4549 } 4550 4551 public int getProcessLimit() { 4552 synchronized (this) { 4553 return mProcessLimitOverride; 4554 } 4555 } 4556 4557 void foregroundTokenDied(ForegroundToken token) { 4558 synchronized (ActivityManagerService.this) { 4559 synchronized (mPidsSelfLocked) { 4560 ForegroundToken cur 4561 = mForegroundProcesses.get(token.pid); 4562 if (cur != token) { 4563 return; 4564 } 4565 mForegroundProcesses.remove(token.pid); 4566 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4567 if (pr == null) { 4568 return; 4569 } 4570 pr.forcingToForeground = null; 4571 pr.foregroundServices = false; 4572 } 4573 updateOomAdjLocked(); 4574 } 4575 } 4576 4577 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4578 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4579 "setProcessForeground()"); 4580 synchronized(this) { 4581 boolean changed = false; 4582 4583 synchronized (mPidsSelfLocked) { 4584 ProcessRecord pr = mPidsSelfLocked.get(pid); 4585 if (pr == null && isForeground) { 4586 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4587 return; 4588 } 4589 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4590 if (oldToken != null) { 4591 oldToken.token.unlinkToDeath(oldToken, 0); 4592 mForegroundProcesses.remove(pid); 4593 if (pr != null) { 4594 pr.forcingToForeground = null; 4595 } 4596 changed = true; 4597 } 4598 if (isForeground && token != null) { 4599 ForegroundToken newToken = new ForegroundToken() { 4600 public void binderDied() { 4601 foregroundTokenDied(this); 4602 } 4603 }; 4604 newToken.pid = pid; 4605 newToken.token = token; 4606 try { 4607 token.linkToDeath(newToken, 0); 4608 mForegroundProcesses.put(pid, newToken); 4609 pr.forcingToForeground = token; 4610 changed = true; 4611 } catch (RemoteException e) { 4612 // If the process died while doing this, we will later 4613 // do the cleanup with the process death link. 4614 } 4615 } 4616 } 4617 4618 if (changed) { 4619 updateOomAdjLocked(); 4620 } 4621 } 4622 } 4623 4624 // ========================================================= 4625 // PERMISSIONS 4626 // ========================================================= 4627 4628 static class PermissionController extends IPermissionController.Stub { 4629 ActivityManagerService mActivityManagerService; 4630 PermissionController(ActivityManagerService activityManagerService) { 4631 mActivityManagerService = activityManagerService; 4632 } 4633 4634 public boolean checkPermission(String permission, int pid, int uid) { 4635 return mActivityManagerService.checkPermission(permission, pid, 4636 uid) == PackageManager.PERMISSION_GRANTED; 4637 } 4638 } 4639 4640 /** 4641 * This can be called with or without the global lock held. 4642 */ 4643 int checkComponentPermission(String permission, int pid, int uid, 4644 int owningUid, boolean exported) { 4645 // We might be performing an operation on behalf of an indirect binder 4646 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4647 // client identity accordingly before proceeding. 4648 Identity tlsIdentity = sCallerIdentity.get(); 4649 if (tlsIdentity != null) { 4650 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4651 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4652 uid = tlsIdentity.uid; 4653 pid = tlsIdentity.pid; 4654 } 4655 4656 if (pid == MY_PID) { 4657 return PackageManager.PERMISSION_GRANTED; 4658 } 4659 4660 return ActivityManager.checkComponentPermission(permission, uid, 4661 owningUid, exported); 4662 } 4663 4664 /** 4665 * As the only public entry point for permissions checking, this method 4666 * can enforce the semantic that requesting a check on a null global 4667 * permission is automatically denied. (Internally a null permission 4668 * string is used when calling {@link #checkComponentPermission} in cases 4669 * when only uid-based security is needed.) 4670 * 4671 * This can be called with or without the global lock held. 4672 */ 4673 public int checkPermission(String permission, int pid, int uid) { 4674 if (permission == null) { 4675 return PackageManager.PERMISSION_DENIED; 4676 } 4677 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4678 } 4679 4680 /** 4681 * Binder IPC calls go through the public entry point. 4682 * This can be called with or without the global lock held. 4683 */ 4684 int checkCallingPermission(String permission) { 4685 return checkPermission(permission, 4686 Binder.getCallingPid(), 4687 UserId.getAppId(Binder.getCallingUid())); 4688 } 4689 4690 /** 4691 * This can be called with or without the global lock held. 4692 */ 4693 void enforceCallingPermission(String permission, String func) { 4694 if (checkCallingPermission(permission) 4695 == PackageManager.PERMISSION_GRANTED) { 4696 return; 4697 } 4698 4699 String msg = "Permission Denial: " + func + " from pid=" 4700 + Binder.getCallingPid() 4701 + ", uid=" + Binder.getCallingUid() 4702 + " requires " + permission; 4703 Slog.w(TAG, msg); 4704 throw new SecurityException(msg); 4705 } 4706 4707 /** 4708 * Determine if UID is holding permissions required to access {@link Uri} in 4709 * the given {@link ProviderInfo}. Final permission checking is always done 4710 * in {@link ContentProvider}. 4711 */ 4712 private final boolean checkHoldingPermissionsLocked( 4713 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4714 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4715 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4716 4717 if (pi.applicationInfo.uid == uid) { 4718 return true; 4719 } else if (!pi.exported) { 4720 return false; 4721 } 4722 4723 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4724 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4725 try { 4726 // check if target holds top-level <provider> permissions 4727 if (!readMet && pi.readPermission != null 4728 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4729 readMet = true; 4730 } 4731 if (!writeMet && pi.writePermission != null 4732 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4733 writeMet = true; 4734 } 4735 4736 // track if unprotected read/write is allowed; any denied 4737 // <path-permission> below removes this ability 4738 boolean allowDefaultRead = pi.readPermission == null; 4739 boolean allowDefaultWrite = pi.writePermission == null; 4740 4741 // check if target holds any <path-permission> that match uri 4742 final PathPermission[] pps = pi.pathPermissions; 4743 if (pps != null) { 4744 final String path = uri.getPath(); 4745 int i = pps.length; 4746 while (i > 0 && (!readMet || !writeMet)) { 4747 i--; 4748 PathPermission pp = pps[i]; 4749 if (pp.match(path)) { 4750 if (!readMet) { 4751 final String pprperm = pp.getReadPermission(); 4752 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4753 + pprperm + " for " + pp.getPath() 4754 + ": match=" + pp.match(path) 4755 + " check=" + pm.checkUidPermission(pprperm, uid)); 4756 if (pprperm != null) { 4757 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4758 readMet = true; 4759 } else { 4760 allowDefaultRead = false; 4761 } 4762 } 4763 } 4764 if (!writeMet) { 4765 final String ppwperm = pp.getWritePermission(); 4766 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4767 + ppwperm + " for " + pp.getPath() 4768 + ": match=" + pp.match(path) 4769 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4770 if (ppwperm != null) { 4771 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4772 writeMet = true; 4773 } else { 4774 allowDefaultWrite = false; 4775 } 4776 } 4777 } 4778 } 4779 } 4780 } 4781 4782 // grant unprotected <provider> read/write, if not blocked by 4783 // <path-permission> above 4784 if (allowDefaultRead) readMet = true; 4785 if (allowDefaultWrite) writeMet = true; 4786 4787 } catch (RemoteException e) { 4788 return false; 4789 } 4790 4791 return readMet && writeMet; 4792 } 4793 4794 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4795 int modeFlags) { 4796 // Root gets to do everything. 4797 if (uid == 0) { 4798 return true; 4799 } 4800 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4801 if (perms == null) return false; 4802 UriPermission perm = perms.get(uri); 4803 if (perm == null) return false; 4804 return (modeFlags&perm.modeFlags) == modeFlags; 4805 } 4806 4807 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4808 enforceNotIsolatedCaller("checkUriPermission"); 4809 4810 // Another redirected-binder-call permissions check as in 4811 // {@link checkComponentPermission}. 4812 Identity tlsIdentity = sCallerIdentity.get(); 4813 if (tlsIdentity != null) { 4814 uid = tlsIdentity.uid; 4815 pid = tlsIdentity.pid; 4816 } 4817 4818 uid = UserId.getAppId(uid); 4819 // Our own process gets to do everything. 4820 if (pid == MY_PID) { 4821 return PackageManager.PERMISSION_GRANTED; 4822 } 4823 synchronized(this) { 4824 return checkUriPermissionLocked(uri, uid, modeFlags) 4825 ? PackageManager.PERMISSION_GRANTED 4826 : PackageManager.PERMISSION_DENIED; 4827 } 4828 } 4829 4830 /** 4831 * Check if the targetPkg can be granted permission to access uri by 4832 * the callingUid using the given modeFlags. Throws a security exception 4833 * if callingUid is not allowed to do this. Returns the uid of the target 4834 * if the URI permission grant should be performed; returns -1 if it is not 4835 * needed (for example targetPkg already has permission to access the URI). 4836 * If you already know the uid of the target, you can supply it in 4837 * lastTargetUid else set that to -1. 4838 */ 4839 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4840 Uri uri, int modeFlags, int lastTargetUid) { 4841 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4842 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4843 if (modeFlags == 0) { 4844 return -1; 4845 } 4846 4847 if (targetPkg != null) { 4848 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4849 "Checking grant " + targetPkg + " permission to " + uri); 4850 } 4851 4852 final IPackageManager pm = AppGlobals.getPackageManager(); 4853 4854 // If this is not a content: uri, we can't do anything with it. 4855 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4856 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4857 "Can't grant URI permission for non-content URI: " + uri); 4858 return -1; 4859 } 4860 4861 String name = uri.getAuthority(); 4862 ProviderInfo pi = null; 4863 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4864 UserId.getUserId(callingUid)); 4865 if (cpr != null) { 4866 pi = cpr.info; 4867 } else { 4868 try { 4869 pi = pm.resolveContentProvider(name, 4870 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4871 } catch (RemoteException ex) { 4872 } 4873 } 4874 if (pi == null) { 4875 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4876 return -1; 4877 } 4878 4879 int targetUid = lastTargetUid; 4880 if (targetUid < 0 && targetPkg != null) { 4881 try { 4882 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4883 if (targetUid < 0) { 4884 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4885 "Can't grant URI permission no uid for: " + targetPkg); 4886 return -1; 4887 } 4888 } catch (RemoteException ex) { 4889 return -1; 4890 } 4891 } 4892 4893 if (targetUid >= 0) { 4894 // First... does the target actually need this permission? 4895 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4896 // No need to grant the target this permission. 4897 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4898 "Target " + targetPkg + " already has full permission to " + uri); 4899 return -1; 4900 } 4901 } else { 4902 // First... there is no target package, so can anyone access it? 4903 boolean allowed = pi.exported; 4904 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4905 if (pi.readPermission != null) { 4906 allowed = false; 4907 } 4908 } 4909 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4910 if (pi.writePermission != null) { 4911 allowed = false; 4912 } 4913 } 4914 if (allowed) { 4915 return -1; 4916 } 4917 } 4918 4919 // Second... is the provider allowing granting of URI permissions? 4920 if (!pi.grantUriPermissions) { 4921 throw new SecurityException("Provider " + pi.packageName 4922 + "/" + pi.name 4923 + " does not allow granting of Uri permissions (uri " 4924 + uri + ")"); 4925 } 4926 if (pi.uriPermissionPatterns != null) { 4927 final int N = pi.uriPermissionPatterns.length; 4928 boolean allowed = false; 4929 for (int i=0; i<N; i++) { 4930 if (pi.uriPermissionPatterns[i] != null 4931 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4932 allowed = true; 4933 break; 4934 } 4935 } 4936 if (!allowed) { 4937 throw new SecurityException("Provider " + pi.packageName 4938 + "/" + pi.name 4939 + " does not allow granting of permission to path of Uri " 4940 + uri); 4941 } 4942 } 4943 4944 // Third... does the caller itself have permission to access 4945 // this uri? 4946 if (callingUid != Process.myUid()) { 4947 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4948 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4949 throw new SecurityException("Uid " + callingUid 4950 + " does not have permission to uri " + uri); 4951 } 4952 } 4953 } 4954 4955 return targetUid; 4956 } 4957 4958 public int checkGrantUriPermission(int callingUid, String targetPkg, 4959 Uri uri, int modeFlags) { 4960 enforceNotIsolatedCaller("checkGrantUriPermission"); 4961 synchronized(this) { 4962 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4963 } 4964 } 4965 4966 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4967 Uri uri, int modeFlags, UriPermissionOwner owner) { 4968 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4969 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4970 if (modeFlags == 0) { 4971 return; 4972 } 4973 4974 // So here we are: the caller has the assumed permission 4975 // to the uri, and the target doesn't. Let's now give this to 4976 // the target. 4977 4978 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4979 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4980 4981 HashMap<Uri, UriPermission> targetUris 4982 = mGrantedUriPermissions.get(targetUid); 4983 if (targetUris == null) { 4984 targetUris = new HashMap<Uri, UriPermission>(); 4985 mGrantedUriPermissions.put(targetUid, targetUris); 4986 } 4987 4988 UriPermission perm = targetUris.get(uri); 4989 if (perm == null) { 4990 perm = new UriPermission(targetUid, uri); 4991 targetUris.put(uri, perm); 4992 } 4993 4994 perm.modeFlags |= modeFlags; 4995 if (owner == null) { 4996 perm.globalModeFlags |= modeFlags; 4997 } else { 4998 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4999 perm.readOwners.add(owner); 5000 owner.addReadPermission(perm); 5001 } 5002 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5003 perm.writeOwners.add(owner); 5004 owner.addWritePermission(perm); 5005 } 5006 } 5007 } 5008 5009 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5010 int modeFlags, UriPermissionOwner owner) { 5011 if (targetPkg == null) { 5012 throw new NullPointerException("targetPkg"); 5013 } 5014 5015 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5016 if (targetUid < 0) { 5017 return; 5018 } 5019 5020 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5021 } 5022 5023 static class NeededUriGrants extends ArrayList<Uri> { 5024 final String targetPkg; 5025 final int targetUid; 5026 final int flags; 5027 5028 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5029 targetPkg = _targetPkg; 5030 targetUid = _targetUid; 5031 flags = _flags; 5032 } 5033 } 5034 5035 /** 5036 * Like checkGrantUriPermissionLocked, but takes an Intent. 5037 */ 5038 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5039 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5040 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5041 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5042 + " clip=" + (intent != null ? intent.getClipData() : null) 5043 + " from " + intent + "; flags=0x" 5044 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5045 5046 if (targetPkg == null) { 5047 throw new NullPointerException("targetPkg"); 5048 } 5049 5050 if (intent == null) { 5051 return null; 5052 } 5053 Uri data = intent.getData(); 5054 ClipData clip = intent.getClipData(); 5055 if (data == null && clip == null) { 5056 return null; 5057 } 5058 if (data != null) { 5059 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5060 mode, needed != null ? needed.targetUid : -1); 5061 if (target > 0) { 5062 if (needed == null) { 5063 needed = new NeededUriGrants(targetPkg, target, mode); 5064 } 5065 needed.add(data); 5066 } 5067 } 5068 if (clip != null) { 5069 for (int i=0; i<clip.getItemCount(); i++) { 5070 Uri uri = clip.getItemAt(i).getUri(); 5071 if (uri != null) { 5072 int target = -1; 5073 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5074 mode, needed != null ? needed.targetUid : -1); 5075 if (target > 0) { 5076 if (needed == null) { 5077 needed = new NeededUriGrants(targetPkg, target, mode); 5078 } 5079 needed.add(uri); 5080 } 5081 } else { 5082 Intent clipIntent = clip.getItemAt(i).getIntent(); 5083 if (clipIntent != null) { 5084 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5085 callingUid, targetPkg, clipIntent, mode, needed); 5086 if (newNeeded != null) { 5087 needed = newNeeded; 5088 } 5089 } 5090 } 5091 } 5092 } 5093 5094 return needed; 5095 } 5096 5097 /** 5098 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5099 */ 5100 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5101 UriPermissionOwner owner) { 5102 if (needed != null) { 5103 for (int i=0; i<needed.size(); i++) { 5104 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5105 needed.get(i), needed.flags, owner); 5106 } 5107 } 5108 } 5109 5110 void grantUriPermissionFromIntentLocked(int callingUid, 5111 String targetPkg, Intent intent, UriPermissionOwner owner) { 5112 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5113 intent, intent != null ? intent.getFlags() : 0, null); 5114 if (needed == null) { 5115 return; 5116 } 5117 5118 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5119 } 5120 5121 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5122 Uri uri, int modeFlags) { 5123 enforceNotIsolatedCaller("grantUriPermission"); 5124 synchronized(this) { 5125 final ProcessRecord r = getRecordForAppLocked(caller); 5126 if (r == null) { 5127 throw new SecurityException("Unable to find app for caller " 5128 + caller 5129 + " when granting permission to uri " + uri); 5130 } 5131 if (targetPkg == null) { 5132 throw new IllegalArgumentException("null target"); 5133 } 5134 if (uri == null) { 5135 throw new IllegalArgumentException("null uri"); 5136 } 5137 5138 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5139 null); 5140 } 5141 } 5142 5143 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5144 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5145 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5146 HashMap<Uri, UriPermission> perms 5147 = mGrantedUriPermissions.get(perm.uid); 5148 if (perms != null) { 5149 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5150 "Removing " + perm.uid + " permission to " + perm.uri); 5151 perms.remove(perm.uri); 5152 if (perms.size() == 0) { 5153 mGrantedUriPermissions.remove(perm.uid); 5154 } 5155 } 5156 } 5157 } 5158 5159 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5160 int modeFlags) { 5161 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5162 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5163 if (modeFlags == 0) { 5164 return; 5165 } 5166 5167 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5168 "Revoking all granted permissions to " + uri); 5169 5170 final IPackageManager pm = AppGlobals.getPackageManager(); 5171 5172 final String authority = uri.getAuthority(); 5173 ProviderInfo pi = null; 5174 int userId = UserId.getUserId(callingUid); 5175 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5176 if (cpr != null) { 5177 pi = cpr.info; 5178 } else { 5179 try { 5180 pi = pm.resolveContentProvider(authority, 5181 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5182 } catch (RemoteException ex) { 5183 } 5184 } 5185 if (pi == null) { 5186 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5187 return; 5188 } 5189 5190 // Does the caller have this permission on the URI? 5191 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5192 // Right now, if you are not the original owner of the permission, 5193 // you are not allowed to revoke it. 5194 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5195 throw new SecurityException("Uid " + callingUid 5196 + " does not have permission to uri " + uri); 5197 //} 5198 } 5199 5200 // Go through all of the permissions and remove any that match. 5201 final List<String> SEGMENTS = uri.getPathSegments(); 5202 if (SEGMENTS != null) { 5203 final int NS = SEGMENTS.size(); 5204 int N = mGrantedUriPermissions.size(); 5205 for (int i=0; i<N; i++) { 5206 HashMap<Uri, UriPermission> perms 5207 = mGrantedUriPermissions.valueAt(i); 5208 Iterator<UriPermission> it = perms.values().iterator(); 5209 toploop: 5210 while (it.hasNext()) { 5211 UriPermission perm = it.next(); 5212 Uri targetUri = perm.uri; 5213 if (!authority.equals(targetUri.getAuthority())) { 5214 continue; 5215 } 5216 List<String> targetSegments = targetUri.getPathSegments(); 5217 if (targetSegments == null) { 5218 continue; 5219 } 5220 if (targetSegments.size() < NS) { 5221 continue; 5222 } 5223 for (int j=0; j<NS; j++) { 5224 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5225 continue toploop; 5226 } 5227 } 5228 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5229 "Revoking " + perm.uid + " permission to " + perm.uri); 5230 perm.clearModes(modeFlags); 5231 if (perm.modeFlags == 0) { 5232 it.remove(); 5233 } 5234 } 5235 if (perms.size() == 0) { 5236 mGrantedUriPermissions.remove( 5237 mGrantedUriPermissions.keyAt(i)); 5238 N--; 5239 i--; 5240 } 5241 } 5242 } 5243 } 5244 5245 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5246 int modeFlags) { 5247 enforceNotIsolatedCaller("revokeUriPermission"); 5248 synchronized(this) { 5249 final ProcessRecord r = getRecordForAppLocked(caller); 5250 if (r == null) { 5251 throw new SecurityException("Unable to find app for caller " 5252 + caller 5253 + " when revoking permission to uri " + uri); 5254 } 5255 if (uri == null) { 5256 Slog.w(TAG, "revokeUriPermission: null uri"); 5257 return; 5258 } 5259 5260 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5261 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5262 if (modeFlags == 0) { 5263 return; 5264 } 5265 5266 final IPackageManager pm = AppGlobals.getPackageManager(); 5267 5268 final String authority = uri.getAuthority(); 5269 ProviderInfo pi = null; 5270 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5271 if (cpr != null) { 5272 pi = cpr.info; 5273 } else { 5274 try { 5275 pi = pm.resolveContentProvider(authority, 5276 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5277 } catch (RemoteException ex) { 5278 } 5279 } 5280 if (pi == null) { 5281 Slog.w(TAG, "No content provider found for permission revoke: " 5282 + uri.toSafeString()); 5283 return; 5284 } 5285 5286 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5287 } 5288 } 5289 5290 @Override 5291 public IBinder newUriPermissionOwner(String name) { 5292 enforceNotIsolatedCaller("newUriPermissionOwner"); 5293 synchronized(this) { 5294 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5295 return owner.getExternalTokenLocked(); 5296 } 5297 } 5298 5299 @Override 5300 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5301 Uri uri, int modeFlags) { 5302 synchronized(this) { 5303 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5304 if (owner == null) { 5305 throw new IllegalArgumentException("Unknown owner: " + token); 5306 } 5307 if (fromUid != Binder.getCallingUid()) { 5308 if (Binder.getCallingUid() != Process.myUid()) { 5309 // Only system code can grant URI permissions on behalf 5310 // of other users. 5311 throw new SecurityException("nice try"); 5312 } 5313 } 5314 if (targetPkg == null) { 5315 throw new IllegalArgumentException("null target"); 5316 } 5317 if (uri == null) { 5318 throw new IllegalArgumentException("null uri"); 5319 } 5320 5321 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5322 } 5323 } 5324 5325 @Override 5326 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5327 synchronized(this) { 5328 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5329 if (owner == null) { 5330 throw new IllegalArgumentException("Unknown owner: " + token); 5331 } 5332 5333 if (uri == null) { 5334 owner.removeUriPermissionsLocked(mode); 5335 } else { 5336 owner.removeUriPermissionLocked(uri, mode); 5337 } 5338 } 5339 } 5340 5341 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5342 synchronized (this) { 5343 ProcessRecord app = 5344 who != null ? getRecordForAppLocked(who) : null; 5345 if (app == null) return; 5346 5347 Message msg = Message.obtain(); 5348 msg.what = WAIT_FOR_DEBUGGER_MSG; 5349 msg.obj = app; 5350 msg.arg1 = waiting ? 1 : 0; 5351 mHandler.sendMessage(msg); 5352 } 5353 } 5354 5355 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5356 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5357 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5358 outInfo.availMem = Process.getFreeMemory(); 5359 outInfo.totalMem = Process.getTotalMemory(); 5360 outInfo.threshold = homeAppMem; 5361 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5362 outInfo.hiddenAppThreshold = hiddenAppMem; 5363 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5364 ProcessList.SERVICE_ADJ); 5365 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5366 ProcessList.VISIBLE_APP_ADJ); 5367 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5368 ProcessList.FOREGROUND_APP_ADJ); 5369 } 5370 5371 // ========================================================= 5372 // TASK MANAGEMENT 5373 // ========================================================= 5374 5375 public List getTasks(int maxNum, int flags, 5376 IThumbnailReceiver receiver) { 5377 ArrayList list = new ArrayList(); 5378 5379 PendingThumbnailsRecord pending = null; 5380 IApplicationThread topThumbnail = null; 5381 ActivityRecord topRecord = null; 5382 5383 synchronized(this) { 5384 if (localLOGV) Slog.v( 5385 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5386 + ", receiver=" + receiver); 5387 5388 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5389 != PackageManager.PERMISSION_GRANTED) { 5390 if (receiver != null) { 5391 // If the caller wants to wait for pending thumbnails, 5392 // it ain't gonna get them. 5393 try { 5394 receiver.finished(); 5395 } catch (RemoteException ex) { 5396 } 5397 } 5398 String msg = "Permission Denial: getTasks() from pid=" 5399 + Binder.getCallingPid() 5400 + ", uid=" + Binder.getCallingUid() 5401 + " requires " + android.Manifest.permission.GET_TASKS; 5402 Slog.w(TAG, msg); 5403 throw new SecurityException(msg); 5404 } 5405 5406 int pos = mMainStack.mHistory.size()-1; 5407 ActivityRecord next = 5408 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5409 ActivityRecord top = null; 5410 TaskRecord curTask = null; 5411 int numActivities = 0; 5412 int numRunning = 0; 5413 while (pos >= 0 && maxNum > 0) { 5414 final ActivityRecord r = next; 5415 pos--; 5416 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5417 5418 // Initialize state for next task if needed. 5419 if (top == null || 5420 (top.state == ActivityState.INITIALIZING 5421 && top.task == r.task)) { 5422 top = r; 5423 curTask = r.task; 5424 numActivities = numRunning = 0; 5425 } 5426 5427 // Add 'r' into the current task. 5428 numActivities++; 5429 if (r.app != null && r.app.thread != null) { 5430 numRunning++; 5431 } 5432 5433 if (localLOGV) Slog.v( 5434 TAG, r.intent.getComponent().flattenToShortString() 5435 + ": task=" + r.task); 5436 5437 // If the next one is a different task, generate a new 5438 // TaskInfo entry for what we have. 5439 if (next == null || next.task != curTask) { 5440 ActivityManager.RunningTaskInfo ci 5441 = new ActivityManager.RunningTaskInfo(); 5442 ci.id = curTask.taskId; 5443 ci.baseActivity = r.intent.getComponent(); 5444 ci.topActivity = top.intent.getComponent(); 5445 if (top.thumbHolder != null) { 5446 ci.description = top.thumbHolder.lastDescription; 5447 } 5448 ci.numActivities = numActivities; 5449 ci.numRunning = numRunning; 5450 //System.out.println( 5451 // "#" + maxNum + ": " + " descr=" + ci.description); 5452 if (ci.thumbnail == null && receiver != null) { 5453 if (localLOGV) Slog.v( 5454 TAG, "State=" + top.state + "Idle=" + top.idle 5455 + " app=" + top.app 5456 + " thr=" + (top.app != null ? top.app.thread : null)); 5457 if (top.state == ActivityState.RESUMED 5458 || top.state == ActivityState.PAUSING) { 5459 if (top.idle && top.app != null 5460 && top.app.thread != null) { 5461 topRecord = top; 5462 topThumbnail = top.app.thread; 5463 } else { 5464 top.thumbnailNeeded = true; 5465 } 5466 } 5467 if (pending == null) { 5468 pending = new PendingThumbnailsRecord(receiver); 5469 } 5470 pending.pendingRecords.add(top); 5471 } 5472 list.add(ci); 5473 maxNum--; 5474 top = null; 5475 } 5476 } 5477 5478 if (pending != null) { 5479 mPendingThumbnails.add(pending); 5480 } 5481 } 5482 5483 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5484 5485 if (topThumbnail != null) { 5486 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5487 try { 5488 topThumbnail.requestThumbnail(topRecord.appToken); 5489 } catch (Exception e) { 5490 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5491 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5492 } 5493 } 5494 5495 if (pending == null && receiver != null) { 5496 // In this case all thumbnails were available and the client 5497 // is being asked to be told when the remaining ones come in... 5498 // which is unusually, since the top-most currently running 5499 // activity should never have a canned thumbnail! Oh well. 5500 try { 5501 receiver.finished(); 5502 } catch (RemoteException ex) { 5503 } 5504 } 5505 5506 return list; 5507 } 5508 5509 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5510 int flags, int userId) { 5511 final int callingUid = Binder.getCallingUid(); 5512 if (userId != UserId.getCallingUserId()) { 5513 // Check if the caller is holding permissions for cross-user requests. 5514 if (checkComponentPermission( 5515 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5516 Binder.getCallingPid(), callingUid, -1, true) 5517 != PackageManager.PERMISSION_GRANTED) { 5518 String msg = "Permission Denial: " 5519 + "Request to get recent tasks for user " + userId 5520 + " but is calling from user " + UserId.getUserId(callingUid) 5521 + "; this requires " 5522 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5523 Slog.w(TAG, msg); 5524 throw new SecurityException(msg); 5525 } else { 5526 if (userId == UserId.USER_CURRENT) { 5527 userId = mCurrentUserId; 5528 } 5529 } 5530 } 5531 5532 synchronized (this) { 5533 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5534 "getRecentTasks()"); 5535 final boolean detailed = checkCallingPermission( 5536 android.Manifest.permission.GET_DETAILED_TASKS) 5537 == PackageManager.PERMISSION_GRANTED; 5538 5539 IPackageManager pm = AppGlobals.getPackageManager(); 5540 5541 final int N = mRecentTasks.size(); 5542 ArrayList<ActivityManager.RecentTaskInfo> res 5543 = new ArrayList<ActivityManager.RecentTaskInfo>( 5544 maxNum < N ? maxNum : N); 5545 for (int i=0; i<N && maxNum > 0; i++) { 5546 TaskRecord tr = mRecentTasks.get(i); 5547 // Only add calling user's recent tasks 5548 if (tr.userId != userId) continue; 5549 // Return the entry if desired by the caller. We always return 5550 // the first entry, because callers always expect this to be the 5551 // foreground app. We may filter others if the caller has 5552 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5553 // we should exclude the entry. 5554 5555 if (i == 0 5556 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5557 || (tr.intent == null) 5558 || ((tr.intent.getFlags() 5559 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5560 ActivityManager.RecentTaskInfo rti 5561 = new ActivityManager.RecentTaskInfo(); 5562 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5563 rti.persistentId = tr.taskId; 5564 rti.baseIntent = new Intent( 5565 tr.intent != null ? tr.intent : tr.affinityIntent); 5566 if (!detailed) { 5567 rti.baseIntent.replaceExtras((Bundle)null); 5568 } 5569 rti.origActivity = tr.origActivity; 5570 rti.description = tr.lastDescription; 5571 5572 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5573 // Check whether this activity is currently available. 5574 try { 5575 if (rti.origActivity != null) { 5576 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5577 == null) { 5578 continue; 5579 } 5580 } else if (rti.baseIntent != null) { 5581 if (pm.queryIntentActivities(rti.baseIntent, 5582 null, 0, userId) == null) { 5583 continue; 5584 } 5585 } 5586 } catch (RemoteException e) { 5587 // Will never happen. 5588 } 5589 } 5590 5591 res.add(rti); 5592 maxNum--; 5593 } 5594 } 5595 return res; 5596 } 5597 } 5598 5599 private TaskRecord taskForIdLocked(int id) { 5600 final int N = mRecentTasks.size(); 5601 for (int i=0; i<N; i++) { 5602 TaskRecord tr = mRecentTasks.get(i); 5603 if (tr.taskId == id) { 5604 return tr; 5605 } 5606 } 5607 return null; 5608 } 5609 5610 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5611 synchronized (this) { 5612 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5613 "getTaskThumbnails()"); 5614 TaskRecord tr = taskForIdLocked(id); 5615 if (tr != null) { 5616 return mMainStack.getTaskThumbnailsLocked(tr); 5617 } 5618 } 5619 return null; 5620 } 5621 5622 public boolean removeSubTask(int taskId, int subTaskIndex) { 5623 synchronized (this) { 5624 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5625 "removeSubTask()"); 5626 long ident = Binder.clearCallingIdentity(); 5627 try { 5628 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5629 true) != null; 5630 } finally { 5631 Binder.restoreCallingIdentity(ident); 5632 } 5633 } 5634 } 5635 5636 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5637 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5638 Intent baseIntent = new Intent( 5639 tr.intent != null ? tr.intent : tr.affinityIntent); 5640 ComponentName component = baseIntent.getComponent(); 5641 if (component == null) { 5642 Slog.w(TAG, "Now component for base intent of task: " + tr); 5643 return; 5644 } 5645 5646 // Find any running services associated with this app. 5647 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5648 5649 if (killProcesses) { 5650 // Find any running processes associated with this app. 5651 final String pkg = component.getPackageName(); 5652 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5653 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5654 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5655 for (int i=0; i<uids.size(); i++) { 5656 ProcessRecord proc = uids.valueAt(i); 5657 if (proc.userId != tr.userId) { 5658 continue; 5659 } 5660 if (!proc.pkgList.contains(pkg)) { 5661 continue; 5662 } 5663 procs.add(proc); 5664 } 5665 } 5666 5667 // Kill the running processes. 5668 for (int i=0; i<procs.size(); i++) { 5669 ProcessRecord pr = procs.get(i); 5670 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5671 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5672 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5673 pr.processName, pr.setAdj, "remove task"); 5674 pr.killedBackground = true; 5675 Process.killProcessQuiet(pr.pid); 5676 } else { 5677 pr.waitingToKill = "remove task"; 5678 } 5679 } 5680 } 5681 } 5682 5683 public boolean removeTask(int taskId, int flags) { 5684 synchronized (this) { 5685 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5686 "removeTask()"); 5687 long ident = Binder.clearCallingIdentity(); 5688 try { 5689 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5690 false); 5691 if (r != null) { 5692 mRecentTasks.remove(r.task); 5693 cleanUpRemovedTaskLocked(r.task, flags); 5694 return true; 5695 } else { 5696 TaskRecord tr = null; 5697 int i=0; 5698 while (i < mRecentTasks.size()) { 5699 TaskRecord t = mRecentTasks.get(i); 5700 if (t.taskId == taskId) { 5701 tr = t; 5702 break; 5703 } 5704 i++; 5705 } 5706 if (tr != null) { 5707 if (tr.numActivities <= 0) { 5708 // Caller is just removing a recent task that is 5709 // not actively running. That is easy! 5710 mRecentTasks.remove(i); 5711 cleanUpRemovedTaskLocked(tr, flags); 5712 return true; 5713 } else { 5714 Slog.w(TAG, "removeTask: task " + taskId 5715 + " does not have activities to remove, " 5716 + " but numActivities=" + tr.numActivities 5717 + ": " + tr); 5718 } 5719 } 5720 } 5721 } finally { 5722 Binder.restoreCallingIdentity(ident); 5723 } 5724 } 5725 return false; 5726 } 5727 5728 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5729 int j; 5730 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5731 TaskRecord jt = startTask; 5732 5733 // First look backwards 5734 for (j=startIndex-1; j>=0; j--) { 5735 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5736 if (r.task != jt) { 5737 jt = r.task; 5738 if (affinity.equals(jt.affinity)) { 5739 return j; 5740 } 5741 } 5742 } 5743 5744 // Now look forwards 5745 final int N = mMainStack.mHistory.size(); 5746 jt = startTask; 5747 for (j=startIndex+1; j<N; j++) { 5748 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5749 if (r.task != jt) { 5750 if (affinity.equals(jt.affinity)) { 5751 return j; 5752 } 5753 jt = r.task; 5754 } 5755 } 5756 5757 // Might it be at the top? 5758 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5759 return N-1; 5760 } 5761 5762 return -1; 5763 } 5764 5765 /** 5766 * TODO: Add mController hook 5767 */ 5768 public void moveTaskToFront(int task, int flags, Bundle options) { 5769 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5770 "moveTaskToFront()"); 5771 5772 synchronized(this) { 5773 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5774 Binder.getCallingUid(), "Task to front")) { 5775 ActivityOptions.abort(options); 5776 return; 5777 } 5778 final long origId = Binder.clearCallingIdentity(); 5779 try { 5780 TaskRecord tr = taskForIdLocked(task); 5781 if (tr != null) { 5782 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5783 mMainStack.mUserLeaving = true; 5784 } 5785 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5786 // Caller wants the home activity moved with it. To accomplish this, 5787 // we'll just move the home task to the top first. 5788 mMainStack.moveHomeToFrontLocked(); 5789 } 5790 mMainStack.moveTaskToFrontLocked(tr, null, options); 5791 return; 5792 } 5793 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5794 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5795 if (hr.task.taskId == task) { 5796 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5797 mMainStack.mUserLeaving = true; 5798 } 5799 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5800 // Caller wants the home activity moved with it. To accomplish this, 5801 // we'll just move the home task to the top first. 5802 mMainStack.moveHomeToFrontLocked(); 5803 } 5804 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5805 return; 5806 } 5807 } 5808 } finally { 5809 Binder.restoreCallingIdentity(origId); 5810 } 5811 ActivityOptions.abort(options); 5812 } 5813 } 5814 5815 public void moveTaskToBack(int task) { 5816 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5817 "moveTaskToBack()"); 5818 5819 synchronized(this) { 5820 if (mMainStack.mResumedActivity != null 5821 && mMainStack.mResumedActivity.task.taskId == task) { 5822 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5823 Binder.getCallingUid(), "Task to back")) { 5824 return; 5825 } 5826 } 5827 final long origId = Binder.clearCallingIdentity(); 5828 mMainStack.moveTaskToBackLocked(task, null); 5829 Binder.restoreCallingIdentity(origId); 5830 } 5831 } 5832 5833 /** 5834 * Moves an activity, and all of the other activities within the same task, to the bottom 5835 * of the history stack. The activity's order within the task is unchanged. 5836 * 5837 * @param token A reference to the activity we wish to move 5838 * @param nonRoot If false then this only works if the activity is the root 5839 * of a task; if true it will work for any activity in a task. 5840 * @return Returns true if the move completed, false if not. 5841 */ 5842 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5843 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5844 synchronized(this) { 5845 final long origId = Binder.clearCallingIdentity(); 5846 int taskId = getTaskForActivityLocked(token, !nonRoot); 5847 if (taskId >= 0) { 5848 return mMainStack.moveTaskToBackLocked(taskId, null); 5849 } 5850 Binder.restoreCallingIdentity(origId); 5851 } 5852 return false; 5853 } 5854 5855 public void moveTaskBackwards(int task) { 5856 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5857 "moveTaskBackwards()"); 5858 5859 synchronized(this) { 5860 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5861 Binder.getCallingUid(), "Task backwards")) { 5862 return; 5863 } 5864 final long origId = Binder.clearCallingIdentity(); 5865 moveTaskBackwardsLocked(task); 5866 Binder.restoreCallingIdentity(origId); 5867 } 5868 } 5869 5870 private final void moveTaskBackwardsLocked(int task) { 5871 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5872 } 5873 5874 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5875 synchronized(this) { 5876 return getTaskForActivityLocked(token, onlyRoot); 5877 } 5878 } 5879 5880 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5881 final int N = mMainStack.mHistory.size(); 5882 TaskRecord lastTask = null; 5883 for (int i=0; i<N; i++) { 5884 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5885 if (r.appToken == token) { 5886 if (!onlyRoot || lastTask != r.task) { 5887 return r.task.taskId; 5888 } 5889 return -1; 5890 } 5891 lastTask = r.task; 5892 } 5893 5894 return -1; 5895 } 5896 5897 // ========================================================= 5898 // THUMBNAILS 5899 // ========================================================= 5900 5901 public void reportThumbnail(IBinder token, 5902 Bitmap thumbnail, CharSequence description) { 5903 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5904 final long origId = Binder.clearCallingIdentity(); 5905 sendPendingThumbnail(null, token, thumbnail, description, true); 5906 Binder.restoreCallingIdentity(origId); 5907 } 5908 5909 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5910 Bitmap thumbnail, CharSequence description, boolean always) { 5911 TaskRecord task = null; 5912 ArrayList receivers = null; 5913 5914 //System.out.println("Send pending thumbnail: " + r); 5915 5916 synchronized(this) { 5917 if (r == null) { 5918 r = mMainStack.isInStackLocked(token); 5919 if (r == null) { 5920 return; 5921 } 5922 } 5923 if (thumbnail == null && r.thumbHolder != null) { 5924 thumbnail = r.thumbHolder.lastThumbnail; 5925 description = r.thumbHolder.lastDescription; 5926 } 5927 if (thumbnail == null && !always) { 5928 // If there is no thumbnail, and this entry is not actually 5929 // going away, then abort for now and pick up the next 5930 // thumbnail we get. 5931 return; 5932 } 5933 task = r.task; 5934 5935 int N = mPendingThumbnails.size(); 5936 int i=0; 5937 while (i<N) { 5938 PendingThumbnailsRecord pr = 5939 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5940 //System.out.println("Looking in " + pr.pendingRecords); 5941 if (pr.pendingRecords.remove(r)) { 5942 if (receivers == null) { 5943 receivers = new ArrayList(); 5944 } 5945 receivers.add(pr); 5946 if (pr.pendingRecords.size() == 0) { 5947 pr.finished = true; 5948 mPendingThumbnails.remove(i); 5949 N--; 5950 continue; 5951 } 5952 } 5953 i++; 5954 } 5955 } 5956 5957 if (receivers != null) { 5958 final int N = receivers.size(); 5959 for (int i=0; i<N; i++) { 5960 try { 5961 PendingThumbnailsRecord pr = 5962 (PendingThumbnailsRecord)receivers.get(i); 5963 pr.receiver.newThumbnail( 5964 task != null ? task.taskId : -1, thumbnail, description); 5965 if (pr.finished) { 5966 pr.receiver.finished(); 5967 } 5968 } catch (Exception e) { 5969 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5970 } 5971 } 5972 } 5973 } 5974 5975 // ========================================================= 5976 // CONTENT PROVIDERS 5977 // ========================================================= 5978 5979 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5980 List<ProviderInfo> providers = null; 5981 try { 5982 providers = AppGlobals.getPackageManager(). 5983 queryContentProviders(app.processName, app.uid, 5984 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5985 } catch (RemoteException ex) { 5986 } 5987 if (DEBUG_MU) 5988 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 5989 int userId = app.userId; 5990 if (providers != null) { 5991 int N = providers.size(); 5992 for (int i=0; i<N; i++) { 5993 ProviderInfo cpi = 5994 (ProviderInfo)providers.get(i); 5995 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 5996 cpi.name, cpi.flags); 5997 if (singleton && UserId.getUserId(app.uid) != 0) { 5998 // This is a singleton provider, but a user besides the 5999 // default user is asking to initialize a process it runs 6000 // in... well, no, it doesn't actually run in this process, 6001 // it runs in the process of the default user. Get rid of it. 6002 providers.remove(i); 6003 N--; 6004 continue; 6005 } 6006 6007 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6008 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6009 if (cpr == null) { 6010 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6011 mProviderMap.putProviderByClass(comp, cpr); 6012 } 6013 if (DEBUG_MU) 6014 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6015 app.pubProviders.put(cpi.name, cpr); 6016 app.addPackage(cpi.applicationInfo.packageName); 6017 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6018 } 6019 } 6020 return providers; 6021 } 6022 6023 /** 6024 * Check if {@link ProcessRecord} has a possible chance at accessing the 6025 * given {@link ProviderInfo}. Final permission checking is always done 6026 * in {@link ContentProvider}. 6027 */ 6028 private final String checkContentProviderPermissionLocked( 6029 ProviderInfo cpi, ProcessRecord r) { 6030 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6031 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6032 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6033 cpi.applicationInfo.uid, cpi.exported) 6034 == PackageManager.PERMISSION_GRANTED) { 6035 return null; 6036 } 6037 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6038 cpi.applicationInfo.uid, cpi.exported) 6039 == PackageManager.PERMISSION_GRANTED) { 6040 return null; 6041 } 6042 6043 PathPermission[] pps = cpi.pathPermissions; 6044 if (pps != null) { 6045 int i = pps.length; 6046 while (i > 0) { 6047 i--; 6048 PathPermission pp = pps[i]; 6049 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6050 cpi.applicationInfo.uid, cpi.exported) 6051 == PackageManager.PERMISSION_GRANTED) { 6052 return null; 6053 } 6054 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6055 cpi.applicationInfo.uid, cpi.exported) 6056 == PackageManager.PERMISSION_GRANTED) { 6057 return null; 6058 } 6059 } 6060 } 6061 6062 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6063 if (perms != null) { 6064 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6065 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6066 return null; 6067 } 6068 } 6069 } 6070 6071 String msg; 6072 if (!cpi.exported) { 6073 msg = "Permission Denial: opening provider " + cpi.name 6074 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6075 + ", uid=" + callingUid + ") that is not exported from uid " 6076 + cpi.applicationInfo.uid; 6077 } else { 6078 msg = "Permission Denial: opening provider " + cpi.name 6079 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6080 + ", uid=" + callingUid + ") requires " 6081 + cpi.readPermission + " or " + cpi.writePermission; 6082 } 6083 Slog.w(TAG, msg); 6084 return msg; 6085 } 6086 6087 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6088 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6089 if (r != null) { 6090 for (int i=0; i<r.conProviders.size(); i++) { 6091 ContentProviderConnection conn = r.conProviders.get(i); 6092 if (conn.provider == cpr) { 6093 if (DEBUG_PROVIDER) Slog.v(TAG, 6094 "Adding provider requested by " 6095 + r.processName + " from process " 6096 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6097 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6098 if (stable) { 6099 conn.stableCount++; 6100 conn.numStableIncs++; 6101 } else { 6102 conn.unstableCount++; 6103 conn.numUnstableIncs++; 6104 } 6105 return conn; 6106 } 6107 } 6108 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6109 if (stable) { 6110 conn.stableCount = 1; 6111 conn.numStableIncs = 1; 6112 } else { 6113 conn.unstableCount = 1; 6114 conn.numUnstableIncs = 1; 6115 } 6116 cpr.connections.add(conn); 6117 r.conProviders.add(conn); 6118 return conn; 6119 } 6120 cpr.addExternalProcessHandleLocked(externalProcessToken); 6121 return null; 6122 } 6123 6124 boolean decProviderCountLocked(ContentProviderConnection conn, 6125 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6126 if (conn != null) { 6127 cpr = conn.provider; 6128 if (DEBUG_PROVIDER) Slog.v(TAG, 6129 "Removing provider requested by " 6130 + conn.client.processName + " from process " 6131 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6132 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6133 if (stable) { 6134 conn.stableCount--; 6135 } else { 6136 conn.unstableCount--; 6137 } 6138 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6139 cpr.connections.remove(conn); 6140 conn.client.conProviders.remove(conn); 6141 return true; 6142 } 6143 return false; 6144 } 6145 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6146 return false; 6147 } 6148 6149 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6150 String name, IBinder token, boolean stable) { 6151 ContentProviderRecord cpr; 6152 ContentProviderConnection conn = null; 6153 ProviderInfo cpi = null; 6154 6155 synchronized(this) { 6156 ProcessRecord r = null; 6157 if (caller != null) { 6158 r = getRecordForAppLocked(caller); 6159 if (r == null) { 6160 throw new SecurityException( 6161 "Unable to find app for caller " + caller 6162 + " (pid=" + Binder.getCallingPid() 6163 + ") when getting content provider " + name); 6164 } 6165 } 6166 6167 // First check if this content provider has been published... 6168 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6169 cpr = mProviderMap.getProviderByName(name, userId); 6170 boolean providerRunning = cpr != null; 6171 if (providerRunning) { 6172 cpi = cpr.info; 6173 String msg; 6174 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6175 throw new SecurityException(msg); 6176 } 6177 6178 if (r != null && cpr.canRunHere(r)) { 6179 // This provider has been published or is in the process 6180 // of being published... but it is also allowed to run 6181 // in the caller's process, so don't make a connection 6182 // and just let the caller instantiate its own instance. 6183 ContentProviderHolder holder = cpr.newHolder(null); 6184 // don't give caller the provider object, it needs 6185 // to make its own. 6186 holder.provider = null; 6187 return holder; 6188 } 6189 6190 final long origId = Binder.clearCallingIdentity(); 6191 6192 // In this case the provider instance already exists, so we can 6193 // return it right away. 6194 conn = incProviderCountLocked(r, cpr, token, stable); 6195 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6196 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6197 // If this is a perceptible app accessing the provider, 6198 // make sure to count it as being accessed and thus 6199 // back up on the LRU list. This is good because 6200 // content providers are often expensive to start. 6201 updateLruProcessLocked(cpr.proc, false, true); 6202 } 6203 } 6204 6205 if (cpr.proc != null) { 6206 if (false) { 6207 if (cpr.name.flattenToShortString().equals( 6208 "com.android.providers.calendar/.CalendarProvider2")) { 6209 Slog.v(TAG, "****************** KILLING " 6210 + cpr.name.flattenToShortString()); 6211 Process.killProcess(cpr.proc.pid); 6212 } 6213 } 6214 boolean success = updateOomAdjLocked(cpr.proc); 6215 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6216 // NOTE: there is still a race here where a signal could be 6217 // pending on the process even though we managed to update its 6218 // adj level. Not sure what to do about this, but at least 6219 // the race is now smaller. 6220 if (!success) { 6221 // Uh oh... it looks like the provider's process 6222 // has been killed on us. We need to wait for a new 6223 // process to be started, and make sure its death 6224 // doesn't kill our process. 6225 Slog.i(TAG, 6226 "Existing provider " + cpr.name.flattenToShortString() 6227 + " is crashing; detaching " + r); 6228 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6229 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6230 if (!lastRef) { 6231 // This wasn't the last ref our process had on 6232 // the provider... we have now been killed, bail. 6233 return null; 6234 } 6235 providerRunning = false; 6236 conn = null; 6237 } 6238 } 6239 6240 Binder.restoreCallingIdentity(origId); 6241 } 6242 6243 boolean singleton; 6244 if (!providerRunning) { 6245 try { 6246 cpi = AppGlobals.getPackageManager(). 6247 resolveContentProvider(name, 6248 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6249 } catch (RemoteException ex) { 6250 } 6251 if (cpi == null) { 6252 return null; 6253 } 6254 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6255 cpi.name, cpi.flags); 6256 if (singleton) { 6257 userId = 0; 6258 } 6259 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6260 6261 String msg; 6262 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6263 throw new SecurityException(msg); 6264 } 6265 6266 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6267 && !cpi.processName.equals("system")) { 6268 // If this content provider does not run in the system 6269 // process, and the system is not yet ready to run other 6270 // processes, then fail fast instead of hanging. 6271 throw new IllegalArgumentException( 6272 "Attempt to launch content provider before system ready"); 6273 } 6274 6275 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6276 cpr = mProviderMap.getProviderByClass(comp, userId); 6277 final boolean firstClass = cpr == null; 6278 if (firstClass) { 6279 try { 6280 ApplicationInfo ai = 6281 AppGlobals.getPackageManager(). 6282 getApplicationInfo( 6283 cpi.applicationInfo.packageName, 6284 STOCK_PM_FLAGS, userId); 6285 if (ai == null) { 6286 Slog.w(TAG, "No package info for content provider " 6287 + cpi.name); 6288 return null; 6289 } 6290 ai = getAppInfoForUser(ai, userId); 6291 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6292 } catch (RemoteException ex) { 6293 // pm is in same process, this will never happen. 6294 } 6295 } 6296 6297 if (r != null && cpr.canRunHere(r)) { 6298 // If this is a multiprocess provider, then just return its 6299 // info and allow the caller to instantiate it. Only do 6300 // this if the provider is the same user as the caller's 6301 // process, or can run as root (so can be in any process). 6302 return cpr.newHolder(null); 6303 } 6304 6305 if (DEBUG_PROVIDER) { 6306 RuntimeException e = new RuntimeException("here"); 6307 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6308 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6309 } 6310 6311 // This is single process, and our app is now connecting to it. 6312 // See if we are already in the process of launching this 6313 // provider. 6314 final int N = mLaunchingProviders.size(); 6315 int i; 6316 for (i=0; i<N; i++) { 6317 if (mLaunchingProviders.get(i) == cpr) { 6318 break; 6319 } 6320 } 6321 6322 // If the provider is not already being launched, then get it 6323 // started. 6324 if (i >= N) { 6325 final long origId = Binder.clearCallingIdentity(); 6326 6327 try { 6328 // Content provider is now in use, its package can't be stopped. 6329 try { 6330 AppGlobals.getPackageManager().setPackageStoppedState( 6331 cpr.appInfo.packageName, false, userId); 6332 } catch (RemoteException e) { 6333 } catch (IllegalArgumentException e) { 6334 Slog.w(TAG, "Failed trying to unstop package " 6335 + cpr.appInfo.packageName + ": " + e); 6336 } 6337 6338 ProcessRecord proc = startProcessLocked(cpi.processName, 6339 cpr.appInfo, false, 0, "content provider", 6340 new ComponentName(cpi.applicationInfo.packageName, 6341 cpi.name), false, false); 6342 if (proc == null) { 6343 Slog.w(TAG, "Unable to launch app " 6344 + cpi.applicationInfo.packageName + "/" 6345 + cpi.applicationInfo.uid + " for provider " 6346 + name + ": process is bad"); 6347 return null; 6348 } 6349 cpr.launchingApp = proc; 6350 mLaunchingProviders.add(cpr); 6351 } finally { 6352 Binder.restoreCallingIdentity(origId); 6353 } 6354 } 6355 6356 // Make sure the provider is published (the same provider class 6357 // may be published under multiple names). 6358 if (firstClass) { 6359 mProviderMap.putProviderByClass(comp, cpr); 6360 } 6361 6362 mProviderMap.putProviderByName(name, cpr); 6363 conn = incProviderCountLocked(r, cpr, token, stable); 6364 if (conn != null) { 6365 conn.waiting = true; 6366 } 6367 } 6368 } 6369 6370 // Wait for the provider to be published... 6371 synchronized (cpr) { 6372 while (cpr.provider == null) { 6373 if (cpr.launchingApp == null) { 6374 Slog.w(TAG, "Unable to launch app " 6375 + cpi.applicationInfo.packageName + "/" 6376 + cpi.applicationInfo.uid + " for provider " 6377 + name + ": launching app became null"); 6378 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6379 cpi.applicationInfo.packageName, 6380 cpi.applicationInfo.uid, name); 6381 return null; 6382 } 6383 try { 6384 if (DEBUG_MU) { 6385 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6386 + cpr.launchingApp); 6387 } 6388 if (conn != null) { 6389 conn.waiting = true; 6390 } 6391 cpr.wait(); 6392 } catch (InterruptedException ex) { 6393 } finally { 6394 if (conn != null) { 6395 conn.waiting = false; 6396 } 6397 } 6398 } 6399 } 6400 return cpr != null ? cpr.newHolder(conn) : null; 6401 } 6402 6403 public final ContentProviderHolder getContentProvider( 6404 IApplicationThread caller, String name, boolean stable) { 6405 enforceNotIsolatedCaller("getContentProvider"); 6406 if (caller == null) { 6407 String msg = "null IApplicationThread when getting content provider " 6408 + name; 6409 Slog.w(TAG, msg); 6410 throw new SecurityException(msg); 6411 } 6412 6413 return getContentProviderImpl(caller, name, null, stable); 6414 } 6415 6416 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6417 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6418 "Do not have permission in call getContentProviderExternal()"); 6419 return getContentProviderExternalUnchecked(name, token); 6420 } 6421 6422 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6423 return getContentProviderImpl(null, name, token, true); 6424 } 6425 6426 /** 6427 * Drop a content provider from a ProcessRecord's bookkeeping 6428 * @param cpr 6429 */ 6430 public void removeContentProvider(IBinder connection, boolean stable) { 6431 enforceNotIsolatedCaller("removeContentProvider"); 6432 synchronized (this) { 6433 ContentProviderConnection conn; 6434 try { 6435 conn = (ContentProviderConnection)connection; 6436 } catch (ClassCastException e) { 6437 String msg ="removeContentProvider: " + connection 6438 + " not a ContentProviderConnection"; 6439 Slog.w(TAG, msg); 6440 throw new IllegalArgumentException(msg); 6441 } 6442 if (conn == null) { 6443 throw new NullPointerException("connection is null"); 6444 } 6445 if (decProviderCountLocked(conn, null, null, stable)) { 6446 updateOomAdjLocked(); 6447 } 6448 } 6449 } 6450 6451 public void removeContentProviderExternal(String name, IBinder token) { 6452 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6453 "Do not have permission in call removeContentProviderExternal()"); 6454 removeContentProviderExternalUnchecked(name, token); 6455 } 6456 6457 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6458 synchronized (this) { 6459 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6460 Binder.getOrigCallingUser()); 6461 if(cpr == null) { 6462 //remove from mProvidersByClass 6463 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6464 return; 6465 } 6466 6467 //update content provider record entry info 6468 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6469 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6470 Binder.getOrigCallingUser()); 6471 if (localCpr.hasExternalProcessHandles()) { 6472 if (localCpr.removeExternalProcessHandleLocked(token)) { 6473 updateOomAdjLocked(); 6474 } else { 6475 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6476 + " with no external reference for token: " 6477 + token + "."); 6478 } 6479 } else { 6480 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6481 + " with no external references."); 6482 } 6483 } 6484 } 6485 6486 public final void publishContentProviders(IApplicationThread caller, 6487 List<ContentProviderHolder> providers) { 6488 if (providers == null) { 6489 return; 6490 } 6491 6492 enforceNotIsolatedCaller("publishContentProviders"); 6493 synchronized (this) { 6494 final ProcessRecord r = getRecordForAppLocked(caller); 6495 if (DEBUG_MU) 6496 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6497 if (r == null) { 6498 throw new SecurityException( 6499 "Unable to find app for caller " + caller 6500 + " (pid=" + Binder.getCallingPid() 6501 + ") when publishing content providers"); 6502 } 6503 6504 final long origId = Binder.clearCallingIdentity(); 6505 6506 final int N = providers.size(); 6507 for (int i=0; i<N; i++) { 6508 ContentProviderHolder src = providers.get(i); 6509 if (src == null || src.info == null || src.provider == null) { 6510 continue; 6511 } 6512 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6513 if (DEBUG_MU) 6514 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6515 if (dst != null) { 6516 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6517 mProviderMap.putProviderByClass(comp, dst); 6518 String names[] = dst.info.authority.split(";"); 6519 for (int j = 0; j < names.length; j++) { 6520 mProviderMap.putProviderByName(names[j], dst); 6521 } 6522 6523 int NL = mLaunchingProviders.size(); 6524 int j; 6525 for (j=0; j<NL; j++) { 6526 if (mLaunchingProviders.get(j) == dst) { 6527 mLaunchingProviders.remove(j); 6528 j--; 6529 NL--; 6530 } 6531 } 6532 synchronized (dst) { 6533 dst.provider = src.provider; 6534 dst.proc = r; 6535 dst.notifyAll(); 6536 } 6537 updateOomAdjLocked(r); 6538 } 6539 } 6540 6541 Binder.restoreCallingIdentity(origId); 6542 } 6543 } 6544 6545 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6546 ContentProviderConnection conn; 6547 try { 6548 conn = (ContentProviderConnection)connection; 6549 } catch (ClassCastException e) { 6550 String msg ="refContentProvider: " + connection 6551 + " not a ContentProviderConnection"; 6552 Slog.w(TAG, msg); 6553 throw new IllegalArgumentException(msg); 6554 } 6555 if (conn == null) { 6556 throw new NullPointerException("connection is null"); 6557 } 6558 6559 synchronized (this) { 6560 if (stable > 0) { 6561 conn.numStableIncs += stable; 6562 } 6563 stable = conn.stableCount + stable; 6564 if (stable < 0) { 6565 throw new IllegalStateException("stableCount < 0: " + stable); 6566 } 6567 6568 if (unstable > 0) { 6569 conn.numUnstableIncs += unstable; 6570 } 6571 unstable = conn.unstableCount + unstable; 6572 if (unstable < 0) { 6573 throw new IllegalStateException("unstableCount < 0: " + unstable); 6574 } 6575 6576 if ((stable+unstable) <= 0) { 6577 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6578 + stable + " unstable=" + unstable); 6579 } 6580 conn.stableCount = stable; 6581 conn.unstableCount = unstable; 6582 return !conn.dead; 6583 } 6584 } 6585 6586 public void unstableProviderDied(IBinder connection) { 6587 ContentProviderConnection conn; 6588 try { 6589 conn = (ContentProviderConnection)connection; 6590 } catch (ClassCastException e) { 6591 String msg ="refContentProvider: " + connection 6592 + " not a ContentProviderConnection"; 6593 Slog.w(TAG, msg); 6594 throw new IllegalArgumentException(msg); 6595 } 6596 if (conn == null) { 6597 throw new NullPointerException("connection is null"); 6598 } 6599 6600 // Safely retrieve the content provider associated with the connection. 6601 IContentProvider provider; 6602 synchronized (this) { 6603 provider = conn.provider.provider; 6604 } 6605 6606 if (provider == null) { 6607 // Um, yeah, we're way ahead of you. 6608 return; 6609 } 6610 6611 // Make sure the caller is being honest with us. 6612 if (provider.asBinder().pingBinder()) { 6613 // Er, no, still looks good to us. 6614 synchronized (this) { 6615 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6616 + " says " + conn + " died, but we don't agree"); 6617 return; 6618 } 6619 } 6620 6621 // Well look at that! It's dead! 6622 synchronized (this) { 6623 if (conn.provider.provider != provider) { 6624 // But something changed... good enough. 6625 return; 6626 } 6627 6628 ProcessRecord proc = conn.provider.proc; 6629 if (proc == null || proc.thread == null) { 6630 // Seems like the process is already cleaned up. 6631 return; 6632 } 6633 6634 // As far as we're concerned, this is just like receiving a 6635 // death notification... just a bit prematurely. 6636 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6637 + ") early provider death"); 6638 final long ident = Binder.clearCallingIdentity(); 6639 try { 6640 appDiedLocked(proc, proc.pid, proc.thread); 6641 } finally { 6642 Binder.restoreCallingIdentity(ident); 6643 } 6644 } 6645 } 6646 6647 public static final void installSystemProviders() { 6648 List<ProviderInfo> providers; 6649 synchronized (mSelf) { 6650 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6651 providers = mSelf.generateApplicationProvidersLocked(app); 6652 if (providers != null) { 6653 for (int i=providers.size()-1; i>=0; i--) { 6654 ProviderInfo pi = (ProviderInfo)providers.get(i); 6655 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6656 Slog.w(TAG, "Not installing system proc provider " + pi.name 6657 + ": not system .apk"); 6658 providers.remove(i); 6659 } 6660 } 6661 } 6662 } 6663 if (providers != null) { 6664 mSystemThread.installSystemProviders(providers); 6665 } 6666 6667 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6668 6669 mSelf.mUsageStatsService.monitorPackages(); 6670 } 6671 6672 /** 6673 * Allows app to retrieve the MIME type of a URI without having permission 6674 * to access its content provider. 6675 * 6676 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6677 * 6678 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6679 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6680 */ 6681 public String getProviderMimeType(Uri uri) { 6682 enforceNotIsolatedCaller("getProviderMimeType"); 6683 final String name = uri.getAuthority(); 6684 final long ident = Binder.clearCallingIdentity(); 6685 ContentProviderHolder holder = null; 6686 6687 try { 6688 holder = getContentProviderExternalUnchecked(name, null); 6689 if (holder != null) { 6690 return holder.provider.getType(uri); 6691 } 6692 } catch (RemoteException e) { 6693 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6694 return null; 6695 } finally { 6696 if (holder != null) { 6697 removeContentProviderExternalUnchecked(name, null); 6698 } 6699 Binder.restoreCallingIdentity(ident); 6700 } 6701 6702 return null; 6703 } 6704 6705 // ========================================================= 6706 // GLOBAL MANAGEMENT 6707 // ========================================================= 6708 6709 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6710 ApplicationInfo info, String customProcess, boolean isolated) { 6711 String proc = customProcess != null ? customProcess : info.processName; 6712 BatteryStatsImpl.Uid.Proc ps = null; 6713 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6714 int uid = info.uid; 6715 if (isolated) { 6716 int userId = UserId.getUserId(uid); 6717 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6718 uid = 0; 6719 while (true) { 6720 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6721 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6722 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6723 } 6724 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6725 mNextIsolatedProcessUid++; 6726 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6727 // No process for this uid, use it. 6728 break; 6729 } 6730 stepsLeft--; 6731 if (stepsLeft <= 0) { 6732 return null; 6733 } 6734 } 6735 } 6736 synchronized (stats) { 6737 ps = stats.getProcessStatsLocked(info.uid, proc); 6738 } 6739 return new ProcessRecord(ps, thread, info, proc, uid); 6740 } 6741 6742 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6743 ProcessRecord app; 6744 if (!isolated) { 6745 app = getProcessRecordLocked(info.processName, info.uid); 6746 } else { 6747 app = null; 6748 } 6749 6750 if (app == null) { 6751 app = newProcessRecordLocked(null, info, null, isolated); 6752 mProcessNames.put(info.processName, app.uid, app); 6753 if (isolated) { 6754 mIsolatedProcesses.put(app.uid, app); 6755 } 6756 updateLruProcessLocked(app, true, true); 6757 } 6758 6759 // This package really, really can not be stopped. 6760 try { 6761 AppGlobals.getPackageManager().setPackageStoppedState( 6762 info.packageName, false, UserId.getUserId(app.uid)); 6763 } catch (RemoteException e) { 6764 } catch (IllegalArgumentException e) { 6765 Slog.w(TAG, "Failed trying to unstop package " 6766 + info.packageName + ": " + e); 6767 } 6768 6769 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6770 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6771 app.persistent = true; 6772 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6773 } 6774 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6775 mPersistentStartingProcesses.add(app); 6776 startProcessLocked(app, "added application", app.processName); 6777 } 6778 6779 return app; 6780 } 6781 6782 public void unhandledBack() { 6783 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6784 "unhandledBack()"); 6785 6786 synchronized(this) { 6787 int count = mMainStack.mHistory.size(); 6788 if (DEBUG_SWITCH) Slog.d( 6789 TAG, "Performing unhandledBack(): stack size = " + count); 6790 if (count > 1) { 6791 final long origId = Binder.clearCallingIdentity(); 6792 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6793 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6794 Binder.restoreCallingIdentity(origId); 6795 } 6796 } 6797 } 6798 6799 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6800 enforceNotIsolatedCaller("openContentUri"); 6801 String name = uri.getAuthority(); 6802 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6803 ParcelFileDescriptor pfd = null; 6804 if (cph != null) { 6805 // We record the binder invoker's uid in thread-local storage before 6806 // going to the content provider to open the file. Later, in the code 6807 // that handles all permissions checks, we look for this uid and use 6808 // that rather than the Activity Manager's own uid. The effect is that 6809 // we do the check against the caller's permissions even though it looks 6810 // to the content provider like the Activity Manager itself is making 6811 // the request. 6812 sCallerIdentity.set(new Identity( 6813 Binder.getCallingPid(), Binder.getCallingUid())); 6814 try { 6815 pfd = cph.provider.openFile(uri, "r"); 6816 } catch (FileNotFoundException e) { 6817 // do nothing; pfd will be returned null 6818 } finally { 6819 // Ensure that whatever happens, we clean up the identity state 6820 sCallerIdentity.remove(); 6821 } 6822 6823 // We've got the fd now, so we're done with the provider. 6824 removeContentProviderExternalUnchecked(name, null); 6825 } else { 6826 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6827 } 6828 return pfd; 6829 } 6830 6831 // Actually is sleeping or shutting down or whatever else in the future 6832 // is an inactive state. 6833 public boolean isSleeping() { 6834 return mSleeping || mShuttingDown; 6835 } 6836 6837 public void goingToSleep() { 6838 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6839 != PackageManager.PERMISSION_GRANTED) { 6840 throw new SecurityException("Requires permission " 6841 + android.Manifest.permission.DEVICE_POWER); 6842 } 6843 6844 synchronized(this) { 6845 mWentToSleep = true; 6846 updateEventDispatchingLocked(); 6847 6848 if (!mSleeping) { 6849 mSleeping = true; 6850 mMainStack.stopIfSleepingLocked(); 6851 6852 // Initialize the wake times of all processes. 6853 checkExcessivePowerUsageLocked(false); 6854 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6855 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6856 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6857 } 6858 } 6859 } 6860 6861 public boolean shutdown(int timeout) { 6862 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6863 != PackageManager.PERMISSION_GRANTED) { 6864 throw new SecurityException("Requires permission " 6865 + android.Manifest.permission.SHUTDOWN); 6866 } 6867 6868 boolean timedout = false; 6869 6870 synchronized(this) { 6871 mShuttingDown = true; 6872 updateEventDispatchingLocked(); 6873 6874 if (mMainStack.mResumedActivity != null) { 6875 mMainStack.stopIfSleepingLocked(); 6876 final long endTime = System.currentTimeMillis() + timeout; 6877 while (mMainStack.mResumedActivity != null 6878 || mMainStack.mPausingActivity != null) { 6879 long delay = endTime - System.currentTimeMillis(); 6880 if (delay <= 0) { 6881 Slog.w(TAG, "Activity manager shutdown timed out"); 6882 timedout = true; 6883 break; 6884 } 6885 try { 6886 this.wait(); 6887 } catch (InterruptedException e) { 6888 } 6889 } 6890 } 6891 } 6892 6893 mUsageStatsService.shutdown(); 6894 mBatteryStatsService.shutdown(); 6895 6896 return timedout; 6897 } 6898 6899 public final void activitySlept(IBinder token) { 6900 if (localLOGV) Slog.v( 6901 TAG, "Activity slept: token=" + token); 6902 6903 ActivityRecord r = null; 6904 6905 final long origId = Binder.clearCallingIdentity(); 6906 6907 synchronized (this) { 6908 r = mMainStack.isInStackLocked(token); 6909 if (r != null) { 6910 mMainStack.activitySleptLocked(r); 6911 } 6912 } 6913 6914 Binder.restoreCallingIdentity(origId); 6915 } 6916 6917 private void comeOutOfSleepIfNeededLocked() { 6918 if (!mWentToSleep && !mLockScreenShown) { 6919 if (mSleeping) { 6920 mSleeping = false; 6921 mMainStack.awakeFromSleepingLocked(); 6922 mMainStack.resumeTopActivityLocked(null); 6923 } 6924 } 6925 } 6926 6927 public void wakingUp() { 6928 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6929 != PackageManager.PERMISSION_GRANTED) { 6930 throw new SecurityException("Requires permission " 6931 + android.Manifest.permission.DEVICE_POWER); 6932 } 6933 6934 synchronized(this) { 6935 mWentToSleep = false; 6936 updateEventDispatchingLocked(); 6937 comeOutOfSleepIfNeededLocked(); 6938 } 6939 } 6940 6941 private void updateEventDispatchingLocked() { 6942 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6943 } 6944 6945 public void setLockScreenShown(boolean shown) { 6946 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6947 != PackageManager.PERMISSION_GRANTED) { 6948 throw new SecurityException("Requires permission " 6949 + android.Manifest.permission.DEVICE_POWER); 6950 } 6951 6952 synchronized(this) { 6953 mLockScreenShown = shown; 6954 comeOutOfSleepIfNeededLocked(); 6955 } 6956 } 6957 6958 public void stopAppSwitches() { 6959 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6960 != PackageManager.PERMISSION_GRANTED) { 6961 throw new SecurityException("Requires permission " 6962 + android.Manifest.permission.STOP_APP_SWITCHES); 6963 } 6964 6965 synchronized(this) { 6966 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6967 + APP_SWITCH_DELAY_TIME; 6968 mDidAppSwitch = false; 6969 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6970 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6971 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6972 } 6973 } 6974 6975 public void resumeAppSwitches() { 6976 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6977 != PackageManager.PERMISSION_GRANTED) { 6978 throw new SecurityException("Requires permission " 6979 + android.Manifest.permission.STOP_APP_SWITCHES); 6980 } 6981 6982 synchronized(this) { 6983 // Note that we don't execute any pending app switches... we will 6984 // let those wait until either the timeout, or the next start 6985 // activity request. 6986 mAppSwitchesAllowedTime = 0; 6987 } 6988 } 6989 6990 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6991 String name) { 6992 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6993 return true; 6994 } 6995 6996 final int perm = checkComponentPermission( 6997 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6998 callingUid, -1, true); 6999 if (perm == PackageManager.PERMISSION_GRANTED) { 7000 return true; 7001 } 7002 7003 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7004 return false; 7005 } 7006 7007 public void setDebugApp(String packageName, boolean waitForDebugger, 7008 boolean persistent) { 7009 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7010 "setDebugApp()"); 7011 7012 // Note that this is not really thread safe if there are multiple 7013 // callers into it at the same time, but that's not a situation we 7014 // care about. 7015 if (persistent) { 7016 final ContentResolver resolver = mContext.getContentResolver(); 7017 Settings.System.putString( 7018 resolver, Settings.System.DEBUG_APP, 7019 packageName); 7020 Settings.System.putInt( 7021 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7022 waitForDebugger ? 1 : 0); 7023 } 7024 7025 synchronized (this) { 7026 if (!persistent) { 7027 mOrigDebugApp = mDebugApp; 7028 mOrigWaitForDebugger = mWaitForDebugger; 7029 } 7030 mDebugApp = packageName; 7031 mWaitForDebugger = waitForDebugger; 7032 mDebugTransient = !persistent; 7033 if (packageName != null) { 7034 final long origId = Binder.clearCallingIdentity(); 7035 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7036 Binder.restoreCallingIdentity(origId); 7037 } 7038 } 7039 } 7040 7041 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7042 synchronized (this) { 7043 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7044 if (!isDebuggable) { 7045 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7046 throw new SecurityException("Process not debuggable: " + app.packageName); 7047 } 7048 } 7049 7050 mOpenGlTraceApp = processName; 7051 } 7052 } 7053 7054 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7055 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7056 synchronized (this) { 7057 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7058 if (!isDebuggable) { 7059 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7060 throw new SecurityException("Process not debuggable: " + app.packageName); 7061 } 7062 } 7063 mProfileApp = processName; 7064 mProfileFile = profileFile; 7065 if (mProfileFd != null) { 7066 try { 7067 mProfileFd.close(); 7068 } catch (IOException e) { 7069 } 7070 mProfileFd = null; 7071 } 7072 mProfileFd = profileFd; 7073 mProfileType = 0; 7074 mAutoStopProfiler = autoStopProfiler; 7075 } 7076 } 7077 7078 public void setAlwaysFinish(boolean enabled) { 7079 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7080 "setAlwaysFinish()"); 7081 7082 Settings.System.putInt( 7083 mContext.getContentResolver(), 7084 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7085 7086 synchronized (this) { 7087 mAlwaysFinishActivities = enabled; 7088 } 7089 } 7090 7091 public void setActivityController(IActivityController controller) { 7092 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7093 "setActivityController()"); 7094 synchronized (this) { 7095 mController = controller; 7096 } 7097 } 7098 7099 public boolean isUserAMonkey() { 7100 // For now the fact that there is a controller implies 7101 // we have a monkey. 7102 synchronized (this) { 7103 return mController != null; 7104 } 7105 } 7106 7107 public void registerProcessObserver(IProcessObserver observer) { 7108 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7109 "registerProcessObserver()"); 7110 synchronized (this) { 7111 mProcessObservers.register(observer); 7112 } 7113 } 7114 7115 public void unregisterProcessObserver(IProcessObserver observer) { 7116 synchronized (this) { 7117 mProcessObservers.unregister(observer); 7118 } 7119 } 7120 7121 public void setImmersive(IBinder token, boolean immersive) { 7122 synchronized(this) { 7123 ActivityRecord r = mMainStack.isInStackLocked(token); 7124 if (r == null) { 7125 throw new IllegalArgumentException(); 7126 } 7127 r.immersive = immersive; 7128 } 7129 } 7130 7131 public boolean isImmersive(IBinder token) { 7132 synchronized (this) { 7133 ActivityRecord r = mMainStack.isInStackLocked(token); 7134 if (r == null) { 7135 throw new IllegalArgumentException(); 7136 } 7137 return r.immersive; 7138 } 7139 } 7140 7141 public boolean isTopActivityImmersive() { 7142 enforceNotIsolatedCaller("startActivity"); 7143 synchronized (this) { 7144 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7145 return (r != null) ? r.immersive : false; 7146 } 7147 } 7148 7149 public final void enterSafeMode() { 7150 synchronized(this) { 7151 // It only makes sense to do this before the system is ready 7152 // and started launching other packages. 7153 if (!mSystemReady) { 7154 try { 7155 AppGlobals.getPackageManager().enterSafeMode(); 7156 } catch (RemoteException e) { 7157 } 7158 } 7159 } 7160 } 7161 7162 public final void showSafeModeOverlay() { 7163 View v = LayoutInflater.from(mContext).inflate( 7164 com.android.internal.R.layout.safe_mode, null); 7165 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7166 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7167 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7168 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7169 lp.gravity = Gravity.BOTTOM | Gravity.START; 7170 lp.format = v.getBackground().getOpacity(); 7171 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7172 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7173 ((WindowManager)mContext.getSystemService( 7174 Context.WINDOW_SERVICE)).addView(v, lp); 7175 } 7176 7177 public void noteWakeupAlarm(IIntentSender sender) { 7178 if (!(sender instanceof PendingIntentRecord)) { 7179 return; 7180 } 7181 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7182 synchronized (stats) { 7183 if (mBatteryStatsService.isOnBattery()) { 7184 mBatteryStatsService.enforceCallingPermission(); 7185 PendingIntentRecord rec = (PendingIntentRecord)sender; 7186 int MY_UID = Binder.getCallingUid(); 7187 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7188 BatteryStatsImpl.Uid.Pkg pkg = 7189 stats.getPackageStatsLocked(uid, rec.key.packageName); 7190 pkg.incWakeupsLocked(); 7191 } 7192 } 7193 } 7194 7195 public boolean killPids(int[] pids, String pReason, boolean secure) { 7196 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7197 throw new SecurityException("killPids only available to the system"); 7198 } 7199 String reason = (pReason == null) ? "Unknown" : pReason; 7200 // XXX Note: don't acquire main activity lock here, because the window 7201 // manager calls in with its locks held. 7202 7203 boolean killed = false; 7204 synchronized (mPidsSelfLocked) { 7205 int[] types = new int[pids.length]; 7206 int worstType = 0; 7207 for (int i=0; i<pids.length; i++) { 7208 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7209 if (proc != null) { 7210 int type = proc.setAdj; 7211 types[i] = type; 7212 if (type > worstType) { 7213 worstType = type; 7214 } 7215 } 7216 } 7217 7218 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7219 // then constrain it so we will kill all hidden procs. 7220 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7221 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7222 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7223 } 7224 7225 // If this is not a secure call, don't let it kill processes that 7226 // are important. 7227 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7228 worstType = ProcessList.SERVICE_ADJ; 7229 } 7230 7231 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7232 for (int i=0; i<pids.length; i++) { 7233 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7234 if (proc == null) { 7235 continue; 7236 } 7237 int adj = proc.setAdj; 7238 if (adj >= worstType && !proc.killedBackground) { 7239 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7240 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7241 proc.processName, adj, reason); 7242 killed = true; 7243 proc.killedBackground = true; 7244 Process.killProcessQuiet(pids[i]); 7245 } 7246 } 7247 } 7248 return killed; 7249 } 7250 7251 @Override 7252 public boolean killProcessesBelowForeground(String reason) { 7253 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7254 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7255 } 7256 7257 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7258 } 7259 7260 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7261 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7262 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7263 } 7264 7265 boolean killed = false; 7266 synchronized (mPidsSelfLocked) { 7267 final int size = mPidsSelfLocked.size(); 7268 for (int i = 0; i < size; i++) { 7269 final int pid = mPidsSelfLocked.keyAt(i); 7270 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7271 if (proc == null) continue; 7272 7273 final int adj = proc.setAdj; 7274 if (adj > belowAdj && !proc.killedBackground) { 7275 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7276 EventLog.writeEvent( 7277 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7278 killed = true; 7279 proc.killedBackground = true; 7280 Process.killProcessQuiet(pid); 7281 } 7282 } 7283 } 7284 return killed; 7285 } 7286 7287 public final void startRunning(String pkg, String cls, String action, 7288 String data) { 7289 synchronized(this) { 7290 if (mStartRunning) { 7291 return; 7292 } 7293 mStartRunning = true; 7294 mTopComponent = pkg != null && cls != null 7295 ? new ComponentName(pkg, cls) : null; 7296 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7297 mTopData = data; 7298 if (!mSystemReady) { 7299 return; 7300 } 7301 } 7302 7303 systemReady(null); 7304 } 7305 7306 private void retrieveSettings() { 7307 final ContentResolver resolver = mContext.getContentResolver(); 7308 String debugApp = Settings.System.getString( 7309 resolver, Settings.System.DEBUG_APP); 7310 boolean waitForDebugger = Settings.System.getInt( 7311 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7312 boolean alwaysFinishActivities = Settings.System.getInt( 7313 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7314 7315 Configuration configuration = new Configuration(); 7316 Settings.System.getConfiguration(resolver, configuration); 7317 7318 synchronized (this) { 7319 mDebugApp = mOrigDebugApp = debugApp; 7320 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7321 mAlwaysFinishActivities = alwaysFinishActivities; 7322 // This happens before any activities are started, so we can 7323 // change mConfiguration in-place. 7324 updateConfigurationLocked(configuration, null, false, true); 7325 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7326 } 7327 } 7328 7329 public boolean testIsSystemReady() { 7330 // no need to synchronize(this) just to read & return the value 7331 return mSystemReady; 7332 } 7333 7334 private static File getCalledPreBootReceiversFile() { 7335 File dataDir = Environment.getDataDirectory(); 7336 File systemDir = new File(dataDir, "system"); 7337 File fname = new File(systemDir, "called_pre_boots.dat"); 7338 return fname; 7339 } 7340 7341 static final int LAST_DONE_VERSION = 10000; 7342 7343 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7344 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7345 File file = getCalledPreBootReceiversFile(); 7346 FileInputStream fis = null; 7347 try { 7348 fis = new FileInputStream(file); 7349 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7350 int fvers = dis.readInt(); 7351 if (fvers == LAST_DONE_VERSION) { 7352 String vers = dis.readUTF(); 7353 String codename = dis.readUTF(); 7354 String build = dis.readUTF(); 7355 if (android.os.Build.VERSION.RELEASE.equals(vers) 7356 && android.os.Build.VERSION.CODENAME.equals(codename) 7357 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7358 int num = dis.readInt(); 7359 while (num > 0) { 7360 num--; 7361 String pkg = dis.readUTF(); 7362 String cls = dis.readUTF(); 7363 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7364 } 7365 } 7366 } 7367 } catch (FileNotFoundException e) { 7368 } catch (IOException e) { 7369 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7370 } finally { 7371 if (fis != null) { 7372 try { 7373 fis.close(); 7374 } catch (IOException e) { 7375 } 7376 } 7377 } 7378 return lastDoneReceivers; 7379 } 7380 7381 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7382 File file = getCalledPreBootReceiversFile(); 7383 FileOutputStream fos = null; 7384 DataOutputStream dos = null; 7385 try { 7386 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7387 fos = new FileOutputStream(file); 7388 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7389 dos.writeInt(LAST_DONE_VERSION); 7390 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7391 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7392 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7393 dos.writeInt(list.size()); 7394 for (int i=0; i<list.size(); i++) { 7395 dos.writeUTF(list.get(i).getPackageName()); 7396 dos.writeUTF(list.get(i).getClassName()); 7397 } 7398 } catch (IOException e) { 7399 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7400 file.delete(); 7401 } finally { 7402 FileUtils.sync(fos); 7403 if (dos != null) { 7404 try { 7405 dos.close(); 7406 } catch (IOException e) { 7407 // TODO Auto-generated catch block 7408 e.printStackTrace(); 7409 } 7410 } 7411 } 7412 } 7413 7414 public void systemReady(final Runnable goingCallback) { 7415 synchronized(this) { 7416 if (mSystemReady) { 7417 if (goingCallback != null) goingCallback.run(); 7418 return; 7419 } 7420 7421 // Check to see if there are any update receivers to run. 7422 if (!mDidUpdate) { 7423 if (mWaitingUpdate) { 7424 return; 7425 } 7426 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7427 List<ResolveInfo> ris = null; 7428 try { 7429 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7430 intent, null, 0, 0); 7431 } catch (RemoteException e) { 7432 } 7433 if (ris != null) { 7434 for (int i=ris.size()-1; i>=0; i--) { 7435 if ((ris.get(i).activityInfo.applicationInfo.flags 7436 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7437 ris.remove(i); 7438 } 7439 } 7440 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7441 7442 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7443 7444 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7445 for (int i=0; i<ris.size(); i++) { 7446 ActivityInfo ai = ris.get(i).activityInfo; 7447 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7448 if (lastDoneReceivers.contains(comp)) { 7449 ris.remove(i); 7450 i--; 7451 } 7452 } 7453 7454 for (int i=0; i<ris.size(); i++) { 7455 ActivityInfo ai = ris.get(i).activityInfo; 7456 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7457 doneReceivers.add(comp); 7458 intent.setComponent(comp); 7459 IIntentReceiver finisher = null; 7460 if (i == ris.size()-1) { 7461 finisher = new IIntentReceiver.Stub() { 7462 public void performReceive(Intent intent, int resultCode, 7463 String data, Bundle extras, boolean ordered, 7464 boolean sticky) { 7465 // The raw IIntentReceiver interface is called 7466 // with the AM lock held, so redispatch to 7467 // execute our code without the lock. 7468 mHandler.post(new Runnable() { 7469 public void run() { 7470 synchronized (ActivityManagerService.this) { 7471 mDidUpdate = true; 7472 } 7473 writeLastDonePreBootReceivers(doneReceivers); 7474 showBootMessage(mContext.getText( 7475 R.string.android_upgrading_complete), 7476 false); 7477 systemReady(goingCallback); 7478 } 7479 }); 7480 } 7481 }; 7482 } 7483 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7484 /* TODO: Send this to all users */ 7485 broadcastIntentLocked(null, null, intent, null, finisher, 7486 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7487 0 /* UserId zero */); 7488 if (finisher != null) { 7489 mWaitingUpdate = true; 7490 } 7491 } 7492 } 7493 if (mWaitingUpdate) { 7494 return; 7495 } 7496 mDidUpdate = true; 7497 } 7498 7499 mSystemReady = true; 7500 if (!mStartRunning) { 7501 return; 7502 } 7503 } 7504 7505 ArrayList<ProcessRecord> procsToKill = null; 7506 synchronized(mPidsSelfLocked) { 7507 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7508 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7509 if (!isAllowedWhileBooting(proc.info)){ 7510 if (procsToKill == null) { 7511 procsToKill = new ArrayList<ProcessRecord>(); 7512 } 7513 procsToKill.add(proc); 7514 } 7515 } 7516 } 7517 7518 synchronized(this) { 7519 if (procsToKill != null) { 7520 for (int i=procsToKill.size()-1; i>=0; i--) { 7521 ProcessRecord proc = procsToKill.get(i); 7522 Slog.i(TAG, "Removing system update proc: " + proc); 7523 removeProcessLocked(proc, true, false, "system update done"); 7524 } 7525 } 7526 7527 // Now that we have cleaned up any update processes, we 7528 // are ready to start launching real processes and know that 7529 // we won't trample on them any more. 7530 mProcessesReady = true; 7531 } 7532 7533 Slog.i(TAG, "System now ready"); 7534 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7535 SystemClock.uptimeMillis()); 7536 7537 synchronized(this) { 7538 // Make sure we have no pre-ready processes sitting around. 7539 7540 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7541 ResolveInfo ri = mContext.getPackageManager() 7542 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7543 STOCK_PM_FLAGS); 7544 CharSequence errorMsg = null; 7545 if (ri != null) { 7546 ActivityInfo ai = ri.activityInfo; 7547 ApplicationInfo app = ai.applicationInfo; 7548 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7549 mTopAction = Intent.ACTION_FACTORY_TEST; 7550 mTopData = null; 7551 mTopComponent = new ComponentName(app.packageName, 7552 ai.name); 7553 } else { 7554 errorMsg = mContext.getResources().getText( 7555 com.android.internal.R.string.factorytest_not_system); 7556 } 7557 } else { 7558 errorMsg = mContext.getResources().getText( 7559 com.android.internal.R.string.factorytest_no_action); 7560 } 7561 if (errorMsg != null) { 7562 mTopAction = null; 7563 mTopData = null; 7564 mTopComponent = null; 7565 Message msg = Message.obtain(); 7566 msg.what = SHOW_FACTORY_ERROR_MSG; 7567 msg.getData().putCharSequence("msg", errorMsg); 7568 mHandler.sendMessage(msg); 7569 } 7570 } 7571 } 7572 7573 retrieveSettings(); 7574 7575 if (goingCallback != null) goingCallback.run(); 7576 7577 synchronized (this) { 7578 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7579 try { 7580 List apps = AppGlobals.getPackageManager(). 7581 getPersistentApplications(STOCK_PM_FLAGS); 7582 if (apps != null) { 7583 int N = apps.size(); 7584 int i; 7585 for (i=0; i<N; i++) { 7586 ApplicationInfo info 7587 = (ApplicationInfo)apps.get(i); 7588 if (info != null && 7589 !info.packageName.equals("android")) { 7590 addAppLocked(info, false); 7591 } 7592 } 7593 } 7594 } catch (RemoteException ex) { 7595 // pm is in same process, this will never happen. 7596 } 7597 } 7598 7599 // Start up initial activity. 7600 mBooting = true; 7601 7602 try { 7603 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7604 Message msg = Message.obtain(); 7605 msg.what = SHOW_UID_ERROR_MSG; 7606 mHandler.sendMessage(msg); 7607 } 7608 } catch (RemoteException e) { 7609 } 7610 7611 mMainStack.resumeTopActivityLocked(null); 7612 } 7613 } 7614 7615 private boolean makeAppCrashingLocked(ProcessRecord app, 7616 String shortMsg, String longMsg, String stackTrace) { 7617 app.crashing = true; 7618 app.crashingReport = generateProcessError(app, 7619 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7620 startAppProblemLocked(app); 7621 app.stopFreezingAllLocked(); 7622 return handleAppCrashLocked(app); 7623 } 7624 7625 private void makeAppNotRespondingLocked(ProcessRecord app, 7626 String activity, String shortMsg, String longMsg) { 7627 app.notResponding = true; 7628 app.notRespondingReport = generateProcessError(app, 7629 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7630 activity, shortMsg, longMsg, null); 7631 startAppProblemLocked(app); 7632 app.stopFreezingAllLocked(); 7633 } 7634 7635 /** 7636 * Generate a process error record, suitable for attachment to a ProcessRecord. 7637 * 7638 * @param app The ProcessRecord in which the error occurred. 7639 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7640 * ActivityManager.AppErrorStateInfo 7641 * @param activity The activity associated with the crash, if known. 7642 * @param shortMsg Short message describing the crash. 7643 * @param longMsg Long message describing the crash. 7644 * @param stackTrace Full crash stack trace, may be null. 7645 * 7646 * @return Returns a fully-formed AppErrorStateInfo record. 7647 */ 7648 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7649 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7650 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7651 7652 report.condition = condition; 7653 report.processName = app.processName; 7654 report.pid = app.pid; 7655 report.uid = app.info.uid; 7656 report.tag = activity; 7657 report.shortMsg = shortMsg; 7658 report.longMsg = longMsg; 7659 report.stackTrace = stackTrace; 7660 7661 return report; 7662 } 7663 7664 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7665 synchronized (this) { 7666 app.crashing = false; 7667 app.crashingReport = null; 7668 app.notResponding = false; 7669 app.notRespondingReport = null; 7670 if (app.anrDialog == fromDialog) { 7671 app.anrDialog = null; 7672 } 7673 if (app.waitDialog == fromDialog) { 7674 app.waitDialog = null; 7675 } 7676 if (app.pid > 0 && app.pid != MY_PID) { 7677 handleAppCrashLocked(app); 7678 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7679 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7680 app.processName, app.setAdj, "user's request after error"); 7681 Process.killProcessQuiet(app.pid); 7682 } 7683 } 7684 } 7685 7686 private boolean handleAppCrashLocked(ProcessRecord app) { 7687 if (mHeadless) { 7688 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7689 return false; 7690 } 7691 long now = SystemClock.uptimeMillis(); 7692 7693 Long crashTime; 7694 if (!app.isolated) { 7695 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7696 } else { 7697 crashTime = null; 7698 } 7699 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7700 // This process loses! 7701 Slog.w(TAG, "Process " + app.info.processName 7702 + " has crashed too many times: killing!"); 7703 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7704 app.info.processName, app.uid); 7705 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7706 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7707 if (r.app == app) { 7708 Slog.w(TAG, " Force finishing activity " 7709 + r.intent.getComponent().flattenToShortString()); 7710 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7711 } 7712 } 7713 if (!app.persistent) { 7714 // We don't want to start this process again until the user 7715 // explicitly does so... but for persistent process, we really 7716 // need to keep it running. If a persistent process is actually 7717 // repeatedly crashing, then badness for everyone. 7718 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7719 app.info.processName); 7720 if (!app.isolated) { 7721 // XXX We don't have a way to mark isolated processes 7722 // as bad, since they don't have a peristent identity. 7723 mBadProcesses.put(app.info.processName, app.uid, now); 7724 mProcessCrashTimes.remove(app.info.processName, app.uid); 7725 } 7726 app.bad = true; 7727 app.removed = true; 7728 // Don't let services in this process be restarted and potentially 7729 // annoy the user repeatedly. Unless it is persistent, since those 7730 // processes run critical code. 7731 removeProcessLocked(app, false, false, "crash"); 7732 mMainStack.resumeTopActivityLocked(null); 7733 return false; 7734 } 7735 mMainStack.resumeTopActivityLocked(null); 7736 } else { 7737 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7738 if (r != null && r.app == app) { 7739 // If the top running activity is from this crashing 7740 // process, then terminate it to avoid getting in a loop. 7741 Slog.w(TAG, " Force finishing activity " 7742 + r.intent.getComponent().flattenToShortString()); 7743 int index = mMainStack.indexOfActivityLocked(r); 7744 r.stack.finishActivityLocked(r, index, 7745 Activity.RESULT_CANCELED, null, "crashed"); 7746 // Also terminate any activities below it that aren't yet 7747 // stopped, to avoid a situation where one will get 7748 // re-start our crashing activity once it gets resumed again. 7749 index--; 7750 if (index >= 0) { 7751 r = (ActivityRecord)mMainStack.mHistory.get(index); 7752 if (r.state == ActivityState.RESUMED 7753 || r.state == ActivityState.PAUSING 7754 || r.state == ActivityState.PAUSED) { 7755 if (!r.isHomeActivity || mHomeProcess != r.app) { 7756 Slog.w(TAG, " Force finishing activity " 7757 + r.intent.getComponent().flattenToShortString()); 7758 r.stack.finishActivityLocked(r, index, 7759 Activity.RESULT_CANCELED, null, "crashed"); 7760 } 7761 } 7762 } 7763 } 7764 } 7765 7766 // Bump up the crash count of any services currently running in the proc. 7767 if (app.services.size() != 0) { 7768 // Any services running in the application need to be placed 7769 // back in the pending list. 7770 Iterator<ServiceRecord> it = app.services.iterator(); 7771 while (it.hasNext()) { 7772 ServiceRecord sr = it.next(); 7773 sr.crashCount++; 7774 } 7775 } 7776 7777 // If the crashing process is what we consider to be the "home process" and it has been 7778 // replaced by a third-party app, clear the package preferred activities from packages 7779 // with a home activity running in the process to prevent a repeatedly crashing app 7780 // from blocking the user to manually clear the list. 7781 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7782 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7783 Iterator it = mHomeProcess.activities.iterator(); 7784 while (it.hasNext()) { 7785 ActivityRecord r = (ActivityRecord)it.next(); 7786 if (r.isHomeActivity) { 7787 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7788 try { 7789 ActivityThread.getPackageManager() 7790 .clearPackagePreferredActivities(r.packageName); 7791 } catch (RemoteException c) { 7792 // pm is in same process, this will never happen. 7793 } 7794 } 7795 } 7796 } 7797 7798 if (!app.isolated) { 7799 // XXX Can't keep track of crash times for isolated processes, 7800 // because they don't have a perisistent identity. 7801 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7802 } 7803 7804 return true; 7805 } 7806 7807 void startAppProblemLocked(ProcessRecord app) { 7808 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7809 mContext, app.info.packageName, app.info.flags); 7810 skipCurrentReceiverLocked(app); 7811 } 7812 7813 void skipCurrentReceiverLocked(ProcessRecord app) { 7814 for (BroadcastQueue queue : mBroadcastQueues) { 7815 queue.skipCurrentReceiverLocked(app); 7816 } 7817 } 7818 7819 /** 7820 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7821 * The application process will exit immediately after this call returns. 7822 * @param app object of the crashing app, null for the system server 7823 * @param crashInfo describing the exception 7824 */ 7825 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7826 ProcessRecord r = findAppProcess(app, "Crash"); 7827 final String processName = app == null ? "system_server" 7828 : (r == null ? "unknown" : r.processName); 7829 7830 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7831 processName, 7832 r == null ? -1 : r.info.flags, 7833 crashInfo.exceptionClassName, 7834 crashInfo.exceptionMessage, 7835 crashInfo.throwFileName, 7836 crashInfo.throwLineNumber); 7837 7838 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7839 7840 crashApplication(r, crashInfo); 7841 } 7842 7843 public void handleApplicationStrictModeViolation( 7844 IBinder app, 7845 int violationMask, 7846 StrictMode.ViolationInfo info) { 7847 ProcessRecord r = findAppProcess(app, "StrictMode"); 7848 if (r == null) { 7849 return; 7850 } 7851 7852 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7853 Integer stackFingerprint = info.hashCode(); 7854 boolean logIt = true; 7855 synchronized (mAlreadyLoggedViolatedStacks) { 7856 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7857 logIt = false; 7858 // TODO: sub-sample into EventLog for these, with 7859 // the info.durationMillis? Then we'd get 7860 // the relative pain numbers, without logging all 7861 // the stack traces repeatedly. We'd want to do 7862 // likewise in the client code, which also does 7863 // dup suppression, before the Binder call. 7864 } else { 7865 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7866 mAlreadyLoggedViolatedStacks.clear(); 7867 } 7868 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7869 } 7870 } 7871 if (logIt) { 7872 logStrictModeViolationToDropBox(r, info); 7873 } 7874 } 7875 7876 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7877 AppErrorResult result = new AppErrorResult(); 7878 synchronized (this) { 7879 final long origId = Binder.clearCallingIdentity(); 7880 7881 Message msg = Message.obtain(); 7882 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7883 HashMap<String, Object> data = new HashMap<String, Object>(); 7884 data.put("result", result); 7885 data.put("app", r); 7886 data.put("violationMask", violationMask); 7887 data.put("info", info); 7888 msg.obj = data; 7889 mHandler.sendMessage(msg); 7890 7891 Binder.restoreCallingIdentity(origId); 7892 } 7893 int res = result.get(); 7894 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7895 } 7896 } 7897 7898 // Depending on the policy in effect, there could be a bunch of 7899 // these in quick succession so we try to batch these together to 7900 // minimize disk writes, number of dropbox entries, and maximize 7901 // compression, by having more fewer, larger records. 7902 private void logStrictModeViolationToDropBox( 7903 ProcessRecord process, 7904 StrictMode.ViolationInfo info) { 7905 if (info == null) { 7906 return; 7907 } 7908 final boolean isSystemApp = process == null || 7909 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7910 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7911 final String processName = process == null ? "unknown" : process.processName; 7912 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7913 final DropBoxManager dbox = (DropBoxManager) 7914 mContext.getSystemService(Context.DROPBOX_SERVICE); 7915 7916 // Exit early if the dropbox isn't configured to accept this report type. 7917 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7918 7919 boolean bufferWasEmpty; 7920 boolean needsFlush; 7921 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7922 synchronized (sb) { 7923 bufferWasEmpty = sb.length() == 0; 7924 appendDropBoxProcessHeaders(process, processName, sb); 7925 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7926 sb.append("System-App: ").append(isSystemApp).append("\n"); 7927 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7928 if (info.violationNumThisLoop != 0) { 7929 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7930 } 7931 if (info.numAnimationsRunning != 0) { 7932 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7933 } 7934 if (info.broadcastIntentAction != null) { 7935 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7936 } 7937 if (info.durationMillis != -1) { 7938 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7939 } 7940 if (info.numInstances != -1) { 7941 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7942 } 7943 if (info.tags != null) { 7944 for (String tag : info.tags) { 7945 sb.append("Span-Tag: ").append(tag).append("\n"); 7946 } 7947 } 7948 sb.append("\n"); 7949 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7950 sb.append(info.crashInfo.stackTrace); 7951 } 7952 sb.append("\n"); 7953 7954 // Only buffer up to ~64k. Various logging bits truncate 7955 // things at 128k. 7956 needsFlush = (sb.length() > 64 * 1024); 7957 } 7958 7959 // Flush immediately if the buffer's grown too large, or this 7960 // is a non-system app. Non-system apps are isolated with a 7961 // different tag & policy and not batched. 7962 // 7963 // Batching is useful during internal testing with 7964 // StrictMode settings turned up high. Without batching, 7965 // thousands of separate files could be created on boot. 7966 if (!isSystemApp || needsFlush) { 7967 new Thread("Error dump: " + dropboxTag) { 7968 @Override 7969 public void run() { 7970 String report; 7971 synchronized (sb) { 7972 report = sb.toString(); 7973 sb.delete(0, sb.length()); 7974 sb.trimToSize(); 7975 } 7976 if (report.length() != 0) { 7977 dbox.addText(dropboxTag, report); 7978 } 7979 } 7980 }.start(); 7981 return; 7982 } 7983 7984 // System app batching: 7985 if (!bufferWasEmpty) { 7986 // An existing dropbox-writing thread is outstanding, so 7987 // we don't need to start it up. The existing thread will 7988 // catch the buffer appends we just did. 7989 return; 7990 } 7991 7992 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7993 // (After this point, we shouldn't access AMS internal data structures.) 7994 new Thread("Error dump: " + dropboxTag) { 7995 @Override 7996 public void run() { 7997 // 5 second sleep to let stacks arrive and be batched together 7998 try { 7999 Thread.sleep(5000); // 5 seconds 8000 } catch (InterruptedException e) {} 8001 8002 String errorReport; 8003 synchronized (mStrictModeBuffer) { 8004 errorReport = mStrictModeBuffer.toString(); 8005 if (errorReport.length() == 0) { 8006 return; 8007 } 8008 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8009 mStrictModeBuffer.trimToSize(); 8010 } 8011 dbox.addText(dropboxTag, errorReport); 8012 } 8013 }.start(); 8014 } 8015 8016 /** 8017 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8018 * @param app object of the crashing app, null for the system server 8019 * @param tag reported by the caller 8020 * @param crashInfo describing the context of the error 8021 * @return true if the process should exit immediately (WTF is fatal) 8022 */ 8023 public boolean handleApplicationWtf(IBinder app, String tag, 8024 ApplicationErrorReport.CrashInfo crashInfo) { 8025 ProcessRecord r = findAppProcess(app, "WTF"); 8026 final String processName = app == null ? "system_server" 8027 : (r == null ? "unknown" : r.processName); 8028 8029 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8030 processName, 8031 r == null ? -1 : r.info.flags, 8032 tag, crashInfo.exceptionMessage); 8033 8034 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8035 8036 if (r != null && r.pid != Process.myPid() && 8037 Settings.Secure.getInt(mContext.getContentResolver(), 8038 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8039 crashApplication(r, crashInfo); 8040 return true; 8041 } else { 8042 return false; 8043 } 8044 } 8045 8046 /** 8047 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8048 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8049 */ 8050 private ProcessRecord findAppProcess(IBinder app, String reason) { 8051 if (app == null) { 8052 return null; 8053 } 8054 8055 synchronized (this) { 8056 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8057 final int NA = apps.size(); 8058 for (int ia=0; ia<NA; ia++) { 8059 ProcessRecord p = apps.valueAt(ia); 8060 if (p.thread != null && p.thread.asBinder() == app) { 8061 return p; 8062 } 8063 } 8064 } 8065 8066 Slog.w(TAG, "Can't find mystery application for " + reason 8067 + " from pid=" + Binder.getCallingPid() 8068 + " uid=" + Binder.getCallingUid() + ": " + app); 8069 return null; 8070 } 8071 } 8072 8073 /** 8074 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8075 * to append various headers to the dropbox log text. 8076 */ 8077 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8078 StringBuilder sb) { 8079 // Watchdog thread ends up invoking this function (with 8080 // a null ProcessRecord) to add the stack file to dropbox. 8081 // Do not acquire a lock on this (am) in such cases, as it 8082 // could cause a potential deadlock, if and when watchdog 8083 // is invoked due to unavailability of lock on am and it 8084 // would prevent watchdog from killing system_server. 8085 if (process == null) { 8086 sb.append("Process: ").append(processName).append("\n"); 8087 return; 8088 } 8089 // Note: ProcessRecord 'process' is guarded by the service 8090 // instance. (notably process.pkgList, which could otherwise change 8091 // concurrently during execution of this method) 8092 synchronized (this) { 8093 sb.append("Process: ").append(processName).append("\n"); 8094 int flags = process.info.flags; 8095 IPackageManager pm = AppGlobals.getPackageManager(); 8096 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8097 for (String pkg : process.pkgList) { 8098 sb.append("Package: ").append(pkg); 8099 try { 8100 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8101 if (pi != null) { 8102 sb.append(" v").append(pi.versionCode); 8103 if (pi.versionName != null) { 8104 sb.append(" (").append(pi.versionName).append(")"); 8105 } 8106 } 8107 } catch (RemoteException e) { 8108 Slog.e(TAG, "Error getting package info: " + pkg, e); 8109 } 8110 sb.append("\n"); 8111 } 8112 } 8113 } 8114 8115 private static String processClass(ProcessRecord process) { 8116 if (process == null || process.pid == MY_PID) { 8117 return "system_server"; 8118 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8119 return "system_app"; 8120 } else { 8121 return "data_app"; 8122 } 8123 } 8124 8125 /** 8126 * Write a description of an error (crash, WTF, ANR) to the drop box. 8127 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8128 * @param process which caused the error, null means the system server 8129 * @param activity which triggered the error, null if unknown 8130 * @param parent activity related to the error, null if unknown 8131 * @param subject line related to the error, null if absent 8132 * @param report in long form describing the error, null if absent 8133 * @param logFile to include in the report, null if none 8134 * @param crashInfo giving an application stack trace, null if absent 8135 */ 8136 public void addErrorToDropBox(String eventType, 8137 ProcessRecord process, String processName, ActivityRecord activity, 8138 ActivityRecord parent, String subject, 8139 final String report, final File logFile, 8140 final ApplicationErrorReport.CrashInfo crashInfo) { 8141 // NOTE -- this must never acquire the ActivityManagerService lock, 8142 // otherwise the watchdog may be prevented from resetting the system. 8143 8144 final String dropboxTag = processClass(process) + "_" + eventType; 8145 final DropBoxManager dbox = (DropBoxManager) 8146 mContext.getSystemService(Context.DROPBOX_SERVICE); 8147 8148 // Exit early if the dropbox isn't configured to accept this report type. 8149 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8150 8151 final StringBuilder sb = new StringBuilder(1024); 8152 appendDropBoxProcessHeaders(process, processName, sb); 8153 if (activity != null) { 8154 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8155 } 8156 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8157 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8158 } 8159 if (parent != null && parent != activity) { 8160 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8161 } 8162 if (subject != null) { 8163 sb.append("Subject: ").append(subject).append("\n"); 8164 } 8165 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8166 if (Debug.isDebuggerConnected()) { 8167 sb.append("Debugger: Connected\n"); 8168 } 8169 sb.append("\n"); 8170 8171 // Do the rest in a worker thread to avoid blocking the caller on I/O 8172 // (After this point, we shouldn't access AMS internal data structures.) 8173 Thread worker = new Thread("Error dump: " + dropboxTag) { 8174 @Override 8175 public void run() { 8176 if (report != null) { 8177 sb.append(report); 8178 } 8179 if (logFile != null) { 8180 try { 8181 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8182 } catch (IOException e) { 8183 Slog.e(TAG, "Error reading " + logFile, e); 8184 } 8185 } 8186 if (crashInfo != null && crashInfo.stackTrace != null) { 8187 sb.append(crashInfo.stackTrace); 8188 } 8189 8190 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8191 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8192 if (lines > 0) { 8193 sb.append("\n"); 8194 8195 // Merge several logcat streams, and take the last N lines 8196 InputStreamReader input = null; 8197 try { 8198 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8199 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8200 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8201 8202 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8203 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8204 input = new InputStreamReader(logcat.getInputStream()); 8205 8206 int num; 8207 char[] buf = new char[8192]; 8208 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8209 } catch (IOException e) { 8210 Slog.e(TAG, "Error running logcat", e); 8211 } finally { 8212 if (input != null) try { input.close(); } catch (IOException e) {} 8213 } 8214 } 8215 8216 dbox.addText(dropboxTag, sb.toString()); 8217 } 8218 }; 8219 8220 if (process == null) { 8221 // If process is null, we are being called from some internal code 8222 // and may be about to die -- run this synchronously. 8223 worker.run(); 8224 } else { 8225 worker.start(); 8226 } 8227 } 8228 8229 /** 8230 * Bring up the "unexpected error" dialog box for a crashing app. 8231 * Deal with edge cases (intercepts from instrumented applications, 8232 * ActivityController, error intent receivers, that sort of thing). 8233 * @param r the application crashing 8234 * @param crashInfo describing the failure 8235 */ 8236 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8237 long timeMillis = System.currentTimeMillis(); 8238 String shortMsg = crashInfo.exceptionClassName; 8239 String longMsg = crashInfo.exceptionMessage; 8240 String stackTrace = crashInfo.stackTrace; 8241 if (shortMsg != null && longMsg != null) { 8242 longMsg = shortMsg + ": " + longMsg; 8243 } else if (shortMsg != null) { 8244 longMsg = shortMsg; 8245 } 8246 8247 AppErrorResult result = new AppErrorResult(); 8248 synchronized (this) { 8249 if (mController != null) { 8250 try { 8251 String name = r != null ? r.processName : null; 8252 int pid = r != null ? r.pid : Binder.getCallingPid(); 8253 if (!mController.appCrashed(name, pid, 8254 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8255 Slog.w(TAG, "Force-killing crashed app " + name 8256 + " at watcher's request"); 8257 Process.killProcess(pid); 8258 return; 8259 } 8260 } catch (RemoteException e) { 8261 mController = null; 8262 } 8263 } 8264 8265 final long origId = Binder.clearCallingIdentity(); 8266 8267 // If this process is running instrumentation, finish it. 8268 if (r != null && r.instrumentationClass != null) { 8269 Slog.w(TAG, "Error in app " + r.processName 8270 + " running instrumentation " + r.instrumentationClass + ":"); 8271 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8272 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8273 Bundle info = new Bundle(); 8274 info.putString("shortMsg", shortMsg); 8275 info.putString("longMsg", longMsg); 8276 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8277 Binder.restoreCallingIdentity(origId); 8278 return; 8279 } 8280 8281 // If we can't identify the process or it's already exceeded its crash quota, 8282 // quit right away without showing a crash dialog. 8283 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8284 Binder.restoreCallingIdentity(origId); 8285 return; 8286 } 8287 8288 Message msg = Message.obtain(); 8289 msg.what = SHOW_ERROR_MSG; 8290 HashMap data = new HashMap(); 8291 data.put("result", result); 8292 data.put("app", r); 8293 msg.obj = data; 8294 mHandler.sendMessage(msg); 8295 8296 Binder.restoreCallingIdentity(origId); 8297 } 8298 8299 int res = result.get(); 8300 8301 Intent appErrorIntent = null; 8302 synchronized (this) { 8303 if (r != null && !r.isolated) { 8304 // XXX Can't keep track of crash time for isolated processes, 8305 // since they don't have a persistent identity. 8306 mProcessCrashTimes.put(r.info.processName, r.uid, 8307 SystemClock.uptimeMillis()); 8308 } 8309 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8310 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8311 } 8312 } 8313 8314 if (appErrorIntent != null) { 8315 try { 8316 mContext.startActivity(appErrorIntent); 8317 } catch (ActivityNotFoundException e) { 8318 Slog.w(TAG, "bug report receiver dissappeared", e); 8319 } 8320 } 8321 } 8322 8323 Intent createAppErrorIntentLocked(ProcessRecord r, 8324 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8325 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8326 if (report == null) { 8327 return null; 8328 } 8329 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8330 result.setComponent(r.errorReportReceiver); 8331 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8332 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8333 return result; 8334 } 8335 8336 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8337 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8338 if (r.errorReportReceiver == null) { 8339 return null; 8340 } 8341 8342 if (!r.crashing && !r.notResponding) { 8343 return null; 8344 } 8345 8346 ApplicationErrorReport report = new ApplicationErrorReport(); 8347 report.packageName = r.info.packageName; 8348 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8349 report.processName = r.processName; 8350 report.time = timeMillis; 8351 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8352 8353 if (r.crashing) { 8354 report.type = ApplicationErrorReport.TYPE_CRASH; 8355 report.crashInfo = crashInfo; 8356 } else if (r.notResponding) { 8357 report.type = ApplicationErrorReport.TYPE_ANR; 8358 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8359 8360 report.anrInfo.activity = r.notRespondingReport.tag; 8361 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8362 report.anrInfo.info = r.notRespondingReport.longMsg; 8363 } 8364 8365 return report; 8366 } 8367 8368 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8369 enforceNotIsolatedCaller("getProcessesInErrorState"); 8370 // assume our apps are happy - lazy create the list 8371 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8372 8373 synchronized (this) { 8374 8375 // iterate across all processes 8376 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8377 ProcessRecord app = mLruProcesses.get(i); 8378 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8379 // This one's in trouble, so we'll generate a report for it 8380 // crashes are higher priority (in case there's a crash *and* an anr) 8381 ActivityManager.ProcessErrorStateInfo report = null; 8382 if (app.crashing) { 8383 report = app.crashingReport; 8384 } else if (app.notResponding) { 8385 report = app.notRespondingReport; 8386 } 8387 8388 if (report != null) { 8389 if (errList == null) { 8390 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8391 } 8392 errList.add(report); 8393 } else { 8394 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8395 " crashing = " + app.crashing + 8396 " notResponding = " + app.notResponding); 8397 } 8398 } 8399 } 8400 } 8401 8402 return errList; 8403 } 8404 8405 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8406 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8407 if (currApp != null) { 8408 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8409 } 8410 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8411 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8412 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8413 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8414 if (currApp != null) { 8415 currApp.lru = 0; 8416 } 8417 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8418 } else if (adj >= ProcessList.SERVICE_ADJ) { 8419 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8420 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8421 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8422 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8423 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8424 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8425 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8426 } else { 8427 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8428 } 8429 } 8430 8431 private void fillInProcMemInfo(ProcessRecord app, 8432 ActivityManager.RunningAppProcessInfo outInfo) { 8433 outInfo.pid = app.pid; 8434 outInfo.uid = app.info.uid; 8435 if (mHeavyWeightProcess == app) { 8436 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8437 } 8438 if (app.persistent) { 8439 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8440 } 8441 outInfo.lastTrimLevel = app.trimMemoryLevel; 8442 int adj = app.curAdj; 8443 outInfo.importance = oomAdjToImportance(adj, outInfo); 8444 outInfo.importanceReasonCode = app.adjTypeCode; 8445 } 8446 8447 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8448 enforceNotIsolatedCaller("getRunningAppProcesses"); 8449 // Lazy instantiation of list 8450 List<ActivityManager.RunningAppProcessInfo> runList = null; 8451 synchronized (this) { 8452 // Iterate across all processes 8453 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8454 ProcessRecord app = mLruProcesses.get(i); 8455 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8456 // Generate process state info for running application 8457 ActivityManager.RunningAppProcessInfo currApp = 8458 new ActivityManager.RunningAppProcessInfo(app.processName, 8459 app.pid, app.getPackageList()); 8460 fillInProcMemInfo(app, currApp); 8461 if (app.adjSource instanceof ProcessRecord) { 8462 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8463 currApp.importanceReasonImportance = oomAdjToImportance( 8464 app.adjSourceOom, null); 8465 } else if (app.adjSource instanceof ActivityRecord) { 8466 ActivityRecord r = (ActivityRecord)app.adjSource; 8467 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8468 } 8469 if (app.adjTarget instanceof ComponentName) { 8470 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8471 } 8472 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8473 // + " lru=" + currApp.lru); 8474 if (runList == null) { 8475 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8476 } 8477 runList.add(currApp); 8478 } 8479 } 8480 } 8481 return runList; 8482 } 8483 8484 public List<ApplicationInfo> getRunningExternalApplications() { 8485 enforceNotIsolatedCaller("getRunningExternalApplications"); 8486 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8487 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8488 if (runningApps != null && runningApps.size() > 0) { 8489 Set<String> extList = new HashSet<String>(); 8490 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8491 if (app.pkgList != null) { 8492 for (String pkg : app.pkgList) { 8493 extList.add(pkg); 8494 } 8495 } 8496 } 8497 IPackageManager pm = AppGlobals.getPackageManager(); 8498 for (String pkg : extList) { 8499 try { 8500 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8501 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8502 retList.add(info); 8503 } 8504 } catch (RemoteException e) { 8505 } 8506 } 8507 } 8508 return retList; 8509 } 8510 8511 @Override 8512 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8513 enforceNotIsolatedCaller("getMyMemoryState"); 8514 synchronized (this) { 8515 ProcessRecord proc; 8516 synchronized (mPidsSelfLocked) { 8517 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8518 } 8519 fillInProcMemInfo(proc, outInfo); 8520 } 8521 } 8522 8523 @Override 8524 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8525 if (checkCallingPermission(android.Manifest.permission.DUMP) 8526 != PackageManager.PERMISSION_GRANTED) { 8527 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8528 + Binder.getCallingPid() 8529 + ", uid=" + Binder.getCallingUid() 8530 + " without permission " 8531 + android.Manifest.permission.DUMP); 8532 return; 8533 } 8534 8535 boolean dumpAll = false; 8536 boolean dumpClient = false; 8537 String dumpPackage = null; 8538 8539 int opti = 0; 8540 while (opti < args.length) { 8541 String opt = args[opti]; 8542 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8543 break; 8544 } 8545 opti++; 8546 if ("-a".equals(opt)) { 8547 dumpAll = true; 8548 } else if ("-c".equals(opt)) { 8549 dumpClient = true; 8550 } else if ("-h".equals(opt)) { 8551 pw.println("Activity manager dump options:"); 8552 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8553 pw.println(" cmd may be one of:"); 8554 pw.println(" a[ctivities]: activity stack state"); 8555 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8556 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8557 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8558 pw.println(" o[om]: out of memory management"); 8559 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8560 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8561 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8562 pw.println(" service [COMP_SPEC]: service client-side state"); 8563 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8564 pw.println(" all: dump all activities"); 8565 pw.println(" top: dump the top activity"); 8566 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8567 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8568 pw.println(" a partial substring in a component name, a"); 8569 pw.println(" hex object identifier."); 8570 pw.println(" -a: include all available server state."); 8571 pw.println(" -c: include client state."); 8572 return; 8573 } else { 8574 pw.println("Unknown argument: " + opt + "; use -h for help"); 8575 } 8576 } 8577 8578 long origId = Binder.clearCallingIdentity(); 8579 boolean more = false; 8580 // Is the caller requesting to dump a particular piece of data? 8581 if (opti < args.length) { 8582 String cmd = args[opti]; 8583 opti++; 8584 if ("activities".equals(cmd) || "a".equals(cmd)) { 8585 synchronized (this) { 8586 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8587 } 8588 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8589 String[] newArgs; 8590 String name; 8591 if (opti >= args.length) { 8592 name = null; 8593 newArgs = EMPTY_STRING_ARRAY; 8594 } else { 8595 name = args[opti]; 8596 opti++; 8597 newArgs = new String[args.length - opti]; 8598 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8599 args.length - opti); 8600 } 8601 synchronized (this) { 8602 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8603 } 8604 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8605 String[] newArgs; 8606 String name; 8607 if (opti >= args.length) { 8608 name = null; 8609 newArgs = EMPTY_STRING_ARRAY; 8610 } else { 8611 name = args[opti]; 8612 opti++; 8613 newArgs = new String[args.length - opti]; 8614 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8615 args.length - opti); 8616 } 8617 synchronized (this) { 8618 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8619 } 8620 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8621 String[] newArgs; 8622 String name; 8623 if (opti >= args.length) { 8624 name = null; 8625 newArgs = EMPTY_STRING_ARRAY; 8626 } else { 8627 name = args[opti]; 8628 opti++; 8629 newArgs = new String[args.length - opti]; 8630 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8631 args.length - opti); 8632 } 8633 synchronized (this) { 8634 dumpProcessesLocked(fd, pw, args, opti, true, name); 8635 } 8636 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8637 synchronized (this) { 8638 dumpOomLocked(fd, pw, args, opti, true); 8639 } 8640 } else if ("provider".equals(cmd)) { 8641 String[] newArgs; 8642 String name; 8643 if (opti >= args.length) { 8644 name = null; 8645 newArgs = EMPTY_STRING_ARRAY; 8646 } else { 8647 name = args[opti]; 8648 opti++; 8649 newArgs = new String[args.length - opti]; 8650 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8651 } 8652 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8653 pw.println("No providers match: " + name); 8654 pw.println("Use -h for help."); 8655 } 8656 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8657 synchronized (this) { 8658 dumpProvidersLocked(fd, pw, args, opti, true, null); 8659 } 8660 } else if ("service".equals(cmd)) { 8661 String[] newArgs; 8662 String name; 8663 if (opti >= args.length) { 8664 name = null; 8665 newArgs = EMPTY_STRING_ARRAY; 8666 } else { 8667 name = args[opti]; 8668 opti++; 8669 newArgs = new String[args.length - opti]; 8670 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8671 args.length - opti); 8672 } 8673 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8674 pw.println("No services match: " + name); 8675 pw.println("Use -h for help."); 8676 } 8677 } else if ("package".equals(cmd)) { 8678 String[] newArgs; 8679 if (opti >= args.length) { 8680 pw.println("package: no package name specified"); 8681 pw.println("Use -h for help."); 8682 } else { 8683 dumpPackage = args[opti]; 8684 opti++; 8685 newArgs = new String[args.length - opti]; 8686 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8687 args.length - opti); 8688 args = newArgs; 8689 opti = 0; 8690 more = true; 8691 } 8692 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8693 synchronized (this) { 8694 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8695 } 8696 } else { 8697 // Dumping a single activity? 8698 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8699 pw.println("Bad activity command, or no activities match: " + cmd); 8700 pw.println("Use -h for help."); 8701 } 8702 } 8703 if (!more) { 8704 Binder.restoreCallingIdentity(origId); 8705 return; 8706 } 8707 } 8708 8709 // No piece of data specified, dump everything. 8710 synchronized (this) { 8711 boolean needSep; 8712 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8713 if (needSep) { 8714 pw.println(" "); 8715 } 8716 if (dumpAll) { 8717 pw.println("-------------------------------------------------------------------------------"); 8718 } 8719 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8720 if (needSep) { 8721 pw.println(" "); 8722 } 8723 if (dumpAll) { 8724 pw.println("-------------------------------------------------------------------------------"); 8725 } 8726 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8727 if (needSep) { 8728 pw.println(" "); 8729 } 8730 if (dumpAll) { 8731 pw.println("-------------------------------------------------------------------------------"); 8732 } 8733 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8734 if (needSep) { 8735 pw.println(" "); 8736 } 8737 if (dumpAll) { 8738 pw.println("-------------------------------------------------------------------------------"); 8739 } 8740 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8741 if (needSep) { 8742 pw.println(" "); 8743 } 8744 if (dumpAll) { 8745 pw.println("-------------------------------------------------------------------------------"); 8746 } 8747 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8748 } 8749 Binder.restoreCallingIdentity(origId); 8750 } 8751 8752 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8753 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8754 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8755 pw.println(" Main stack:"); 8756 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8757 dumpPackage); 8758 pw.println(" "); 8759 pw.println(" Running activities (most recent first):"); 8760 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8761 dumpPackage); 8762 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8763 pw.println(" "); 8764 pw.println(" Activities waiting for another to become visible:"); 8765 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8766 !dumpAll, false, dumpPackage); 8767 } 8768 if (mMainStack.mStoppingActivities.size() > 0) { 8769 pw.println(" "); 8770 pw.println(" Activities waiting to stop:"); 8771 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8772 !dumpAll, false, dumpPackage); 8773 } 8774 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8775 pw.println(" "); 8776 pw.println(" Activities waiting to sleep:"); 8777 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8778 !dumpAll, false, dumpPackage); 8779 } 8780 if (mMainStack.mFinishingActivities.size() > 0) { 8781 pw.println(" "); 8782 pw.println(" Activities waiting to finish:"); 8783 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8784 !dumpAll, false, dumpPackage); 8785 } 8786 8787 pw.println(" "); 8788 if (mMainStack.mPausingActivity != null) { 8789 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8790 } 8791 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8792 pw.println(" mFocusedActivity: " + mFocusedActivity); 8793 if (dumpAll) { 8794 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8795 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8796 pw.println(" mDismissKeyguardOnNextActivity: " 8797 + mMainStack.mDismissKeyguardOnNextActivity); 8798 } 8799 8800 if (mRecentTasks.size() > 0) { 8801 pw.println(); 8802 pw.println(" Recent tasks:"); 8803 8804 final int N = mRecentTasks.size(); 8805 for (int i=0; i<N; i++) { 8806 TaskRecord tr = mRecentTasks.get(i); 8807 if (dumpPackage != null) { 8808 if (tr.realActivity == null || 8809 !dumpPackage.equals(tr.realActivity)) { 8810 continue; 8811 } 8812 } 8813 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8814 pw.println(tr); 8815 if (dumpAll) { 8816 mRecentTasks.get(i).dump(pw, " "); 8817 } 8818 } 8819 } 8820 8821 if (dumpAll) { 8822 pw.println(" "); 8823 pw.println(" mCurTask: " + mCurTask); 8824 } 8825 8826 return true; 8827 } 8828 8829 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8830 int opti, boolean dumpAll, String dumpPackage) { 8831 boolean needSep = false; 8832 int numPers = 0; 8833 8834 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8835 8836 if (dumpAll) { 8837 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8838 final int NA = procs.size(); 8839 for (int ia=0; ia<NA; ia++) { 8840 ProcessRecord r = procs.valueAt(ia); 8841 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8842 continue; 8843 } 8844 if (!needSep) { 8845 pw.println(" All known processes:"); 8846 needSep = true; 8847 } 8848 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8849 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8850 pw.print(" "); pw.println(r); 8851 r.dump(pw, " "); 8852 if (r.persistent) { 8853 numPers++; 8854 } 8855 } 8856 } 8857 } 8858 8859 if (mIsolatedProcesses.size() > 0) { 8860 if (needSep) pw.println(" "); 8861 needSep = true; 8862 pw.println(" Isolated process list (sorted by uid):"); 8863 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8864 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8865 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8866 continue; 8867 } 8868 pw.println(String.format("%sIsolated #%2d: %s", 8869 " ", i, r.toString())); 8870 } 8871 } 8872 8873 if (mLruProcesses.size() > 0) { 8874 if (needSep) pw.println(" "); 8875 needSep = true; 8876 pw.println(" Process LRU list (sorted by oom_adj):"); 8877 dumpProcessOomList(pw, this, mLruProcesses, " ", 8878 "Proc", "PERS", false, dumpPackage); 8879 needSep = true; 8880 } 8881 8882 if (dumpAll) { 8883 synchronized (mPidsSelfLocked) { 8884 boolean printed = false; 8885 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8886 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8887 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8888 continue; 8889 } 8890 if (!printed) { 8891 if (needSep) pw.println(" "); 8892 needSep = true; 8893 pw.println(" PID mappings:"); 8894 printed = true; 8895 } 8896 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8897 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8898 } 8899 } 8900 } 8901 8902 if (mForegroundProcesses.size() > 0) { 8903 synchronized (mPidsSelfLocked) { 8904 boolean printed = false; 8905 for (int i=0; i<mForegroundProcesses.size(); i++) { 8906 ProcessRecord r = mPidsSelfLocked.get( 8907 mForegroundProcesses.valueAt(i).pid); 8908 if (dumpPackage != null && (r == null 8909 || !dumpPackage.equals(r.info.packageName))) { 8910 continue; 8911 } 8912 if (!printed) { 8913 if (needSep) pw.println(" "); 8914 needSep = true; 8915 pw.println(" Foreground Processes:"); 8916 printed = true; 8917 } 8918 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8919 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8920 } 8921 } 8922 } 8923 8924 if (mPersistentStartingProcesses.size() > 0) { 8925 if (needSep) pw.println(" "); 8926 needSep = true; 8927 pw.println(" Persisent processes that are starting:"); 8928 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8929 "Starting Norm", "Restarting PERS", dumpPackage); 8930 } 8931 8932 if (mRemovedProcesses.size() > 0) { 8933 if (needSep) pw.println(" "); 8934 needSep = true; 8935 pw.println(" Processes that are being removed:"); 8936 dumpProcessList(pw, this, mRemovedProcesses, " ", 8937 "Removed Norm", "Removed PERS", dumpPackage); 8938 } 8939 8940 if (mProcessesOnHold.size() > 0) { 8941 if (needSep) pw.println(" "); 8942 needSep = true; 8943 pw.println(" Processes that are on old until the system is ready:"); 8944 dumpProcessList(pw, this, mProcessesOnHold, " ", 8945 "OnHold Norm", "OnHold PERS", dumpPackage); 8946 } 8947 8948 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8949 8950 if (mProcessCrashTimes.getMap().size() > 0) { 8951 boolean printed = false; 8952 long now = SystemClock.uptimeMillis(); 8953 for (Map.Entry<String, SparseArray<Long>> procs 8954 : mProcessCrashTimes.getMap().entrySet()) { 8955 String pname = procs.getKey(); 8956 SparseArray<Long> uids = procs.getValue(); 8957 final int N = uids.size(); 8958 for (int i=0; i<N; i++) { 8959 int puid = uids.keyAt(i); 8960 ProcessRecord r = mProcessNames.get(pname, puid); 8961 if (dumpPackage != null && (r == null 8962 || !dumpPackage.equals(r.info.packageName))) { 8963 continue; 8964 } 8965 if (!printed) { 8966 if (needSep) pw.println(" "); 8967 needSep = true; 8968 pw.println(" Time since processes crashed:"); 8969 printed = true; 8970 } 8971 pw.print(" Process "); pw.print(pname); 8972 pw.print(" uid "); pw.print(puid); 8973 pw.print(": last crashed "); 8974 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8975 pw.println(" ago"); 8976 } 8977 } 8978 } 8979 8980 if (mBadProcesses.getMap().size() > 0) { 8981 boolean printed = false; 8982 for (Map.Entry<String, SparseArray<Long>> procs 8983 : mBadProcesses.getMap().entrySet()) { 8984 String pname = procs.getKey(); 8985 SparseArray<Long> uids = procs.getValue(); 8986 final int N = uids.size(); 8987 for (int i=0; i<N; i++) { 8988 int puid = uids.keyAt(i); 8989 ProcessRecord r = mProcessNames.get(pname, puid); 8990 if (dumpPackage != null && (r == null 8991 || !dumpPackage.equals(r.info.packageName))) { 8992 continue; 8993 } 8994 if (!printed) { 8995 if (needSep) pw.println(" "); 8996 needSep = true; 8997 pw.println(" Bad processes:"); 8998 } 8999 pw.print(" Bad process "); pw.print(pname); 9000 pw.print(" uid "); pw.print(puid); 9001 pw.print(": crashed at time "); 9002 pw.println(uids.valueAt(i)); 9003 } 9004 } 9005 } 9006 9007 pw.println(); 9008 pw.println(" mHomeProcess: " + mHomeProcess); 9009 pw.println(" mPreviousProcess: " + mPreviousProcess); 9010 if (dumpAll) { 9011 StringBuilder sb = new StringBuilder(128); 9012 sb.append(" mPreviousProcessVisibleTime: "); 9013 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9014 pw.println(sb); 9015 } 9016 if (mHeavyWeightProcess != null) { 9017 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9018 } 9019 pw.println(" mConfiguration: " + mConfiguration); 9020 if (dumpAll) { 9021 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9022 if (mCompatModePackages.getPackages().size() > 0) { 9023 boolean printed = false; 9024 for (Map.Entry<String, Integer> entry 9025 : mCompatModePackages.getPackages().entrySet()) { 9026 String pkg = entry.getKey(); 9027 int mode = entry.getValue(); 9028 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9029 continue; 9030 } 9031 if (!printed) { 9032 pw.println(" mScreenCompatPackages:"); 9033 printed = true; 9034 } 9035 pw.print(" "); pw.print(pkg); pw.print(": "); 9036 pw.print(mode); pw.println(); 9037 } 9038 } 9039 } 9040 if (mSleeping || mWentToSleep || mLockScreenShown) { 9041 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9042 + " mLockScreenShown " + mLockScreenShown); 9043 } 9044 if (mShuttingDown) { 9045 pw.println(" mShuttingDown=" + mShuttingDown); 9046 } 9047 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9048 || mOrigWaitForDebugger) { 9049 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9050 + " mDebugTransient=" + mDebugTransient 9051 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9052 } 9053 if (mOpenGlTraceApp != null) { 9054 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9055 } 9056 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9057 || mProfileFd != null) { 9058 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9059 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9060 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9061 + mAutoStopProfiler); 9062 } 9063 if (mAlwaysFinishActivities || mController != null) { 9064 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9065 + " mController=" + mController); 9066 } 9067 if (dumpAll) { 9068 pw.println(" Total persistent processes: " + numPers); 9069 pw.println(" mStartRunning=" + mStartRunning 9070 + " mProcessesReady=" + mProcessesReady 9071 + " mSystemReady=" + mSystemReady); 9072 pw.println(" mBooting=" + mBooting 9073 + " mBooted=" + mBooted 9074 + " mFactoryTest=" + mFactoryTest); 9075 pw.print(" mLastPowerCheckRealtime="); 9076 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9077 pw.println(""); 9078 pw.print(" mLastPowerCheckUptime="); 9079 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9080 pw.println(""); 9081 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9082 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9083 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9084 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9085 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9086 } 9087 9088 return true; 9089 } 9090 9091 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9092 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9093 if (mProcessesToGc.size() > 0) { 9094 boolean printed = false; 9095 long now = SystemClock.uptimeMillis(); 9096 for (int i=0; i<mProcessesToGc.size(); i++) { 9097 ProcessRecord proc = mProcessesToGc.get(i); 9098 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9099 continue; 9100 } 9101 if (!printed) { 9102 if (needSep) pw.println(" "); 9103 needSep = true; 9104 pw.println(" Processes that are waiting to GC:"); 9105 printed = true; 9106 } 9107 pw.print(" Process "); pw.println(proc); 9108 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9109 pw.print(", last gced="); 9110 pw.print(now-proc.lastRequestedGc); 9111 pw.print(" ms ago, last lowMem="); 9112 pw.print(now-proc.lastLowMemory); 9113 pw.println(" ms ago"); 9114 9115 } 9116 } 9117 return needSep; 9118 } 9119 9120 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9121 int opti, boolean dumpAll) { 9122 boolean needSep = false; 9123 9124 if (mLruProcesses.size() > 0) { 9125 if (needSep) pw.println(" "); 9126 needSep = true; 9127 pw.println(" OOM levels:"); 9128 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9129 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9130 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9131 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9132 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9133 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9134 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9135 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9136 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9137 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9138 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9139 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9140 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9141 9142 if (needSep) pw.println(" "); 9143 needSep = true; 9144 pw.println(" Process OOM control:"); 9145 dumpProcessOomList(pw, this, mLruProcesses, " ", 9146 "Proc", "PERS", true, null); 9147 needSep = true; 9148 } 9149 9150 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9151 9152 pw.println(); 9153 pw.println(" mHomeProcess: " + mHomeProcess); 9154 pw.println(" mPreviousProcess: " + mPreviousProcess); 9155 if (mHeavyWeightProcess != null) { 9156 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9157 } 9158 9159 return true; 9160 } 9161 9162 /** 9163 * There are three ways to call this: 9164 * - no provider specified: dump all the providers 9165 * - a flattened component name that matched an existing provider was specified as the 9166 * first arg: dump that one provider 9167 * - the first arg isn't the flattened component name of an existing provider: 9168 * dump all providers whose component contains the first arg as a substring 9169 */ 9170 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9171 int opti, boolean dumpAll) { 9172 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9173 } 9174 9175 static class ItemMatcher { 9176 ArrayList<ComponentName> components; 9177 ArrayList<String> strings; 9178 ArrayList<Integer> objects; 9179 boolean all; 9180 9181 ItemMatcher() { 9182 all = true; 9183 } 9184 9185 void build(String name) { 9186 ComponentName componentName = ComponentName.unflattenFromString(name); 9187 if (componentName != null) { 9188 if (components == null) { 9189 components = new ArrayList<ComponentName>(); 9190 } 9191 components.add(componentName); 9192 all = false; 9193 } else { 9194 int objectId = 0; 9195 // Not a '/' separated full component name; maybe an object ID? 9196 try { 9197 objectId = Integer.parseInt(name, 16); 9198 if (objects == null) { 9199 objects = new ArrayList<Integer>(); 9200 } 9201 objects.add(objectId); 9202 all = false; 9203 } catch (RuntimeException e) { 9204 // Not an integer; just do string match. 9205 if (strings == null) { 9206 strings = new ArrayList<String>(); 9207 } 9208 strings.add(name); 9209 all = false; 9210 } 9211 } 9212 } 9213 9214 int build(String[] args, int opti) { 9215 for (; opti<args.length; opti++) { 9216 String name = args[opti]; 9217 if ("--".equals(name)) { 9218 return opti+1; 9219 } 9220 build(name); 9221 } 9222 return opti; 9223 } 9224 9225 boolean match(Object object, ComponentName comp) { 9226 if (all) { 9227 return true; 9228 } 9229 if (components != null) { 9230 for (int i=0; i<components.size(); i++) { 9231 if (components.get(i).equals(comp)) { 9232 return true; 9233 } 9234 } 9235 } 9236 if (objects != null) { 9237 for (int i=0; i<objects.size(); i++) { 9238 if (System.identityHashCode(object) == objects.get(i)) { 9239 return true; 9240 } 9241 } 9242 } 9243 if (strings != null) { 9244 String flat = comp.flattenToString(); 9245 for (int i=0; i<strings.size(); i++) { 9246 if (flat.contains(strings.get(i))) { 9247 return true; 9248 } 9249 } 9250 } 9251 return false; 9252 } 9253 } 9254 9255 /** 9256 * There are three things that cmd can be: 9257 * - a flattened component name that matches an existing activity 9258 * - the cmd arg isn't the flattened component name of an existing activity: 9259 * dump all activity whose component contains the cmd as a substring 9260 * - A hex number of the ActivityRecord object instance. 9261 */ 9262 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9263 int opti, boolean dumpAll) { 9264 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9265 9266 if ("all".equals(name)) { 9267 synchronized (this) { 9268 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9269 activities.add(r1); 9270 } 9271 } 9272 } else if ("top".equals(name)) { 9273 synchronized (this) { 9274 final int N = mMainStack.mHistory.size(); 9275 if (N > 0) { 9276 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9277 } 9278 } 9279 } else { 9280 ItemMatcher matcher = new ItemMatcher(); 9281 matcher.build(name); 9282 9283 synchronized (this) { 9284 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9285 if (matcher.match(r1, r1.intent.getComponent())) { 9286 activities.add(r1); 9287 } 9288 } 9289 } 9290 } 9291 9292 if (activities.size() <= 0) { 9293 return false; 9294 } 9295 9296 String[] newArgs = new String[args.length - opti]; 9297 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9298 9299 TaskRecord lastTask = null; 9300 boolean needSep = false; 9301 for (int i=activities.size()-1; i>=0; i--) { 9302 ActivityRecord r = (ActivityRecord)activities.get(i); 9303 if (needSep) { 9304 pw.println(); 9305 } 9306 needSep = true; 9307 synchronized (this) { 9308 if (lastTask != r.task) { 9309 lastTask = r.task; 9310 pw.print("TASK "); pw.print(lastTask.affinity); 9311 pw.print(" id="); pw.println(lastTask.taskId); 9312 if (dumpAll) { 9313 lastTask.dump(pw, " "); 9314 } 9315 } 9316 } 9317 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9318 } 9319 return true; 9320 } 9321 9322 /** 9323 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9324 * there is a thread associated with the activity. 9325 */ 9326 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9327 final ActivityRecord r, String[] args, boolean dumpAll) { 9328 String innerPrefix = prefix + " "; 9329 synchronized (this) { 9330 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9331 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9332 pw.print(" pid="); 9333 if (r.app != null) pw.println(r.app.pid); 9334 else pw.println("(not running)"); 9335 if (dumpAll) { 9336 r.dump(pw, innerPrefix); 9337 } 9338 } 9339 if (r.app != null && r.app.thread != null) { 9340 // flush anything that is already in the PrintWriter since the thread is going 9341 // to write to the file descriptor directly 9342 pw.flush(); 9343 try { 9344 TransferPipe tp = new TransferPipe(); 9345 try { 9346 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9347 r.appToken, innerPrefix, args); 9348 tp.go(fd); 9349 } finally { 9350 tp.kill(); 9351 } 9352 } catch (IOException e) { 9353 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9354 } catch (RemoteException e) { 9355 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9356 } 9357 } 9358 } 9359 9360 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9361 int opti, boolean dumpAll, String dumpPackage) { 9362 boolean needSep = false; 9363 9364 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9365 if (dumpAll) { 9366 if (mRegisteredReceivers.size() > 0) { 9367 boolean printed = false; 9368 Iterator it = mRegisteredReceivers.values().iterator(); 9369 while (it.hasNext()) { 9370 ReceiverList r = (ReceiverList)it.next(); 9371 if (dumpPackage != null && (r.app == null || 9372 !dumpPackage.equals(r.app.info.packageName))) { 9373 continue; 9374 } 9375 if (!printed) { 9376 pw.println(" Registered Receivers:"); 9377 needSep = true; 9378 printed = true; 9379 } 9380 pw.print(" * "); pw.println(r); 9381 r.dump(pw, " "); 9382 } 9383 } 9384 9385 if (mReceiverResolver.dump(pw, needSep ? 9386 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9387 " ", dumpPackage, false)) { 9388 needSep = true; 9389 } 9390 } 9391 9392 for (BroadcastQueue q : mBroadcastQueues) { 9393 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9394 } 9395 9396 needSep = true; 9397 9398 if (mStickyBroadcasts != null && dumpPackage == null) { 9399 if (needSep) { 9400 pw.println(); 9401 } 9402 needSep = true; 9403 pw.println(" Sticky broadcasts:"); 9404 StringBuilder sb = new StringBuilder(128); 9405 for (Map.Entry<String, ArrayList<Intent>> ent 9406 : mStickyBroadcasts.entrySet()) { 9407 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9408 if (dumpAll) { 9409 pw.println(":"); 9410 ArrayList<Intent> intents = ent.getValue(); 9411 final int N = intents.size(); 9412 for (int i=0; i<N; i++) { 9413 sb.setLength(0); 9414 sb.append(" Intent: "); 9415 intents.get(i).toShortString(sb, false, true, false, false); 9416 pw.println(sb.toString()); 9417 Bundle bundle = intents.get(i).getExtras(); 9418 if (bundle != null) { 9419 pw.print(" "); 9420 pw.println(bundle.toString()); 9421 } 9422 } 9423 } else { 9424 pw.println(""); 9425 } 9426 } 9427 needSep = true; 9428 } 9429 9430 if (dumpAll) { 9431 pw.println(); 9432 for (BroadcastQueue queue : mBroadcastQueues) { 9433 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9434 + queue.mBroadcastsScheduled); 9435 } 9436 pw.println(" mHandler:"); 9437 mHandler.dump(new PrintWriterPrinter(pw), " "); 9438 needSep = true; 9439 } 9440 9441 return needSep; 9442 } 9443 9444 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9445 int opti, boolean dumpAll, String dumpPackage) { 9446 boolean needSep = true; 9447 9448 ItemMatcher matcher = new ItemMatcher(); 9449 matcher.build(args, opti); 9450 9451 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9452 9453 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9454 9455 if (mLaunchingProviders.size() > 0) { 9456 boolean printed = false; 9457 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9458 ContentProviderRecord r = mLaunchingProviders.get(i); 9459 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9460 continue; 9461 } 9462 if (!printed) { 9463 if (needSep) pw.println(" "); 9464 needSep = true; 9465 pw.println(" Launching content providers:"); 9466 printed = true; 9467 } 9468 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9469 pw.println(r); 9470 } 9471 } 9472 9473 if (mGrantedUriPermissions.size() > 0) { 9474 if (needSep) pw.println(); 9475 needSep = true; 9476 pw.println("Granted Uri Permissions:"); 9477 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9478 int uid = mGrantedUriPermissions.keyAt(i); 9479 HashMap<Uri, UriPermission> perms 9480 = mGrantedUriPermissions.valueAt(i); 9481 pw.print(" * UID "); pw.print(uid); 9482 pw.println(" holds:"); 9483 for (UriPermission perm : perms.values()) { 9484 pw.print(" "); pw.println(perm); 9485 if (dumpAll) { 9486 perm.dump(pw, " "); 9487 } 9488 } 9489 } 9490 needSep = true; 9491 } 9492 9493 return needSep; 9494 } 9495 9496 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9497 int opti, boolean dumpAll, String dumpPackage) { 9498 boolean needSep = false; 9499 9500 if (mIntentSenderRecords.size() > 0) { 9501 boolean printed = false; 9502 Iterator<WeakReference<PendingIntentRecord>> it 9503 = mIntentSenderRecords.values().iterator(); 9504 while (it.hasNext()) { 9505 WeakReference<PendingIntentRecord> ref = it.next(); 9506 PendingIntentRecord rec = ref != null ? ref.get(): null; 9507 if (dumpPackage != null && (rec == null 9508 || !dumpPackage.equals(rec.key.packageName))) { 9509 continue; 9510 } 9511 if (!printed) { 9512 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9513 printed = true; 9514 } 9515 needSep = true; 9516 if (rec != null) { 9517 pw.print(" * "); pw.println(rec); 9518 if (dumpAll) { 9519 rec.dump(pw, " "); 9520 } 9521 } else { 9522 pw.print(" * "); pw.println(ref); 9523 } 9524 } 9525 } 9526 9527 return needSep; 9528 } 9529 9530 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9531 String prefix, String label, boolean complete, boolean brief, boolean client, 9532 String dumpPackage) { 9533 TaskRecord lastTask = null; 9534 boolean needNL = false; 9535 final String innerPrefix = prefix + " "; 9536 final String[] args = new String[0]; 9537 for (int i=list.size()-1; i>=0; i--) { 9538 final ActivityRecord r = (ActivityRecord)list.get(i); 9539 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9540 continue; 9541 } 9542 final boolean full = !brief && (complete || !r.isInHistory()); 9543 if (needNL) { 9544 pw.println(" "); 9545 needNL = false; 9546 } 9547 if (lastTask != r.task) { 9548 lastTask = r.task; 9549 pw.print(prefix); 9550 pw.print(full ? "* " : " "); 9551 pw.println(lastTask); 9552 if (full) { 9553 lastTask.dump(pw, prefix + " "); 9554 } else if (complete) { 9555 // Complete + brief == give a summary. Isn't that obvious?!? 9556 if (lastTask.intent != null) { 9557 pw.print(prefix); pw.print(" "); 9558 pw.println(lastTask.intent.toInsecureStringWithClip()); 9559 } 9560 } 9561 } 9562 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9563 pw.print(" #"); pw.print(i); pw.print(": "); 9564 pw.println(r); 9565 if (full) { 9566 r.dump(pw, innerPrefix); 9567 } else if (complete) { 9568 // Complete + brief == give a summary. Isn't that obvious?!? 9569 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9570 if (r.app != null) { 9571 pw.print(innerPrefix); pw.println(r.app); 9572 } 9573 } 9574 if (client && r.app != null && r.app.thread != null) { 9575 // flush anything that is already in the PrintWriter since the thread is going 9576 // to write to the file descriptor directly 9577 pw.flush(); 9578 try { 9579 TransferPipe tp = new TransferPipe(); 9580 try { 9581 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9582 r.appToken, innerPrefix, args); 9583 // Short timeout, since blocking here can 9584 // deadlock with the application. 9585 tp.go(fd, 2000); 9586 } finally { 9587 tp.kill(); 9588 } 9589 } catch (IOException e) { 9590 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9591 } catch (RemoteException e) { 9592 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9593 } 9594 needNL = true; 9595 } 9596 } 9597 } 9598 9599 private static String buildOomTag(String prefix, String space, int val, int base) { 9600 if (val == base) { 9601 if (space == null) return prefix; 9602 return prefix + " "; 9603 } 9604 return prefix + "+" + Integer.toString(val-base); 9605 } 9606 9607 private static final int dumpProcessList(PrintWriter pw, 9608 ActivityManagerService service, List list, 9609 String prefix, String normalLabel, String persistentLabel, 9610 String dumpPackage) { 9611 int numPers = 0; 9612 final int N = list.size()-1; 9613 for (int i=N; i>=0; i--) { 9614 ProcessRecord r = (ProcessRecord)list.get(i); 9615 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9616 continue; 9617 } 9618 pw.println(String.format("%s%s #%2d: %s", 9619 prefix, (r.persistent ? persistentLabel : normalLabel), 9620 i, r.toString())); 9621 if (r.persistent) { 9622 numPers++; 9623 } 9624 } 9625 return numPers; 9626 } 9627 9628 private static final boolean dumpProcessOomList(PrintWriter pw, 9629 ActivityManagerService service, List<ProcessRecord> origList, 9630 String prefix, String normalLabel, String persistentLabel, 9631 boolean inclDetails, String dumpPackage) { 9632 9633 ArrayList<Pair<ProcessRecord, Integer>> list 9634 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9635 for (int i=0; i<origList.size(); i++) { 9636 ProcessRecord r = origList.get(i); 9637 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9638 continue; 9639 } 9640 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9641 } 9642 9643 if (list.size() <= 0) { 9644 return false; 9645 } 9646 9647 Comparator<Pair<ProcessRecord, Integer>> comparator 9648 = new Comparator<Pair<ProcessRecord, Integer>>() { 9649 @Override 9650 public int compare(Pair<ProcessRecord, Integer> object1, 9651 Pair<ProcessRecord, Integer> object2) { 9652 if (object1.first.setAdj != object2.first.setAdj) { 9653 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9654 } 9655 if (object1.second.intValue() != object2.second.intValue()) { 9656 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9657 } 9658 return 0; 9659 } 9660 }; 9661 9662 Collections.sort(list, comparator); 9663 9664 final long curRealtime = SystemClock.elapsedRealtime(); 9665 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9666 final long curUptime = SystemClock.uptimeMillis(); 9667 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9668 9669 for (int i=list.size()-1; i>=0; i--) { 9670 ProcessRecord r = list.get(i).first; 9671 String oomAdj; 9672 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9673 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9674 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9675 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9676 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9677 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9678 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9679 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9680 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9681 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9682 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9683 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9684 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9685 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9686 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9687 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9688 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9689 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9690 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9691 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9692 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9693 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9694 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9695 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9696 } else { 9697 oomAdj = Integer.toString(r.setAdj); 9698 } 9699 String schedGroup; 9700 switch (r.setSchedGroup) { 9701 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9702 schedGroup = "B"; 9703 break; 9704 case Process.THREAD_GROUP_DEFAULT: 9705 schedGroup = "F"; 9706 break; 9707 default: 9708 schedGroup = Integer.toString(r.setSchedGroup); 9709 break; 9710 } 9711 String foreground; 9712 if (r.foregroundActivities) { 9713 foreground = "A"; 9714 } else if (r.foregroundServices) { 9715 foreground = "S"; 9716 } else { 9717 foreground = " "; 9718 } 9719 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9720 prefix, (r.persistent ? persistentLabel : normalLabel), 9721 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9722 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9723 if (r.adjSource != null || r.adjTarget != null) { 9724 pw.print(prefix); 9725 pw.print(" "); 9726 if (r.adjTarget instanceof ComponentName) { 9727 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9728 } else if (r.adjTarget != null) { 9729 pw.print(r.adjTarget.toString()); 9730 } else { 9731 pw.print("{null}"); 9732 } 9733 pw.print("<="); 9734 if (r.adjSource instanceof ProcessRecord) { 9735 pw.print("Proc{"); 9736 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9737 pw.println("}"); 9738 } else if (r.adjSource != null) { 9739 pw.println(r.adjSource.toString()); 9740 } else { 9741 pw.println("{null}"); 9742 } 9743 } 9744 if (inclDetails) { 9745 pw.print(prefix); 9746 pw.print(" "); 9747 pw.print("oom: max="); pw.print(r.maxAdj); 9748 pw.print(" hidden="); pw.print(r.hiddenAdj); 9749 pw.print(" curRaw="); pw.print(r.curRawAdj); 9750 pw.print(" setRaw="); pw.print(r.setRawAdj); 9751 pw.print(" cur="); pw.print(r.curAdj); 9752 pw.print(" set="); pw.println(r.setAdj); 9753 pw.print(prefix); 9754 pw.print(" "); 9755 pw.print("keeping="); pw.print(r.keeping); 9756 pw.print(" hidden="); pw.print(r.hidden); 9757 pw.print(" empty="); pw.print(r.empty); 9758 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9759 9760 if (!r.keeping) { 9761 if (r.lastWakeTime != 0) { 9762 long wtime; 9763 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9764 synchronized (stats) { 9765 wtime = stats.getProcessWakeTime(r.info.uid, 9766 r.pid, curRealtime); 9767 } 9768 long timeUsed = wtime - r.lastWakeTime; 9769 pw.print(prefix); 9770 pw.print(" "); 9771 pw.print("keep awake over "); 9772 TimeUtils.formatDuration(realtimeSince, pw); 9773 pw.print(" used "); 9774 TimeUtils.formatDuration(timeUsed, pw); 9775 pw.print(" ("); 9776 pw.print((timeUsed*100)/realtimeSince); 9777 pw.println("%)"); 9778 } 9779 if (r.lastCpuTime != 0) { 9780 long timeUsed = r.curCpuTime - r.lastCpuTime; 9781 pw.print(prefix); 9782 pw.print(" "); 9783 pw.print("run cpu over "); 9784 TimeUtils.formatDuration(uptimeSince, pw); 9785 pw.print(" used "); 9786 TimeUtils.formatDuration(timeUsed, pw); 9787 pw.print(" ("); 9788 pw.print((timeUsed*100)/uptimeSince); 9789 pw.println("%)"); 9790 } 9791 } 9792 } 9793 } 9794 return true; 9795 } 9796 9797 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9798 ArrayList<ProcessRecord> procs; 9799 synchronized (this) { 9800 if (args != null && args.length > start 9801 && args[start].charAt(0) != '-') { 9802 procs = new ArrayList<ProcessRecord>(); 9803 int pid = -1; 9804 try { 9805 pid = Integer.parseInt(args[start]); 9806 } catch (NumberFormatException e) { 9807 9808 } 9809 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9810 ProcessRecord proc = mLruProcesses.get(i); 9811 if (proc.pid == pid) { 9812 procs.add(proc); 9813 } else if (proc.processName.equals(args[start])) { 9814 procs.add(proc); 9815 } 9816 } 9817 if (procs.size() <= 0) { 9818 pw.println("No process found for: " + args[start]); 9819 return null; 9820 } 9821 } else { 9822 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9823 } 9824 } 9825 return procs; 9826 } 9827 9828 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9829 PrintWriter pw, String[] args) { 9830 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9831 if (procs == null) { 9832 return; 9833 } 9834 9835 long uptime = SystemClock.uptimeMillis(); 9836 long realtime = SystemClock.elapsedRealtime(); 9837 pw.println("Applications Graphics Acceleration Info:"); 9838 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9839 9840 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9841 ProcessRecord r = procs.get(i); 9842 if (r.thread != null) { 9843 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9844 pw.flush(); 9845 try { 9846 TransferPipe tp = new TransferPipe(); 9847 try { 9848 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9849 tp.go(fd); 9850 } finally { 9851 tp.kill(); 9852 } 9853 } catch (IOException e) { 9854 pw.println("Failure while dumping the app: " + r); 9855 pw.flush(); 9856 } catch (RemoteException e) { 9857 pw.println("Got a RemoteException while dumping the app " + r); 9858 pw.flush(); 9859 } 9860 } 9861 } 9862 } 9863 9864 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9865 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9866 if (procs == null) { 9867 return; 9868 } 9869 9870 pw.println("Applications Database Info:"); 9871 9872 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9873 ProcessRecord r = procs.get(i); 9874 if (r.thread != null) { 9875 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9876 pw.flush(); 9877 try { 9878 TransferPipe tp = new TransferPipe(); 9879 try { 9880 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9881 tp.go(fd); 9882 } finally { 9883 tp.kill(); 9884 } 9885 } catch (IOException e) { 9886 pw.println("Failure while dumping the app: " + r); 9887 pw.flush(); 9888 } catch (RemoteException e) { 9889 pw.println("Got a RemoteException while dumping the app " + r); 9890 pw.flush(); 9891 } 9892 } 9893 } 9894 } 9895 9896 final static class MemItem { 9897 final String label; 9898 final String shortLabel; 9899 final long pss; 9900 final int id; 9901 ArrayList<MemItem> subitems; 9902 9903 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9904 label = _label; 9905 shortLabel = _shortLabel; 9906 pss = _pss; 9907 id = _id; 9908 } 9909 } 9910 9911 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9912 boolean sort) { 9913 if (sort) { 9914 Collections.sort(items, new Comparator<MemItem>() { 9915 @Override 9916 public int compare(MemItem lhs, MemItem rhs) { 9917 if (lhs.pss < rhs.pss) { 9918 return 1; 9919 } else if (lhs.pss > rhs.pss) { 9920 return -1; 9921 } 9922 return 0; 9923 } 9924 }); 9925 } 9926 9927 for (int i=0; i<items.size(); i++) { 9928 MemItem mi = items.get(i); 9929 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9930 if (mi.subitems != null) { 9931 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9932 } 9933 } 9934 } 9935 9936 // These are in KB. 9937 static final long[] DUMP_MEM_BUCKETS = new long[] { 9938 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9939 120*1024, 160*1024, 200*1024, 9940 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9941 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9942 }; 9943 9944 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9945 boolean stackLike) { 9946 int start = label.lastIndexOf('.'); 9947 if (start >= 0) start++; 9948 else start = 0; 9949 int end = label.length(); 9950 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9951 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9952 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9953 out.append(bucket); 9954 out.append(stackLike ? "MB." : "MB "); 9955 out.append(label, start, end); 9956 return; 9957 } 9958 } 9959 out.append(memKB/1024); 9960 out.append(stackLike ? "MB." : "MB "); 9961 out.append(label, start, end); 9962 } 9963 9964 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9965 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9966 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9967 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9968 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9969 }; 9970 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9971 "System", "Persistent", "Foreground", 9972 "Visible", "Perceptible", "Heavy Weight", 9973 "Backup", "A Services", "Home", "Previous", 9974 "B Services", "Background" 9975 }; 9976 9977 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9978 PrintWriter pw, String prefix, String[] args, boolean brief, 9979 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9980 boolean dumpAll = false; 9981 boolean oomOnly = false; 9982 9983 int opti = 0; 9984 while (opti < args.length) { 9985 String opt = args[opti]; 9986 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9987 break; 9988 } 9989 opti++; 9990 if ("-a".equals(opt)) { 9991 dumpAll = true; 9992 } else if ("--oom".equals(opt)) { 9993 oomOnly = true; 9994 } else if ("-h".equals(opt)) { 9995 pw.println("meminfo dump options: [-a] [--oom] [process]"); 9996 pw.println(" -a: include all available information for each process."); 9997 pw.println(" --oom: only show processes organized by oom adj."); 9998 pw.println("If [process] is specified it can be the name or "); 9999 pw.println("pid of a specific process to dump."); 10000 return; 10001 } else { 10002 pw.println("Unknown argument: " + opt + "; use -h for help"); 10003 } 10004 } 10005 10006 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10007 if (procs == null) { 10008 return; 10009 } 10010 10011 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10012 long uptime = SystemClock.uptimeMillis(); 10013 long realtime = SystemClock.elapsedRealtime(); 10014 10015 if (procs.size() == 1 || isCheckinRequest) { 10016 dumpAll = true; 10017 } 10018 10019 if (isCheckinRequest) { 10020 // short checkin version 10021 pw.println(uptime + "," + realtime); 10022 pw.flush(); 10023 } else { 10024 pw.println("Applications Memory Usage (kB):"); 10025 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10026 } 10027 10028 String[] innerArgs = new String[args.length-opti]; 10029 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10030 10031 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10032 long nativePss=0, dalvikPss=0, otherPss=0; 10033 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10034 10035 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10036 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10037 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10038 10039 long totalPss = 0; 10040 10041 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10042 ProcessRecord r = procs.get(i); 10043 if (r.thread != null) { 10044 if (!isCheckinRequest && dumpAll) { 10045 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10046 pw.flush(); 10047 } 10048 Debug.MemoryInfo mi = null; 10049 if (dumpAll) { 10050 try { 10051 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10052 } catch (RemoteException e) { 10053 if (!isCheckinRequest) { 10054 pw.println("Got RemoteException!"); 10055 pw.flush(); 10056 } 10057 } 10058 } else { 10059 mi = new Debug.MemoryInfo(); 10060 Debug.getMemoryInfo(r.pid, mi); 10061 } 10062 10063 if (!isCheckinRequest && mi != null) { 10064 long myTotalPss = mi.getTotalPss(); 10065 totalPss += myTotalPss; 10066 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10067 r.processName, myTotalPss, 0); 10068 procMems.add(pssItem); 10069 10070 nativePss += mi.nativePss; 10071 dalvikPss += mi.dalvikPss; 10072 otherPss += mi.otherPss; 10073 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10074 long mem = mi.getOtherPss(j); 10075 miscPss[j] += mem; 10076 otherPss -= mem; 10077 } 10078 10079 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10080 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10081 || oomIndex == (oomPss.length-1)) { 10082 oomPss[oomIndex] += myTotalPss; 10083 if (oomProcs[oomIndex] == null) { 10084 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10085 } 10086 oomProcs[oomIndex].add(pssItem); 10087 break; 10088 } 10089 } 10090 } 10091 } 10092 } 10093 10094 if (!isCheckinRequest && procs.size() > 1) { 10095 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10096 10097 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10098 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10099 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10100 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10101 String label = Debug.MemoryInfo.getOtherLabel(j); 10102 catMems.add(new MemItem(label, label, miscPss[j], j)); 10103 } 10104 10105 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10106 for (int j=0; j<oomPss.length; j++) { 10107 if (oomPss[j] != 0) { 10108 String label = DUMP_MEM_OOM_LABEL[j]; 10109 MemItem item = new MemItem(label, label, oomPss[j], 10110 DUMP_MEM_OOM_ADJ[j]); 10111 item.subitems = oomProcs[j]; 10112 oomMems.add(item); 10113 } 10114 } 10115 10116 if (outTag != null || outStack != null) { 10117 if (outTag != null) { 10118 appendMemBucket(outTag, totalPss, "total", false); 10119 } 10120 if (outStack != null) { 10121 appendMemBucket(outStack, totalPss, "total", true); 10122 } 10123 boolean firstLine = true; 10124 for (int i=0; i<oomMems.size(); i++) { 10125 MemItem miCat = oomMems.get(i); 10126 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10127 continue; 10128 } 10129 if (miCat.id < ProcessList.SERVICE_ADJ 10130 || miCat.id == ProcessList.HOME_APP_ADJ 10131 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10132 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10133 outTag.append(" / "); 10134 } 10135 if (outStack != null) { 10136 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10137 if (firstLine) { 10138 outStack.append(":"); 10139 firstLine = false; 10140 } 10141 outStack.append("\n\t at "); 10142 } else { 10143 outStack.append("$"); 10144 } 10145 } 10146 for (int j=0; j<miCat.subitems.size(); j++) { 10147 MemItem mi = miCat.subitems.get(j); 10148 if (j > 0) { 10149 if (outTag != null) { 10150 outTag.append(" "); 10151 } 10152 if (outStack != null) { 10153 outStack.append("$"); 10154 } 10155 } 10156 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10157 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10158 } 10159 if (outStack != null) { 10160 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10161 } 10162 } 10163 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10164 outStack.append("("); 10165 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10166 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10167 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10168 outStack.append(":"); 10169 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10170 } 10171 } 10172 outStack.append(")"); 10173 } 10174 } 10175 } 10176 } 10177 10178 if (!brief && !oomOnly) { 10179 pw.println(); 10180 pw.println("Total PSS by process:"); 10181 dumpMemItems(pw, " ", procMems, true); 10182 pw.println(); 10183 } 10184 pw.println("Total PSS by OOM adjustment:"); 10185 dumpMemItems(pw, " ", oomMems, false); 10186 if (!oomOnly) { 10187 PrintWriter out = categoryPw != null ? categoryPw : pw; 10188 out.println(); 10189 out.println("Total PSS by category:"); 10190 dumpMemItems(out, " ", catMems, true); 10191 } 10192 pw.println(); 10193 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10194 final int[] SINGLE_LONG_FORMAT = new int[] { 10195 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10196 }; 10197 long[] longOut = new long[1]; 10198 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10199 SINGLE_LONG_FORMAT, null, longOut, null); 10200 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10201 longOut[0] = 0; 10202 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10203 SINGLE_LONG_FORMAT, null, longOut, null); 10204 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10205 longOut[0] = 0; 10206 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10207 SINGLE_LONG_FORMAT, null, longOut, null); 10208 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10209 longOut[0] = 0; 10210 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10211 SINGLE_LONG_FORMAT, null, longOut, null); 10212 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10213 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10214 pw.print(shared); pw.println(" kB"); 10215 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10216 pw.print(voltile); pw.println(" kB volatile"); 10217 } 10218 } 10219 10220 /** 10221 * Searches array of arguments for the specified string 10222 * @param args array of argument strings 10223 * @param value value to search for 10224 * @return true if the value is contained in the array 10225 */ 10226 private static boolean scanArgs(String[] args, String value) { 10227 if (args != null) { 10228 for (String arg : args) { 10229 if (value.equals(arg)) { 10230 return true; 10231 } 10232 } 10233 } 10234 return false; 10235 } 10236 10237 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10238 ContentProviderRecord cpr, boolean always) { 10239 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10240 10241 if (!inLaunching || always) { 10242 synchronized (cpr) { 10243 cpr.launchingApp = null; 10244 cpr.notifyAll(); 10245 } 10246 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10247 String names[] = cpr.info.authority.split(";"); 10248 for (int j = 0; j < names.length; j++) { 10249 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10250 } 10251 } 10252 10253 for (int i=0; i<cpr.connections.size(); i++) { 10254 ContentProviderConnection conn = cpr.connections.get(i); 10255 if (conn.waiting) { 10256 // If this connection is waiting for the provider, then we don't 10257 // need to mess with its process unless we are always removing 10258 // or for some reason the provider is not currently launching. 10259 if (inLaunching && !always) { 10260 continue; 10261 } 10262 } 10263 ProcessRecord capp = conn.client; 10264 conn.dead = true; 10265 if (conn.stableCount > 0) { 10266 if (!capp.persistent && capp.thread != null 10267 && capp.pid != 0 10268 && capp.pid != MY_PID) { 10269 Slog.i(TAG, "Kill " + capp.processName 10270 + " (pid " + capp.pid + "): provider " + cpr.info.name 10271 + " in dying process " + (proc != null ? proc.processName : "??")); 10272 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10273 capp.processName, capp.setAdj, "dying provider " 10274 + cpr.name.toShortString()); 10275 Process.killProcessQuiet(capp.pid); 10276 } 10277 } else if (capp.thread != null && conn.provider.provider != null) { 10278 try { 10279 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10280 } catch (RemoteException e) { 10281 } 10282 // In the protocol here, we don't expect the client to correctly 10283 // clean up this connection, we'll just remove it. 10284 cpr.connections.remove(i); 10285 conn.client.conProviders.remove(conn); 10286 } 10287 } 10288 10289 if (inLaunching && always) { 10290 mLaunchingProviders.remove(cpr); 10291 } 10292 return inLaunching; 10293 } 10294 10295 /** 10296 * Main code for cleaning up a process when it has gone away. This is 10297 * called both as a result of the process dying, or directly when stopping 10298 * a process when running in single process mode. 10299 */ 10300 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10301 boolean restarting, boolean allowRestart, int index) { 10302 if (index >= 0) { 10303 mLruProcesses.remove(index); 10304 } 10305 10306 mProcessesToGc.remove(app); 10307 10308 // Dismiss any open dialogs. 10309 if (app.crashDialog != null) { 10310 app.crashDialog.dismiss(); 10311 app.crashDialog = null; 10312 } 10313 if (app.anrDialog != null) { 10314 app.anrDialog.dismiss(); 10315 app.anrDialog = null; 10316 } 10317 if (app.waitDialog != null) { 10318 app.waitDialog.dismiss(); 10319 app.waitDialog = null; 10320 } 10321 10322 app.crashing = false; 10323 app.notResponding = false; 10324 10325 app.resetPackageList(); 10326 app.unlinkDeathRecipient(); 10327 app.thread = null; 10328 app.forcingToForeground = null; 10329 app.foregroundServices = false; 10330 app.foregroundActivities = false; 10331 app.hasShownUi = false; 10332 app.hasAboveClient = false; 10333 10334 mServices.killServicesLocked(app, allowRestart); 10335 10336 boolean restart = false; 10337 10338 // Remove published content providers. 10339 if (!app.pubProviders.isEmpty()) { 10340 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10341 while (it.hasNext()) { 10342 ContentProviderRecord cpr = it.next(); 10343 10344 final boolean always = app.bad || !allowRestart; 10345 if (removeDyingProviderLocked(app, cpr, always) || always) { 10346 // We left the provider in the launching list, need to 10347 // restart it. 10348 restart = true; 10349 } 10350 10351 cpr.provider = null; 10352 cpr.proc = null; 10353 } 10354 app.pubProviders.clear(); 10355 } 10356 10357 // Take care of any launching providers waiting for this process. 10358 if (checkAppInLaunchingProvidersLocked(app, false)) { 10359 restart = true; 10360 } 10361 10362 // Unregister from connected content providers. 10363 if (!app.conProviders.isEmpty()) { 10364 for (int i=0; i<app.conProviders.size(); i++) { 10365 ContentProviderConnection conn = app.conProviders.get(i); 10366 conn.provider.connections.remove(conn); 10367 } 10368 app.conProviders.clear(); 10369 } 10370 10371 // At this point there may be remaining entries in mLaunchingProviders 10372 // where we were the only one waiting, so they are no longer of use. 10373 // Look for these and clean up if found. 10374 // XXX Commented out for now. Trying to figure out a way to reproduce 10375 // the actual situation to identify what is actually going on. 10376 if (false) { 10377 for (int i=0; i<mLaunchingProviders.size(); i++) { 10378 ContentProviderRecord cpr = (ContentProviderRecord) 10379 mLaunchingProviders.get(i); 10380 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10381 synchronized (cpr) { 10382 cpr.launchingApp = null; 10383 cpr.notifyAll(); 10384 } 10385 } 10386 } 10387 } 10388 10389 skipCurrentReceiverLocked(app); 10390 10391 // Unregister any receivers. 10392 if (app.receivers.size() > 0) { 10393 Iterator<ReceiverList> it = app.receivers.iterator(); 10394 while (it.hasNext()) { 10395 removeReceiverLocked(it.next()); 10396 } 10397 app.receivers.clear(); 10398 } 10399 10400 // If the app is undergoing backup, tell the backup manager about it 10401 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10402 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10403 try { 10404 IBackupManager bm = IBackupManager.Stub.asInterface( 10405 ServiceManager.getService(Context.BACKUP_SERVICE)); 10406 bm.agentDisconnected(app.info.packageName); 10407 } catch (RemoteException e) { 10408 // can't happen; backup manager is local 10409 } 10410 } 10411 10412 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10413 ProcessChangeItem item = mPendingProcessChanges.get(i); 10414 if (item.pid == app.pid) { 10415 mPendingProcessChanges.remove(i); 10416 mAvailProcessChanges.add(item); 10417 } 10418 } 10419 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10420 10421 // If the caller is restarting this app, then leave it in its 10422 // current lists and let the caller take care of it. 10423 if (restarting) { 10424 return; 10425 } 10426 10427 if (!app.persistent || app.isolated) { 10428 if (DEBUG_PROCESSES) Slog.v(TAG, 10429 "Removing non-persistent process during cleanup: " + app); 10430 mProcessNames.remove(app.processName, app.uid); 10431 mIsolatedProcesses.remove(app.uid); 10432 if (mHeavyWeightProcess == app) { 10433 mHeavyWeightProcess = null; 10434 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10435 } 10436 } else if (!app.removed) { 10437 // This app is persistent, so we need to keep its record around. 10438 // If it is not already on the pending app list, add it there 10439 // and start a new process for it. 10440 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10441 mPersistentStartingProcesses.add(app); 10442 restart = true; 10443 } 10444 } 10445 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10446 "Clean-up removing on hold: " + app); 10447 mProcessesOnHold.remove(app); 10448 10449 if (app == mHomeProcess) { 10450 mHomeProcess = null; 10451 } 10452 if (app == mPreviousProcess) { 10453 mPreviousProcess = null; 10454 } 10455 10456 if (restart && !app.isolated) { 10457 // We have components that still need to be running in the 10458 // process, so re-launch it. 10459 mProcessNames.put(app.processName, app.uid, app); 10460 startProcessLocked(app, "restart", app.processName); 10461 } else if (app.pid > 0 && app.pid != MY_PID) { 10462 // Goodbye! 10463 synchronized (mPidsSelfLocked) { 10464 mPidsSelfLocked.remove(app.pid); 10465 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10466 } 10467 app.setPid(0); 10468 } 10469 } 10470 10471 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10472 // Look through the content providers we are waiting to have launched, 10473 // and if any run in this process then either schedule a restart of 10474 // the process or kill the client waiting for it if this process has 10475 // gone bad. 10476 int NL = mLaunchingProviders.size(); 10477 boolean restart = false; 10478 for (int i=0; i<NL; i++) { 10479 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10480 if (cpr.launchingApp == app) { 10481 if (!alwaysBad && !app.bad) { 10482 restart = true; 10483 } else { 10484 removeDyingProviderLocked(app, cpr, true); 10485 NL = mLaunchingProviders.size(); 10486 } 10487 } 10488 } 10489 return restart; 10490 } 10491 10492 // ========================================================= 10493 // SERVICES 10494 // ========================================================= 10495 10496 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10497 int flags) { 10498 enforceNotIsolatedCaller("getServices"); 10499 synchronized (this) { 10500 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10501 } 10502 } 10503 10504 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10505 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10506 synchronized (this) { 10507 return mServices.getRunningServiceControlPanelLocked(name); 10508 } 10509 } 10510 10511 public ComponentName startService(IApplicationThread caller, Intent service, 10512 String resolvedType) { 10513 enforceNotIsolatedCaller("startService"); 10514 // Refuse possible leaked file descriptors 10515 if (service != null && service.hasFileDescriptors() == true) { 10516 throw new IllegalArgumentException("File descriptors passed in Intent"); 10517 } 10518 10519 if (DEBUG_SERVICE) 10520 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10521 synchronized(this) { 10522 final int callingPid = Binder.getCallingPid(); 10523 final int callingUid = Binder.getCallingUid(); 10524 final long origId = Binder.clearCallingIdentity(); 10525 ComponentName res = mServices.startServiceLocked(caller, service, 10526 resolvedType, callingPid, callingUid); 10527 Binder.restoreCallingIdentity(origId); 10528 return res; 10529 } 10530 } 10531 10532 ComponentName startServiceInPackage(int uid, 10533 Intent service, String resolvedType) { 10534 synchronized(this) { 10535 if (DEBUG_SERVICE) 10536 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10537 final long origId = Binder.clearCallingIdentity(); 10538 ComponentName res = mServices.startServiceLocked(null, service, 10539 resolvedType, -1, uid); 10540 Binder.restoreCallingIdentity(origId); 10541 return res; 10542 } 10543 } 10544 10545 public int stopService(IApplicationThread caller, Intent service, 10546 String resolvedType) { 10547 enforceNotIsolatedCaller("stopService"); 10548 // Refuse possible leaked file descriptors 10549 if (service != null && service.hasFileDescriptors() == true) { 10550 throw new IllegalArgumentException("File descriptors passed in Intent"); 10551 } 10552 10553 synchronized(this) { 10554 return mServices.stopServiceLocked(caller, service, resolvedType); 10555 } 10556 } 10557 10558 public IBinder peekService(Intent service, String resolvedType) { 10559 enforceNotIsolatedCaller("peekService"); 10560 // Refuse possible leaked file descriptors 10561 if (service != null && service.hasFileDescriptors() == true) { 10562 throw new IllegalArgumentException("File descriptors passed in Intent"); 10563 } 10564 synchronized(this) { 10565 return mServices.peekServiceLocked(service, resolvedType); 10566 } 10567 } 10568 10569 public boolean stopServiceToken(ComponentName className, IBinder token, 10570 int startId) { 10571 synchronized(this) { 10572 return mServices.stopServiceTokenLocked(className, token, startId); 10573 } 10574 } 10575 10576 public void setServiceForeground(ComponentName className, IBinder token, 10577 int id, Notification notification, boolean removeNotification) { 10578 synchronized(this) { 10579 mServices.setServiceForegroundLocked(className, token, id, notification, 10580 removeNotification); 10581 } 10582 } 10583 10584 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10585 String className, int flags) { 10586 boolean result = false; 10587 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10588 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10589 if (ActivityManager.checkUidPermission( 10590 android.Manifest.permission.INTERACT_ACROSS_USERS, 10591 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10592 ComponentName comp = new ComponentName(aInfo.packageName, className); 10593 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10594 + " requests FLAG_SINGLE_USER, but app does not hold " 10595 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10596 Slog.w(TAG, msg); 10597 throw new SecurityException(msg); 10598 } 10599 result = true; 10600 } 10601 } else if (componentProcessName == aInfo.packageName) { 10602 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10603 } else if ("system".equals(componentProcessName)) { 10604 result = true; 10605 } 10606 if (DEBUG_MU) { 10607 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10608 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10609 } 10610 return result; 10611 } 10612 10613 public int bindService(IApplicationThread caller, IBinder token, 10614 Intent service, String resolvedType, 10615 IServiceConnection connection, int flags, int userId) { 10616 enforceNotIsolatedCaller("bindService"); 10617 // Refuse possible leaked file descriptors 10618 if (service != null && service.hasFileDescriptors() == true) { 10619 throw new IllegalArgumentException("File descriptors passed in Intent"); 10620 } 10621 10622 checkValidCaller(Binder.getCallingUid(), userId); 10623 10624 synchronized(this) { 10625 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10626 connection, flags, userId); 10627 } 10628 } 10629 10630 public boolean unbindService(IServiceConnection connection) { 10631 synchronized (this) { 10632 return mServices.unbindServiceLocked(connection); 10633 } 10634 } 10635 10636 public void publishService(IBinder token, Intent intent, IBinder service) { 10637 // Refuse possible leaked file descriptors 10638 if (intent != null && intent.hasFileDescriptors() == true) { 10639 throw new IllegalArgumentException("File descriptors passed in Intent"); 10640 } 10641 10642 synchronized(this) { 10643 if (!(token instanceof ServiceRecord)) { 10644 throw new IllegalArgumentException("Invalid service token"); 10645 } 10646 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10647 } 10648 } 10649 10650 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10651 // Refuse possible leaked file descriptors 10652 if (intent != null && intent.hasFileDescriptors() == true) { 10653 throw new IllegalArgumentException("File descriptors passed in Intent"); 10654 } 10655 10656 synchronized(this) { 10657 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10658 } 10659 } 10660 10661 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10662 synchronized(this) { 10663 if (!(token instanceof ServiceRecord)) { 10664 throw new IllegalArgumentException("Invalid service token"); 10665 } 10666 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10667 } 10668 } 10669 10670 // ========================================================= 10671 // BACKUP AND RESTORE 10672 // ========================================================= 10673 10674 // Cause the target app to be launched if necessary and its backup agent 10675 // instantiated. The backup agent will invoke backupAgentCreated() on the 10676 // activity manager to announce its creation. 10677 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10678 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10679 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10680 10681 synchronized(this) { 10682 // !!! TODO: currently no check here that we're already bound 10683 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10684 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10685 synchronized (stats) { 10686 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10687 } 10688 10689 // Backup agent is now in use, its package can't be stopped. 10690 try { 10691 AppGlobals.getPackageManager().setPackageStoppedState( 10692 app.packageName, false, UserId.getUserId(app.uid)); 10693 } catch (RemoteException e) { 10694 } catch (IllegalArgumentException e) { 10695 Slog.w(TAG, "Failed trying to unstop package " 10696 + app.packageName + ": " + e); 10697 } 10698 10699 BackupRecord r = new BackupRecord(ss, app, backupMode); 10700 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10701 ? new ComponentName(app.packageName, app.backupAgentName) 10702 : new ComponentName("android", "FullBackupAgent"); 10703 // startProcessLocked() returns existing proc's record if it's already running 10704 ProcessRecord proc = startProcessLocked(app.processName, app, 10705 false, 0, "backup", hostingName, false, false); 10706 if (proc == null) { 10707 Slog.e(TAG, "Unable to start backup agent process " + r); 10708 return false; 10709 } 10710 10711 r.app = proc; 10712 mBackupTarget = r; 10713 mBackupAppName = app.packageName; 10714 10715 // Try not to kill the process during backup 10716 updateOomAdjLocked(proc); 10717 10718 // If the process is already attached, schedule the creation of the backup agent now. 10719 // If it is not yet live, this will be done when it attaches to the framework. 10720 if (proc.thread != null) { 10721 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10722 try { 10723 proc.thread.scheduleCreateBackupAgent(app, 10724 compatibilityInfoForPackageLocked(app), backupMode); 10725 } catch (RemoteException e) { 10726 // Will time out on the backup manager side 10727 } 10728 } else { 10729 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10730 } 10731 // Invariants: at this point, the target app process exists and the application 10732 // is either already running or in the process of coming up. mBackupTarget and 10733 // mBackupAppName describe the app, so that when it binds back to the AM we 10734 // know that it's scheduled for a backup-agent operation. 10735 } 10736 10737 return true; 10738 } 10739 10740 // A backup agent has just come up 10741 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10742 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10743 + " = " + agent); 10744 10745 synchronized(this) { 10746 if (!agentPackageName.equals(mBackupAppName)) { 10747 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10748 return; 10749 } 10750 } 10751 10752 long oldIdent = Binder.clearCallingIdentity(); 10753 try { 10754 IBackupManager bm = IBackupManager.Stub.asInterface( 10755 ServiceManager.getService(Context.BACKUP_SERVICE)); 10756 bm.agentConnected(agentPackageName, agent); 10757 } catch (RemoteException e) { 10758 // can't happen; the backup manager service is local 10759 } catch (Exception e) { 10760 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10761 e.printStackTrace(); 10762 } finally { 10763 Binder.restoreCallingIdentity(oldIdent); 10764 } 10765 } 10766 10767 // done with this agent 10768 public void unbindBackupAgent(ApplicationInfo appInfo) { 10769 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10770 if (appInfo == null) { 10771 Slog.w(TAG, "unbind backup agent for null app"); 10772 return; 10773 } 10774 10775 synchronized(this) { 10776 if (mBackupAppName == null) { 10777 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10778 return; 10779 } 10780 10781 if (!mBackupAppName.equals(appInfo.packageName)) { 10782 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10783 return; 10784 } 10785 10786 ProcessRecord proc = mBackupTarget.app; 10787 mBackupTarget = null; 10788 mBackupAppName = null; 10789 10790 // Not backing this app up any more; reset its OOM adjustment 10791 updateOomAdjLocked(proc); 10792 10793 // If the app crashed during backup, 'thread' will be null here 10794 if (proc.thread != null) { 10795 try { 10796 proc.thread.scheduleDestroyBackupAgent(appInfo, 10797 compatibilityInfoForPackageLocked(appInfo)); 10798 } catch (Exception e) { 10799 Slog.e(TAG, "Exception when unbinding backup agent:"); 10800 e.printStackTrace(); 10801 } 10802 } 10803 } 10804 } 10805 // ========================================================= 10806 // BROADCASTS 10807 // ========================================================= 10808 10809 private final List getStickiesLocked(String action, IntentFilter filter, 10810 List cur) { 10811 final ContentResolver resolver = mContext.getContentResolver(); 10812 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10813 if (list == null) { 10814 return cur; 10815 } 10816 int N = list.size(); 10817 for (int i=0; i<N; i++) { 10818 Intent intent = list.get(i); 10819 if (filter.match(resolver, intent, true, TAG) >= 0) { 10820 if (cur == null) { 10821 cur = new ArrayList<Intent>(); 10822 } 10823 cur.add(intent); 10824 } 10825 } 10826 return cur; 10827 } 10828 10829 boolean isPendingBroadcastProcessLocked(int pid) { 10830 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10831 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10832 } 10833 10834 void skipPendingBroadcastLocked(int pid) { 10835 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10836 for (BroadcastQueue queue : mBroadcastQueues) { 10837 queue.skipPendingBroadcastLocked(pid); 10838 } 10839 } 10840 10841 // The app just attached; send any pending broadcasts that it should receive 10842 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10843 boolean didSomething = false; 10844 for (BroadcastQueue queue : mBroadcastQueues) { 10845 didSomething |= queue.sendPendingBroadcastsLocked(app); 10846 } 10847 return didSomething; 10848 } 10849 10850 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10851 IIntentReceiver receiver, IntentFilter filter, String permission) { 10852 enforceNotIsolatedCaller("registerReceiver"); 10853 int callingUid; 10854 synchronized(this) { 10855 ProcessRecord callerApp = null; 10856 if (caller != null) { 10857 callerApp = getRecordForAppLocked(caller); 10858 if (callerApp == null) { 10859 throw new SecurityException( 10860 "Unable to find app for caller " + caller 10861 + " (pid=" + Binder.getCallingPid() 10862 + ") when registering receiver " + receiver); 10863 } 10864 if (callerApp.info.uid != Process.SYSTEM_UID && 10865 !callerApp.pkgList.contains(callerPackage)) { 10866 throw new SecurityException("Given caller package " + callerPackage 10867 + " is not running in process " + callerApp); 10868 } 10869 callingUid = callerApp.info.uid; 10870 } else { 10871 callerPackage = null; 10872 callingUid = Binder.getCallingUid(); 10873 } 10874 10875 List allSticky = null; 10876 10877 // Look for any matching sticky broadcasts... 10878 Iterator actions = filter.actionsIterator(); 10879 if (actions != null) { 10880 while (actions.hasNext()) { 10881 String action = (String)actions.next(); 10882 allSticky = getStickiesLocked(action, filter, allSticky); 10883 } 10884 } else { 10885 allSticky = getStickiesLocked(null, filter, allSticky); 10886 } 10887 10888 // The first sticky in the list is returned directly back to 10889 // the client. 10890 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10891 10892 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10893 + ": " + sticky); 10894 10895 if (receiver == null) { 10896 return sticky; 10897 } 10898 10899 ReceiverList rl 10900 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10901 if (rl == null) { 10902 rl = new ReceiverList(this, callerApp, 10903 Binder.getCallingPid(), 10904 Binder.getCallingUid(), receiver); 10905 if (rl.app != null) { 10906 rl.app.receivers.add(rl); 10907 } else { 10908 try { 10909 receiver.asBinder().linkToDeath(rl, 0); 10910 } catch (RemoteException e) { 10911 return sticky; 10912 } 10913 rl.linkedToDeath = true; 10914 } 10915 mRegisteredReceivers.put(receiver.asBinder(), rl); 10916 } 10917 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10918 permission, callingUid); 10919 rl.add(bf); 10920 if (!bf.debugCheck()) { 10921 Slog.w(TAG, "==> For Dynamic broadast"); 10922 } 10923 mReceiverResolver.addFilter(bf); 10924 10925 // Enqueue broadcasts for all existing stickies that match 10926 // this filter. 10927 if (allSticky != null) { 10928 ArrayList receivers = new ArrayList(); 10929 receivers.add(bf); 10930 10931 int N = allSticky.size(); 10932 for (int i=0; i<N; i++) { 10933 Intent intent = (Intent)allSticky.get(i); 10934 BroadcastQueue queue = broadcastQueueForIntent(intent); 10935 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10936 null, -1, -1, null, receivers, null, 0, null, null, 10937 false, true, true, false); 10938 queue.enqueueParallelBroadcastLocked(r); 10939 queue.scheduleBroadcastsLocked(); 10940 } 10941 } 10942 10943 return sticky; 10944 } 10945 } 10946 10947 public void unregisterReceiver(IIntentReceiver receiver) { 10948 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10949 10950 final long origId = Binder.clearCallingIdentity(); 10951 try { 10952 boolean doTrim = false; 10953 10954 synchronized(this) { 10955 ReceiverList rl 10956 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10957 if (rl != null) { 10958 if (rl.curBroadcast != null) { 10959 BroadcastRecord r = rl.curBroadcast; 10960 final boolean doNext = finishReceiverLocked( 10961 receiver.asBinder(), r.resultCode, r.resultData, 10962 r.resultExtras, r.resultAbort, true); 10963 if (doNext) { 10964 doTrim = true; 10965 r.queue.processNextBroadcast(false); 10966 } 10967 } 10968 10969 if (rl.app != null) { 10970 rl.app.receivers.remove(rl); 10971 } 10972 removeReceiverLocked(rl); 10973 if (rl.linkedToDeath) { 10974 rl.linkedToDeath = false; 10975 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10976 } 10977 } 10978 } 10979 10980 // If we actually concluded any broadcasts, we might now be able 10981 // to trim the recipients' apps from our working set 10982 if (doTrim) { 10983 trimApplications(); 10984 return; 10985 } 10986 10987 } finally { 10988 Binder.restoreCallingIdentity(origId); 10989 } 10990 } 10991 10992 void removeReceiverLocked(ReceiverList rl) { 10993 mRegisteredReceivers.remove(rl.receiver.asBinder()); 10994 int N = rl.size(); 10995 for (int i=0; i<N; i++) { 10996 mReceiverResolver.removeFilter(rl.get(i)); 10997 } 10998 } 10999 11000 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11002 ProcessRecord r = mLruProcesses.get(i); 11003 if (r.thread != null) { 11004 try { 11005 r.thread.dispatchPackageBroadcast(cmd, packages); 11006 } catch (RemoteException ex) { 11007 } 11008 } 11009 } 11010 } 11011 11012 private final int broadcastIntentLocked(ProcessRecord callerApp, 11013 String callerPackage, Intent intent, String resolvedType, 11014 IIntentReceiver resultTo, int resultCode, String resultData, 11015 Bundle map, String requiredPermission, 11016 boolean ordered, boolean sticky, int callingPid, int callingUid, 11017 int userId) { 11018 intent = new Intent(intent); 11019 11020 // By default broadcasts do not go to stopped apps. 11021 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11022 11023 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11024 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11025 + " ordered=" + ordered + " userid=" + userId); 11026 if ((resultTo != null) && !ordered) { 11027 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11028 } 11029 11030 boolean onlySendToCaller = false; 11031 11032 // If the caller is trying to send this broadcast to a different 11033 // user, verify that is allowed. 11034 if (UserId.getUserId(callingUid) != userId) { 11035 if (checkComponentPermission( 11036 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11037 callingPid, callingUid, -1, true) 11038 != PackageManager.PERMISSION_GRANTED) { 11039 if (checkComponentPermission( 11040 android.Manifest.permission.INTERACT_ACROSS_USERS, 11041 callingPid, callingUid, -1, true) 11042 == PackageManager.PERMISSION_GRANTED) { 11043 onlySendToCaller = true; 11044 } else { 11045 String msg = "Permission Denial: " + intent.getAction() 11046 + " broadcast from " + callerPackage 11047 + " asks to send as user " + userId 11048 + " but is calling from user " + UserId.getUserId(callingUid) 11049 + "; this requires " 11050 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11051 Slog.w(TAG, msg); 11052 throw new SecurityException(msg); 11053 } 11054 } 11055 } 11056 11057 // Handle special intents: if this broadcast is from the package 11058 // manager about a package being removed, we need to remove all of 11059 // its activities from the history stack. 11060 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11061 intent.getAction()); 11062 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11063 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11064 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11065 || uidRemoved) { 11066 if (checkComponentPermission( 11067 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11068 callingPid, callingUid, -1, true) 11069 == PackageManager.PERMISSION_GRANTED) { 11070 if (uidRemoved) { 11071 final Bundle intentExtras = intent.getExtras(); 11072 final int uid = intentExtras != null 11073 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11074 if (uid >= 0) { 11075 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11076 synchronized (bs) { 11077 bs.removeUidStatsLocked(uid); 11078 } 11079 } 11080 } else { 11081 // If resources are unvailble just force stop all 11082 // those packages and flush the attribute cache as well. 11083 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11084 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11085 if (list != null && (list.length > 0)) { 11086 for (String pkg : list) { 11087 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11088 } 11089 sendPackageBroadcastLocked( 11090 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11091 } 11092 } else { 11093 Uri data = intent.getData(); 11094 String ssp; 11095 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11096 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11097 forceStopPackageLocked(ssp, 11098 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11099 false, userId); 11100 } 11101 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11102 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11103 new String[] {ssp}); 11104 } 11105 } 11106 } 11107 } 11108 } else { 11109 String msg = "Permission Denial: " + intent.getAction() 11110 + " broadcast from " + callerPackage + " (pid=" + callingPid 11111 + ", uid=" + callingUid + ")" 11112 + " requires " 11113 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11114 Slog.w(TAG, msg); 11115 throw new SecurityException(msg); 11116 } 11117 11118 // Special case for adding a package: by default turn on compatibility 11119 // mode. 11120 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11121 Uri data = intent.getData(); 11122 String ssp; 11123 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11124 mCompatModePackages.handlePackageAddedLocked(ssp, 11125 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11126 } 11127 } 11128 11129 /* 11130 * If this is the time zone changed action, queue up a message that will reset the timezone 11131 * of all currently running processes. This message will get queued up before the broadcast 11132 * happens. 11133 */ 11134 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11135 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11136 } 11137 11138 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11139 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11140 } 11141 11142 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11143 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11144 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11145 } 11146 11147 /* 11148 * Prevent non-system code (defined here to be non-persistent 11149 * processes) from sending protected broadcasts. 11150 */ 11151 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11152 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11153 callingUid == 0) { 11154 // Always okay. 11155 } else if (callerApp == null || !callerApp.persistent) { 11156 try { 11157 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11158 intent.getAction())) { 11159 String msg = "Permission Denial: not allowed to send broadcast " 11160 + intent.getAction() + " from pid=" 11161 + callingPid + ", uid=" + callingUid; 11162 Slog.w(TAG, msg); 11163 throw new SecurityException(msg); 11164 } 11165 } catch (RemoteException e) { 11166 Slog.w(TAG, "Remote exception", e); 11167 return ActivityManager.BROADCAST_SUCCESS; 11168 } 11169 } 11170 11171 // Add to the sticky list if requested. 11172 if (sticky) { 11173 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11174 callingPid, callingUid) 11175 != PackageManager.PERMISSION_GRANTED) { 11176 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11177 + callingPid + ", uid=" + callingUid 11178 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11179 Slog.w(TAG, msg); 11180 throw new SecurityException(msg); 11181 } 11182 if (requiredPermission != null) { 11183 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11184 + " and enforce permission " + requiredPermission); 11185 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11186 } 11187 if (intent.getComponent() != null) { 11188 throw new SecurityException( 11189 "Sticky broadcasts can't target a specific component"); 11190 } 11191 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11192 if (list == null) { 11193 list = new ArrayList<Intent>(); 11194 mStickyBroadcasts.put(intent.getAction(), list); 11195 } 11196 int N = list.size(); 11197 int i; 11198 for (i=0; i<N; i++) { 11199 if (intent.filterEquals(list.get(i))) { 11200 // This sticky already exists, replace it. 11201 list.set(i, new Intent(intent)); 11202 break; 11203 } 11204 } 11205 if (i >= N) { 11206 list.add(new Intent(intent)); 11207 } 11208 } 11209 11210 // Figure out who all will receive this broadcast. 11211 List receivers = null; 11212 List<BroadcastFilter> registeredReceivers = null; 11213 try { 11214 // Need to resolve the intent to interested receivers... 11215 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11216 == 0) { 11217 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11218 intent, resolvedType, STOCK_PM_FLAGS, userId); 11219 } 11220 if (intent.getComponent() == null) { 11221 registeredReceivers = mReceiverResolver.queryIntent(intent, 11222 resolvedType, false, userId); 11223 } 11224 } catch (RemoteException ex) { 11225 // pm is in same process, this will never happen. 11226 } 11227 11228 final boolean replacePending = 11229 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11230 11231 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11232 + " replacePending=" + replacePending); 11233 11234 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11235 if (!ordered && NR > 0) { 11236 // If we are not serializing this broadcast, then send the 11237 // registered receivers separately so they don't wait for the 11238 // components to be launched. 11239 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11240 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11241 callerPackage, callingPid, callingUid, requiredPermission, 11242 registeredReceivers, resultTo, resultCode, resultData, map, 11243 ordered, sticky, false, onlySendToCaller); 11244 if (DEBUG_BROADCAST) Slog.v( 11245 TAG, "Enqueueing parallel broadcast " + r); 11246 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11247 if (!replaced) { 11248 queue.enqueueParallelBroadcastLocked(r); 11249 queue.scheduleBroadcastsLocked(); 11250 } 11251 registeredReceivers = null; 11252 NR = 0; 11253 } 11254 11255 // Merge into one list. 11256 int ir = 0; 11257 if (receivers != null) { 11258 // A special case for PACKAGE_ADDED: do not allow the package 11259 // being added to see this broadcast. This prevents them from 11260 // using this as a back door to get run as soon as they are 11261 // installed. Maybe in the future we want to have a special install 11262 // broadcast or such for apps, but we'd like to deliberately make 11263 // this decision. 11264 String skipPackages[] = null; 11265 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11266 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11267 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11268 Uri data = intent.getData(); 11269 if (data != null) { 11270 String pkgName = data.getSchemeSpecificPart(); 11271 if (pkgName != null) { 11272 skipPackages = new String[] { pkgName }; 11273 } 11274 } 11275 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11276 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11277 } 11278 if (skipPackages != null && (skipPackages.length > 0)) { 11279 for (String skipPackage : skipPackages) { 11280 if (skipPackage != null) { 11281 int NT = receivers.size(); 11282 for (int it=0; it<NT; it++) { 11283 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11284 if (curt.activityInfo.packageName.equals(skipPackage)) { 11285 receivers.remove(it); 11286 it--; 11287 NT--; 11288 } 11289 } 11290 } 11291 } 11292 } 11293 11294 int NT = receivers != null ? receivers.size() : 0; 11295 int it = 0; 11296 ResolveInfo curt = null; 11297 BroadcastFilter curr = null; 11298 while (it < NT && ir < NR) { 11299 if (curt == null) { 11300 curt = (ResolveInfo)receivers.get(it); 11301 } 11302 if (curr == null) { 11303 curr = registeredReceivers.get(ir); 11304 } 11305 if (curr.getPriority() >= curt.priority) { 11306 // Insert this broadcast record into the final list. 11307 receivers.add(it, curr); 11308 ir++; 11309 curr = null; 11310 it++; 11311 NT++; 11312 } else { 11313 // Skip to the next ResolveInfo in the final list. 11314 it++; 11315 curt = null; 11316 } 11317 } 11318 } 11319 while (ir < NR) { 11320 if (receivers == null) { 11321 receivers = new ArrayList(); 11322 } 11323 receivers.add(registeredReceivers.get(ir)); 11324 ir++; 11325 } 11326 11327 if ((receivers != null && receivers.size() > 0) 11328 || resultTo != null) { 11329 BroadcastQueue queue = broadcastQueueForIntent(intent); 11330 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11331 callerPackage, callingPid, callingUid, requiredPermission, 11332 receivers, resultTo, resultCode, resultData, map, ordered, 11333 sticky, false, onlySendToCaller); 11334 if (DEBUG_BROADCAST) Slog.v( 11335 TAG, "Enqueueing ordered broadcast " + r 11336 + ": prev had " + queue.mOrderedBroadcasts.size()); 11337 if (DEBUG_BROADCAST) { 11338 int seq = r.intent.getIntExtra("seq", -1); 11339 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11340 } 11341 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11342 if (!replaced) { 11343 queue.enqueueOrderedBroadcastLocked(r); 11344 queue.scheduleBroadcastsLocked(); 11345 } 11346 } 11347 11348 return ActivityManager.BROADCAST_SUCCESS; 11349 } 11350 11351 final Intent verifyBroadcastLocked(Intent intent) { 11352 // Refuse possible leaked file descriptors 11353 if (intent != null && intent.hasFileDescriptors() == true) { 11354 throw new IllegalArgumentException("File descriptors passed in Intent"); 11355 } 11356 11357 int flags = intent.getFlags(); 11358 11359 if (!mProcessesReady) { 11360 // if the caller really truly claims to know what they're doing, go 11361 // ahead and allow the broadcast without launching any receivers 11362 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11363 intent = new Intent(intent); 11364 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11365 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11366 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11367 + " before boot completion"); 11368 throw new IllegalStateException("Cannot broadcast before boot completed"); 11369 } 11370 } 11371 11372 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11373 throw new IllegalArgumentException( 11374 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11375 } 11376 11377 return intent; 11378 } 11379 11380 public final int broadcastIntent(IApplicationThread caller, 11381 Intent intent, String resolvedType, IIntentReceiver resultTo, 11382 int resultCode, String resultData, Bundle map, 11383 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11384 enforceNotIsolatedCaller("broadcastIntent"); 11385 synchronized(this) { 11386 intent = verifyBroadcastLocked(intent); 11387 11388 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11389 final int callingPid = Binder.getCallingPid(); 11390 final int callingUid = Binder.getCallingUid(); 11391 final long origId = Binder.clearCallingIdentity(); 11392 int res = broadcastIntentLocked(callerApp, 11393 callerApp != null ? callerApp.info.packageName : null, 11394 intent, resolvedType, resultTo, 11395 resultCode, resultData, map, requiredPermission, serialized, sticky, 11396 callingPid, callingUid, userId); 11397 Binder.restoreCallingIdentity(origId); 11398 return res; 11399 } 11400 } 11401 11402 int broadcastIntentInPackage(String packageName, int uid, 11403 Intent intent, String resolvedType, IIntentReceiver resultTo, 11404 int resultCode, String resultData, Bundle map, 11405 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11406 synchronized(this) { 11407 intent = verifyBroadcastLocked(intent); 11408 11409 final long origId = Binder.clearCallingIdentity(); 11410 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11411 resultTo, resultCode, resultData, map, requiredPermission, 11412 serialized, sticky, -1, uid, userId); 11413 Binder.restoreCallingIdentity(origId); 11414 return res; 11415 } 11416 } 11417 11418 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11419 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11420 // Refuse possible leaked file descriptors 11421 if (intent != null && intent.hasFileDescriptors() == true) { 11422 throw new IllegalArgumentException("File descriptors passed in Intent"); 11423 } 11424 11425 synchronized(this) { 11426 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11427 != PackageManager.PERMISSION_GRANTED) { 11428 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11429 + Binder.getCallingPid() 11430 + ", uid=" + Binder.getCallingUid() 11431 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11432 Slog.w(TAG, msg); 11433 throw new SecurityException(msg); 11434 } 11435 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11436 if (list != null) { 11437 int N = list.size(); 11438 int i; 11439 for (i=0; i<N; i++) { 11440 if (intent.filterEquals(list.get(i))) { 11441 list.remove(i); 11442 break; 11443 } 11444 } 11445 } 11446 } 11447 } 11448 11449 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11450 String resultData, Bundle resultExtras, boolean resultAbort, 11451 boolean explicit) { 11452 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11453 if (r == null) { 11454 Slog.w(TAG, "finishReceiver called but not found on queue"); 11455 return false; 11456 } 11457 11458 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11459 explicit); 11460 } 11461 11462 public void finishReceiver(IBinder who, int resultCode, String resultData, 11463 Bundle resultExtras, boolean resultAbort) { 11464 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11465 11466 // Refuse possible leaked file descriptors 11467 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11468 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11469 } 11470 11471 final long origId = Binder.clearCallingIdentity(); 11472 try { 11473 boolean doNext = false; 11474 BroadcastRecord r = null; 11475 11476 synchronized(this) { 11477 r = broadcastRecordForReceiverLocked(who); 11478 if (r != null) { 11479 doNext = r.queue.finishReceiverLocked(r, resultCode, 11480 resultData, resultExtras, resultAbort, true); 11481 } 11482 } 11483 11484 if (doNext) { 11485 r.queue.processNextBroadcast(false); 11486 } 11487 trimApplications(); 11488 } finally { 11489 Binder.restoreCallingIdentity(origId); 11490 } 11491 } 11492 11493 // ========================================================= 11494 // INSTRUMENTATION 11495 // ========================================================= 11496 11497 public boolean startInstrumentation(ComponentName className, 11498 String profileFile, int flags, Bundle arguments, 11499 IInstrumentationWatcher watcher) { 11500 enforceNotIsolatedCaller("startInstrumentation"); 11501 // Refuse possible leaked file descriptors 11502 if (arguments != null && arguments.hasFileDescriptors()) { 11503 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11504 } 11505 11506 synchronized(this) { 11507 InstrumentationInfo ii = null; 11508 ApplicationInfo ai = null; 11509 try { 11510 ii = mContext.getPackageManager().getInstrumentationInfo( 11511 className, STOCK_PM_FLAGS); 11512 ai = mContext.getPackageManager().getApplicationInfo( 11513 ii.targetPackage, STOCK_PM_FLAGS); 11514 } catch (PackageManager.NameNotFoundException e) { 11515 } 11516 if (ii == null) { 11517 reportStartInstrumentationFailure(watcher, className, 11518 "Unable to find instrumentation info for: " + className); 11519 return false; 11520 } 11521 if (ai == null) { 11522 reportStartInstrumentationFailure(watcher, className, 11523 "Unable to find instrumentation target package: " + ii.targetPackage); 11524 return false; 11525 } 11526 11527 int match = mContext.getPackageManager().checkSignatures( 11528 ii.targetPackage, ii.packageName); 11529 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11530 String msg = "Permission Denial: starting instrumentation " 11531 + className + " from pid=" 11532 + Binder.getCallingPid() 11533 + ", uid=" + Binder.getCallingPid() 11534 + " not allowed because package " + ii.packageName 11535 + " does not have a signature matching the target " 11536 + ii.targetPackage; 11537 reportStartInstrumentationFailure(watcher, className, msg); 11538 throw new SecurityException(msg); 11539 } 11540 11541 int userId = UserId.getCallingUserId(); 11542 final long origId = Binder.clearCallingIdentity(); 11543 // Instrumentation can kill and relaunch even persistent processes 11544 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11545 ProcessRecord app = addAppLocked(ai, false); 11546 app.instrumentationClass = className; 11547 app.instrumentationInfo = ai; 11548 app.instrumentationProfileFile = profileFile; 11549 app.instrumentationArguments = arguments; 11550 app.instrumentationWatcher = watcher; 11551 app.instrumentationResultClass = className; 11552 Binder.restoreCallingIdentity(origId); 11553 } 11554 11555 return true; 11556 } 11557 11558 /** 11559 * Report errors that occur while attempting to start Instrumentation. Always writes the 11560 * error to the logs, but if somebody is watching, send the report there too. This enables 11561 * the "am" command to report errors with more information. 11562 * 11563 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11564 * @param cn The component name of the instrumentation. 11565 * @param report The error report. 11566 */ 11567 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11568 ComponentName cn, String report) { 11569 Slog.w(TAG, report); 11570 try { 11571 if (watcher != null) { 11572 Bundle results = new Bundle(); 11573 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11574 results.putString("Error", report); 11575 watcher.instrumentationStatus(cn, -1, results); 11576 } 11577 } catch (RemoteException e) { 11578 Slog.w(TAG, e); 11579 } 11580 } 11581 11582 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11583 if (app.instrumentationWatcher != null) { 11584 try { 11585 // NOTE: IInstrumentationWatcher *must* be oneway here 11586 app.instrumentationWatcher.instrumentationFinished( 11587 app.instrumentationClass, 11588 resultCode, 11589 results); 11590 } catch (RemoteException e) { 11591 } 11592 } 11593 app.instrumentationWatcher = null; 11594 app.instrumentationClass = null; 11595 app.instrumentationInfo = null; 11596 app.instrumentationProfileFile = null; 11597 app.instrumentationArguments = null; 11598 11599 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11600 } 11601 11602 public void finishInstrumentation(IApplicationThread target, 11603 int resultCode, Bundle results) { 11604 int userId = UserId.getCallingUserId(); 11605 // Refuse possible leaked file descriptors 11606 if (results != null && results.hasFileDescriptors()) { 11607 throw new IllegalArgumentException("File descriptors passed in Intent"); 11608 } 11609 11610 synchronized(this) { 11611 ProcessRecord app = getRecordForAppLocked(target); 11612 if (app == null) { 11613 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11614 return; 11615 } 11616 final long origId = Binder.clearCallingIdentity(); 11617 finishInstrumentationLocked(app, resultCode, results); 11618 Binder.restoreCallingIdentity(origId); 11619 } 11620 } 11621 11622 // ========================================================= 11623 // CONFIGURATION 11624 // ========================================================= 11625 11626 public ConfigurationInfo getDeviceConfigurationInfo() { 11627 ConfigurationInfo config = new ConfigurationInfo(); 11628 synchronized (this) { 11629 config.reqTouchScreen = mConfiguration.touchscreen; 11630 config.reqKeyboardType = mConfiguration.keyboard; 11631 config.reqNavigation = mConfiguration.navigation; 11632 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11633 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11634 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11635 } 11636 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11637 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11638 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11639 } 11640 config.reqGlEsVersion = GL_ES_VERSION; 11641 } 11642 return config; 11643 } 11644 11645 public Configuration getConfiguration() { 11646 Configuration ci; 11647 synchronized(this) { 11648 ci = new Configuration(mConfiguration); 11649 } 11650 return ci; 11651 } 11652 11653 public void updatePersistentConfiguration(Configuration values) { 11654 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11655 "updateConfiguration()"); 11656 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11657 "updateConfiguration()"); 11658 if (values == null) { 11659 throw new NullPointerException("Configuration must not be null"); 11660 } 11661 11662 synchronized(this) { 11663 final long origId = Binder.clearCallingIdentity(); 11664 updateConfigurationLocked(values, null, true, false); 11665 Binder.restoreCallingIdentity(origId); 11666 } 11667 } 11668 11669 public void updateConfiguration(Configuration values) { 11670 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11671 "updateConfiguration()"); 11672 11673 synchronized(this) { 11674 if (values == null && mWindowManager != null) { 11675 // sentinel: fetch the current configuration from the window manager 11676 values = mWindowManager.computeNewConfiguration(); 11677 } 11678 11679 if (mWindowManager != null) { 11680 mProcessList.applyDisplaySize(mWindowManager); 11681 } 11682 11683 final long origId = Binder.clearCallingIdentity(); 11684 if (values != null) { 11685 Settings.System.clearConfiguration(values); 11686 } 11687 updateConfigurationLocked(values, null, false, false); 11688 Binder.restoreCallingIdentity(origId); 11689 } 11690 } 11691 11692 /** 11693 * Do either or both things: (1) change the current configuration, and (2) 11694 * make sure the given activity is running with the (now) current 11695 * configuration. Returns true if the activity has been left running, or 11696 * false if <var>starting</var> is being destroyed to match the new 11697 * configuration. 11698 * @param persistent TODO 11699 */ 11700 boolean updateConfigurationLocked(Configuration values, 11701 ActivityRecord starting, boolean persistent, boolean initLocale) { 11702 // do nothing if we are headless 11703 if (mHeadless) return true; 11704 11705 int changes = 0; 11706 11707 boolean kept = true; 11708 11709 if (values != null) { 11710 Configuration newConfig = new Configuration(mConfiguration); 11711 changes = newConfig.updateFrom(values); 11712 if (changes != 0) { 11713 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11714 Slog.i(TAG, "Updating configuration to: " + values); 11715 } 11716 11717 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11718 11719 if (values.locale != null && !initLocale) { 11720 saveLocaleLocked(values.locale, 11721 !values.locale.equals(mConfiguration.locale), 11722 values.userSetLocale); 11723 } 11724 11725 mConfigurationSeq++; 11726 if (mConfigurationSeq <= 0) { 11727 mConfigurationSeq = 1; 11728 } 11729 newConfig.seq = mConfigurationSeq; 11730 mConfiguration = newConfig; 11731 Slog.i(TAG, "Config changed: " + newConfig); 11732 11733 final Configuration configCopy = new Configuration(mConfiguration); 11734 11735 // TODO: If our config changes, should we auto dismiss any currently 11736 // showing dialogs? 11737 mShowDialogs = shouldShowDialogs(newConfig); 11738 11739 AttributeCache ac = AttributeCache.instance(); 11740 if (ac != null) { 11741 ac.updateConfiguration(configCopy); 11742 } 11743 11744 // Make sure all resources in our process are updated 11745 // right now, so that anyone who is going to retrieve 11746 // resource values after we return will be sure to get 11747 // the new ones. This is especially important during 11748 // boot, where the first config change needs to guarantee 11749 // all resources have that config before following boot 11750 // code is executed. 11751 mSystemThread.applyConfigurationToResources(configCopy); 11752 11753 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11754 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11755 msg.obj = new Configuration(configCopy); 11756 mHandler.sendMessage(msg); 11757 } 11758 11759 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11760 ProcessRecord app = mLruProcesses.get(i); 11761 try { 11762 if (app.thread != null) { 11763 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11764 + app.processName + " new config " + mConfiguration); 11765 app.thread.scheduleConfigurationChanged(configCopy); 11766 } 11767 } catch (Exception e) { 11768 } 11769 } 11770 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11771 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11772 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11773 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11774 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11775 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11776 broadcastIntentLocked(null, null, 11777 new Intent(Intent.ACTION_LOCALE_CHANGED), 11778 null, null, 0, null, null, 11779 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11780 } 11781 } 11782 } 11783 11784 if (changes != 0 && starting == null) { 11785 // If the configuration changed, and the caller is not already 11786 // in the process of starting an activity, then find the top 11787 // activity to check if its configuration needs to change. 11788 starting = mMainStack.topRunningActivityLocked(null); 11789 } 11790 11791 if (starting != null) { 11792 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11793 // And we need to make sure at this point that all other activities 11794 // are made visible with the correct configuration. 11795 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11796 } 11797 11798 if (values != null && mWindowManager != null) { 11799 mWindowManager.setNewConfiguration(mConfiguration); 11800 } 11801 11802 return kept; 11803 } 11804 11805 /** 11806 * Decide based on the configuration whether we should shouw the ANR, 11807 * crash, etc dialogs. The idea is that if there is no affordnace to 11808 * press the on-screen buttons, we shouldn't show the dialog. 11809 * 11810 * A thought: SystemUI might also want to get told about this, the Power 11811 * dialog / global actions also might want different behaviors. 11812 */ 11813 private static final boolean shouldShowDialogs(Configuration config) { 11814 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11815 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11816 } 11817 11818 /** 11819 * Save the locale. You must be inside a synchronized (this) block. 11820 */ 11821 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11822 if(isDiff) { 11823 SystemProperties.set("user.language", l.getLanguage()); 11824 SystemProperties.set("user.region", l.getCountry()); 11825 } 11826 11827 if(isPersist) { 11828 SystemProperties.set("persist.sys.language", l.getLanguage()); 11829 SystemProperties.set("persist.sys.country", l.getCountry()); 11830 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11831 } 11832 } 11833 11834 @Override 11835 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11836 ActivityRecord srec = ActivityRecord.forToken(token); 11837 return srec != null && srec.task.affinity != null && 11838 srec.task.affinity.equals(destAffinity); 11839 } 11840 11841 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11842 Intent resultData) { 11843 ComponentName dest = destIntent.getComponent(); 11844 11845 synchronized (this) { 11846 ActivityRecord srec = ActivityRecord.forToken(token); 11847 if (srec == null) { 11848 return false; 11849 } 11850 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11851 final int start = history.indexOf(srec); 11852 if (start < 0) { 11853 // Current activity is not in history stack; do nothing. 11854 return false; 11855 } 11856 int finishTo = start - 1; 11857 ActivityRecord parent = null; 11858 boolean foundParentInTask = false; 11859 if (dest != null) { 11860 TaskRecord tr = srec.task; 11861 for (int i = start - 1; i >= 0; i--) { 11862 ActivityRecord r = history.get(i); 11863 if (tr != r.task) { 11864 // Couldn't find parent in the same task; stop at the one above this. 11865 // (Root of current task; in-app "home" behavior) 11866 // Always at least finish the current activity. 11867 finishTo = Math.min(start - 1, i + 1); 11868 parent = history.get(finishTo); 11869 break; 11870 } else if (r.info.packageName.equals(dest.getPackageName()) && 11871 r.info.name.equals(dest.getClassName())) { 11872 finishTo = i; 11873 parent = r; 11874 foundParentInTask = true; 11875 break; 11876 } 11877 } 11878 } 11879 11880 if (mController != null) { 11881 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11882 if (next != null) { 11883 // ask watcher if this is allowed 11884 boolean resumeOK = true; 11885 try { 11886 resumeOK = mController.activityResuming(next.packageName); 11887 } catch (RemoteException e) { 11888 mController = null; 11889 } 11890 11891 if (!resumeOK) { 11892 return false; 11893 } 11894 } 11895 } 11896 final long origId = Binder.clearCallingIdentity(); 11897 for (int i = start; i > finishTo; i--) { 11898 ActivityRecord r = history.get(i); 11899 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11900 "navigate-up"); 11901 // Only return the supplied result for the first activity finished 11902 resultCode = Activity.RESULT_CANCELED; 11903 resultData = null; 11904 } 11905 11906 if (parent != null && foundParentInTask) { 11907 final int parentLaunchMode = parent.info.launchMode; 11908 final int destIntentFlags = destIntent.getFlags(); 11909 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11910 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11911 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11912 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11913 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11914 } else { 11915 try { 11916 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11917 destIntent.getComponent(), 0, UserId.getCallingUserId()); 11918 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11919 null, aInfo, parent.appToken, null, 11920 0, -1, parent.launchedFromUid, 0, null, true, null); 11921 foundParentInTask = res == ActivityManager.START_SUCCESS; 11922 } catch (RemoteException e) { 11923 foundParentInTask = false; 11924 } 11925 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11926 resultData, "navigate-up"); 11927 } 11928 } 11929 Binder.restoreCallingIdentity(origId); 11930 return foundParentInTask; 11931 } 11932 } 11933 11934 public int getLaunchedFromUid(IBinder activityToken) { 11935 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11936 if (srec == null) { 11937 return -1; 11938 } 11939 return srec.launchedFromUid; 11940 } 11941 11942 // ========================================================= 11943 // LIFETIME MANAGEMENT 11944 // ========================================================= 11945 11946 // Returns which broadcast queue the app is the current [or imminent] receiver 11947 // on, or 'null' if the app is not an active broadcast recipient. 11948 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11949 BroadcastRecord r = app.curReceiver; 11950 if (r != null) { 11951 return r.queue; 11952 } 11953 11954 // It's not the current receiver, but it might be starting up to become one 11955 synchronized (this) { 11956 for (BroadcastQueue queue : mBroadcastQueues) { 11957 r = queue.mPendingBroadcast; 11958 if (r != null && r.curApp == app) { 11959 // found it; report which queue it's in 11960 return queue; 11961 } 11962 } 11963 } 11964 11965 return null; 11966 } 11967 11968 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11969 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11970 if (mAdjSeq == app.adjSeq) { 11971 // This adjustment has already been computed. If we are calling 11972 // from the top, we may have already computed our adjustment with 11973 // an earlier hidden adjustment that isn't really for us... if 11974 // so, use the new hidden adjustment. 11975 if (!recursed && app.hidden) { 11976 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 11977 } 11978 return app.curRawAdj; 11979 } 11980 11981 if (app.thread == null) { 11982 app.adjSeq = mAdjSeq; 11983 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 11984 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 11985 } 11986 11987 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 11988 app.adjSource = null; 11989 app.adjTarget = null; 11990 app.empty = false; 11991 app.hidden = false; 11992 11993 final int activitiesSize = app.activities.size(); 11994 11995 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 11996 // The max adjustment doesn't allow this app to be anything 11997 // below foreground, so it is not worth doing work for it. 11998 app.adjType = "fixed"; 11999 app.adjSeq = mAdjSeq; 12000 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12001 app.foregroundActivities = false; 12002 app.keeping = true; 12003 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12004 // System process can do UI, and when they do we want to have 12005 // them trim their memory after the user leaves the UI. To 12006 // facilitate this, here we need to determine whether or not it 12007 // is currently showing UI. 12008 app.systemNoUi = true; 12009 if (app == TOP_APP) { 12010 app.systemNoUi = false; 12011 } else if (activitiesSize > 0) { 12012 for (int j = 0; j < activitiesSize; j++) { 12013 final ActivityRecord r = app.activities.get(j); 12014 if (r.visible) { 12015 app.systemNoUi = false; 12016 break; 12017 } 12018 } 12019 } 12020 return (app.curAdj=app.maxAdj); 12021 } 12022 12023 app.keeping = false; 12024 app.systemNoUi = false; 12025 12026 // Determine the importance of the process, starting with most 12027 // important to least, and assign an appropriate OOM adjustment. 12028 int adj; 12029 int schedGroup; 12030 boolean foregroundActivities = false; 12031 boolean interesting = false; 12032 BroadcastQueue queue; 12033 if (app == TOP_APP) { 12034 // The last app on the list is the foreground app. 12035 adj = ProcessList.FOREGROUND_APP_ADJ; 12036 schedGroup = Process.THREAD_GROUP_DEFAULT; 12037 app.adjType = "top-activity"; 12038 foregroundActivities = true; 12039 interesting = true; 12040 } else if (app.instrumentationClass != null) { 12041 // Don't want to kill running instrumentation. 12042 adj = ProcessList.FOREGROUND_APP_ADJ; 12043 schedGroup = Process.THREAD_GROUP_DEFAULT; 12044 app.adjType = "instrumentation"; 12045 interesting = true; 12046 } else if ((queue = isReceivingBroadcast(app)) != null) { 12047 // An app that is currently receiving a broadcast also 12048 // counts as being in the foreground for OOM killer purposes. 12049 // It's placed in a sched group based on the nature of the 12050 // broadcast as reflected by which queue it's active in. 12051 adj = ProcessList.FOREGROUND_APP_ADJ; 12052 schedGroup = (queue == mFgBroadcastQueue) 12053 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12054 app.adjType = "broadcast"; 12055 } else if (app.executingServices.size() > 0) { 12056 // An app that is currently executing a service callback also 12057 // counts as being in the foreground. 12058 adj = ProcessList.FOREGROUND_APP_ADJ; 12059 schedGroup = Process.THREAD_GROUP_DEFAULT; 12060 app.adjType = "exec-service"; 12061 } else if (activitiesSize > 0) { 12062 // This app is in the background with paused activities. 12063 // We inspect activities to potentially upgrade adjustment further below. 12064 adj = hiddenAdj; 12065 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12066 app.hidden = true; 12067 app.adjType = "bg-activities"; 12068 } else { 12069 // A very not-needed process. If this is lower in the lru list, 12070 // we will push it in to the empty bucket. 12071 adj = hiddenAdj; 12072 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12073 app.hidden = true; 12074 app.empty = true; 12075 app.adjType = "bg-empty"; 12076 } 12077 12078 boolean hasStoppingActivities = false; 12079 12080 // Examine all activities if not already foreground. 12081 if (!foregroundActivities && activitiesSize > 0) { 12082 for (int j = 0; j < activitiesSize; j++) { 12083 final ActivityRecord r = app.activities.get(j); 12084 if (r.visible) { 12085 // App has a visible activity; only upgrade adjustment. 12086 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12087 adj = ProcessList.VISIBLE_APP_ADJ; 12088 app.adjType = "visible"; 12089 } 12090 schedGroup = Process.THREAD_GROUP_DEFAULT; 12091 app.hidden = false; 12092 foregroundActivities = true; 12093 break; 12094 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12095 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12096 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12097 app.adjType = "pausing"; 12098 } 12099 app.hidden = false; 12100 foregroundActivities = true; 12101 } else if (r.state == ActivityState.STOPPING) { 12102 // We will apply the actual adjustment later, because 12103 // we want to allow this process to immediately go through 12104 // any memory trimming that is in effect. 12105 app.hidden = false; 12106 foregroundActivities = true; 12107 hasStoppingActivities = true; 12108 } 12109 } 12110 } 12111 12112 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12113 if (app.foregroundServices) { 12114 // The user is aware of this app, so make it visible. 12115 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12116 app.hidden = false; 12117 app.adjType = "foreground-service"; 12118 schedGroup = Process.THREAD_GROUP_DEFAULT; 12119 } else if (app.forcingToForeground != null) { 12120 // The user is aware of this app, so make it visible. 12121 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12122 app.hidden = false; 12123 app.adjType = "force-foreground"; 12124 app.adjSource = app.forcingToForeground; 12125 schedGroup = Process.THREAD_GROUP_DEFAULT; 12126 } 12127 } 12128 12129 if (app.foregroundServices) { 12130 interesting = true; 12131 } 12132 12133 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12134 // We don't want to kill the current heavy-weight process. 12135 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12136 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12137 app.hidden = false; 12138 app.adjType = "heavy"; 12139 } 12140 12141 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12142 // This process is hosting what we currently consider to be the 12143 // home app, so we don't want to let it go into the background. 12144 adj = ProcessList.HOME_APP_ADJ; 12145 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12146 app.hidden = false; 12147 app.adjType = "home"; 12148 } 12149 12150 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12151 && app.activities.size() > 0) { 12152 // This was the previous process that showed UI to the user. 12153 // We want to try to keep it around more aggressively, to give 12154 // a good experience around switching between two apps. 12155 adj = ProcessList.PREVIOUS_APP_ADJ; 12156 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12157 app.hidden = false; 12158 app.adjType = "previous"; 12159 } 12160 12161 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12162 + " reason=" + app.adjType); 12163 12164 // By default, we use the computed adjustment. It may be changed if 12165 // there are applications dependent on our services or providers, but 12166 // this gives us a baseline and makes sure we don't get into an 12167 // infinite recursion. 12168 app.adjSeq = mAdjSeq; 12169 app.curRawAdj = app.nonStoppingAdj = adj; 12170 12171 if (mBackupTarget != null && app == mBackupTarget.app) { 12172 // If possible we want to avoid killing apps while they're being backed up 12173 if (adj > ProcessList.BACKUP_APP_ADJ) { 12174 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12175 adj = ProcessList.BACKUP_APP_ADJ; 12176 app.adjType = "backup"; 12177 app.hidden = false; 12178 } 12179 } 12180 12181 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12182 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12183 final long now = SystemClock.uptimeMillis(); 12184 // This process is more important if the top activity is 12185 // bound to the service. 12186 Iterator<ServiceRecord> jt = app.services.iterator(); 12187 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12188 ServiceRecord s = jt.next(); 12189 if (s.startRequested) { 12190 if (app.hasShownUi && app != mHomeProcess) { 12191 // If this process has shown some UI, let it immediately 12192 // go to the LRU list because it may be pretty heavy with 12193 // UI stuff. We'll tag it with a label just to help 12194 // debug and understand what is going on. 12195 if (adj > ProcessList.SERVICE_ADJ) { 12196 app.adjType = "started-bg-ui-services"; 12197 } 12198 } else { 12199 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12200 // This service has seen some activity within 12201 // recent memory, so we will keep its process ahead 12202 // of the background processes. 12203 if (adj > ProcessList.SERVICE_ADJ) { 12204 adj = ProcessList.SERVICE_ADJ; 12205 app.adjType = "started-services"; 12206 app.hidden = false; 12207 } 12208 } 12209 // If we have let the service slide into the background 12210 // state, still have some text describing what it is doing 12211 // even though the service no longer has an impact. 12212 if (adj > ProcessList.SERVICE_ADJ) { 12213 app.adjType = "started-bg-services"; 12214 } 12215 } 12216 // Don't kill this process because it is doing work; it 12217 // has said it is doing work. 12218 app.keeping = true; 12219 } 12220 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12221 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12222 Iterator<ArrayList<ConnectionRecord>> kt 12223 = s.connections.values().iterator(); 12224 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12225 ArrayList<ConnectionRecord> clist = kt.next(); 12226 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12227 // XXX should compute this based on the max of 12228 // all connected clients. 12229 ConnectionRecord cr = clist.get(i); 12230 if (cr.binding.client == app) { 12231 // Binding to ourself is not interesting. 12232 continue; 12233 } 12234 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12235 ProcessRecord client = cr.binding.client; 12236 int clientAdj = adj; 12237 int myHiddenAdj = hiddenAdj; 12238 if (myHiddenAdj > client.hiddenAdj) { 12239 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12240 myHiddenAdj = client.hiddenAdj; 12241 } else { 12242 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12243 } 12244 } 12245 clientAdj = computeOomAdjLocked( 12246 client, myHiddenAdj, TOP_APP, true, doingAll); 12247 String adjType = null; 12248 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12249 // Not doing bind OOM management, so treat 12250 // this guy more like a started service. 12251 if (app.hasShownUi && app != mHomeProcess) { 12252 // If this process has shown some UI, let it immediately 12253 // go to the LRU list because it may be pretty heavy with 12254 // UI stuff. We'll tag it with a label just to help 12255 // debug and understand what is going on. 12256 if (adj > clientAdj) { 12257 adjType = "bound-bg-ui-services"; 12258 } 12259 app.hidden = false; 12260 clientAdj = adj; 12261 } else { 12262 if (now >= (s.lastActivity 12263 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12264 // This service has not seen activity within 12265 // recent memory, so allow it to drop to the 12266 // LRU list if there is no other reason to keep 12267 // it around. We'll also tag it with a label just 12268 // to help debug and undertand what is going on. 12269 if (adj > clientAdj) { 12270 adjType = "bound-bg-services"; 12271 } 12272 clientAdj = adj; 12273 } 12274 } 12275 } 12276 if (adj > clientAdj) { 12277 // If this process has recently shown UI, and 12278 // the process that is binding to it is less 12279 // important than being visible, then we don't 12280 // care about the binding as much as we care 12281 // about letting this process get into the LRU 12282 // list to be killed and restarted if needed for 12283 // memory. 12284 if (app.hasShownUi && app != mHomeProcess 12285 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12286 adjType = "bound-bg-ui-services"; 12287 } else { 12288 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12289 |Context.BIND_IMPORTANT)) != 0) { 12290 adj = clientAdj; 12291 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12292 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12293 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12294 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12295 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12296 adj = clientAdj; 12297 } else { 12298 app.pendingUiClean = true; 12299 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12300 adj = ProcessList.VISIBLE_APP_ADJ; 12301 } 12302 } 12303 if (!client.hidden) { 12304 app.hidden = false; 12305 } 12306 if (client.keeping) { 12307 app.keeping = true; 12308 } 12309 adjType = "service"; 12310 } 12311 } 12312 if (adjType != null) { 12313 app.adjType = adjType; 12314 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12315 .REASON_SERVICE_IN_USE; 12316 app.adjSource = cr.binding.client; 12317 app.adjSourceOom = clientAdj; 12318 app.adjTarget = s.name; 12319 } 12320 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12321 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12322 schedGroup = Process.THREAD_GROUP_DEFAULT; 12323 } 12324 } 12325 } 12326 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12327 ActivityRecord a = cr.activity; 12328 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12329 (a.visible || a.state == ActivityState.RESUMED 12330 || a.state == ActivityState.PAUSING)) { 12331 adj = ProcessList.FOREGROUND_APP_ADJ; 12332 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12333 schedGroup = Process.THREAD_GROUP_DEFAULT; 12334 } 12335 app.hidden = false; 12336 app.adjType = "service"; 12337 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12338 .REASON_SERVICE_IN_USE; 12339 app.adjSource = a; 12340 app.adjSourceOom = adj; 12341 app.adjTarget = s.name; 12342 } 12343 } 12344 } 12345 } 12346 } 12347 } 12348 12349 // Finally, if this process has active services running in it, we 12350 // would like to avoid killing it unless it would prevent the current 12351 // application from running. By default we put the process in 12352 // with the rest of the background processes; as we scan through 12353 // its services we may bump it up from there. 12354 if (adj > hiddenAdj) { 12355 adj = hiddenAdj; 12356 app.hidden = false; 12357 app.adjType = "bg-services"; 12358 } 12359 } 12360 12361 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12362 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12363 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12364 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12365 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12366 ContentProviderRecord cpr = jt.next(); 12367 for (int i = cpr.connections.size()-1; 12368 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12369 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12370 i--) { 12371 ContentProviderConnection conn = cpr.connections.get(i); 12372 ProcessRecord client = conn.client; 12373 if (client == app) { 12374 // Being our own client is not interesting. 12375 continue; 12376 } 12377 int myHiddenAdj = hiddenAdj; 12378 if (myHiddenAdj > client.hiddenAdj) { 12379 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12380 myHiddenAdj = client.hiddenAdj; 12381 } else { 12382 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12383 } 12384 } 12385 int clientAdj = computeOomAdjLocked( 12386 client, myHiddenAdj, TOP_APP, true, doingAll); 12387 if (adj > clientAdj) { 12388 if (app.hasShownUi && app != mHomeProcess 12389 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12390 app.adjType = "bg-ui-provider"; 12391 } else { 12392 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12393 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12394 app.adjType = "provider"; 12395 } 12396 if (!client.hidden) { 12397 app.hidden = false; 12398 } 12399 if (client.keeping) { 12400 app.keeping = true; 12401 } 12402 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12403 .REASON_PROVIDER_IN_USE; 12404 app.adjSource = client; 12405 app.adjSourceOom = clientAdj; 12406 app.adjTarget = cpr.name; 12407 } 12408 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12409 schedGroup = Process.THREAD_GROUP_DEFAULT; 12410 } 12411 } 12412 // If the provider has external (non-framework) process 12413 // dependencies, ensure that its adjustment is at least 12414 // FOREGROUND_APP_ADJ. 12415 if (cpr.hasExternalProcessHandles()) { 12416 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12417 adj = ProcessList.FOREGROUND_APP_ADJ; 12418 schedGroup = Process.THREAD_GROUP_DEFAULT; 12419 app.hidden = false; 12420 app.keeping = true; 12421 app.adjType = "provider"; 12422 app.adjTarget = cpr.name; 12423 } 12424 } 12425 } 12426 } 12427 12428 if (adj == ProcessList.SERVICE_ADJ) { 12429 if (doingAll) { 12430 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12431 mNewNumServiceProcs++; 12432 } 12433 if (app.serviceb) { 12434 adj = ProcessList.SERVICE_B_ADJ; 12435 } 12436 } else { 12437 app.serviceb = false; 12438 } 12439 12440 app.nonStoppingAdj = adj; 12441 12442 if (hasStoppingActivities) { 12443 // Only upgrade adjustment. 12444 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12445 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12446 app.adjType = "stopping"; 12447 } 12448 } 12449 12450 app.curRawAdj = adj; 12451 12452 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12453 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12454 if (adj > app.maxAdj) { 12455 adj = app.maxAdj; 12456 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12457 schedGroup = Process.THREAD_GROUP_DEFAULT; 12458 } 12459 } 12460 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12461 app.keeping = true; 12462 } 12463 12464 if (app.hasAboveClient) { 12465 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12466 // then we need to drop its adjustment to be lower than the service's 12467 // in order to honor the request. We want to drop it by one adjustment 12468 // level... but there is special meaning applied to various levels so 12469 // we will skip some of them. 12470 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12471 // System process will not get dropped, ever 12472 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12473 adj = ProcessList.VISIBLE_APP_ADJ; 12474 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12475 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12476 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12477 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12478 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12479 adj++; 12480 } 12481 } 12482 12483 int importance = app.memImportance; 12484 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12485 app.curAdj = adj; 12486 app.curSchedGroup = schedGroup; 12487 if (!interesting) { 12488 // For this reporting, if there is not something explicitly 12489 // interesting in this process then we will push it to the 12490 // background importance. 12491 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12492 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12493 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12494 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12495 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12496 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12497 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12498 } else if (adj >= ProcessList.SERVICE_ADJ) { 12499 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12500 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12501 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12502 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12503 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12504 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12505 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12506 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12507 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12508 } else { 12509 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12510 } 12511 } 12512 12513 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12514 if (foregroundActivities != app.foregroundActivities) { 12515 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12516 } 12517 if (changes != 0) { 12518 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12519 app.memImportance = importance; 12520 app.foregroundActivities = foregroundActivities; 12521 int i = mPendingProcessChanges.size()-1; 12522 ProcessChangeItem item = null; 12523 while (i >= 0) { 12524 item = mPendingProcessChanges.get(i); 12525 if (item.pid == app.pid) { 12526 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12527 break; 12528 } 12529 i--; 12530 } 12531 if (i < 0) { 12532 // No existing item in pending changes; need a new one. 12533 final int NA = mAvailProcessChanges.size(); 12534 if (NA > 0) { 12535 item = mAvailProcessChanges.remove(NA-1); 12536 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12537 } else { 12538 item = new ProcessChangeItem(); 12539 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12540 } 12541 item.changes = 0; 12542 item.pid = app.pid; 12543 item.uid = app.info.uid; 12544 if (mPendingProcessChanges.size() == 0) { 12545 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12546 "*** Enqueueing dispatch processes changed!"); 12547 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12548 } 12549 mPendingProcessChanges.add(item); 12550 } 12551 item.changes |= changes; 12552 item.importance = importance; 12553 item.foregroundActivities = foregroundActivities; 12554 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12555 + Integer.toHexString(System.identityHashCode(item)) 12556 + " " + app.toShortString() + ": changes=" + item.changes 12557 + " importance=" + item.importance 12558 + " foreground=" + item.foregroundActivities 12559 + " type=" + app.adjType + " source=" + app.adjSource 12560 + " target=" + app.adjTarget); 12561 } 12562 12563 return app.curRawAdj; 12564 } 12565 12566 /** 12567 * Ask a given process to GC right now. 12568 */ 12569 final void performAppGcLocked(ProcessRecord app) { 12570 try { 12571 app.lastRequestedGc = SystemClock.uptimeMillis(); 12572 if (app.thread != null) { 12573 if (app.reportLowMemory) { 12574 app.reportLowMemory = false; 12575 app.thread.scheduleLowMemory(); 12576 } else { 12577 app.thread.processInBackground(); 12578 } 12579 } 12580 } catch (Exception e) { 12581 // whatever. 12582 } 12583 } 12584 12585 /** 12586 * Returns true if things are idle enough to perform GCs. 12587 */ 12588 private final boolean canGcNowLocked() { 12589 boolean processingBroadcasts = false; 12590 for (BroadcastQueue q : mBroadcastQueues) { 12591 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12592 processingBroadcasts = true; 12593 } 12594 } 12595 return !processingBroadcasts 12596 && (mSleeping || (mMainStack.mResumedActivity != null && 12597 mMainStack.mResumedActivity.idle)); 12598 } 12599 12600 /** 12601 * Perform GCs on all processes that are waiting for it, but only 12602 * if things are idle. 12603 */ 12604 final void performAppGcsLocked() { 12605 final int N = mProcessesToGc.size(); 12606 if (N <= 0) { 12607 return; 12608 } 12609 if (canGcNowLocked()) { 12610 while (mProcessesToGc.size() > 0) { 12611 ProcessRecord proc = mProcessesToGc.remove(0); 12612 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12613 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12614 <= SystemClock.uptimeMillis()) { 12615 // To avoid spamming the system, we will GC processes one 12616 // at a time, waiting a few seconds between each. 12617 performAppGcLocked(proc); 12618 scheduleAppGcsLocked(); 12619 return; 12620 } else { 12621 // It hasn't been long enough since we last GCed this 12622 // process... put it in the list to wait for its time. 12623 addProcessToGcListLocked(proc); 12624 break; 12625 } 12626 } 12627 } 12628 12629 scheduleAppGcsLocked(); 12630 } 12631 } 12632 12633 /** 12634 * If all looks good, perform GCs on all processes waiting for them. 12635 */ 12636 final void performAppGcsIfAppropriateLocked() { 12637 if (canGcNowLocked()) { 12638 performAppGcsLocked(); 12639 return; 12640 } 12641 // Still not idle, wait some more. 12642 scheduleAppGcsLocked(); 12643 } 12644 12645 /** 12646 * Schedule the execution of all pending app GCs. 12647 */ 12648 final void scheduleAppGcsLocked() { 12649 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12650 12651 if (mProcessesToGc.size() > 0) { 12652 // Schedule a GC for the time to the next process. 12653 ProcessRecord proc = mProcessesToGc.get(0); 12654 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12655 12656 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12657 long now = SystemClock.uptimeMillis(); 12658 if (when < (now+GC_TIMEOUT)) { 12659 when = now + GC_TIMEOUT; 12660 } 12661 mHandler.sendMessageAtTime(msg, when); 12662 } 12663 } 12664 12665 /** 12666 * Add a process to the array of processes waiting to be GCed. Keeps the 12667 * list in sorted order by the last GC time. The process can't already be 12668 * on the list. 12669 */ 12670 final void addProcessToGcListLocked(ProcessRecord proc) { 12671 boolean added = false; 12672 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12673 if (mProcessesToGc.get(i).lastRequestedGc < 12674 proc.lastRequestedGc) { 12675 added = true; 12676 mProcessesToGc.add(i+1, proc); 12677 break; 12678 } 12679 } 12680 if (!added) { 12681 mProcessesToGc.add(0, proc); 12682 } 12683 } 12684 12685 /** 12686 * Set up to ask a process to GC itself. This will either do it 12687 * immediately, or put it on the list of processes to gc the next 12688 * time things are idle. 12689 */ 12690 final void scheduleAppGcLocked(ProcessRecord app) { 12691 long now = SystemClock.uptimeMillis(); 12692 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12693 return; 12694 } 12695 if (!mProcessesToGc.contains(app)) { 12696 addProcessToGcListLocked(app); 12697 scheduleAppGcsLocked(); 12698 } 12699 } 12700 12701 final void checkExcessivePowerUsageLocked(boolean doKills) { 12702 updateCpuStatsNow(); 12703 12704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12705 boolean doWakeKills = doKills; 12706 boolean doCpuKills = doKills; 12707 if (mLastPowerCheckRealtime == 0) { 12708 doWakeKills = false; 12709 } 12710 if (mLastPowerCheckUptime == 0) { 12711 doCpuKills = false; 12712 } 12713 if (stats.isScreenOn()) { 12714 doWakeKills = false; 12715 } 12716 final long curRealtime = SystemClock.elapsedRealtime(); 12717 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12718 final long curUptime = SystemClock.uptimeMillis(); 12719 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12720 mLastPowerCheckRealtime = curRealtime; 12721 mLastPowerCheckUptime = curUptime; 12722 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12723 doWakeKills = false; 12724 } 12725 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12726 doCpuKills = false; 12727 } 12728 int i = mLruProcesses.size(); 12729 while (i > 0) { 12730 i--; 12731 ProcessRecord app = mLruProcesses.get(i); 12732 if (!app.keeping) { 12733 long wtime; 12734 synchronized (stats) { 12735 wtime = stats.getProcessWakeTime(app.info.uid, 12736 app.pid, curRealtime); 12737 } 12738 long wtimeUsed = wtime - app.lastWakeTime; 12739 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12740 if (DEBUG_POWER) { 12741 StringBuilder sb = new StringBuilder(128); 12742 sb.append("Wake for "); 12743 app.toShortString(sb); 12744 sb.append(": over "); 12745 TimeUtils.formatDuration(realtimeSince, sb); 12746 sb.append(" used "); 12747 TimeUtils.formatDuration(wtimeUsed, sb); 12748 sb.append(" ("); 12749 sb.append((wtimeUsed*100)/realtimeSince); 12750 sb.append("%)"); 12751 Slog.i(TAG, sb.toString()); 12752 sb.setLength(0); 12753 sb.append("CPU for "); 12754 app.toShortString(sb); 12755 sb.append(": over "); 12756 TimeUtils.formatDuration(uptimeSince, sb); 12757 sb.append(" used "); 12758 TimeUtils.formatDuration(cputimeUsed, sb); 12759 sb.append(" ("); 12760 sb.append((cputimeUsed*100)/uptimeSince); 12761 sb.append("%)"); 12762 Slog.i(TAG, sb.toString()); 12763 } 12764 // If a process has held a wake lock for more 12765 // than 50% of the time during this period, 12766 // that sounds bad. Kill! 12767 if (doWakeKills && realtimeSince > 0 12768 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12769 synchronized (stats) { 12770 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12771 realtimeSince, wtimeUsed); 12772 } 12773 Slog.w(TAG, "Excessive wake lock in " + app.processName 12774 + " (pid " + app.pid + "): held " + wtimeUsed 12775 + " during " + realtimeSince); 12776 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12777 app.processName, app.setAdj, "excessive wake lock"); 12778 Process.killProcessQuiet(app.pid); 12779 } else if (doCpuKills && uptimeSince > 0 12780 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12781 synchronized (stats) { 12782 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12783 uptimeSince, cputimeUsed); 12784 } 12785 Slog.w(TAG, "Excessive CPU in " + app.processName 12786 + " (pid " + app.pid + "): used " + cputimeUsed 12787 + " during " + uptimeSince); 12788 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12789 app.processName, app.setAdj, "excessive cpu"); 12790 Process.killProcessQuiet(app.pid); 12791 } else { 12792 app.lastWakeTime = wtime; 12793 app.lastCpuTime = app.curCpuTime; 12794 } 12795 } 12796 } 12797 } 12798 12799 private final boolean updateOomAdjLocked( 12800 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 12801 app.hiddenAdj = hiddenAdj; 12802 12803 if (app.thread == null) { 12804 return false; 12805 } 12806 12807 final boolean wasKeeping = app.keeping; 12808 12809 boolean success = true; 12810 12811 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 12812 12813 if (app.curRawAdj != app.setRawAdj) { 12814 if (wasKeeping && !app.keeping) { 12815 // This app is no longer something we want to keep. Note 12816 // its current wake lock time to later know to kill it if 12817 // it is not behaving well. 12818 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12819 synchronized (stats) { 12820 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12821 app.pid, SystemClock.elapsedRealtime()); 12822 } 12823 app.lastCpuTime = app.curCpuTime; 12824 } 12825 12826 app.setRawAdj = app.curRawAdj; 12827 } 12828 12829 if (app.curAdj != app.setAdj) { 12830 if (Process.setOomAdj(app.pid, app.curAdj)) { 12831 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12832 TAG, "Set " + app.pid + " " + app.processName + 12833 " adj " + app.curAdj + ": " + app.adjType); 12834 app.setAdj = app.curAdj; 12835 } else { 12836 success = false; 12837 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12838 } 12839 } 12840 if (app.setSchedGroup != app.curSchedGroup) { 12841 app.setSchedGroup = app.curSchedGroup; 12842 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12843 "Setting process group of " + app.processName 12844 + " to " + app.curSchedGroup); 12845 if (app.waitingToKill != null && 12846 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12847 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12848 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12849 app.processName, app.setAdj, app.waitingToKill); 12850 app.killedBackground = true; 12851 Process.killProcessQuiet(app.pid); 12852 success = false; 12853 } else { 12854 if (true) { 12855 long oldId = Binder.clearCallingIdentity(); 12856 try { 12857 Process.setProcessGroup(app.pid, app.curSchedGroup); 12858 } catch (Exception e) { 12859 Slog.w(TAG, "Failed setting process group of " + app.pid 12860 + " to " + app.curSchedGroup); 12861 e.printStackTrace(); 12862 } finally { 12863 Binder.restoreCallingIdentity(oldId); 12864 } 12865 } else { 12866 if (app.thread != null) { 12867 try { 12868 app.thread.setSchedulingGroup(app.curSchedGroup); 12869 } catch (RemoteException e) { 12870 } 12871 } 12872 } 12873 } 12874 } 12875 return success; 12876 } 12877 12878 private final ActivityRecord resumedAppLocked() { 12879 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12880 if (resumedActivity == null || resumedActivity.app == null) { 12881 resumedActivity = mMainStack.mPausingActivity; 12882 if (resumedActivity == null || resumedActivity.app == null) { 12883 resumedActivity = mMainStack.topRunningActivityLocked(null); 12884 } 12885 } 12886 return resumedActivity; 12887 } 12888 12889 final boolean updateOomAdjLocked(ProcessRecord app) { 12890 final ActivityRecord TOP_ACT = resumedAppLocked(); 12891 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12892 int curAdj = app.curAdj; 12893 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12894 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12895 12896 mAdjSeq++; 12897 12898 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 12899 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12900 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12901 if (nowHidden != wasHidden) { 12902 // Changed to/from hidden state, so apps after it in the LRU 12903 // list may also be changed. 12904 updateOomAdjLocked(); 12905 } 12906 return success; 12907 } 12908 12909 final void updateOomAdjLocked() { 12910 final ActivityRecord TOP_ACT = resumedAppLocked(); 12911 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12912 12913 if (false) { 12914 RuntimeException e = new RuntimeException(); 12915 e.fillInStackTrace(); 12916 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12917 } 12918 12919 mAdjSeq++; 12920 mNewNumServiceProcs = 0; 12921 12922 // Let's determine how many processes we have running vs. 12923 // how many slots we have for background processes; we may want 12924 // to put multiple processes in a slot of there are enough of 12925 // them. 12926 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 12927 int factor = (mLruProcesses.size()-4)/numSlots; 12928 if (factor < 1) factor = 1; 12929 int step = 0; 12930 int numHidden = 0; 12931 int numTrimming = 0; 12932 12933 // First update the OOM adjustment for each of the 12934 // application processes based on their current state. 12935 int i = mLruProcesses.size(); 12936 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12937 while (i > 0) { 12938 i--; 12939 ProcessRecord app = mLruProcesses.get(i); 12940 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 12941 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 12942 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 12943 && app.curAdj == curHiddenAdj) { 12944 step++; 12945 if (step >= factor) { 12946 step = 0; 12947 curHiddenAdj++; 12948 } 12949 } 12950 if (!app.killedBackground) { 12951 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12952 numHidden++; 12953 if (numHidden > mProcessLimit) { 12954 Slog.i(TAG, "No longer want " + app.processName 12955 + " (pid " + app.pid + "): hidden #" + numHidden); 12956 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12957 app.processName, app.setAdj, "too many background"); 12958 app.killedBackground = true; 12959 Process.killProcessQuiet(app.pid); 12960 } 12961 } 12962 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 12963 // If this is an isolated process, and there are no 12964 // services running in it, then the process is no longer 12965 // needed. We agressively kill these because we can by 12966 // definition not re-use the same process again, and it is 12967 // good to avoid having whatever code was running in them 12968 // left sitting around after no longer needed. 12969 Slog.i(TAG, "Isolated process " + app.processName 12970 + " (pid " + app.pid + ") no longer needed"); 12971 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12972 app.processName, app.setAdj, "isolated not needed"); 12973 app.killedBackground = true; 12974 Process.killProcessQuiet(app.pid); 12975 } 12976 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12977 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12978 && !app.killedBackground) { 12979 numTrimming++; 12980 } 12981 } 12982 } 12983 12984 mNumServiceProcs = mNewNumServiceProcs; 12985 12986 // Now determine the memory trimming level of background processes. 12987 // Unfortunately we need to start at the back of the list to do this 12988 // properly. We only do this if the number of background apps we 12989 // are managing to keep around is less than half the maximum we desire; 12990 // if we are keeping a good number around, we'll let them use whatever 12991 // memory they want. 12992 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 12993 final int N = mLruProcesses.size(); 12994 factor = numTrimming/3; 12995 int minFactor = 2; 12996 if (mHomeProcess != null) minFactor++; 12997 if (mPreviousProcess != null) minFactor++; 12998 if (factor < minFactor) factor = minFactor; 12999 step = 0; 13000 int fgTrimLevel; 13001 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13002 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13003 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13004 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13005 } else { 13006 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13007 } 13008 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13009 for (i=0; i<N; i++) { 13010 ProcessRecord app = mLruProcesses.get(i); 13011 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13012 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13013 && !app.killedBackground) { 13014 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13015 try { 13016 app.thread.scheduleTrimMemory(curLevel); 13017 } catch (RemoteException e) { 13018 } 13019 if (false) { 13020 // For now we won't do this; our memory trimming seems 13021 // to be good enough at this point that destroying 13022 // activities causes more harm than good. 13023 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13024 && app != mHomeProcess && app != mPreviousProcess) { 13025 // Need to do this on its own message because the stack may not 13026 // be in a consistent state at this point. 13027 // For these apps we will also finish their activities 13028 // to help them free memory. 13029 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13030 } 13031 } 13032 } 13033 app.trimMemoryLevel = curLevel; 13034 step++; 13035 if (step >= factor) { 13036 step = 0; 13037 switch (curLevel) { 13038 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13039 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13040 break; 13041 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13042 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13043 break; 13044 } 13045 } 13046 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13047 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13048 && app.thread != null) { 13049 try { 13050 app.thread.scheduleTrimMemory( 13051 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13052 } catch (RemoteException e) { 13053 } 13054 } 13055 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13056 } else { 13057 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13058 && app.pendingUiClean) { 13059 // If this application is now in the background and it 13060 // had done UI, then give it the special trim level to 13061 // have it free UI resources. 13062 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13063 if (app.trimMemoryLevel < level && app.thread != null) { 13064 try { 13065 app.thread.scheduleTrimMemory(level); 13066 } catch (RemoteException e) { 13067 } 13068 } 13069 app.pendingUiClean = false; 13070 } 13071 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13072 try { 13073 app.thread.scheduleTrimMemory(fgTrimLevel); 13074 } catch (RemoteException e) { 13075 } 13076 } 13077 app.trimMemoryLevel = fgTrimLevel; 13078 } 13079 } 13080 } else { 13081 final int N = mLruProcesses.size(); 13082 for (i=0; i<N; i++) { 13083 ProcessRecord app = mLruProcesses.get(i); 13084 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13085 && app.pendingUiClean) { 13086 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13087 && app.thread != null) { 13088 try { 13089 app.thread.scheduleTrimMemory( 13090 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13091 } catch (RemoteException e) { 13092 } 13093 } 13094 app.pendingUiClean = false; 13095 } 13096 app.trimMemoryLevel = 0; 13097 } 13098 } 13099 13100 if (mAlwaysFinishActivities) { 13101 // Need to do this on its own message because the stack may not 13102 // be in a consistent state at this point. 13103 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13104 } 13105 } 13106 13107 final void trimApplications() { 13108 synchronized (this) { 13109 int i; 13110 13111 // First remove any unused application processes whose package 13112 // has been removed. 13113 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13114 final ProcessRecord app = mRemovedProcesses.get(i); 13115 if (app.activities.size() == 0 13116 && app.curReceiver == null && app.services.size() == 0) { 13117 Slog.i( 13118 TAG, "Exiting empty application process " 13119 + app.processName + " (" 13120 + (app.thread != null ? app.thread.asBinder() : null) 13121 + ")\n"); 13122 if (app.pid > 0 && app.pid != MY_PID) { 13123 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13124 app.processName, app.setAdj, "empty"); 13125 Process.killProcessQuiet(app.pid); 13126 } else { 13127 try { 13128 app.thread.scheduleExit(); 13129 } catch (Exception e) { 13130 // Ignore exceptions. 13131 } 13132 } 13133 cleanUpApplicationRecordLocked(app, false, true, -1); 13134 mRemovedProcesses.remove(i); 13135 13136 if (app.persistent) { 13137 if (app.persistent) { 13138 addAppLocked(app.info, false); 13139 } 13140 } 13141 } 13142 } 13143 13144 // Now update the oom adj for all processes. 13145 updateOomAdjLocked(); 13146 } 13147 } 13148 13149 /** This method sends the specified signal to each of the persistent apps */ 13150 public void signalPersistentProcesses(int sig) throws RemoteException { 13151 if (sig != Process.SIGNAL_USR1) { 13152 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13153 } 13154 13155 synchronized (this) { 13156 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13157 != PackageManager.PERMISSION_GRANTED) { 13158 throw new SecurityException("Requires permission " 13159 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13160 } 13161 13162 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13163 ProcessRecord r = mLruProcesses.get(i); 13164 if (r.thread != null && r.persistent) { 13165 Process.sendSignal(r.pid, sig); 13166 } 13167 } 13168 } 13169 } 13170 13171 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13172 if (proc == null || proc == mProfileProc) { 13173 proc = mProfileProc; 13174 path = mProfileFile; 13175 profileType = mProfileType; 13176 clearProfilerLocked(); 13177 } 13178 if (proc == null) { 13179 return; 13180 } 13181 try { 13182 proc.thread.profilerControl(false, path, null, profileType); 13183 } catch (RemoteException e) { 13184 throw new IllegalStateException("Process disappeared"); 13185 } 13186 } 13187 13188 private void clearProfilerLocked() { 13189 if (mProfileFd != null) { 13190 try { 13191 mProfileFd.close(); 13192 } catch (IOException e) { 13193 } 13194 } 13195 mProfileApp = null; 13196 mProfileProc = null; 13197 mProfileFile = null; 13198 mProfileType = 0; 13199 mAutoStopProfiler = false; 13200 } 13201 13202 public boolean profileControl(String process, boolean start, 13203 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13204 13205 try { 13206 synchronized (this) { 13207 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13208 // its own permission. 13209 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13210 != PackageManager.PERMISSION_GRANTED) { 13211 throw new SecurityException("Requires permission " 13212 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13213 } 13214 13215 if (start && fd == null) { 13216 throw new IllegalArgumentException("null fd"); 13217 } 13218 13219 ProcessRecord proc = null; 13220 if (process != null) { 13221 try { 13222 int pid = Integer.parseInt(process); 13223 synchronized (mPidsSelfLocked) { 13224 proc = mPidsSelfLocked.get(pid); 13225 } 13226 } catch (NumberFormatException e) { 13227 } 13228 13229 if (proc == null) { 13230 HashMap<String, SparseArray<ProcessRecord>> all 13231 = mProcessNames.getMap(); 13232 SparseArray<ProcessRecord> procs = all.get(process); 13233 if (procs != null && procs.size() > 0) { 13234 proc = procs.valueAt(0); 13235 } 13236 } 13237 } 13238 13239 if (start && (proc == null || proc.thread == null)) { 13240 throw new IllegalArgumentException("Unknown process: " + process); 13241 } 13242 13243 if (start) { 13244 stopProfilerLocked(null, null, 0); 13245 setProfileApp(proc.info, proc.processName, path, fd, false); 13246 mProfileProc = proc; 13247 mProfileType = profileType; 13248 try { 13249 fd = fd.dup(); 13250 } catch (IOException e) { 13251 fd = null; 13252 } 13253 proc.thread.profilerControl(start, path, fd, profileType); 13254 fd = null; 13255 mProfileFd = null; 13256 } else { 13257 stopProfilerLocked(proc, path, profileType); 13258 if (fd != null) { 13259 try { 13260 fd.close(); 13261 } catch (IOException e) { 13262 } 13263 } 13264 } 13265 13266 return true; 13267 } 13268 } catch (RemoteException e) { 13269 throw new IllegalStateException("Process disappeared"); 13270 } finally { 13271 if (fd != null) { 13272 try { 13273 fd.close(); 13274 } catch (IOException e) { 13275 } 13276 } 13277 } 13278 } 13279 13280 public boolean dumpHeap(String process, boolean managed, 13281 String path, ParcelFileDescriptor fd) throws RemoteException { 13282 13283 try { 13284 synchronized (this) { 13285 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13286 // its own permission (same as profileControl). 13287 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13288 != PackageManager.PERMISSION_GRANTED) { 13289 throw new SecurityException("Requires permission " 13290 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13291 } 13292 13293 if (fd == null) { 13294 throw new IllegalArgumentException("null fd"); 13295 } 13296 13297 ProcessRecord proc = null; 13298 try { 13299 int pid = Integer.parseInt(process); 13300 synchronized (mPidsSelfLocked) { 13301 proc = mPidsSelfLocked.get(pid); 13302 } 13303 } catch (NumberFormatException e) { 13304 } 13305 13306 if (proc == null) { 13307 HashMap<String, SparseArray<ProcessRecord>> all 13308 = mProcessNames.getMap(); 13309 SparseArray<ProcessRecord> procs = all.get(process); 13310 if (procs != null && procs.size() > 0) { 13311 proc = procs.valueAt(0); 13312 } 13313 } 13314 13315 if (proc == null || proc.thread == null) { 13316 throw new IllegalArgumentException("Unknown process: " + process); 13317 } 13318 13319 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13320 if (!isDebuggable) { 13321 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13322 throw new SecurityException("Process not debuggable: " + proc); 13323 } 13324 } 13325 13326 proc.thread.dumpHeap(managed, path, fd); 13327 fd = null; 13328 return true; 13329 } 13330 } catch (RemoteException e) { 13331 throw new IllegalStateException("Process disappeared"); 13332 } finally { 13333 if (fd != null) { 13334 try { 13335 fd.close(); 13336 } catch (IOException e) { 13337 } 13338 } 13339 } 13340 } 13341 13342 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13343 public void monitor() { 13344 synchronized (this) { } 13345 } 13346 13347 void onCoreSettingsChange(Bundle settings) { 13348 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13349 ProcessRecord processRecord = mLruProcesses.get(i); 13350 try { 13351 if (processRecord.thread != null) { 13352 processRecord.thread.setCoreSettings(settings); 13353 } 13354 } catch (RemoteException re) { 13355 /* ignore */ 13356 } 13357 } 13358 } 13359 13360 // Multi-user methods 13361 13362 public boolean switchUser(int userId) { 13363 final int callingUid = Binder.getCallingUid(); 13364 if (callingUid != 0 && callingUid != Process.myUid()) { 13365 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13366 return false; 13367 } 13368 if (mCurrentUserId == userId) 13369 return true; 13370 13371 synchronized (this) { 13372 // Check if user is already logged in, otherwise check if user exists first before 13373 // adding to the list of logged in users. 13374 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13375 if (!userExists(userId)) { 13376 return false; 13377 } 13378 mLoggedInUsers.append(userId, userId); 13379 } 13380 13381 mCurrentUserId = userId; 13382 boolean haveActivities = mMainStack.switchUser(userId); 13383 if (!haveActivities) { 13384 startHomeActivityLocked(userId); 13385 } 13386 13387 } 13388 13389 // Inform of user switch 13390 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13391 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 13392 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13393 13394 return true; 13395 } 13396 13397 @Override 13398 public UserInfo getCurrentUser() throws RemoteException { 13399 final int callingUid = Binder.getCallingUid(); 13400 if (callingUid != 0 && callingUid != Process.myUid()) { 13401 Slog.e(TAG, "Trying to get user from unauthorized app"); 13402 return null; 13403 } 13404 return getUserManager().getUserInfo(mCurrentUserId); 13405 } 13406 13407 private void onUserRemoved(Intent intent) { 13408 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 13409 if (extraUserId < 1) return; 13410 13411 // Kill all the processes for the user 13412 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13413 synchronized (this) { 13414 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13415 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13416 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13417 for (int i = 0; i < uids.size(); i++) { 13418 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 13419 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13420 } 13421 } 13422 } 13423 13424 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13425 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13426 false, false, true, true, extraUserId); 13427 } 13428 } 13429 } 13430 13431 private boolean userExists(int userId) { 13432 UserInfo user = getUserManager().getUserInfo(userId); 13433 return user != null; 13434 } 13435 13436 UserManager getUserManager() { 13437 if (mUserManager == null) { 13438 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13439 } 13440 return mUserManager; 13441 } 13442 13443 private void checkValidCaller(int uid, int userId) { 13444 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13445 13446 throw new SecurityException("Caller uid=" + uid 13447 + " is not privileged to communicate with user=" + userId); 13448 } 13449 13450 private int applyUserId(int uid, int userId) { 13451 return UserId.getUid(userId, uid); 13452 } 13453 13454 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13455 if (info == null) return null; 13456 ApplicationInfo newInfo = new ApplicationInfo(info); 13457 newInfo.uid = applyUserId(info.uid, userId); 13458 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13459 + info.packageName; 13460 return newInfo; 13461 } 13462 13463 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13464 if (aInfo == null 13465 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 13466 return aInfo; 13467 } 13468 13469 ActivityInfo info = new ActivityInfo(aInfo); 13470 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13471 return info; 13472 } 13473} 13474