ActivityManagerService.java revision 7d19e0242faac8017033dabb872cdf1542fa184c
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IThumbnailReceiver; 50import android.app.Instrumentation; 51import android.app.Notification; 52import android.app.NotificationManager; 53import android.app.PendingIntent; 54import android.app.Service; 55import android.app.backup.IBackupManager; 56import android.content.ActivityNotFoundException; 57import android.content.BroadcastReceiver; 58import android.content.ClipData; 59import android.content.ComponentCallbacks2; 60import android.content.ComponentName; 61import android.content.ContentProvider; 62import android.content.ContentResolver; 63import android.content.Context; 64import android.content.DialogInterface; 65import android.content.IContentProvider; 66import android.content.IIntentReceiver; 67import android.content.IIntentSender; 68import android.content.Intent; 69import android.content.IntentFilter; 70import android.content.IntentSender; 71import android.content.pm.ActivityInfo; 72import android.content.pm.ApplicationInfo; 73import android.content.pm.ConfigurationInfo; 74import android.content.pm.IPackageDataObserver; 75import android.content.pm.IPackageManager; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.PackageInfo; 78import android.content.pm.PackageManager; 79import android.content.pm.PackageManager.NameNotFoundException; 80import android.content.pm.PathPermission; 81import android.content.pm.ProviderInfo; 82import android.content.pm.ResolveInfo; 83import android.content.pm.ServiceInfo; 84import android.content.pm.UserInfo; 85import android.content.res.CompatibilityInfo; 86import android.content.res.Configuration; 87import android.graphics.Bitmap; 88import android.net.Proxy; 89import android.net.ProxyProperties; 90import android.net.Uri; 91import android.os.Binder; 92import android.os.Build; 93import android.os.Bundle; 94import android.os.Debug; 95import android.os.DropBoxManager; 96import android.os.Environment; 97import android.os.FileObserver; 98import android.os.FileUtils; 99import android.os.Handler; 100import android.os.IBinder; 101import android.os.IPermissionController; 102import android.os.Looper; 103import android.os.Message; 104import android.os.Parcel; 105import android.os.ParcelFileDescriptor; 106import android.os.Process; 107import android.os.RemoteCallbackList; 108import android.os.RemoteException; 109import android.os.ServiceManager; 110import android.os.StrictMode; 111import android.os.SystemClock; 112import android.os.SystemProperties; 113import android.os.UserId; 114import android.provider.Settings; 115import android.text.format.Time; 116import android.util.EventLog; 117import android.util.Log; 118import android.util.Pair; 119import android.util.PrintWriterPrinter; 120import android.util.Slog; 121import android.util.SparseArray; 122import android.util.SparseIntArray; 123import android.util.TimeUtils; 124import android.view.Gravity; 125import android.view.LayoutInflater; 126import android.view.View; 127import android.view.WindowManager; 128import android.view.WindowManagerPolicy; 129 130import java.io.BufferedInputStream; 131import java.io.BufferedOutputStream; 132import java.io.BufferedReader; 133import java.io.DataInputStream; 134import java.io.DataOutputStream; 135import java.io.File; 136import java.io.FileDescriptor; 137import java.io.FileInputStream; 138import java.io.FileNotFoundException; 139import java.io.FileOutputStream; 140import java.io.IOException; 141import java.io.InputStreamReader; 142import java.io.PrintWriter; 143import java.io.StringWriter; 144import java.lang.ref.WeakReference; 145import java.util.ArrayList; 146import java.util.Collection; 147import java.util.Collections; 148import java.util.Comparator; 149import java.util.HashMap; 150import java.util.HashSet; 151import java.util.Iterator; 152import java.util.List; 153import java.util.Locale; 154import java.util.Map; 155import java.util.Map.Entry; 156import java.util.Set; 157import java.util.concurrent.atomic.AtomicBoolean; 158import java.util.concurrent.atomic.AtomicLong; 159 160public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait until we timeout on key dispatching. 245 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 246 247 // How long we wait until we timeout on key dispatching during instrumentation. 248 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 249 250 static final int MY_PID = Process.myPid(); 251 252 static final String[] EMPTY_STRING_ARRAY = new String[0]; 253 254 public ActivityStack mMainStack; 255 256 private final boolean mHeadless; 257 258 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 259 // default actuion automatically. Important for devices without direct input 260 // devices. 261 private boolean mShowDialogs = true; 262 263 /** 264 * Description of a request to start a new activity, which has been held 265 * due to app switches being disabled. 266 */ 267 static class PendingActivityLaunch { 268 ActivityRecord r; 269 ActivityRecord sourceRecord; 270 int startFlags; 271 } 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 277 BroadcastQueue mFgBroadcastQueue; 278 BroadcastQueue mBgBroadcastQueue; 279 // Convenient for easy iteration over the queues. Foreground is first 280 // so that dispatch of foreground broadcasts gets precedence. 281 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 282 283 BroadcastQueue broadcastQueueForIntent(Intent intent) { 284 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 285 if (DEBUG_BACKGROUND_BROADCAST) { 286 Slog.i(TAG, "Broadcast intent " + intent + " on " 287 + (isFg ? "foreground" : "background") 288 + " queue"); 289 } 290 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 291 } 292 293 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 294 for (BroadcastQueue queue : mBroadcastQueues) { 295 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 296 if (r != null) { 297 return r; 298 } 299 } 300 return null; 301 } 302 303 /** 304 * Activity we have told the window manager to have key focus. 305 */ 306 ActivityRecord mFocusedActivity = null; 307 /** 308 * List of intents that were used to start the most recent tasks. 309 */ 310 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 311 312 /** 313 * Process management. 314 */ 315 final ProcessList mProcessList = new ProcessList(); 316 317 /** 318 * All of the applications we currently have running organized by name. 319 * The keys are strings of the application package name (as 320 * returned by the package manager), and the keys are ApplicationRecord 321 * objects. 322 */ 323 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 324 325 /** 326 * The currently running isolated processes. 327 */ 328 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 329 330 /** 331 * Counter for assigning isolated process uids, to avoid frequently reusing the 332 * same ones. 333 */ 334 int mNextIsolatedProcessUid = 0; 335 336 /** 337 * The currently running heavy-weight process, if any. 338 */ 339 ProcessRecord mHeavyWeightProcess = null; 340 341 /** 342 * The last time that various processes have crashed. 343 */ 344 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 345 346 /** 347 * Set of applications that we consider to be bad, and will reject 348 * incoming broadcasts from (which the user has no control over). 349 * Processes are added to this set when they have crashed twice within 350 * a minimum amount of time; they are removed from it when they are 351 * later restarted (hopefully due to some user action). The value is the 352 * time it was added to the list. 353 */ 354 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 355 356 /** 357 * All of the processes we currently have running organized by pid. 358 * The keys are the pid running the application. 359 * 360 * <p>NOTE: This object is protected by its own lock, NOT the global 361 * activity manager lock! 362 */ 363 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 364 365 /** 366 * All of the processes that have been forced to be foreground. The key 367 * is the pid of the caller who requested it (we hold a death 368 * link on it). 369 */ 370 abstract class ForegroundToken implements IBinder.DeathRecipient { 371 int pid; 372 IBinder token; 373 } 374 final SparseArray<ForegroundToken> mForegroundProcesses 375 = new SparseArray<ForegroundToken>(); 376 377 /** 378 * List of records for processes that someone had tried to start before the 379 * system was ready. We don't start them at that point, but ensure they 380 * are started by the time booting is complete. 381 */ 382 final ArrayList<ProcessRecord> mProcessesOnHold 383 = new ArrayList<ProcessRecord>(); 384 385 /** 386 * List of persistent applications that are in the process 387 * of being started. 388 */ 389 final ArrayList<ProcessRecord> mPersistentStartingProcesses 390 = new ArrayList<ProcessRecord>(); 391 392 /** 393 * Processes that are being forcibly torn down. 394 */ 395 final ArrayList<ProcessRecord> mRemovedProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of running applications, sorted by recent usage. 400 * The first entry in the list is the least recently used. 401 * It contains ApplicationRecord objects. This list does NOT include 402 * any persistent application records (since we never want to exit them). 403 */ 404 final ArrayList<ProcessRecord> mLruProcesses 405 = new ArrayList<ProcessRecord>(); 406 407 /** 408 * List of processes that should gc as soon as things are idle. 409 */ 410 final ArrayList<ProcessRecord> mProcessesToGc 411 = new ArrayList<ProcessRecord>(); 412 413 /** 414 * This is the process holding what we currently consider to be 415 * the "home" activity. 416 */ 417 ProcessRecord mHomeProcess; 418 419 /** 420 * This is the process holding the activity the user last visited that 421 * is in a different process from the one they are currently in. 422 */ 423 ProcessRecord mPreviousProcess; 424 425 /** 426 * The time at which the previous process was last visible. 427 */ 428 long mPreviousProcessVisibleTime; 429 430 /** 431 * Packages that the user has asked to have run in screen size 432 * compatibility mode instead of filling the screen. 433 */ 434 final CompatModePackages mCompatModePackages; 435 436 /** 437 * Set of PendingResultRecord objects that are currently active. 438 */ 439 final HashSet mPendingResultRecords = new HashSet(); 440 441 /** 442 * Set of IntentSenderRecord objects that are currently active. 443 */ 444 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 445 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 446 447 /** 448 * Fingerprints (hashCode()) of stack traces that we've 449 * already logged DropBox entries for. Guarded by itself. If 450 * something (rogue user app) forces this over 451 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 452 */ 453 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 454 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 455 456 /** 457 * Strict Mode background batched logging state. 458 * 459 * The string buffer is guarded by itself, and its lock is also 460 * used to determine if another batched write is already 461 * in-flight. 462 */ 463 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 464 465 /** 466 * Keeps track of all IIntentReceivers that have been registered for 467 * broadcasts. Hash keys are the receiver IBinder, hash value is 468 * a ReceiverList. 469 */ 470 final HashMap mRegisteredReceivers = new HashMap(); 471 472 /** 473 * Resolver for broadcast intents to registered receivers. 474 * Holds BroadcastFilter (subclass of IntentFilter). 475 */ 476 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 477 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 478 @Override 479 protected boolean allowFilterResult( 480 BroadcastFilter filter, List<BroadcastFilter> dest) { 481 IBinder target = filter.receiverList.receiver.asBinder(); 482 for (int i=dest.size()-1; i>=0; i--) { 483 if (dest.get(i).receiverList.receiver.asBinder() == target) { 484 return false; 485 } 486 } 487 return true; 488 } 489 490 @Override 491 protected BroadcastFilter[] newArray(int size) { 492 return new BroadcastFilter[size]; 493 } 494 495 @Override 496 protected String packageForFilter(BroadcastFilter filter) { 497 return filter.packageName; 498 } 499 }; 500 501 /** 502 * State of all active sticky broadcasts. Keys are the action of the 503 * sticky Intent, values are an ArrayList of all broadcasted intents with 504 * that action (which should usually be one). 505 */ 506 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 507 new HashMap<String, ArrayList<Intent>>(); 508 509 final ActiveServices mServices; 510 511 /** 512 * Backup/restore process management 513 */ 514 String mBackupAppName = null; 515 BackupRecord mBackupTarget = null; 516 517 /** 518 * List of PendingThumbnailsRecord objects of clients who are still 519 * waiting to receive all of the thumbnails for a task. 520 */ 521 final ArrayList mPendingThumbnails = new ArrayList(); 522 523 /** 524 * List of HistoryRecord objects that have been finished and must 525 * still report back to a pending thumbnail receiver. 526 */ 527 final ArrayList mCancelledThumbnails = new ArrayList(); 528 529 final ProviderMap mProviderMap = new ProviderMap(); 530 531 /** 532 * List of content providers who have clients waiting for them. The 533 * application is currently being launched and the provider will be 534 * removed from this list once it is published. 535 */ 536 final ArrayList<ContentProviderRecord> mLaunchingProviders 537 = new ArrayList<ContentProviderRecord>(); 538 539 /** 540 * Global set of specific Uri permissions that have been granted. 541 */ 542 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 543 = new SparseArray<HashMap<Uri, UriPermission>>(); 544 545 CoreSettingsObserver mCoreSettingsObserver; 546 547 /** 548 * Thread-local storage used to carry caller permissions over through 549 * indirect content-provider access. 550 * @see #ActivityManagerService.openContentUri() 551 */ 552 private class Identity { 553 public int pid; 554 public int uid; 555 556 Identity(int _pid, int _uid) { 557 pid = _pid; 558 uid = _uid; 559 } 560 } 561 562 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 563 564 /** 565 * All information we have collected about the runtime performance of 566 * any user id that can impact battery performance. 567 */ 568 final BatteryStatsService mBatteryStatsService; 569 570 /** 571 * information about component usage 572 */ 573 final UsageStatsService mUsageStatsService; 574 575 /** 576 * Current configuration information. HistoryRecord objects are given 577 * a reference to this object to indicate which configuration they are 578 * currently running in, so this object must be kept immutable. 579 */ 580 Configuration mConfiguration = new Configuration(); 581 582 /** 583 * Current sequencing integer of the configuration, for skipping old 584 * configurations. 585 */ 586 int mConfigurationSeq = 0; 587 588 /** 589 * Hardware-reported OpenGLES version. 590 */ 591 final int GL_ES_VERSION; 592 593 /** 594 * List of initialization arguments to pass to all processes when binding applications to them. 595 * For example, references to the commonly used services. 596 */ 597 HashMap<String, IBinder> mAppBindArgs; 598 599 /** 600 * Temporary to avoid allocations. Protected by main lock. 601 */ 602 final StringBuilder mStringBuilder = new StringBuilder(256); 603 604 /** 605 * Used to control how we initialize the service. 606 */ 607 boolean mStartRunning = false; 608 ComponentName mTopComponent; 609 String mTopAction; 610 String mTopData; 611 boolean mProcessesReady = false; 612 boolean mSystemReady = false; 613 boolean mBooting = false; 614 boolean mWaitingUpdate = false; 615 boolean mDidUpdate = false; 616 boolean mOnBattery = false; 617 boolean mLaunchWarningShown = false; 618 619 Context mContext; 620 621 int mFactoryTest; 622 623 boolean mCheckedForSetup; 624 625 /** 626 * The time at which we will allow normal application switches again, 627 * after a call to {@link #stopAppSwitches()}. 628 */ 629 long mAppSwitchesAllowedTime; 630 631 /** 632 * This is set to true after the first switch after mAppSwitchesAllowedTime 633 * is set; any switches after that will clear the time. 634 */ 635 boolean mDidAppSwitch; 636 637 /** 638 * Last time (in realtime) at which we checked for power usage. 639 */ 640 long mLastPowerCheckRealtime; 641 642 /** 643 * Last time (in uptime) at which we checked for power usage. 644 */ 645 long mLastPowerCheckUptime; 646 647 /** 648 * Set while we are wanting to sleep, to prevent any 649 * activities from being started/resumed. 650 */ 651 boolean mSleeping = false; 652 653 /** 654 * State of external calls telling us if the device is asleep. 655 */ 656 boolean mWentToSleep = false; 657 658 /** 659 * State of external call telling us if the lock screen is shown. 660 */ 661 boolean mLockScreenShown = false; 662 663 /** 664 * Set if we are shutting down the system, similar to sleeping. 665 */ 666 boolean mShuttingDown = false; 667 668 /** 669 * Task identifier that activities are currently being started 670 * in. Incremented each time a new task is created. 671 * todo: Replace this with a TokenSpace class that generates non-repeating 672 * integers that won't wrap. 673 */ 674 int mCurTask = 1; 675 676 /** 677 * Current sequence id for oom_adj computation traversal. 678 */ 679 int mAdjSeq = 0; 680 681 /** 682 * Current sequence id for process LRU updating. 683 */ 684 int mLruSeq = 0; 685 686 /** 687 * Keep track of the number of service processes we last found, to 688 * determine on the next iteration which should be B services. 689 */ 690 int mNumServiceProcs = 0; 691 int mNewNumServiceProcs = 0; 692 693 /** 694 * System monitoring: number of processes that died since the last 695 * N procs were started. 696 */ 697 int[] mProcDeaths = new int[20]; 698 699 /** 700 * This is set if we had to do a delayed dexopt of an app before launching 701 * it, to increasing the ANR timeouts in that case. 702 */ 703 boolean mDidDexOpt; 704 705 String mDebugApp = null; 706 boolean mWaitForDebugger = false; 707 boolean mDebugTransient = false; 708 String mOrigDebugApp = null; 709 boolean mOrigWaitForDebugger = false; 710 boolean mAlwaysFinishActivities = false; 711 IActivityController mController = null; 712 String mProfileApp = null; 713 ProcessRecord mProfileProc = null; 714 String mProfileFile; 715 ParcelFileDescriptor mProfileFd; 716 int mProfileType = 0; 717 boolean mAutoStopProfiler = false; 718 String mOpenGlTraceApp = null; 719 720 static class ProcessChangeItem { 721 static final int CHANGE_ACTIVITIES = 1<<0; 722 static final int CHANGE_IMPORTANCE= 1<<1; 723 int changes; 724 int uid; 725 int pid; 726 int importance; 727 boolean foregroundActivities; 728 } 729 730 final RemoteCallbackList<IProcessObserver> mProcessObservers 731 = new RemoteCallbackList<IProcessObserver>(); 732 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 733 734 final ArrayList<ProcessChangeItem> mPendingProcessChanges 735 = new ArrayList<ProcessChangeItem>(); 736 final ArrayList<ProcessChangeItem> mAvailProcessChanges 737 = new ArrayList<ProcessChangeItem>(); 738 739 /** 740 * Callback of last caller to {@link #requestPss}. 741 */ 742 Runnable mRequestPssCallback; 743 744 /** 745 * Remaining processes for which we are waiting results from the last 746 * call to {@link #requestPss}. 747 */ 748 final ArrayList<ProcessRecord> mRequestPssList 749 = new ArrayList<ProcessRecord>(); 750 751 /** 752 * Runtime statistics collection thread. This object's lock is used to 753 * protect all related state. 754 */ 755 final Thread mProcessStatsThread; 756 757 /** 758 * Used to collect process stats when showing not responding dialog. 759 * Protected by mProcessStatsThread. 760 */ 761 final ProcessStats mProcessStats = new ProcessStats( 762 MONITOR_THREAD_CPU_USAGE); 763 final AtomicLong mLastCpuTime = new AtomicLong(0); 764 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 765 766 long mLastWriteTime = 0; 767 768 /** 769 * Set to true after the system has finished booting. 770 */ 771 boolean mBooted = false; 772 773 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 774 int mProcessLimitOverride = -1; 775 776 WindowManagerService mWindowManager; 777 778 static ActivityManagerService mSelf; 779 static ActivityThread mSystemThread; 780 781 private final class AppDeathRecipient implements IBinder.DeathRecipient { 782 final ProcessRecord mApp; 783 final int mPid; 784 final IApplicationThread mAppThread; 785 786 AppDeathRecipient(ProcessRecord app, int pid, 787 IApplicationThread thread) { 788 if (localLOGV) Slog.v( 789 TAG, "New death recipient " + this 790 + " for thread " + thread.asBinder()); 791 mApp = app; 792 mPid = pid; 793 mAppThread = thread; 794 } 795 796 public void binderDied() { 797 if (localLOGV) Slog.v( 798 TAG, "Death received in " + this 799 + " for thread " + mAppThread.asBinder()); 800 synchronized(ActivityManagerService.this) { 801 appDiedLocked(mApp, mPid, mAppThread); 802 } 803 } 804 } 805 806 static final int SHOW_ERROR_MSG = 1; 807 static final int SHOW_NOT_RESPONDING_MSG = 2; 808 static final int SHOW_FACTORY_ERROR_MSG = 3; 809 static final int UPDATE_CONFIGURATION_MSG = 4; 810 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 811 static final int WAIT_FOR_DEBUGGER_MSG = 6; 812 static final int SERVICE_TIMEOUT_MSG = 12; 813 static final int UPDATE_TIME_ZONE = 13; 814 static final int SHOW_UID_ERROR_MSG = 14; 815 static final int IM_FEELING_LUCKY_MSG = 15; 816 static final int PROC_START_TIMEOUT_MSG = 20; 817 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 818 static final int KILL_APPLICATION_MSG = 22; 819 static final int FINALIZE_PENDING_INTENT_MSG = 23; 820 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 821 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 822 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 823 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 824 static final int CLEAR_DNS_CACHE = 28; 825 static final int UPDATE_HTTP_PROXY = 29; 826 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 827 static final int DISPATCH_PROCESSES_CHANGED = 31; 828 static final int DISPATCH_PROCESS_DIED = 32; 829 static final int REPORT_MEM_USAGE = 33; 830 831 static final int FIRST_ACTIVITY_STACK_MSG = 100; 832 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 833 static final int FIRST_COMPAT_MODE_MSG = 300; 834 835 AlertDialog mUidAlert; 836 CompatModeDialog mCompatModeDialog; 837 long mLastMemUsageReportTime = 0; 838 839 final Handler mHandler = new Handler() { 840 //public Handler() { 841 // if (localLOGV) Slog.v(TAG, "Handler started!"); 842 //} 843 844 public void handleMessage(Message msg) { 845 switch (msg.what) { 846 case SHOW_ERROR_MSG: { 847 HashMap data = (HashMap) msg.obj; 848 synchronized (ActivityManagerService.this) { 849 ProcessRecord proc = (ProcessRecord)data.get("app"); 850 if (proc != null && proc.crashDialog != null) { 851 Slog.e(TAG, "App already has crash dialog: " + proc); 852 return; 853 } 854 AppErrorResult res = (AppErrorResult) data.get("result"); 855 if (mShowDialogs && !mSleeping && !mShuttingDown) { 856 Dialog d = new AppErrorDialog(mContext, res, proc); 857 d.show(); 858 proc.crashDialog = d; 859 } else { 860 // The device is asleep, so just pretend that the user 861 // saw a crash dialog and hit "force quit". 862 res.set(0); 863 } 864 } 865 866 ensureBootCompleted(); 867 } break; 868 case SHOW_NOT_RESPONDING_MSG: { 869 synchronized (ActivityManagerService.this) { 870 HashMap data = (HashMap) msg.obj; 871 ProcessRecord proc = (ProcessRecord)data.get("app"); 872 if (proc != null && proc.anrDialog != null) { 873 Slog.e(TAG, "App already has anr dialog: " + proc); 874 return; 875 } 876 877 Intent intent = new Intent("android.intent.action.ANR"); 878 if (!mProcessesReady) { 879 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 880 | Intent.FLAG_RECEIVER_FOREGROUND); 881 } 882 broadcastIntentLocked(null, null, intent, 883 null, null, 0, null, null, null, 884 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 885 886 if (mShowDialogs) { 887 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 888 mContext, proc, (ActivityRecord)data.get("activity")); 889 d.show(); 890 proc.anrDialog = d; 891 } else { 892 // Just kill the app if there is no dialog to be shown. 893 killAppAtUsersRequest(proc, null); 894 } 895 } 896 897 ensureBootCompleted(); 898 } break; 899 case SHOW_STRICT_MODE_VIOLATION_MSG: { 900 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 901 synchronized (ActivityManagerService.this) { 902 ProcessRecord proc = (ProcessRecord) data.get("app"); 903 if (proc == null) { 904 Slog.e(TAG, "App not found when showing strict mode dialog."); 905 break; 906 } 907 if (proc.crashDialog != null) { 908 Slog.e(TAG, "App already has strict mode dialog: " + proc); 909 return; 910 } 911 AppErrorResult res = (AppErrorResult) data.get("result"); 912 if (mShowDialogs && !mSleeping && !mShuttingDown) { 913 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 914 d.show(); 915 proc.crashDialog = d; 916 } else { 917 // The device is asleep, so just pretend that the user 918 // saw a crash dialog and hit "force quit". 919 res.set(0); 920 } 921 } 922 ensureBootCompleted(); 923 } break; 924 case SHOW_FACTORY_ERROR_MSG: { 925 Dialog d = new FactoryErrorDialog( 926 mContext, msg.getData().getCharSequence("msg")); 927 d.show(); 928 ensureBootCompleted(); 929 } break; 930 case UPDATE_CONFIGURATION_MSG: { 931 final ContentResolver resolver = mContext.getContentResolver(); 932 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 933 } break; 934 case GC_BACKGROUND_PROCESSES_MSG: { 935 synchronized (ActivityManagerService.this) { 936 performAppGcsIfAppropriateLocked(); 937 } 938 } break; 939 case WAIT_FOR_DEBUGGER_MSG: { 940 synchronized (ActivityManagerService.this) { 941 ProcessRecord app = (ProcessRecord)msg.obj; 942 if (msg.arg1 != 0) { 943 if (!app.waitedForDebugger) { 944 Dialog d = new AppWaitingForDebuggerDialog( 945 ActivityManagerService.this, 946 mContext, app); 947 app.waitDialog = d; 948 app.waitedForDebugger = true; 949 d.show(); 950 } 951 } else { 952 if (app.waitDialog != null) { 953 app.waitDialog.dismiss(); 954 app.waitDialog = null; 955 } 956 } 957 } 958 } break; 959 case SERVICE_TIMEOUT_MSG: { 960 if (mDidDexOpt) { 961 mDidDexOpt = false; 962 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 963 nmsg.obj = msg.obj; 964 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 965 return; 966 } 967 mServices.serviceTimeout((ProcessRecord)msg.obj); 968 } break; 969 case UPDATE_TIME_ZONE: { 970 synchronized (ActivityManagerService.this) { 971 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 972 ProcessRecord r = mLruProcesses.get(i); 973 if (r.thread != null) { 974 try { 975 r.thread.updateTimeZone(); 976 } catch (RemoteException ex) { 977 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 978 } 979 } 980 } 981 } 982 } break; 983 case CLEAR_DNS_CACHE: { 984 synchronized (ActivityManagerService.this) { 985 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 986 ProcessRecord r = mLruProcesses.get(i); 987 if (r.thread != null) { 988 try { 989 r.thread.clearDnsCache(); 990 } catch (RemoteException ex) { 991 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 992 } 993 } 994 } 995 } 996 } break; 997 case UPDATE_HTTP_PROXY: { 998 ProxyProperties proxy = (ProxyProperties)msg.obj; 999 String host = ""; 1000 String port = ""; 1001 String exclList = ""; 1002 if (proxy != null) { 1003 host = proxy.getHost(); 1004 port = Integer.toString(proxy.getPort()); 1005 exclList = proxy.getExclusionList(); 1006 } 1007 synchronized (ActivityManagerService.this) { 1008 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1009 ProcessRecord r = mLruProcesses.get(i); 1010 if (r.thread != null) { 1011 try { 1012 r.thread.setHttpProxy(host, port, exclList); 1013 } catch (RemoteException ex) { 1014 Slog.w(TAG, "Failed to update http proxy for: " + 1015 r.info.processName); 1016 } 1017 } 1018 } 1019 } 1020 } break; 1021 case SHOW_UID_ERROR_MSG: { 1022 String title = "System UIDs Inconsistent"; 1023 String text = "UIDs on the system are inconsistent, you need to wipe your" 1024 + " data partition or your device will be unstable."; 1025 Log.e(TAG, title + ": " + text); 1026 if (mShowDialogs) { 1027 // XXX This is a temporary dialog, no need to localize. 1028 AlertDialog d = new BaseErrorDialog(mContext); 1029 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1030 d.setCancelable(false); 1031 d.setTitle(title); 1032 d.setMessage(text); 1033 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1034 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1035 mUidAlert = d; 1036 d.show(); 1037 } 1038 } break; 1039 case IM_FEELING_LUCKY_MSG: { 1040 if (mUidAlert != null) { 1041 mUidAlert.dismiss(); 1042 mUidAlert = null; 1043 } 1044 } break; 1045 case PROC_START_TIMEOUT_MSG: { 1046 if (mDidDexOpt) { 1047 mDidDexOpt = false; 1048 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1049 nmsg.obj = msg.obj; 1050 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1051 return; 1052 } 1053 ProcessRecord app = (ProcessRecord)msg.obj; 1054 synchronized (ActivityManagerService.this) { 1055 processStartTimedOutLocked(app); 1056 } 1057 } break; 1058 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1059 synchronized (ActivityManagerService.this) { 1060 doPendingActivityLaunchesLocked(true); 1061 } 1062 } break; 1063 case KILL_APPLICATION_MSG: { 1064 synchronized (ActivityManagerService.this) { 1065 int uid = msg.arg1; 1066 boolean restart = (msg.arg2 == 1); 1067 String pkg = (String) msg.obj; 1068 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1069 UserId.getUserId(uid)); 1070 } 1071 } break; 1072 case FINALIZE_PENDING_INTENT_MSG: { 1073 ((PendingIntentRecord)msg.obj).completeFinalize(); 1074 } break; 1075 case POST_HEAVY_NOTIFICATION_MSG: { 1076 INotificationManager inm = NotificationManager.getService(); 1077 if (inm == null) { 1078 return; 1079 } 1080 1081 ActivityRecord root = (ActivityRecord)msg.obj; 1082 ProcessRecord process = root.app; 1083 if (process == null) { 1084 return; 1085 } 1086 1087 try { 1088 Context context = mContext.createPackageContext(process.info.packageName, 0); 1089 String text = mContext.getString(R.string.heavy_weight_notification, 1090 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1091 Notification notification = new Notification(); 1092 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1093 notification.when = 0; 1094 notification.flags = Notification.FLAG_ONGOING_EVENT; 1095 notification.tickerText = text; 1096 notification.defaults = 0; // please be quiet 1097 notification.sound = null; 1098 notification.vibrate = null; 1099 notification.setLatestEventInfo(context, text, 1100 mContext.getText(R.string.heavy_weight_notification_detail), 1101 PendingIntent.getActivity(mContext, 0, root.intent, 1102 PendingIntent.FLAG_CANCEL_CURRENT)); 1103 1104 try { 1105 int[] outId = new int[1]; 1106 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1107 notification, outId); 1108 } catch (RuntimeException e) { 1109 Slog.w(ActivityManagerService.TAG, 1110 "Error showing notification for heavy-weight app", e); 1111 } catch (RemoteException e) { 1112 } 1113 } catch (NameNotFoundException e) { 1114 Slog.w(TAG, "Unable to create context for heavy notification", e); 1115 } 1116 } break; 1117 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1118 INotificationManager inm = NotificationManager.getService(); 1119 if (inm == null) { 1120 return; 1121 } 1122 try { 1123 inm.cancelNotification("android", 1124 R.string.heavy_weight_notification); 1125 } catch (RuntimeException e) { 1126 Slog.w(ActivityManagerService.TAG, 1127 "Error canceling notification for service", e); 1128 } catch (RemoteException e) { 1129 } 1130 } break; 1131 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1132 synchronized (ActivityManagerService.this) { 1133 checkExcessivePowerUsageLocked(true); 1134 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1135 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1136 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1137 } 1138 } break; 1139 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1140 synchronized (ActivityManagerService.this) { 1141 ActivityRecord ar = (ActivityRecord)msg.obj; 1142 if (mCompatModeDialog != null) { 1143 if (mCompatModeDialog.mAppInfo.packageName.equals( 1144 ar.info.applicationInfo.packageName)) { 1145 return; 1146 } 1147 mCompatModeDialog.dismiss(); 1148 mCompatModeDialog = null; 1149 } 1150 if (ar != null && false) { 1151 if (mCompatModePackages.getPackageAskCompatModeLocked( 1152 ar.packageName)) { 1153 int mode = mCompatModePackages.computeCompatModeLocked( 1154 ar.info.applicationInfo); 1155 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1156 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1157 mCompatModeDialog = new CompatModeDialog( 1158 ActivityManagerService.this, mContext, 1159 ar.info.applicationInfo); 1160 mCompatModeDialog.show(); 1161 } 1162 } 1163 } 1164 } 1165 break; 1166 } 1167 case DISPATCH_PROCESSES_CHANGED: { 1168 dispatchProcessesChanged(); 1169 break; 1170 } 1171 case DISPATCH_PROCESS_DIED: { 1172 final int pid = msg.arg1; 1173 final int uid = msg.arg2; 1174 dispatchProcessDied(pid, uid); 1175 break; 1176 } 1177 case REPORT_MEM_USAGE: { 1178 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1179 if (!isDebuggable) { 1180 return; 1181 } 1182 synchronized (ActivityManagerService.this) { 1183 long now = SystemClock.uptimeMillis(); 1184 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1185 // Don't report more than every 5 minutes to somewhat 1186 // avoid spamming. 1187 return; 1188 } 1189 mLastMemUsageReportTime = now; 1190 } 1191 Thread thread = new Thread() { 1192 @Override public void run() { 1193 StringBuilder dropBuilder = new StringBuilder(1024); 1194 StringBuilder logBuilder = new StringBuilder(1024); 1195 StringWriter oomSw = new StringWriter(); 1196 PrintWriter oomPw = new PrintWriter(oomSw); 1197 StringWriter catSw = new StringWriter(); 1198 PrintWriter catPw = new PrintWriter(catSw); 1199 String[] emptyArgs = new String[] { }; 1200 StringBuilder tag = new StringBuilder(128); 1201 StringBuilder stack = new StringBuilder(128); 1202 tag.append("Low on memory -- "); 1203 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1204 tag, stack); 1205 dropBuilder.append(stack); 1206 dropBuilder.append('\n'); 1207 dropBuilder.append('\n'); 1208 String oomString = oomSw.toString(); 1209 dropBuilder.append(oomString); 1210 dropBuilder.append('\n'); 1211 logBuilder.append(oomString); 1212 try { 1213 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1214 "procrank", }); 1215 final InputStreamReader converter = new InputStreamReader( 1216 proc.getInputStream()); 1217 BufferedReader in = new BufferedReader(converter); 1218 String line; 1219 while (true) { 1220 line = in.readLine(); 1221 if (line == null) { 1222 break; 1223 } 1224 if (line.length() > 0) { 1225 logBuilder.append(line); 1226 logBuilder.append('\n'); 1227 } 1228 dropBuilder.append(line); 1229 dropBuilder.append('\n'); 1230 } 1231 converter.close(); 1232 } catch (IOException e) { 1233 } 1234 synchronized (ActivityManagerService.this) { 1235 catPw.println(); 1236 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1237 catPw.println(); 1238 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1239 false, false, null); 1240 catPw.println(); 1241 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1242 } 1243 dropBuilder.append(catSw.toString()); 1244 addErrorToDropBox("lowmem", null, "system_server", null, 1245 null, tag.toString(), dropBuilder.toString(), null, null); 1246 Slog.i(TAG, logBuilder.toString()); 1247 synchronized (ActivityManagerService.this) { 1248 long now = SystemClock.uptimeMillis(); 1249 if (mLastMemUsageReportTime < now) { 1250 mLastMemUsageReportTime = now; 1251 } 1252 } 1253 } 1254 }; 1255 thread.start(); 1256 break; 1257 } 1258 } 1259 } 1260 }; 1261 1262 public static void setSystemProcess() { 1263 try { 1264 ActivityManagerService m = mSelf; 1265 1266 ServiceManager.addService("activity", m, true); 1267 ServiceManager.addService("meminfo", new MemBinder(m)); 1268 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1269 ServiceManager.addService("dbinfo", new DbBinder(m)); 1270 if (MONITOR_CPU_USAGE) { 1271 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1272 } 1273 ServiceManager.addService("permission", new PermissionController(m)); 1274 1275 ApplicationInfo info = 1276 mSelf.mContext.getPackageManager().getApplicationInfo( 1277 "android", STOCK_PM_FLAGS); 1278 mSystemThread.installSystemApplicationInfo(info); 1279 1280 synchronized (mSelf) { 1281 ProcessRecord app = mSelf.newProcessRecordLocked( 1282 mSystemThread.getApplicationThread(), info, 1283 info.processName, false); 1284 app.persistent = true; 1285 app.pid = MY_PID; 1286 app.maxAdj = ProcessList.SYSTEM_ADJ; 1287 mSelf.mProcessNames.put(app.processName, app.uid, app); 1288 synchronized (mSelf.mPidsSelfLocked) { 1289 mSelf.mPidsSelfLocked.put(app.pid, app); 1290 } 1291 mSelf.updateLruProcessLocked(app, true, true); 1292 } 1293 } catch (PackageManager.NameNotFoundException e) { 1294 throw new RuntimeException( 1295 "Unable to find android system package", e); 1296 } 1297 } 1298 1299 public void setWindowManager(WindowManagerService wm) { 1300 mWindowManager = wm; 1301 } 1302 1303 public static final Context main(int factoryTest) { 1304 AThread thr = new AThread(); 1305 thr.start(); 1306 1307 synchronized (thr) { 1308 while (thr.mService == null) { 1309 try { 1310 thr.wait(); 1311 } catch (InterruptedException e) { 1312 } 1313 } 1314 } 1315 1316 ActivityManagerService m = thr.mService; 1317 mSelf = m; 1318 ActivityThread at = ActivityThread.systemMain(); 1319 mSystemThread = at; 1320 Context context = at.getSystemContext(); 1321 context.setTheme(android.R.style.Theme_Holo); 1322 m.mContext = context; 1323 m.mFactoryTest = factoryTest; 1324 m.mMainStack = new ActivityStack(m, context, true); 1325 1326 m.mBatteryStatsService.publish(context); 1327 m.mUsageStatsService.publish(context); 1328 1329 synchronized (thr) { 1330 thr.mReady = true; 1331 thr.notifyAll(); 1332 } 1333 1334 m.startRunning(null, null, null, null); 1335 1336 return context; 1337 } 1338 1339 public static ActivityManagerService self() { 1340 return mSelf; 1341 } 1342 1343 static class AThread extends Thread { 1344 ActivityManagerService mService; 1345 boolean mReady = false; 1346 1347 public AThread() { 1348 super("ActivityManager"); 1349 } 1350 1351 public void run() { 1352 Looper.prepare(); 1353 1354 android.os.Process.setThreadPriority( 1355 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1356 android.os.Process.setCanSelfBackground(false); 1357 1358 ActivityManagerService m = new ActivityManagerService(); 1359 1360 synchronized (this) { 1361 mService = m; 1362 notifyAll(); 1363 } 1364 1365 synchronized (this) { 1366 while (!mReady) { 1367 try { 1368 wait(); 1369 } catch (InterruptedException e) { 1370 } 1371 } 1372 } 1373 1374 // For debug builds, log event loop stalls to dropbox for analysis. 1375 if (StrictMode.conditionallyEnableDebugLogging()) { 1376 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1377 } 1378 1379 Looper.loop(); 1380 } 1381 } 1382 1383 static class MemBinder extends Binder { 1384 ActivityManagerService mActivityManagerService; 1385 MemBinder(ActivityManagerService activityManagerService) { 1386 mActivityManagerService = activityManagerService; 1387 } 1388 1389 @Override 1390 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1391 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1392 != PackageManager.PERMISSION_GRANTED) { 1393 pw.println("Permission Denial: can't dump meminfo from from pid=" 1394 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1395 + " without permission " + android.Manifest.permission.DUMP); 1396 return; 1397 } 1398 1399 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1400 false, null, null, null); 1401 } 1402 } 1403 1404 static class GraphicsBinder extends Binder { 1405 ActivityManagerService mActivityManagerService; 1406 GraphicsBinder(ActivityManagerService activityManagerService) { 1407 mActivityManagerService = activityManagerService; 1408 } 1409 1410 @Override 1411 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1412 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1413 != PackageManager.PERMISSION_GRANTED) { 1414 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1415 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1416 + " without permission " + android.Manifest.permission.DUMP); 1417 return; 1418 } 1419 1420 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1421 } 1422 } 1423 1424 static class DbBinder extends Binder { 1425 ActivityManagerService mActivityManagerService; 1426 DbBinder(ActivityManagerService activityManagerService) { 1427 mActivityManagerService = activityManagerService; 1428 } 1429 1430 @Override 1431 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1432 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1433 != PackageManager.PERMISSION_GRANTED) { 1434 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1435 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1436 + " without permission " + android.Manifest.permission.DUMP); 1437 return; 1438 } 1439 1440 mActivityManagerService.dumpDbInfo(fd, pw, args); 1441 } 1442 } 1443 1444 static class CpuBinder extends Binder { 1445 ActivityManagerService mActivityManagerService; 1446 CpuBinder(ActivityManagerService activityManagerService) { 1447 mActivityManagerService = activityManagerService; 1448 } 1449 1450 @Override 1451 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1452 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1453 != PackageManager.PERMISSION_GRANTED) { 1454 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1455 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1456 + " without permission " + android.Manifest.permission.DUMP); 1457 return; 1458 } 1459 1460 synchronized (mActivityManagerService.mProcessStatsThread) { 1461 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1462 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1463 SystemClock.uptimeMillis())); 1464 } 1465 } 1466 } 1467 1468 private ActivityManagerService() { 1469 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1470 1471 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1472 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1473 mBroadcastQueues[0] = mFgBroadcastQueue; 1474 mBroadcastQueues[1] = mBgBroadcastQueue; 1475 1476 mServices = new ActiveServices(this); 1477 1478 File dataDir = Environment.getDataDirectory(); 1479 File systemDir = new File(dataDir, "system"); 1480 systemDir.mkdirs(); 1481 mBatteryStatsService = new BatteryStatsService(new File( 1482 systemDir, "batterystats.bin").toString()); 1483 mBatteryStatsService.getActiveStatistics().readLocked(); 1484 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1485 mOnBattery = DEBUG_POWER ? true 1486 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1487 mBatteryStatsService.getActiveStatistics().setCallback(this); 1488 1489 mUsageStatsService = new UsageStatsService(new File( 1490 systemDir, "usagestats").toString()); 1491 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1492 1493 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1494 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1495 1496 mConfiguration.setToDefaults(); 1497 mConfiguration.locale = Locale.getDefault(); 1498 mConfigurationSeq = mConfiguration.seq = 1; 1499 mProcessStats.init(); 1500 1501 mCompatModePackages = new CompatModePackages(this, systemDir); 1502 1503 // Add ourself to the Watchdog monitors. 1504 Watchdog.getInstance().addMonitor(this); 1505 1506 mProcessStatsThread = new Thread("ProcessStats") { 1507 public void run() { 1508 while (true) { 1509 try { 1510 try { 1511 synchronized(this) { 1512 final long now = SystemClock.uptimeMillis(); 1513 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1514 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1515 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1516 // + ", write delay=" + nextWriteDelay); 1517 if (nextWriteDelay < nextCpuDelay) { 1518 nextCpuDelay = nextWriteDelay; 1519 } 1520 if (nextCpuDelay > 0) { 1521 mProcessStatsMutexFree.set(true); 1522 this.wait(nextCpuDelay); 1523 } 1524 } 1525 } catch (InterruptedException e) { 1526 } 1527 updateCpuStatsNow(); 1528 } catch (Exception e) { 1529 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1530 } 1531 } 1532 } 1533 }; 1534 mProcessStatsThread.start(); 1535 } 1536 1537 @Override 1538 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1539 throws RemoteException { 1540 if (code == SYSPROPS_TRANSACTION) { 1541 // We need to tell all apps about the system property change. 1542 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1543 synchronized(this) { 1544 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1545 final int NA = apps.size(); 1546 for (int ia=0; ia<NA; ia++) { 1547 ProcessRecord app = apps.valueAt(ia); 1548 if (app.thread != null) { 1549 procs.add(app.thread.asBinder()); 1550 } 1551 } 1552 } 1553 } 1554 1555 int N = procs.size(); 1556 for (int i=0; i<N; i++) { 1557 Parcel data2 = Parcel.obtain(); 1558 try { 1559 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1560 } catch (RemoteException e) { 1561 } 1562 data2.recycle(); 1563 } 1564 } 1565 try { 1566 return super.onTransact(code, data, reply, flags); 1567 } catch (RuntimeException e) { 1568 // The activity manager only throws security exceptions, so let's 1569 // log all others. 1570 if (!(e instanceof SecurityException)) { 1571 Slog.e(TAG, "Activity Manager Crash", e); 1572 } 1573 throw e; 1574 } 1575 } 1576 1577 void updateCpuStats() { 1578 final long now = SystemClock.uptimeMillis(); 1579 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1580 return; 1581 } 1582 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1583 synchronized (mProcessStatsThread) { 1584 mProcessStatsThread.notify(); 1585 } 1586 } 1587 } 1588 1589 void updateCpuStatsNow() { 1590 synchronized (mProcessStatsThread) { 1591 mProcessStatsMutexFree.set(false); 1592 final long now = SystemClock.uptimeMillis(); 1593 boolean haveNewCpuStats = false; 1594 1595 if (MONITOR_CPU_USAGE && 1596 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1597 mLastCpuTime.set(now); 1598 haveNewCpuStats = true; 1599 mProcessStats.update(); 1600 //Slog.i(TAG, mProcessStats.printCurrentState()); 1601 //Slog.i(TAG, "Total CPU usage: " 1602 // + mProcessStats.getTotalCpuPercent() + "%"); 1603 1604 // Slog the cpu usage if the property is set. 1605 if ("true".equals(SystemProperties.get("events.cpu"))) { 1606 int user = mProcessStats.getLastUserTime(); 1607 int system = mProcessStats.getLastSystemTime(); 1608 int iowait = mProcessStats.getLastIoWaitTime(); 1609 int irq = mProcessStats.getLastIrqTime(); 1610 int softIrq = mProcessStats.getLastSoftIrqTime(); 1611 int idle = mProcessStats.getLastIdleTime(); 1612 1613 int total = user + system + iowait + irq + softIrq + idle; 1614 if (total == 0) total = 1; 1615 1616 EventLog.writeEvent(EventLogTags.CPU, 1617 ((user+system+iowait+irq+softIrq) * 100) / total, 1618 (user * 100) / total, 1619 (system * 100) / total, 1620 (iowait * 100) / total, 1621 (irq * 100) / total, 1622 (softIrq * 100) / total); 1623 } 1624 } 1625 1626 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1627 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1628 synchronized(bstats) { 1629 synchronized(mPidsSelfLocked) { 1630 if (haveNewCpuStats) { 1631 if (mOnBattery) { 1632 int perc = bstats.startAddingCpuLocked(); 1633 int totalUTime = 0; 1634 int totalSTime = 0; 1635 final int N = mProcessStats.countStats(); 1636 for (int i=0; i<N; i++) { 1637 ProcessStats.Stats st = mProcessStats.getStats(i); 1638 if (!st.working) { 1639 continue; 1640 } 1641 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1642 int otherUTime = (st.rel_utime*perc)/100; 1643 int otherSTime = (st.rel_stime*perc)/100; 1644 totalUTime += otherUTime; 1645 totalSTime += otherSTime; 1646 if (pr != null) { 1647 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1648 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1649 st.rel_stime-otherSTime); 1650 ps.addSpeedStepTimes(cpuSpeedTimes); 1651 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1652 } else { 1653 BatteryStatsImpl.Uid.Proc ps = 1654 bstats.getProcessStatsLocked(st.name, st.pid); 1655 if (ps != null) { 1656 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1657 st.rel_stime-otherSTime); 1658 ps.addSpeedStepTimes(cpuSpeedTimes); 1659 } 1660 } 1661 } 1662 bstats.finishAddingCpuLocked(perc, totalUTime, 1663 totalSTime, cpuSpeedTimes); 1664 } 1665 } 1666 } 1667 1668 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1669 mLastWriteTime = now; 1670 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1671 } 1672 } 1673 } 1674 } 1675 1676 @Override 1677 public void batteryNeedsCpuUpdate() { 1678 updateCpuStatsNow(); 1679 } 1680 1681 @Override 1682 public void batteryPowerChanged(boolean onBattery) { 1683 // When plugging in, update the CPU stats first before changing 1684 // the plug state. 1685 updateCpuStatsNow(); 1686 synchronized (this) { 1687 synchronized(mPidsSelfLocked) { 1688 mOnBattery = DEBUG_POWER ? true : onBattery; 1689 } 1690 } 1691 } 1692 1693 /** 1694 * Initialize the application bind args. These are passed to each 1695 * process when the bindApplication() IPC is sent to the process. They're 1696 * lazily setup to make sure the services are running when they're asked for. 1697 */ 1698 private HashMap<String, IBinder> getCommonServicesLocked() { 1699 if (mAppBindArgs == null) { 1700 mAppBindArgs = new HashMap<String, IBinder>(); 1701 1702 // Setup the application init args 1703 mAppBindArgs.put("package", ServiceManager.getService("package")); 1704 mAppBindArgs.put("window", ServiceManager.getService("window")); 1705 mAppBindArgs.put(Context.ALARM_SERVICE, 1706 ServiceManager.getService(Context.ALARM_SERVICE)); 1707 } 1708 return mAppBindArgs; 1709 } 1710 1711 final void setFocusedActivityLocked(ActivityRecord r) { 1712 if (mFocusedActivity != r) { 1713 mFocusedActivity = r; 1714 if (r != null) { 1715 mWindowManager.setFocusedApp(r.appToken, true); 1716 } 1717 } 1718 } 1719 1720 private final void updateLruProcessInternalLocked(ProcessRecord app, 1721 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1722 // put it on the LRU to keep track of when it should be exited. 1723 int lrui = mLruProcesses.indexOf(app); 1724 if (lrui >= 0) mLruProcesses.remove(lrui); 1725 1726 int i = mLruProcesses.size()-1; 1727 int skipTop = 0; 1728 1729 app.lruSeq = mLruSeq; 1730 1731 // compute the new weight for this process. 1732 if (updateActivityTime) { 1733 app.lastActivityTime = SystemClock.uptimeMillis(); 1734 } 1735 if (app.activities.size() > 0) { 1736 // If this process has activities, we more strongly want to keep 1737 // it around. 1738 app.lruWeight = app.lastActivityTime; 1739 } else if (app.pubProviders.size() > 0) { 1740 // If this process contains content providers, we want to keep 1741 // it a little more strongly. 1742 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1743 // Also don't let it kick out the first few "real" hidden processes. 1744 skipTop = ProcessList.MIN_HIDDEN_APPS; 1745 } else { 1746 // If this process doesn't have activities, we less strongly 1747 // want to keep it around, and generally want to avoid getting 1748 // in front of any very recently used activities. 1749 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1750 // Also don't let it kick out the first few "real" hidden processes. 1751 skipTop = ProcessList.MIN_HIDDEN_APPS; 1752 } 1753 1754 while (i >= 0) { 1755 ProcessRecord p = mLruProcesses.get(i); 1756 // If this app shouldn't be in front of the first N background 1757 // apps, then skip over that many that are currently hidden. 1758 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1759 skipTop--; 1760 } 1761 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1762 mLruProcesses.add(i+1, app); 1763 break; 1764 } 1765 i--; 1766 } 1767 if (i < 0) { 1768 mLruProcesses.add(0, app); 1769 } 1770 1771 // If the app is currently using a content provider or service, 1772 // bump those processes as well. 1773 if (app.connections.size() > 0) { 1774 for (ConnectionRecord cr : app.connections) { 1775 if (cr.binding != null && cr.binding.service != null 1776 && cr.binding.service.app != null 1777 && cr.binding.service.app.lruSeq != mLruSeq) { 1778 updateLruProcessInternalLocked(cr.binding.service.app, false, 1779 updateActivityTime, i+1); 1780 } 1781 } 1782 } 1783 for (int j=app.conProviders.size()-1; j>=0; j--) { 1784 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1785 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1786 updateLruProcessInternalLocked(cpr.proc, false, 1787 updateActivityTime, i+1); 1788 } 1789 } 1790 1791 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1792 if (oomAdj) { 1793 updateOomAdjLocked(); 1794 } 1795 } 1796 1797 final void updateLruProcessLocked(ProcessRecord app, 1798 boolean oomAdj, boolean updateActivityTime) { 1799 mLruSeq++; 1800 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1801 } 1802 1803 final ProcessRecord getProcessRecordLocked( 1804 String processName, int uid) { 1805 if (uid == Process.SYSTEM_UID) { 1806 // The system gets to run in any process. If there are multiple 1807 // processes with the same uid, just pick the first (this 1808 // should never happen). 1809 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1810 processName); 1811 if (procs == null) return null; 1812 final int N = procs.size(); 1813 for (int i = 0; i < N; i++) { 1814 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1815 } 1816 } 1817 ProcessRecord proc = mProcessNames.get(processName, uid); 1818 return proc; 1819 } 1820 1821 void ensurePackageDexOpt(String packageName) { 1822 IPackageManager pm = AppGlobals.getPackageManager(); 1823 try { 1824 if (pm.performDexOpt(packageName)) { 1825 mDidDexOpt = true; 1826 } 1827 } catch (RemoteException e) { 1828 } 1829 } 1830 1831 boolean isNextTransitionForward() { 1832 int transit = mWindowManager.getPendingAppTransition(); 1833 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1834 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1835 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1836 } 1837 1838 final ProcessRecord startProcessLocked(String processName, 1839 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1840 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1841 boolean isolated) { 1842 ProcessRecord app; 1843 if (!isolated) { 1844 app = getProcessRecordLocked(processName, info.uid); 1845 } else { 1846 // If this is an isolated process, it can't re-use an existing process. 1847 app = null; 1848 } 1849 // We don't have to do anything more if: 1850 // (1) There is an existing application record; and 1851 // (2) The caller doesn't think it is dead, OR there is no thread 1852 // object attached to it so we know it couldn't have crashed; and 1853 // (3) There is a pid assigned to it, so it is either starting or 1854 // already running. 1855 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1856 + " app=" + app + " knownToBeDead=" + knownToBeDead 1857 + " thread=" + (app != null ? app.thread : null) 1858 + " pid=" + (app != null ? app.pid : -1)); 1859 if (app != null && app.pid > 0) { 1860 if (!knownToBeDead || app.thread == null) { 1861 // We already have the app running, or are waiting for it to 1862 // come up (we have a pid but not yet its thread), so keep it. 1863 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1864 // If this is a new package in the process, add the package to the list 1865 app.addPackage(info.packageName); 1866 return app; 1867 } else { 1868 // An application record is attached to a previous process, 1869 // clean it up now. 1870 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1871 handleAppDiedLocked(app, true, true); 1872 } 1873 } 1874 1875 String hostingNameStr = hostingName != null 1876 ? hostingName.flattenToShortString() : null; 1877 1878 if (!isolated) { 1879 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1880 // If we are in the background, then check to see if this process 1881 // is bad. If so, we will just silently fail. 1882 if (mBadProcesses.get(info.processName, info.uid) != null) { 1883 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1884 + "/" + info.processName); 1885 return null; 1886 } 1887 } else { 1888 // When the user is explicitly starting a process, then clear its 1889 // crash count so that we won't make it bad until they see at 1890 // least one crash dialog again, and make the process good again 1891 // if it had been bad. 1892 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1893 + "/" + info.processName); 1894 mProcessCrashTimes.remove(info.processName, info.uid); 1895 if (mBadProcesses.get(info.processName, info.uid) != null) { 1896 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1897 info.processName); 1898 mBadProcesses.remove(info.processName, info.uid); 1899 if (app != null) { 1900 app.bad = false; 1901 } 1902 } 1903 } 1904 } 1905 1906 if (app == null) { 1907 app = newProcessRecordLocked(null, info, processName, isolated); 1908 if (app == null) { 1909 Slog.w(TAG, "Failed making new process record for " 1910 + processName + "/" + info.uid + " isolated=" + isolated); 1911 return null; 1912 } 1913 mProcessNames.put(processName, app.uid, app); 1914 if (isolated) { 1915 mIsolatedProcesses.put(app.uid, app); 1916 } 1917 } else { 1918 // If this is a new package in the process, add the package to the list 1919 app.addPackage(info.packageName); 1920 } 1921 1922 // If the system is not ready yet, then hold off on starting this 1923 // process until it is. 1924 if (!mProcessesReady 1925 && !isAllowedWhileBooting(info) 1926 && !allowWhileBooting) { 1927 if (!mProcessesOnHold.contains(app)) { 1928 mProcessesOnHold.add(app); 1929 } 1930 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1931 return app; 1932 } 1933 1934 startProcessLocked(app, hostingType, hostingNameStr); 1935 return (app.pid != 0) ? app : null; 1936 } 1937 1938 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1939 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1940 } 1941 1942 private final void startProcessLocked(ProcessRecord app, 1943 String hostingType, String hostingNameStr) { 1944 if (app.pid > 0 && app.pid != MY_PID) { 1945 synchronized (mPidsSelfLocked) { 1946 mPidsSelfLocked.remove(app.pid); 1947 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1948 } 1949 app.pid = 0; 1950 } 1951 1952 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1953 "startProcessLocked removing on hold: " + app); 1954 mProcessesOnHold.remove(app); 1955 1956 updateCpuStats(); 1957 1958 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1959 mProcDeaths[0] = 0; 1960 1961 try { 1962 int uid = app.uid; 1963 1964 int[] gids = null; 1965 if (!app.isolated) { 1966 try { 1967 gids = mContext.getPackageManager().getPackageGids( 1968 app.info.packageName); 1969 } catch (PackageManager.NameNotFoundException e) { 1970 Slog.w(TAG, "Unable to retrieve gids", e); 1971 } 1972 } 1973 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1974 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1975 && mTopComponent != null 1976 && app.processName.equals(mTopComponent.getPackageName())) { 1977 uid = 0; 1978 } 1979 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1980 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1981 uid = 0; 1982 } 1983 } 1984 int debugFlags = 0; 1985 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1986 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1987 // Also turn on CheckJNI for debuggable apps. It's quite 1988 // awkward to turn on otherwise. 1989 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1990 } 1991 // Run the app in safe mode if its manifest requests so or the 1992 // system is booted in safe mode. 1993 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 1994 Zygote.systemInSafeMode == true) { 1995 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1996 } 1997 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1998 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1999 } 2000 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2001 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2002 } 2003 if ("1".equals(SystemProperties.get("debug.assert"))) { 2004 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2005 } 2006 2007 // Start the process. It will either succeed and return a result containing 2008 // the PID of the new process, or else throw a RuntimeException. 2009 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2010 app.processName, uid, uid, gids, debugFlags, 2011 app.info.targetSdkVersion, null, null); 2012 2013 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2014 synchronized (bs) { 2015 if (bs.isOnBattery()) { 2016 app.batteryStats.incStartsLocked(); 2017 } 2018 } 2019 2020 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2021 app.processName, hostingType, 2022 hostingNameStr != null ? hostingNameStr : ""); 2023 2024 if (app.persistent) { 2025 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2026 } 2027 2028 StringBuilder buf = mStringBuilder; 2029 buf.setLength(0); 2030 buf.append("Start proc "); 2031 buf.append(app.processName); 2032 buf.append(" for "); 2033 buf.append(hostingType); 2034 if (hostingNameStr != null) { 2035 buf.append(" "); 2036 buf.append(hostingNameStr); 2037 } 2038 buf.append(": pid="); 2039 buf.append(startResult.pid); 2040 buf.append(" uid="); 2041 buf.append(uid); 2042 buf.append(" gids={"); 2043 if (gids != null) { 2044 for (int gi=0; gi<gids.length; gi++) { 2045 if (gi != 0) buf.append(", "); 2046 buf.append(gids[gi]); 2047 2048 } 2049 } 2050 buf.append("}"); 2051 Slog.i(TAG, buf.toString()); 2052 app.pid = startResult.pid; 2053 app.usingWrapper = startResult.usingWrapper; 2054 app.removed = false; 2055 synchronized (mPidsSelfLocked) { 2056 this.mPidsSelfLocked.put(startResult.pid, app); 2057 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2058 msg.obj = app; 2059 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2060 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2061 } 2062 } catch (RuntimeException e) { 2063 // XXX do better error recovery. 2064 app.pid = 0; 2065 Slog.e(TAG, "Failure starting process " + app.processName, e); 2066 } 2067 } 2068 2069 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2070 if (resumed) { 2071 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2072 } else { 2073 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2074 } 2075 } 2076 2077 boolean startHomeActivityLocked(int userId) { 2078 if (mHeadless) { 2079 // Added because none of the other calls to ensureBootCompleted seem to fire 2080 // when running headless. 2081 ensureBootCompleted(); 2082 return false; 2083 } 2084 2085 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2086 && mTopAction == null) { 2087 // We are running in factory test mode, but unable to find 2088 // the factory test app, so just sit around displaying the 2089 // error message and don't try to start anything. 2090 return false; 2091 } 2092 Intent intent = new Intent( 2093 mTopAction, 2094 mTopData != null ? Uri.parse(mTopData) : null); 2095 intent.setComponent(mTopComponent); 2096 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2097 intent.addCategory(Intent.CATEGORY_HOME); 2098 } 2099 ActivityInfo aInfo = 2100 intent.resolveActivityInfo(mContext.getPackageManager(), 2101 STOCK_PM_FLAGS); 2102 if (aInfo != null) { 2103 intent.setComponent(new ComponentName( 2104 aInfo.applicationInfo.packageName, aInfo.name)); 2105 // Don't do this if the home app is currently being 2106 // instrumented. 2107 aInfo = new ActivityInfo(aInfo); 2108 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2109 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2110 aInfo.applicationInfo.uid); 2111 if (app == null || app.instrumentationClass == null) { 2112 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2113 mMainStack.startActivityLocked(null, intent, null, aInfo, 2114 null, null, 0, 0, 0, 0, null, false, null); 2115 } 2116 } 2117 2118 return true; 2119 } 2120 2121 /** 2122 * Starts the "new version setup screen" if appropriate. 2123 */ 2124 void startSetupActivityLocked() { 2125 // Only do this once per boot. 2126 if (mCheckedForSetup) { 2127 return; 2128 } 2129 2130 // We will show this screen if the current one is a different 2131 // version than the last one shown, and we are not running in 2132 // low-level factory test mode. 2133 final ContentResolver resolver = mContext.getContentResolver(); 2134 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2135 Settings.Secure.getInt(resolver, 2136 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2137 mCheckedForSetup = true; 2138 2139 // See if we should be showing the platform update setup UI. 2140 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2141 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2142 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2143 2144 // We don't allow third party apps to replace this. 2145 ResolveInfo ri = null; 2146 for (int i=0; ris != null && i<ris.size(); i++) { 2147 if ((ris.get(i).activityInfo.applicationInfo.flags 2148 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2149 ri = ris.get(i); 2150 break; 2151 } 2152 } 2153 2154 if (ri != null) { 2155 String vers = ri.activityInfo.metaData != null 2156 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2157 : null; 2158 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2159 vers = ri.activityInfo.applicationInfo.metaData.getString( 2160 Intent.METADATA_SETUP_VERSION); 2161 } 2162 String lastVers = Settings.Secure.getString( 2163 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2164 if (vers != null && !vers.equals(lastVers)) { 2165 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2166 intent.setComponent(new ComponentName( 2167 ri.activityInfo.packageName, ri.activityInfo.name)); 2168 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2169 null, null, 0, 0, 0, 0, null, false, null); 2170 } 2171 } 2172 } 2173 } 2174 2175 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2176 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2177 } 2178 2179 void enforceNotIsolatedCaller(String caller) { 2180 if (UserId.isIsolated(Binder.getCallingUid())) { 2181 throw new SecurityException("Isolated process not allowed to call " + caller); 2182 } 2183 } 2184 2185 public int getFrontActivityScreenCompatMode() { 2186 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2187 synchronized (this) { 2188 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2189 } 2190 } 2191 2192 public void setFrontActivityScreenCompatMode(int mode) { 2193 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2194 "setFrontActivityScreenCompatMode"); 2195 synchronized (this) { 2196 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2197 } 2198 } 2199 2200 public int getPackageScreenCompatMode(String packageName) { 2201 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2202 synchronized (this) { 2203 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2204 } 2205 } 2206 2207 public void setPackageScreenCompatMode(String packageName, int mode) { 2208 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2209 "setPackageScreenCompatMode"); 2210 synchronized (this) { 2211 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2212 } 2213 } 2214 2215 public boolean getPackageAskScreenCompat(String packageName) { 2216 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2217 synchronized (this) { 2218 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2219 } 2220 } 2221 2222 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2223 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2224 "setPackageAskScreenCompat"); 2225 synchronized (this) { 2226 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2227 } 2228 } 2229 2230 void reportResumedActivityLocked(ActivityRecord r) { 2231 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2232 updateUsageStats(r, true); 2233 } 2234 2235 private void dispatchProcessesChanged() { 2236 int N; 2237 synchronized (this) { 2238 N = mPendingProcessChanges.size(); 2239 if (mActiveProcessChanges.length < N) { 2240 mActiveProcessChanges = new ProcessChangeItem[N]; 2241 } 2242 mPendingProcessChanges.toArray(mActiveProcessChanges); 2243 mAvailProcessChanges.addAll(mPendingProcessChanges); 2244 mPendingProcessChanges.clear(); 2245 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2246 } 2247 int i = mProcessObservers.beginBroadcast(); 2248 while (i > 0) { 2249 i--; 2250 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2251 if (observer != null) { 2252 try { 2253 for (int j=0; j<N; j++) { 2254 ProcessChangeItem item = mActiveProcessChanges[j]; 2255 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2256 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2257 + item.pid + " uid=" + item.uid + ": " 2258 + item.foregroundActivities); 2259 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2260 item.foregroundActivities); 2261 } 2262 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2263 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2264 + item.pid + " uid=" + item.uid + ": " + item.importance); 2265 observer.onImportanceChanged(item.pid, item.uid, 2266 item.importance); 2267 } 2268 } 2269 } catch (RemoteException e) { 2270 } 2271 } 2272 } 2273 mProcessObservers.finishBroadcast(); 2274 } 2275 2276 private void dispatchProcessDied(int pid, int uid) { 2277 int i = mProcessObservers.beginBroadcast(); 2278 while (i > 0) { 2279 i--; 2280 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2281 if (observer != null) { 2282 try { 2283 observer.onProcessDied(pid, uid); 2284 } catch (RemoteException e) { 2285 } 2286 } 2287 } 2288 mProcessObservers.finishBroadcast(); 2289 } 2290 2291 final void doPendingActivityLaunchesLocked(boolean doResume) { 2292 final int N = mPendingActivityLaunches.size(); 2293 if (N <= 0) { 2294 return; 2295 } 2296 for (int i=0; i<N; i++) { 2297 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2298 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2299 pal.startFlags, doResume && i == (N-1), null); 2300 } 2301 mPendingActivityLaunches.clear(); 2302 } 2303 2304 public final int startActivity(IApplicationThread caller, 2305 Intent intent, String resolvedType, IBinder resultTo, 2306 String resultWho, int requestCode, int startFlags, 2307 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2308 enforceNotIsolatedCaller("startActivity"); 2309 int userId = 0; 2310 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2311 // Requesting home, set the identity to the current user 2312 // HACK! 2313 userId = mCurrentUserId; 2314 } else { 2315 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2316 // the current user's userId 2317 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2318 userId = 0; 2319 } else { 2320 userId = Binder.getOrigCallingUser(); 2321 } 2322 } 2323 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2324 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2325 null, null, options, userId); 2326 } 2327 2328 public final WaitResult startActivityAndWait(IApplicationThread caller, 2329 Intent intent, String resolvedType, IBinder resultTo, 2330 String resultWho, int requestCode, int startFlags, String profileFile, 2331 ParcelFileDescriptor profileFd, Bundle options) { 2332 enforceNotIsolatedCaller("startActivityAndWait"); 2333 WaitResult res = new WaitResult(); 2334 int userId = Binder.getOrigCallingUser(); 2335 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2336 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2337 res, null, options, userId); 2338 return res; 2339 } 2340 2341 public final int startActivityWithConfig(IApplicationThread caller, 2342 Intent intent, String resolvedType, IBinder resultTo, 2343 String resultWho, int requestCode, int startFlags, Configuration config, 2344 Bundle options) { 2345 enforceNotIsolatedCaller("startActivityWithConfig"); 2346 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2347 resultTo, resultWho, requestCode, startFlags, 2348 null, null, null, config, options, Binder.getOrigCallingUser()); 2349 return ret; 2350 } 2351 2352 public int startActivityIntentSender(IApplicationThread caller, 2353 IntentSender intent, Intent fillInIntent, String resolvedType, 2354 IBinder resultTo, String resultWho, int requestCode, 2355 int flagsMask, int flagsValues, Bundle options) { 2356 enforceNotIsolatedCaller("startActivityIntentSender"); 2357 // Refuse possible leaked file descriptors 2358 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2359 throw new IllegalArgumentException("File descriptors passed in Intent"); 2360 } 2361 2362 IIntentSender sender = intent.getTarget(); 2363 if (!(sender instanceof PendingIntentRecord)) { 2364 throw new IllegalArgumentException("Bad PendingIntent object"); 2365 } 2366 2367 PendingIntentRecord pir = (PendingIntentRecord)sender; 2368 2369 synchronized (this) { 2370 // If this is coming from the currently resumed activity, it is 2371 // effectively saying that app switches are allowed at this point. 2372 if (mMainStack.mResumedActivity != null 2373 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2374 Binder.getCallingUid()) { 2375 mAppSwitchesAllowedTime = 0; 2376 } 2377 } 2378 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2379 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2380 return ret; 2381 } 2382 2383 public boolean startNextMatchingActivity(IBinder callingActivity, 2384 Intent intent, Bundle options) { 2385 // Refuse possible leaked file descriptors 2386 if (intent != null && intent.hasFileDescriptors() == true) { 2387 throw new IllegalArgumentException("File descriptors passed in Intent"); 2388 } 2389 2390 synchronized (this) { 2391 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2392 if (r == null) { 2393 ActivityOptions.abort(options); 2394 return false; 2395 } 2396 if (r.app == null || r.app.thread == null) { 2397 // The caller is not running... d'oh! 2398 ActivityOptions.abort(options); 2399 return false; 2400 } 2401 intent = new Intent(intent); 2402 // The caller is not allowed to change the data. 2403 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2404 // And we are resetting to find the next component... 2405 intent.setComponent(null); 2406 2407 ActivityInfo aInfo = null; 2408 try { 2409 List<ResolveInfo> resolves = 2410 AppGlobals.getPackageManager().queryIntentActivities( 2411 intent, r.resolvedType, 2412 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2413 UserId.getCallingUserId()); 2414 2415 // Look for the original activity in the list... 2416 final int N = resolves != null ? resolves.size() : 0; 2417 for (int i=0; i<N; i++) { 2418 ResolveInfo rInfo = resolves.get(i); 2419 if (rInfo.activityInfo.packageName.equals(r.packageName) 2420 && rInfo.activityInfo.name.equals(r.info.name)) { 2421 // We found the current one... the next matching is 2422 // after it. 2423 i++; 2424 if (i<N) { 2425 aInfo = resolves.get(i).activityInfo; 2426 } 2427 break; 2428 } 2429 } 2430 } catch (RemoteException e) { 2431 } 2432 2433 if (aInfo == null) { 2434 // Nobody who is next! 2435 ActivityOptions.abort(options); 2436 return false; 2437 } 2438 2439 intent.setComponent(new ComponentName( 2440 aInfo.applicationInfo.packageName, aInfo.name)); 2441 intent.setFlags(intent.getFlags()&~( 2442 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2443 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2444 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2445 Intent.FLAG_ACTIVITY_NEW_TASK)); 2446 2447 // Okay now we need to start the new activity, replacing the 2448 // currently running activity. This is a little tricky because 2449 // we want to start the new one as if the current one is finished, 2450 // but not finish the current one first so that there is no flicker. 2451 // And thus... 2452 final boolean wasFinishing = r.finishing; 2453 r.finishing = true; 2454 2455 // Propagate reply information over to the new activity. 2456 final ActivityRecord resultTo = r.resultTo; 2457 final String resultWho = r.resultWho; 2458 final int requestCode = r.requestCode; 2459 r.resultTo = null; 2460 if (resultTo != null) { 2461 resultTo.removeResultsLocked(r, resultWho, requestCode); 2462 } 2463 2464 final long origId = Binder.clearCallingIdentity(); 2465 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2466 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2467 resultWho, requestCode, -1, r.launchedFromUid, 0, 2468 options, false, null); 2469 Binder.restoreCallingIdentity(origId); 2470 2471 r.finishing = wasFinishing; 2472 if (res != ActivityManager.START_SUCCESS) { 2473 return false; 2474 } 2475 return true; 2476 } 2477 } 2478 2479 public final int startActivityInPackage(int uid, 2480 Intent intent, String resolvedType, IBinder resultTo, 2481 String resultWho, int requestCode, int startFlags, Bundle options) { 2482 2483 // This is so super not safe, that only the system (or okay root) 2484 // can do it. 2485 int userId = Binder.getOrigCallingUser(); 2486 final int callingUid = Binder.getCallingUid(); 2487 if (callingUid != 0 && callingUid != Process.myUid()) { 2488 throw new SecurityException( 2489 "startActivityInPackage only available to the system"); 2490 } 2491 2492 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2493 resultTo, resultWho, requestCode, startFlags, 2494 null, null, null, null, options, userId); 2495 return ret; 2496 } 2497 2498 public final int startActivities(IApplicationThread caller, 2499 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2500 enforceNotIsolatedCaller("startActivities"); 2501 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2502 options, Binder.getOrigCallingUser()); 2503 return ret; 2504 } 2505 2506 public final int startActivitiesInPackage(int uid, 2507 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2508 Bundle options) { 2509 2510 // This is so super not safe, that only the system (or okay root) 2511 // can do it. 2512 final int callingUid = Binder.getCallingUid(); 2513 if (callingUid != 0 && callingUid != Process.myUid()) { 2514 throw new SecurityException( 2515 "startActivityInPackage only available to the system"); 2516 } 2517 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2518 options, UserId.getUserId(uid)); 2519 return ret; 2520 } 2521 2522 final void addRecentTaskLocked(TaskRecord task) { 2523 int N = mRecentTasks.size(); 2524 // Quick case: check if the top-most recent task is the same. 2525 if (N > 0 && mRecentTasks.get(0) == task) { 2526 return; 2527 } 2528 // Remove any existing entries that are the same kind of task. 2529 for (int i=0; i<N; i++) { 2530 TaskRecord tr = mRecentTasks.get(i); 2531 if (task.userId == tr.userId 2532 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2533 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2534 mRecentTasks.remove(i); 2535 i--; 2536 N--; 2537 if (task.intent == null) { 2538 // If the new recent task we are adding is not fully 2539 // specified, then replace it with the existing recent task. 2540 task = tr; 2541 } 2542 } 2543 } 2544 if (N >= MAX_RECENT_TASKS) { 2545 mRecentTasks.remove(N-1); 2546 } 2547 mRecentTasks.add(0, task); 2548 } 2549 2550 public void setRequestedOrientation(IBinder token, 2551 int requestedOrientation) { 2552 synchronized (this) { 2553 ActivityRecord r = mMainStack.isInStackLocked(token); 2554 if (r == null) { 2555 return; 2556 } 2557 final long origId = Binder.clearCallingIdentity(); 2558 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2559 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2560 mConfiguration, 2561 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2562 if (config != null) { 2563 r.frozenBeforeDestroy = true; 2564 if (!updateConfigurationLocked(config, r, false, false)) { 2565 mMainStack.resumeTopActivityLocked(null); 2566 } 2567 } 2568 Binder.restoreCallingIdentity(origId); 2569 } 2570 } 2571 2572 public int getRequestedOrientation(IBinder token) { 2573 synchronized (this) { 2574 ActivityRecord r = mMainStack.isInStackLocked(token); 2575 if (r == null) { 2576 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2577 } 2578 return mWindowManager.getAppOrientation(r.appToken); 2579 } 2580 } 2581 2582 /** 2583 * This is the internal entry point for handling Activity.finish(). 2584 * 2585 * @param token The Binder token referencing the Activity we want to finish. 2586 * @param resultCode Result code, if any, from this Activity. 2587 * @param resultData Result data (Intent), if any, from this Activity. 2588 * 2589 * @return Returns true if the activity successfully finished, or false if it is still running. 2590 */ 2591 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2592 // Refuse possible leaked file descriptors 2593 if (resultData != null && resultData.hasFileDescriptors() == true) { 2594 throw new IllegalArgumentException("File descriptors passed in Intent"); 2595 } 2596 2597 synchronized(this) { 2598 if (mController != null) { 2599 // Find the first activity that is not finishing. 2600 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2601 if (next != null) { 2602 // ask watcher if this is allowed 2603 boolean resumeOK = true; 2604 try { 2605 resumeOK = mController.activityResuming(next.packageName); 2606 } catch (RemoteException e) { 2607 mController = null; 2608 } 2609 2610 if (!resumeOK) { 2611 return false; 2612 } 2613 } 2614 } 2615 final long origId = Binder.clearCallingIdentity(); 2616 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2617 resultData, "app-request"); 2618 Binder.restoreCallingIdentity(origId); 2619 return res; 2620 } 2621 } 2622 2623 public final void finishHeavyWeightApp() { 2624 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2625 != PackageManager.PERMISSION_GRANTED) { 2626 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2627 + Binder.getCallingPid() 2628 + ", uid=" + Binder.getCallingUid() 2629 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2630 Slog.w(TAG, msg); 2631 throw new SecurityException(msg); 2632 } 2633 2634 synchronized(this) { 2635 if (mHeavyWeightProcess == null) { 2636 return; 2637 } 2638 2639 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2640 mHeavyWeightProcess.activities); 2641 for (int i=0; i<activities.size(); i++) { 2642 ActivityRecord r = activities.get(i); 2643 if (!r.finishing) { 2644 int index = mMainStack.indexOfTokenLocked(r.appToken); 2645 if (index >= 0) { 2646 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2647 null, "finish-heavy"); 2648 } 2649 } 2650 } 2651 2652 mHeavyWeightProcess = null; 2653 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2654 } 2655 } 2656 2657 public void crashApplication(int uid, int initialPid, String packageName, 2658 String message) { 2659 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2660 != PackageManager.PERMISSION_GRANTED) { 2661 String msg = "Permission Denial: crashApplication() 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 ProcessRecord proc = null; 2671 2672 // Figure out which process to kill. We don't trust that initialPid 2673 // still has any relation to current pids, so must scan through the 2674 // list. 2675 synchronized (mPidsSelfLocked) { 2676 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2677 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2678 if (p.uid != uid) { 2679 continue; 2680 } 2681 if (p.pid == initialPid) { 2682 proc = p; 2683 break; 2684 } 2685 for (String str : p.pkgList) { 2686 if (str.equals(packageName)) { 2687 proc = p; 2688 } 2689 } 2690 } 2691 } 2692 2693 if (proc == null) { 2694 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2695 + " initialPid=" + initialPid 2696 + " packageName=" + packageName); 2697 return; 2698 } 2699 2700 if (proc.thread != null) { 2701 if (proc.pid == Process.myPid()) { 2702 Log.w(TAG, "crashApplication: trying to crash self!"); 2703 return; 2704 } 2705 long ident = Binder.clearCallingIdentity(); 2706 try { 2707 proc.thread.scheduleCrash(message); 2708 } catch (RemoteException e) { 2709 } 2710 Binder.restoreCallingIdentity(ident); 2711 } 2712 } 2713 } 2714 2715 public final void finishSubActivity(IBinder token, String resultWho, 2716 int requestCode) { 2717 synchronized(this) { 2718 final long origId = Binder.clearCallingIdentity(); 2719 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2720 Binder.restoreCallingIdentity(origId); 2721 } 2722 } 2723 2724 public boolean finishActivityAffinity(IBinder token) { 2725 synchronized(this) { 2726 final long origId = Binder.clearCallingIdentity(); 2727 boolean res = mMainStack.finishActivityAffinityLocked(token); 2728 Binder.restoreCallingIdentity(origId); 2729 return res; 2730 } 2731 } 2732 2733 public boolean willActivityBeVisible(IBinder token) { 2734 synchronized(this) { 2735 int i; 2736 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2737 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2738 if (r.appToken == token) { 2739 return true; 2740 } 2741 if (r.fullscreen && !r.finishing) { 2742 return false; 2743 } 2744 } 2745 return true; 2746 } 2747 } 2748 2749 public void overridePendingTransition(IBinder token, String packageName, 2750 int enterAnim, int exitAnim) { 2751 synchronized(this) { 2752 ActivityRecord self = mMainStack.isInStackLocked(token); 2753 if (self == null) { 2754 return; 2755 } 2756 2757 final long origId = Binder.clearCallingIdentity(); 2758 2759 if (self.state == ActivityState.RESUMED 2760 || self.state == ActivityState.PAUSING) { 2761 mWindowManager.overridePendingAppTransition(packageName, 2762 enterAnim, exitAnim, null); 2763 } 2764 2765 Binder.restoreCallingIdentity(origId); 2766 } 2767 } 2768 2769 /** 2770 * Main function for removing an existing process from the activity manager 2771 * as a result of that process going away. Clears out all connections 2772 * to the process. 2773 */ 2774 private final void handleAppDiedLocked(ProcessRecord app, 2775 boolean restarting, boolean allowRestart) { 2776 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2777 if (!restarting) { 2778 mLruProcesses.remove(app); 2779 } 2780 2781 if (mProfileProc == app) { 2782 clearProfilerLocked(); 2783 } 2784 2785 // Just in case... 2786 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2787 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2788 mMainStack.mPausingActivity = null; 2789 } 2790 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2791 mMainStack.mLastPausedActivity = null; 2792 } 2793 2794 // Remove this application's activities from active lists. 2795 mMainStack.removeHistoryRecordsForAppLocked(app); 2796 2797 boolean atTop = true; 2798 boolean hasVisibleActivities = false; 2799 2800 // Clean out the history list. 2801 int i = mMainStack.mHistory.size(); 2802 if (localLOGV) Slog.v( 2803 TAG, "Removing app " + app + " from history with " + i + " entries"); 2804 while (i > 0) { 2805 i--; 2806 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2807 if (localLOGV) Slog.v( 2808 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2809 if (r.app == app) { 2810 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2811 if (ActivityStack.DEBUG_ADD_REMOVE) { 2812 RuntimeException here = new RuntimeException("here"); 2813 here.fillInStackTrace(); 2814 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2815 + ": haveState=" + r.haveState 2816 + " stateNotNeeded=" + r.stateNotNeeded 2817 + " finishing=" + r.finishing 2818 + " state=" + r.state, here); 2819 } 2820 if (!r.finishing) { 2821 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2822 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2823 System.identityHashCode(r), 2824 r.task.taskId, r.shortComponentName, 2825 "proc died without state saved"); 2826 } 2827 mMainStack.removeActivityFromHistoryLocked(r); 2828 2829 } else { 2830 // We have the current state for this activity, so 2831 // it can be restarted later when needed. 2832 if (localLOGV) Slog.v( 2833 TAG, "Keeping entry, setting app to null"); 2834 if (r.visible) { 2835 hasVisibleActivities = true; 2836 } 2837 r.app = null; 2838 r.nowVisible = false; 2839 if (!r.haveState) { 2840 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2841 "App died, clearing saved state of " + r); 2842 r.icicle = null; 2843 } 2844 } 2845 2846 r.stack.cleanUpActivityLocked(r, true, true); 2847 } 2848 atTop = false; 2849 } 2850 2851 app.activities.clear(); 2852 2853 if (app.instrumentationClass != null) { 2854 Slog.w(TAG, "Crash of app " + app.processName 2855 + " running instrumentation " + app.instrumentationClass); 2856 Bundle info = new Bundle(); 2857 info.putString("shortMsg", "Process crashed."); 2858 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2859 } 2860 2861 if (!restarting) { 2862 if (!mMainStack.resumeTopActivityLocked(null)) { 2863 // If there was nothing to resume, and we are not already 2864 // restarting this process, but there is a visible activity that 2865 // is hosted by the process... then make sure all visible 2866 // activities are running, taking care of restarting this 2867 // process. 2868 if (hasVisibleActivities) { 2869 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2870 } 2871 } 2872 } 2873 } 2874 2875 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2876 IBinder threadBinder = thread.asBinder(); 2877 // Find the application record. 2878 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2879 ProcessRecord rec = mLruProcesses.get(i); 2880 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2881 return i; 2882 } 2883 } 2884 return -1; 2885 } 2886 2887 final ProcessRecord getRecordForAppLocked( 2888 IApplicationThread thread) { 2889 if (thread == null) { 2890 return null; 2891 } 2892 2893 int appIndex = getLRURecordIndexForAppLocked(thread); 2894 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2895 } 2896 2897 final void appDiedLocked(ProcessRecord app, int pid, 2898 IApplicationThread thread) { 2899 2900 mProcDeaths[0]++; 2901 2902 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2903 synchronized (stats) { 2904 stats.noteProcessDiedLocked(app.info.uid, pid); 2905 } 2906 2907 // Clean up already done if the process has been re-started. 2908 if (app.pid == pid && app.thread != null && 2909 app.thread.asBinder() == thread.asBinder()) { 2910 if (!app.killedBackground) { 2911 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2912 + ") has died."); 2913 } 2914 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2915 if (localLOGV) Slog.v( 2916 TAG, "Dying app: " + app + ", pid: " + pid 2917 + ", thread: " + thread.asBinder()); 2918 boolean doLowMem = app.instrumentationClass == null; 2919 handleAppDiedLocked(app, false, true); 2920 2921 if (doLowMem) { 2922 // If there are no longer any background processes running, 2923 // and the app that died was not running instrumentation, 2924 // then tell everyone we are now low on memory. 2925 boolean haveBg = false; 2926 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2927 ProcessRecord rec = mLruProcesses.get(i); 2928 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2929 haveBg = true; 2930 break; 2931 } 2932 } 2933 2934 if (!haveBg) { 2935 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2936 long now = SystemClock.uptimeMillis(); 2937 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2938 ProcessRecord rec = mLruProcesses.get(i); 2939 if (rec != app && rec.thread != null && 2940 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2941 // The low memory report is overriding any current 2942 // state for a GC request. Make sure to do 2943 // heavy/important/visible/foreground processes first. 2944 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2945 rec.lastRequestedGc = 0; 2946 } else { 2947 rec.lastRequestedGc = rec.lastLowMemory; 2948 } 2949 rec.reportLowMemory = true; 2950 rec.lastLowMemory = now; 2951 mProcessesToGc.remove(rec); 2952 addProcessToGcListLocked(rec); 2953 } 2954 } 2955 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 2956 scheduleAppGcsLocked(); 2957 } 2958 } 2959 } else if (app.pid != pid) { 2960 // A new process has already been started. 2961 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2962 + ") has died and restarted (pid " + app.pid + ")."); 2963 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2964 } else if (DEBUG_PROCESSES) { 2965 Slog.d(TAG, "Received spurious death notification for thread " 2966 + thread.asBinder()); 2967 } 2968 } 2969 2970 /** 2971 * If a stack trace dump file is configured, dump process stack traces. 2972 * @param clearTraces causes the dump file to be erased prior to the new 2973 * traces being written, if true; when false, the new traces will be 2974 * appended to any existing file content. 2975 * @param firstPids of dalvik VM processes to dump stack traces for first 2976 * @param lastPids of dalvik VM processes to dump stack traces for last 2977 * @param nativeProcs optional list of native process names to dump stack crawls 2978 * @return file containing stack traces, or null if no dump file is configured 2979 */ 2980 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 2981 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 2982 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 2983 if (tracesPath == null || tracesPath.length() == 0) { 2984 return null; 2985 } 2986 2987 File tracesFile = new File(tracesPath); 2988 try { 2989 File tracesDir = tracesFile.getParentFile(); 2990 if (!tracesDir.exists()) tracesFile.mkdirs(); 2991 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 2992 2993 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 2994 tracesFile.createNewFile(); 2995 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 2996 } catch (IOException e) { 2997 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 2998 return null; 2999 } 3000 3001 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3002 return tracesFile; 3003 } 3004 3005 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3006 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3007 // Use a FileObserver to detect when traces finish writing. 3008 // The order of traces is considered important to maintain for legibility. 3009 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3010 public synchronized void onEvent(int event, String path) { notify(); } 3011 }; 3012 3013 try { 3014 observer.startWatching(); 3015 3016 // First collect all of the stacks of the most important pids. 3017 if (firstPids != null) { 3018 try { 3019 int num = firstPids.size(); 3020 for (int i = 0; i < num; i++) { 3021 synchronized (observer) { 3022 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3023 observer.wait(200); // Wait for write-close, give up after 200msec 3024 } 3025 } 3026 } catch (InterruptedException e) { 3027 Log.wtf(TAG, e); 3028 } 3029 } 3030 3031 // Next measure CPU usage. 3032 if (processStats != null) { 3033 processStats.init(); 3034 System.gc(); 3035 processStats.update(); 3036 try { 3037 synchronized (processStats) { 3038 processStats.wait(500); // measure over 1/2 second. 3039 } 3040 } catch (InterruptedException e) { 3041 } 3042 processStats.update(); 3043 3044 // We'll take the stack crawls of just the top apps using CPU. 3045 final int N = processStats.countWorkingStats(); 3046 int numProcs = 0; 3047 for (int i=0; i<N && numProcs<5; i++) { 3048 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3049 if (lastPids.indexOfKey(stats.pid) >= 0) { 3050 numProcs++; 3051 try { 3052 synchronized (observer) { 3053 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3054 observer.wait(200); // Wait for write-close, give up after 200msec 3055 } 3056 } catch (InterruptedException e) { 3057 Log.wtf(TAG, e); 3058 } 3059 3060 } 3061 } 3062 } 3063 3064 } finally { 3065 observer.stopWatching(); 3066 } 3067 3068 if (nativeProcs != null) { 3069 int[] pids = Process.getPidsForCommands(nativeProcs); 3070 if (pids != null) { 3071 for (int pid : pids) { 3072 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3073 } 3074 } 3075 } 3076 } 3077 3078 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3079 if (true || IS_USER_BUILD) { 3080 return; 3081 } 3082 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3083 if (tracesPath == null || tracesPath.length() == 0) { 3084 return; 3085 } 3086 3087 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3088 StrictMode.allowThreadDiskWrites(); 3089 try { 3090 final File tracesFile = new File(tracesPath); 3091 final File tracesDir = tracesFile.getParentFile(); 3092 final File tracesTmp = new File(tracesDir, "__tmp__"); 3093 try { 3094 if (!tracesDir.exists()) tracesFile.mkdirs(); 3095 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3096 3097 if (tracesFile.exists()) { 3098 tracesTmp.delete(); 3099 tracesFile.renameTo(tracesTmp); 3100 } 3101 StringBuilder sb = new StringBuilder(); 3102 Time tobj = new Time(); 3103 tobj.set(System.currentTimeMillis()); 3104 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3105 sb.append(": "); 3106 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3107 sb.append(" since "); 3108 sb.append(msg); 3109 FileOutputStream fos = new FileOutputStream(tracesFile); 3110 fos.write(sb.toString().getBytes()); 3111 if (app == null) { 3112 fos.write("\n*** No application process!".getBytes()); 3113 } 3114 fos.close(); 3115 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3116 } catch (IOException e) { 3117 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3118 return; 3119 } 3120 3121 if (app != null) { 3122 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3123 firstPids.add(app.pid); 3124 dumpStackTraces(tracesPath, firstPids, null, null, null); 3125 } 3126 3127 File lastTracesFile = null; 3128 File curTracesFile = null; 3129 for (int i=9; i>=0; i--) { 3130 String name = String.format("slow%02d.txt", i); 3131 curTracesFile = new File(tracesDir, name); 3132 if (curTracesFile.exists()) { 3133 if (lastTracesFile != null) { 3134 curTracesFile.renameTo(lastTracesFile); 3135 } else { 3136 curTracesFile.delete(); 3137 } 3138 } 3139 lastTracesFile = curTracesFile; 3140 } 3141 tracesFile.renameTo(curTracesFile); 3142 if (tracesTmp.exists()) { 3143 tracesTmp.renameTo(tracesFile); 3144 } 3145 } finally { 3146 StrictMode.setThreadPolicy(oldPolicy); 3147 } 3148 } 3149 3150 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3151 ActivityRecord parent, final String annotation) { 3152 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3153 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3154 3155 if (mController != null) { 3156 try { 3157 // 0 == continue, -1 = kill process immediately 3158 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3159 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3160 } catch (RemoteException e) { 3161 mController = null; 3162 } 3163 } 3164 3165 long anrTime = SystemClock.uptimeMillis(); 3166 if (MONITOR_CPU_USAGE) { 3167 updateCpuStatsNow(); 3168 } 3169 3170 synchronized (this) { 3171 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3172 if (mShuttingDown) { 3173 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3174 return; 3175 } else if (app.notResponding) { 3176 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3177 return; 3178 } else if (app.crashing) { 3179 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3180 return; 3181 } 3182 3183 // In case we come through here for the same app before completing 3184 // this one, mark as anring now so we will bail out. 3185 app.notResponding = true; 3186 3187 // Log the ANR to the event log. 3188 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3189 annotation); 3190 3191 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3192 firstPids.add(app.pid); 3193 3194 int parentPid = app.pid; 3195 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3196 if (parentPid != app.pid) firstPids.add(parentPid); 3197 3198 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3199 3200 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3201 ProcessRecord r = mLruProcesses.get(i); 3202 if (r != null && r.thread != null) { 3203 int pid = r.pid; 3204 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3205 if (r.persistent) { 3206 firstPids.add(pid); 3207 } else { 3208 lastPids.put(pid, Boolean.TRUE); 3209 } 3210 } 3211 } 3212 } 3213 } 3214 3215 // Log the ANR to the main log. 3216 StringBuilder info = new StringBuilder(); 3217 info.setLength(0); 3218 info.append("ANR in ").append(app.processName); 3219 if (activity != null && activity.shortComponentName != null) { 3220 info.append(" (").append(activity.shortComponentName).append(")"); 3221 } 3222 info.append("\n"); 3223 if (annotation != null) { 3224 info.append("Reason: ").append(annotation).append("\n"); 3225 } 3226 if (parent != null && parent != activity) { 3227 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3228 } 3229 3230 final ProcessStats processStats = new ProcessStats(true); 3231 3232 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3233 3234 String cpuInfo = null; 3235 if (MONITOR_CPU_USAGE) { 3236 updateCpuStatsNow(); 3237 synchronized (mProcessStatsThread) { 3238 cpuInfo = mProcessStats.printCurrentState(anrTime); 3239 } 3240 info.append(processStats.printCurrentLoad()); 3241 info.append(cpuInfo); 3242 } 3243 3244 info.append(processStats.printCurrentState(anrTime)); 3245 3246 Slog.e(TAG, info.toString()); 3247 if (tracesFile == null) { 3248 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3249 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3250 } 3251 3252 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3253 cpuInfo, tracesFile, null); 3254 3255 if (mController != null) { 3256 try { 3257 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3258 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3259 if (res != 0) { 3260 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3261 return; 3262 } 3263 } catch (RemoteException e) { 3264 mController = null; 3265 } 3266 } 3267 3268 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3269 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3270 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3271 3272 synchronized (this) { 3273 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3274 Slog.w(TAG, "Killing " + app + ": background ANR"); 3275 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3276 app.processName, app.setAdj, "background ANR"); 3277 Process.killProcessQuiet(app.pid); 3278 return; 3279 } 3280 3281 // Set the app's notResponding state, and look up the errorReportReceiver 3282 makeAppNotRespondingLocked(app, 3283 activity != null ? activity.shortComponentName : null, 3284 annotation != null ? "ANR " + annotation : "ANR", 3285 info.toString()); 3286 3287 // Bring up the infamous App Not Responding dialog 3288 Message msg = Message.obtain(); 3289 HashMap map = new HashMap(); 3290 msg.what = SHOW_NOT_RESPONDING_MSG; 3291 msg.obj = map; 3292 map.put("app", app); 3293 if (activity != null) { 3294 map.put("activity", activity); 3295 } 3296 3297 mHandler.sendMessage(msg); 3298 } 3299 } 3300 3301 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3302 if (!mLaunchWarningShown) { 3303 mLaunchWarningShown = true; 3304 mHandler.post(new Runnable() { 3305 @Override 3306 public void run() { 3307 synchronized (ActivityManagerService.this) { 3308 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3309 d.show(); 3310 mHandler.postDelayed(new Runnable() { 3311 @Override 3312 public void run() { 3313 synchronized (ActivityManagerService.this) { 3314 d.dismiss(); 3315 mLaunchWarningShown = false; 3316 } 3317 } 3318 }, 4000); 3319 } 3320 } 3321 }); 3322 } 3323 } 3324 3325 public boolean clearApplicationUserData(final String packageName, 3326 final IPackageDataObserver observer, final int userId) { 3327 enforceNotIsolatedCaller("clearApplicationUserData"); 3328 int uid = Binder.getCallingUid(); 3329 int pid = Binder.getCallingPid(); 3330 long callingId = Binder.clearCallingIdentity(); 3331 try { 3332 IPackageManager pm = AppGlobals.getPackageManager(); 3333 int pkgUid = -1; 3334 synchronized(this) { 3335 try { 3336 pkgUid = pm.getPackageUid(packageName, userId); 3337 } catch (RemoteException e) { 3338 } 3339 if (pkgUid == -1) { 3340 Slog.w(TAG, "Invalid packageName:" + packageName); 3341 return false; 3342 } 3343 if (uid == pkgUid || checkComponentPermission( 3344 android.Manifest.permission.CLEAR_APP_USER_DATA, 3345 pid, uid, -1, true) 3346 == PackageManager.PERMISSION_GRANTED) { 3347 forceStopPackageLocked(packageName, pkgUid); 3348 } else { 3349 throw new SecurityException(pid+" does not have permission:"+ 3350 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3351 "for process:"+packageName); 3352 } 3353 } 3354 3355 try { 3356 //clear application user data 3357 pm.clearApplicationUserData(packageName, observer, userId); 3358 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3359 Uri.fromParts("package", packageName, null)); 3360 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3361 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3362 null, null, 0, null, null, null, false, false, userId); 3363 } catch (RemoteException e) { 3364 } 3365 } finally { 3366 Binder.restoreCallingIdentity(callingId); 3367 } 3368 return true; 3369 } 3370 3371 public void killBackgroundProcesses(final String packageName) { 3372 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3373 != PackageManager.PERMISSION_GRANTED && 3374 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3375 != PackageManager.PERMISSION_GRANTED) { 3376 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3377 + Binder.getCallingPid() 3378 + ", uid=" + Binder.getCallingUid() 3379 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3380 Slog.w(TAG, msg); 3381 throw new SecurityException(msg); 3382 } 3383 3384 int userId = UserId.getCallingUserId(); 3385 long callingId = Binder.clearCallingIdentity(); 3386 try { 3387 IPackageManager pm = AppGlobals.getPackageManager(); 3388 int pkgUid = -1; 3389 synchronized(this) { 3390 try { 3391 pkgUid = pm.getPackageUid(packageName, userId); 3392 } catch (RemoteException e) { 3393 } 3394 if (pkgUid == -1) { 3395 Slog.w(TAG, "Invalid packageName: " + packageName); 3396 return; 3397 } 3398 killPackageProcessesLocked(packageName, pkgUid, 3399 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3400 } 3401 } finally { 3402 Binder.restoreCallingIdentity(callingId); 3403 } 3404 } 3405 3406 public void killAllBackgroundProcesses() { 3407 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3408 != PackageManager.PERMISSION_GRANTED) { 3409 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3410 + Binder.getCallingPid() 3411 + ", uid=" + Binder.getCallingUid() 3412 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3413 Slog.w(TAG, msg); 3414 throw new SecurityException(msg); 3415 } 3416 3417 long callingId = Binder.clearCallingIdentity(); 3418 try { 3419 synchronized(this) { 3420 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3421 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3422 final int NA = apps.size(); 3423 for (int ia=0; ia<NA; ia++) { 3424 ProcessRecord app = apps.valueAt(ia); 3425 if (app.persistent) { 3426 // we don't kill persistent processes 3427 continue; 3428 } 3429 if (app.removed) { 3430 procs.add(app); 3431 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3432 app.removed = true; 3433 procs.add(app); 3434 } 3435 } 3436 } 3437 3438 int N = procs.size(); 3439 for (int i=0; i<N; i++) { 3440 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3441 } 3442 } 3443 } finally { 3444 Binder.restoreCallingIdentity(callingId); 3445 } 3446 } 3447 3448 public void forceStopPackage(final String packageName) { 3449 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3450 != PackageManager.PERMISSION_GRANTED) { 3451 String msg = "Permission Denial: forceStopPackage() from pid=" 3452 + Binder.getCallingPid() 3453 + ", uid=" + Binder.getCallingUid() 3454 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3455 Slog.w(TAG, msg); 3456 throw new SecurityException(msg); 3457 } 3458 final int userId = UserId.getCallingUserId(); 3459 long callingId = Binder.clearCallingIdentity(); 3460 try { 3461 IPackageManager pm = AppGlobals.getPackageManager(); 3462 int pkgUid = -1; 3463 synchronized(this) { 3464 try { 3465 pkgUid = pm.getPackageUid(packageName, userId); 3466 } catch (RemoteException e) { 3467 } 3468 if (pkgUid == -1) { 3469 Slog.w(TAG, "Invalid packageName: " + packageName); 3470 return; 3471 } 3472 forceStopPackageLocked(packageName, pkgUid); 3473 try { 3474 pm.setPackageStoppedState(packageName, true, userId); 3475 } catch (RemoteException e) { 3476 } catch (IllegalArgumentException e) { 3477 Slog.w(TAG, "Failed trying to unstop package " 3478 + packageName + ": " + e); 3479 } 3480 } 3481 } finally { 3482 Binder.restoreCallingIdentity(callingId); 3483 } 3484 } 3485 3486 /* 3487 * The pkg name and uid have to be specified. 3488 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3489 */ 3490 public void killApplicationWithUid(String pkg, int uid) { 3491 if (pkg == null) { 3492 return; 3493 } 3494 // Make sure the uid is valid. 3495 if (uid < 0) { 3496 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3497 return; 3498 } 3499 int callerUid = Binder.getCallingUid(); 3500 // Only the system server can kill an application 3501 if (callerUid == Process.SYSTEM_UID) { 3502 // Post an aysnc message to kill the application 3503 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3504 msg.arg1 = uid; 3505 msg.arg2 = 0; 3506 msg.obj = pkg; 3507 mHandler.sendMessage(msg); 3508 } else { 3509 throw new SecurityException(callerUid + " cannot kill pkg: " + 3510 pkg); 3511 } 3512 } 3513 3514 public void closeSystemDialogs(String reason) { 3515 enforceNotIsolatedCaller("closeSystemDialogs"); 3516 3517 final int uid = Binder.getCallingUid(); 3518 final long origId = Binder.clearCallingIdentity(); 3519 synchronized (this) { 3520 closeSystemDialogsLocked(uid, reason); 3521 } 3522 Binder.restoreCallingIdentity(origId); 3523 } 3524 3525 void closeSystemDialogsLocked(int callingUid, String reason) { 3526 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3527 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3528 if (reason != null) { 3529 intent.putExtra("reason", reason); 3530 } 3531 mWindowManager.closeSystemDialogs(reason); 3532 3533 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3534 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3535 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3536 r.stack.finishActivityLocked(r, i, 3537 Activity.RESULT_CANCELED, null, "close-sys"); 3538 } 3539 } 3540 3541 broadcastIntentLocked(null, null, intent, null, 3542 null, 0, null, null, null, false, false, -1, 3543 callingUid, 0 /* TODO: Verify */); 3544 } 3545 3546 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3547 throws RemoteException { 3548 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3549 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3550 for (int i=pids.length-1; i>=0; i--) { 3551 infos[i] = new Debug.MemoryInfo(); 3552 Debug.getMemoryInfo(pids[i], infos[i]); 3553 } 3554 return infos; 3555 } 3556 3557 public long[] getProcessPss(int[] pids) throws RemoteException { 3558 enforceNotIsolatedCaller("getProcessPss"); 3559 long[] pss = new long[pids.length]; 3560 for (int i=pids.length-1; i>=0; i--) { 3561 pss[i] = Debug.getPss(pids[i]); 3562 } 3563 return pss; 3564 } 3565 3566 public void killApplicationProcess(String processName, int uid) { 3567 if (processName == null) { 3568 return; 3569 } 3570 3571 int callerUid = Binder.getCallingUid(); 3572 // Only the system server can kill an application 3573 if (callerUid == Process.SYSTEM_UID) { 3574 synchronized (this) { 3575 ProcessRecord app = getProcessRecordLocked(processName, uid); 3576 if (app != null && app.thread != null) { 3577 try { 3578 app.thread.scheduleSuicide(); 3579 } catch (RemoteException e) { 3580 // If the other end already died, then our work here is done. 3581 } 3582 } else { 3583 Slog.w(TAG, "Process/uid not found attempting kill of " 3584 + processName + " / " + uid); 3585 } 3586 } 3587 } else { 3588 throw new SecurityException(callerUid + " cannot kill app process: " + 3589 processName); 3590 } 3591 } 3592 3593 private void forceStopPackageLocked(final String packageName, int uid) { 3594 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3595 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3596 Uri.fromParts("package", packageName, null)); 3597 if (!mProcessesReady) { 3598 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3599 } 3600 intent.putExtra(Intent.EXTRA_UID, uid); 3601 broadcastIntentLocked(null, null, intent, 3602 null, null, 0, null, null, null, 3603 false, false, 3604 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3605 } 3606 3607 private final boolean killPackageProcessesLocked(String packageName, int uid, 3608 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3609 boolean evenPersistent, String reason) { 3610 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3611 3612 // Remove all processes this package may have touched: all with the 3613 // same UID (except for the system or root user), and all whose name 3614 // matches the package name. 3615 final String procNamePrefix = packageName + ":"; 3616 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3617 final int NA = apps.size(); 3618 for (int ia=0; ia<NA; ia++) { 3619 ProcessRecord app = apps.valueAt(ia); 3620 if (app.persistent && !evenPersistent) { 3621 // we don't kill persistent processes 3622 continue; 3623 } 3624 if (app.removed) { 3625 if (doit) { 3626 procs.add(app); 3627 } 3628 // If uid is specified and the uid and process name match 3629 // Or, the uid is not specified and the process name matches 3630 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3631 || ((app.processName.equals(packageName) 3632 || app.processName.startsWith(procNamePrefix)) 3633 && uid < 0))) { 3634 if (app.setAdj >= minOomAdj) { 3635 if (!doit) { 3636 return true; 3637 } 3638 app.removed = true; 3639 procs.add(app); 3640 } 3641 } 3642 } 3643 } 3644 3645 int N = procs.size(); 3646 for (int i=0; i<N; i++) { 3647 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3648 } 3649 return N > 0; 3650 } 3651 3652 private final boolean forceStopPackageLocked(String name, int uid, 3653 boolean callerWillRestart, boolean purgeCache, boolean doit, 3654 boolean evenPersistent, int userId) { 3655 int i; 3656 int N; 3657 3658 if (uid < 0) { 3659 try { 3660 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3661 } catch (RemoteException e) { 3662 } 3663 } 3664 3665 if (doit) { 3666 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3667 3668 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3669 while (badApps.hasNext()) { 3670 SparseArray<Long> ba = badApps.next(); 3671 if (ba.get(uid) != null) { 3672 badApps.remove(); 3673 } 3674 } 3675 } 3676 3677 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3678 callerWillRestart, false, doit, evenPersistent, "force stop"); 3679 3680 TaskRecord lastTask = null; 3681 for (i=0; i<mMainStack.mHistory.size(); i++) { 3682 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3683 final boolean samePackage = r.packageName.equals(name); 3684 if (r.userId == userId 3685 && (samePackage || r.task == lastTask) 3686 && (r.app == null || evenPersistent || !r.app.persistent)) { 3687 if (!doit) { 3688 if (r.finishing) { 3689 // If this activity is just finishing, then it is not 3690 // interesting as far as something to stop. 3691 continue; 3692 } 3693 return true; 3694 } 3695 didSomething = true; 3696 Slog.i(TAG, " Force finishing activity " + r); 3697 if (samePackage) { 3698 if (r.app != null) { 3699 r.app.removed = true; 3700 } 3701 r.app = null; 3702 } 3703 lastTask = r.task; 3704 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3705 null, "force-stop", true)) { 3706 i--; 3707 } 3708 } 3709 } 3710 3711 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3712 if (!doit) { 3713 return true; 3714 } 3715 didSomething = true; 3716 } 3717 3718 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3719 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3720 if (provider.info.packageName.equals(name) 3721 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3722 if (!doit) { 3723 return true; 3724 } 3725 didSomething = true; 3726 providers.add(provider); 3727 } 3728 } 3729 3730 N = providers.size(); 3731 for (i=0; i<N; i++) { 3732 removeDyingProviderLocked(null, providers.get(i), true); 3733 } 3734 3735 if (doit) { 3736 if (purgeCache) { 3737 AttributeCache ac = AttributeCache.instance(); 3738 if (ac != null) { 3739 ac.removePackage(name); 3740 } 3741 } 3742 if (mBooted) { 3743 mMainStack.resumeTopActivityLocked(null); 3744 mMainStack.scheduleIdleLocked(); 3745 } 3746 } 3747 3748 return didSomething; 3749 } 3750 3751 private final boolean removeProcessLocked(ProcessRecord app, 3752 boolean callerWillRestart, boolean allowRestart, String reason) { 3753 final String name = app.processName; 3754 final int uid = app.uid; 3755 if (DEBUG_PROCESSES) Slog.d( 3756 TAG, "Force removing proc " + app.toShortString() + " (" + name 3757 + "/" + uid + ")"); 3758 3759 mProcessNames.remove(name, uid); 3760 mIsolatedProcesses.remove(app.uid); 3761 if (mHeavyWeightProcess == app) { 3762 mHeavyWeightProcess = null; 3763 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3764 } 3765 boolean needRestart = false; 3766 if (app.pid > 0 && app.pid != MY_PID) { 3767 int pid = app.pid; 3768 synchronized (mPidsSelfLocked) { 3769 mPidsSelfLocked.remove(pid); 3770 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3771 } 3772 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3773 handleAppDiedLocked(app, true, allowRestart); 3774 mLruProcesses.remove(app); 3775 Process.killProcessQuiet(pid); 3776 3777 if (app.persistent && !app.isolated) { 3778 if (!callerWillRestart) { 3779 addAppLocked(app.info, false); 3780 } else { 3781 needRestart = true; 3782 } 3783 } 3784 } else { 3785 mRemovedProcesses.add(app); 3786 } 3787 3788 return needRestart; 3789 } 3790 3791 private final void processStartTimedOutLocked(ProcessRecord app) { 3792 final int pid = app.pid; 3793 boolean gone = false; 3794 synchronized (mPidsSelfLocked) { 3795 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3796 if (knownApp != null && knownApp.thread == null) { 3797 mPidsSelfLocked.remove(pid); 3798 gone = true; 3799 } 3800 } 3801 3802 if (gone) { 3803 Slog.w(TAG, "Process " + app + " failed to attach"); 3804 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3805 app.processName); 3806 mProcessNames.remove(app.processName, app.uid); 3807 mIsolatedProcesses.remove(app.uid); 3808 if (mHeavyWeightProcess == app) { 3809 mHeavyWeightProcess = null; 3810 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3811 } 3812 // Take care of any launching providers waiting for this process. 3813 checkAppInLaunchingProvidersLocked(app, true); 3814 // Take care of any services that are waiting for the process. 3815 mServices.processStartTimedOutLocked(app); 3816 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3817 app.processName, app.setAdj, "start timeout"); 3818 Process.killProcessQuiet(pid); 3819 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3820 Slog.w(TAG, "Unattached app died before backup, skipping"); 3821 try { 3822 IBackupManager bm = IBackupManager.Stub.asInterface( 3823 ServiceManager.getService(Context.BACKUP_SERVICE)); 3824 bm.agentDisconnected(app.info.packageName); 3825 } catch (RemoteException e) { 3826 // Can't happen; the backup manager is local 3827 } 3828 } 3829 if (isPendingBroadcastProcessLocked(pid)) { 3830 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3831 skipPendingBroadcastLocked(pid); 3832 } 3833 } else { 3834 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3835 } 3836 } 3837 3838 private final boolean attachApplicationLocked(IApplicationThread thread, 3839 int pid) { 3840 3841 // Find the application record that is being attached... either via 3842 // the pid if we are running in multiple processes, or just pull the 3843 // next app record if we are emulating process with anonymous threads. 3844 ProcessRecord app; 3845 if (pid != MY_PID && pid >= 0) { 3846 synchronized (mPidsSelfLocked) { 3847 app = mPidsSelfLocked.get(pid); 3848 } 3849 } else { 3850 app = null; 3851 } 3852 3853 if (app == null) { 3854 Slog.w(TAG, "No pending application record for pid " + pid 3855 + " (IApplicationThread " + thread + "); dropping process"); 3856 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3857 if (pid > 0 && pid != MY_PID) { 3858 Process.killProcessQuiet(pid); 3859 } else { 3860 try { 3861 thread.scheduleExit(); 3862 } catch (Exception e) { 3863 // Ignore exceptions. 3864 } 3865 } 3866 return false; 3867 } 3868 3869 // If this application record is still attached to a previous 3870 // process, clean it up now. 3871 if (app.thread != null) { 3872 handleAppDiedLocked(app, true, true); 3873 } 3874 3875 // Tell the process all about itself. 3876 3877 if (localLOGV) Slog.v( 3878 TAG, "Binding process pid " + pid + " to record " + app); 3879 3880 String processName = app.processName; 3881 try { 3882 AppDeathRecipient adr = new AppDeathRecipient( 3883 app, pid, thread); 3884 thread.asBinder().linkToDeath(adr, 0); 3885 app.deathRecipient = adr; 3886 } catch (RemoteException e) { 3887 app.resetPackageList(); 3888 startProcessLocked(app, "link fail", processName); 3889 return false; 3890 } 3891 3892 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3893 3894 app.thread = thread; 3895 app.curAdj = app.setAdj = -100; 3896 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3897 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3898 app.forcingToForeground = null; 3899 app.foregroundServices = false; 3900 app.hasShownUi = false; 3901 app.debugging = false; 3902 3903 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3904 3905 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3906 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3907 3908 if (!normalMode) { 3909 Slog.i(TAG, "Launching preboot mode app: " + app); 3910 } 3911 3912 if (localLOGV) Slog.v( 3913 TAG, "New app record " + app 3914 + " thread=" + thread.asBinder() + " pid=" + pid); 3915 try { 3916 int testMode = IApplicationThread.DEBUG_OFF; 3917 if (mDebugApp != null && mDebugApp.equals(processName)) { 3918 testMode = mWaitForDebugger 3919 ? IApplicationThread.DEBUG_WAIT 3920 : IApplicationThread.DEBUG_ON; 3921 app.debugging = true; 3922 if (mDebugTransient) { 3923 mDebugApp = mOrigDebugApp; 3924 mWaitForDebugger = mOrigWaitForDebugger; 3925 } 3926 } 3927 String profileFile = app.instrumentationProfileFile; 3928 ParcelFileDescriptor profileFd = null; 3929 boolean profileAutoStop = false; 3930 if (mProfileApp != null && mProfileApp.equals(processName)) { 3931 mProfileProc = app; 3932 profileFile = mProfileFile; 3933 profileFd = mProfileFd; 3934 profileAutoStop = mAutoStopProfiler; 3935 } 3936 boolean enableOpenGlTrace = false; 3937 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3938 enableOpenGlTrace = true; 3939 mOpenGlTraceApp = null; 3940 } 3941 3942 // If the app is being launched for restore or full backup, set it up specially 3943 boolean isRestrictedBackupMode = false; 3944 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3945 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3946 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3947 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3948 } 3949 3950 ensurePackageDexOpt(app.instrumentationInfo != null 3951 ? app.instrumentationInfo.packageName 3952 : app.info.packageName); 3953 if (app.instrumentationClass != null) { 3954 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3955 } 3956 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3957 + processName + " with config " + mConfiguration); 3958 ApplicationInfo appInfo = app.instrumentationInfo != null 3959 ? app.instrumentationInfo : app.info; 3960 app.compat = compatibilityInfoForPackageLocked(appInfo); 3961 if (profileFd != null) { 3962 profileFd = profileFd.dup(); 3963 } 3964 thread.bindApplication(processName, appInfo, providers, 3965 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 3966 app.instrumentationArguments, app.instrumentationWatcher, testMode, 3967 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 3968 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 3969 mCoreSettingsObserver.getCoreSettingsLocked()); 3970 updateLruProcessLocked(app, false, true); 3971 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 3972 } catch (Exception e) { 3973 // todo: Yikes! What should we do? For now we will try to 3974 // start another process, but that could easily get us in 3975 // an infinite loop of restarting processes... 3976 Slog.w(TAG, "Exception thrown during bind!", e); 3977 3978 app.resetPackageList(); 3979 app.unlinkDeathRecipient(); 3980 startProcessLocked(app, "bind fail", processName); 3981 return false; 3982 } 3983 3984 // Remove this record from the list of starting applications. 3985 mPersistentStartingProcesses.remove(app); 3986 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3987 "Attach application locked removing on hold: " + app); 3988 mProcessesOnHold.remove(app); 3989 3990 boolean badApp = false; 3991 boolean didSomething = false; 3992 3993 // See if the top visible activity is waiting to run in this process... 3994 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 3995 if (hr != null && normalMode) { 3996 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 3997 && processName.equals(hr.processName)) { 3998 try { 3999 if (mHeadless) { 4000 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4001 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4002 didSomething = true; 4003 } 4004 } catch (Exception e) { 4005 Slog.w(TAG, "Exception in new application when starting activity " 4006 + hr.intent.getComponent().flattenToShortString(), e); 4007 badApp = true; 4008 } 4009 } else { 4010 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4011 } 4012 } 4013 4014 // Find any services that should be running in this process... 4015 if (!badApp) { 4016 try { 4017 didSomething |= mServices.attachApplicationLocked(app, processName); 4018 } catch (Exception e) { 4019 badApp = true; 4020 } 4021 } 4022 4023 // Check if a next-broadcast receiver is in this process... 4024 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4025 try { 4026 didSomething = sendPendingBroadcastsLocked(app); 4027 } catch (Exception e) { 4028 // If the app died trying to launch the receiver we declare it 'bad' 4029 badApp = true; 4030 } 4031 } 4032 4033 // Check whether the next backup agent is in this process... 4034 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4035 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4036 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4037 try { 4038 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4039 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4040 mBackupTarget.backupMode); 4041 } catch (Exception e) { 4042 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4043 e.printStackTrace(); 4044 } 4045 } 4046 4047 if (badApp) { 4048 // todo: Also need to kill application to deal with all 4049 // kinds of exceptions. 4050 handleAppDiedLocked(app, false, true); 4051 return false; 4052 } 4053 4054 if (!didSomething) { 4055 updateOomAdjLocked(); 4056 } 4057 4058 return true; 4059 } 4060 4061 public final void attachApplication(IApplicationThread thread) { 4062 synchronized (this) { 4063 int callingPid = Binder.getCallingPid(); 4064 final long origId = Binder.clearCallingIdentity(); 4065 attachApplicationLocked(thread, callingPid); 4066 Binder.restoreCallingIdentity(origId); 4067 } 4068 } 4069 4070 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4071 final long origId = Binder.clearCallingIdentity(); 4072 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4073 if (stopProfiling) { 4074 synchronized (this) { 4075 if (mProfileProc == r.app) { 4076 if (mProfileFd != null) { 4077 try { 4078 mProfileFd.close(); 4079 } catch (IOException e) { 4080 } 4081 clearProfilerLocked(); 4082 } 4083 } 4084 } 4085 } 4086 Binder.restoreCallingIdentity(origId); 4087 } 4088 4089 void enableScreenAfterBoot() { 4090 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4091 SystemClock.uptimeMillis()); 4092 mWindowManager.enableScreenAfterBoot(); 4093 4094 synchronized (this) { 4095 updateEventDispatchingLocked(); 4096 } 4097 } 4098 4099 public void showBootMessage(final CharSequence msg, final boolean always) { 4100 enforceNotIsolatedCaller("showBootMessage"); 4101 mWindowManager.showBootMessage(msg, always); 4102 } 4103 4104 public void dismissKeyguardOnNextActivity() { 4105 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4106 final long token = Binder.clearCallingIdentity(); 4107 try { 4108 synchronized (this) { 4109 if (mLockScreenShown) { 4110 mLockScreenShown = false; 4111 comeOutOfSleepIfNeededLocked(); 4112 } 4113 mMainStack.dismissKeyguardOnNextActivityLocked(); 4114 } 4115 } finally { 4116 Binder.restoreCallingIdentity(token); 4117 } 4118 } 4119 4120 final void finishBooting() { 4121 IntentFilter pkgFilter = new IntentFilter(); 4122 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4123 pkgFilter.addDataScheme("package"); 4124 mContext.registerReceiver(new BroadcastReceiver() { 4125 @Override 4126 public void onReceive(Context context, Intent intent) { 4127 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4128 if (pkgs != null) { 4129 for (String pkg : pkgs) { 4130 synchronized (ActivityManagerService.this) { 4131 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4132 setResultCode(Activity.RESULT_OK); 4133 return; 4134 } 4135 } 4136 } 4137 } 4138 } 4139 }, pkgFilter); 4140 4141 IntentFilter userFilter = new IntentFilter(); 4142 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4143 mContext.registerReceiver(new BroadcastReceiver() { 4144 @Override 4145 public void onReceive(Context context, Intent intent) { 4146 onUserRemoved(intent); 4147 } 4148 }, userFilter); 4149 4150 synchronized (this) { 4151 // Ensure that any processes we had put on hold are now started 4152 // up. 4153 final int NP = mProcessesOnHold.size(); 4154 if (NP > 0) { 4155 ArrayList<ProcessRecord> procs = 4156 new ArrayList<ProcessRecord>(mProcessesOnHold); 4157 for (int ip=0; ip<NP; ip++) { 4158 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4159 + procs.get(ip)); 4160 startProcessLocked(procs.get(ip), "on-hold", null); 4161 } 4162 } 4163 4164 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4165 // Start looking for apps that are abusing wake locks. 4166 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4167 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4168 // Tell anyone interested that we are done booting! 4169 SystemProperties.set("sys.boot_completed", "1"); 4170 SystemProperties.set("dev.bootcomplete", "1"); 4171 /* TODO: Send this to all users that are to be logged in on startup */ 4172 broadcastIntentLocked(null, null, 4173 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4174 null, null, 0, null, null, 4175 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4176 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser()); 4177 } 4178 } 4179 } 4180 4181 final void ensureBootCompleted() { 4182 boolean booting; 4183 boolean enableScreen; 4184 synchronized (this) { 4185 booting = mBooting; 4186 mBooting = false; 4187 enableScreen = !mBooted; 4188 mBooted = true; 4189 } 4190 4191 if (booting) { 4192 finishBooting(); 4193 } 4194 4195 if (enableScreen) { 4196 enableScreenAfterBoot(); 4197 } 4198 } 4199 4200 public final void activityPaused(IBinder token) { 4201 final long origId = Binder.clearCallingIdentity(); 4202 mMainStack.activityPaused(token, false); 4203 Binder.restoreCallingIdentity(origId); 4204 } 4205 4206 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4207 CharSequence description) { 4208 if (localLOGV) Slog.v( 4209 TAG, "Activity stopped: token=" + token); 4210 4211 // Refuse possible leaked file descriptors 4212 if (icicle != null && icicle.hasFileDescriptors()) { 4213 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4214 } 4215 4216 ActivityRecord r = null; 4217 4218 final long origId = Binder.clearCallingIdentity(); 4219 4220 synchronized (this) { 4221 r = mMainStack.isInStackLocked(token); 4222 if (r != null) { 4223 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4224 } 4225 } 4226 4227 if (r != null) { 4228 sendPendingThumbnail(r, null, null, null, false); 4229 } 4230 4231 trimApplications(); 4232 4233 Binder.restoreCallingIdentity(origId); 4234 } 4235 4236 public final void activityDestroyed(IBinder token) { 4237 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4238 mMainStack.activityDestroyed(token); 4239 } 4240 4241 public String getCallingPackage(IBinder token) { 4242 synchronized (this) { 4243 ActivityRecord r = getCallingRecordLocked(token); 4244 return r != null && r.app != null ? r.info.packageName : null; 4245 } 4246 } 4247 4248 public ComponentName getCallingActivity(IBinder token) { 4249 synchronized (this) { 4250 ActivityRecord r = getCallingRecordLocked(token); 4251 return r != null ? r.intent.getComponent() : null; 4252 } 4253 } 4254 4255 private ActivityRecord getCallingRecordLocked(IBinder token) { 4256 ActivityRecord r = mMainStack.isInStackLocked(token); 4257 if (r == null) { 4258 return null; 4259 } 4260 return r.resultTo; 4261 } 4262 4263 public ComponentName getActivityClassForToken(IBinder token) { 4264 synchronized(this) { 4265 ActivityRecord r = mMainStack.isInStackLocked(token); 4266 if (r == null) { 4267 return null; 4268 } 4269 return r.intent.getComponent(); 4270 } 4271 } 4272 4273 public String getPackageForToken(IBinder token) { 4274 synchronized(this) { 4275 ActivityRecord r = mMainStack.isInStackLocked(token); 4276 if (r == null) { 4277 return null; 4278 } 4279 return r.packageName; 4280 } 4281 } 4282 4283 public IIntentSender getIntentSender(int type, 4284 String packageName, IBinder token, String resultWho, 4285 int requestCode, Intent[] intents, String[] resolvedTypes, 4286 int flags, Bundle options) { 4287 enforceNotIsolatedCaller("getIntentSender"); 4288 // Refuse possible leaked file descriptors 4289 if (intents != null) { 4290 if (intents.length < 1) { 4291 throw new IllegalArgumentException("Intents array length must be >= 1"); 4292 } 4293 for (int i=0; i<intents.length; i++) { 4294 Intent intent = intents[i]; 4295 if (intent != null) { 4296 if (intent.hasFileDescriptors()) { 4297 throw new IllegalArgumentException("File descriptors passed in Intent"); 4298 } 4299 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4300 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4301 throw new IllegalArgumentException( 4302 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4303 } 4304 intents[i] = new Intent(intent); 4305 } 4306 } 4307 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4308 throw new IllegalArgumentException( 4309 "Intent array length does not match resolvedTypes length"); 4310 } 4311 } 4312 if (options != null) { 4313 if (options.hasFileDescriptors()) { 4314 throw new IllegalArgumentException("File descriptors passed in options"); 4315 } 4316 } 4317 4318 synchronized(this) { 4319 int callingUid = Binder.getCallingUid(); 4320 try { 4321 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4322 int uid = AppGlobals.getPackageManager() 4323 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4324 if (!UserId.isSameApp(callingUid, uid)) { 4325 String msg = "Permission Denial: getIntentSender() from pid=" 4326 + Binder.getCallingPid() 4327 + ", uid=" + Binder.getCallingUid() 4328 + ", (need uid=" + uid + ")" 4329 + " is not allowed to send as package " + packageName; 4330 Slog.w(TAG, msg); 4331 throw new SecurityException(msg); 4332 } 4333 } 4334 4335 if (DEBUG_MU) 4336 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4337 + Binder.getOrigCallingUid()); 4338 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4339 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4340 4341 } catch (RemoteException e) { 4342 throw new SecurityException(e); 4343 } 4344 } 4345 } 4346 4347 IIntentSender getIntentSenderLocked(int type, 4348 String packageName, int callingUid, IBinder token, String resultWho, 4349 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4350 Bundle options) { 4351 if (DEBUG_MU) 4352 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4353 ActivityRecord activity = null; 4354 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4355 activity = mMainStack.isInStackLocked(token); 4356 if (activity == null) { 4357 return null; 4358 } 4359 if (activity.finishing) { 4360 return null; 4361 } 4362 } 4363 4364 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4365 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4366 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4367 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4368 |PendingIntent.FLAG_UPDATE_CURRENT); 4369 4370 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4371 type, packageName, activity, resultWho, 4372 requestCode, intents, resolvedTypes, flags, options); 4373 WeakReference<PendingIntentRecord> ref; 4374 ref = mIntentSenderRecords.get(key); 4375 PendingIntentRecord rec = ref != null ? ref.get() : null; 4376 if (rec != null) { 4377 if (!cancelCurrent) { 4378 if (updateCurrent) { 4379 if (rec.key.requestIntent != null) { 4380 rec.key.requestIntent.replaceExtras(intents != null ? 4381 intents[intents.length - 1] : null); 4382 } 4383 if (intents != null) { 4384 intents[intents.length-1] = rec.key.requestIntent; 4385 rec.key.allIntents = intents; 4386 rec.key.allResolvedTypes = resolvedTypes; 4387 } else { 4388 rec.key.allIntents = null; 4389 rec.key.allResolvedTypes = null; 4390 } 4391 } 4392 return rec; 4393 } 4394 rec.canceled = true; 4395 mIntentSenderRecords.remove(key); 4396 } 4397 if (noCreate) { 4398 return rec; 4399 } 4400 rec = new PendingIntentRecord(this, key, callingUid); 4401 mIntentSenderRecords.put(key, rec.ref); 4402 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4403 if (activity.pendingResults == null) { 4404 activity.pendingResults 4405 = new HashSet<WeakReference<PendingIntentRecord>>(); 4406 } 4407 activity.pendingResults.add(rec.ref); 4408 } 4409 return rec; 4410 } 4411 4412 public void cancelIntentSender(IIntentSender sender) { 4413 if (!(sender instanceof PendingIntentRecord)) { 4414 return; 4415 } 4416 synchronized(this) { 4417 PendingIntentRecord rec = (PendingIntentRecord)sender; 4418 try { 4419 int uid = AppGlobals.getPackageManager() 4420 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4421 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4422 String msg = "Permission Denial: cancelIntentSender() from pid=" 4423 + Binder.getCallingPid() 4424 + ", uid=" + Binder.getCallingUid() 4425 + " is not allowed to cancel packges " 4426 + rec.key.packageName; 4427 Slog.w(TAG, msg); 4428 throw new SecurityException(msg); 4429 } 4430 } catch (RemoteException e) { 4431 throw new SecurityException(e); 4432 } 4433 cancelIntentSenderLocked(rec, true); 4434 } 4435 } 4436 4437 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4438 rec.canceled = true; 4439 mIntentSenderRecords.remove(rec.key); 4440 if (cleanActivity && rec.key.activity != null) { 4441 rec.key.activity.pendingResults.remove(rec.ref); 4442 } 4443 } 4444 4445 public String getPackageForIntentSender(IIntentSender pendingResult) { 4446 if (!(pendingResult instanceof PendingIntentRecord)) { 4447 return null; 4448 } 4449 try { 4450 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4451 return res.key.packageName; 4452 } catch (ClassCastException e) { 4453 } 4454 return null; 4455 } 4456 4457 public int getUidForIntentSender(IIntentSender sender) { 4458 if (sender instanceof PendingIntentRecord) { 4459 try { 4460 PendingIntentRecord res = (PendingIntentRecord)sender; 4461 return res.uid; 4462 } catch (ClassCastException e) { 4463 } 4464 } 4465 return -1; 4466 } 4467 4468 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4469 if (!(pendingResult instanceof PendingIntentRecord)) { 4470 return false; 4471 } 4472 try { 4473 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4474 if (res.key.allIntents == null) { 4475 return false; 4476 } 4477 for (int i=0; i<res.key.allIntents.length; i++) { 4478 Intent intent = res.key.allIntents[i]; 4479 if (intent.getPackage() != null && intent.getComponent() != null) { 4480 return false; 4481 } 4482 } 4483 return true; 4484 } catch (ClassCastException e) { 4485 } 4486 return false; 4487 } 4488 4489 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4490 if (!(pendingResult instanceof PendingIntentRecord)) { 4491 return false; 4492 } 4493 try { 4494 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4495 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4496 return true; 4497 } 4498 return false; 4499 } catch (ClassCastException e) { 4500 } 4501 return false; 4502 } 4503 4504 public void setProcessLimit(int max) { 4505 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4506 "setProcessLimit()"); 4507 synchronized (this) { 4508 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4509 mProcessLimitOverride = max; 4510 } 4511 trimApplications(); 4512 } 4513 4514 public int getProcessLimit() { 4515 synchronized (this) { 4516 return mProcessLimitOverride; 4517 } 4518 } 4519 4520 void foregroundTokenDied(ForegroundToken token) { 4521 synchronized (ActivityManagerService.this) { 4522 synchronized (mPidsSelfLocked) { 4523 ForegroundToken cur 4524 = mForegroundProcesses.get(token.pid); 4525 if (cur != token) { 4526 return; 4527 } 4528 mForegroundProcesses.remove(token.pid); 4529 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4530 if (pr == null) { 4531 return; 4532 } 4533 pr.forcingToForeground = null; 4534 pr.foregroundServices = false; 4535 } 4536 updateOomAdjLocked(); 4537 } 4538 } 4539 4540 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4541 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4542 "setProcessForeground()"); 4543 synchronized(this) { 4544 boolean changed = false; 4545 4546 synchronized (mPidsSelfLocked) { 4547 ProcessRecord pr = mPidsSelfLocked.get(pid); 4548 if (pr == null && isForeground) { 4549 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4550 return; 4551 } 4552 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4553 if (oldToken != null) { 4554 oldToken.token.unlinkToDeath(oldToken, 0); 4555 mForegroundProcesses.remove(pid); 4556 if (pr != null) { 4557 pr.forcingToForeground = null; 4558 } 4559 changed = true; 4560 } 4561 if (isForeground && token != null) { 4562 ForegroundToken newToken = new ForegroundToken() { 4563 public void binderDied() { 4564 foregroundTokenDied(this); 4565 } 4566 }; 4567 newToken.pid = pid; 4568 newToken.token = token; 4569 try { 4570 token.linkToDeath(newToken, 0); 4571 mForegroundProcesses.put(pid, newToken); 4572 pr.forcingToForeground = token; 4573 changed = true; 4574 } catch (RemoteException e) { 4575 // If the process died while doing this, we will later 4576 // do the cleanup with the process death link. 4577 } 4578 } 4579 } 4580 4581 if (changed) { 4582 updateOomAdjLocked(); 4583 } 4584 } 4585 } 4586 4587 // ========================================================= 4588 // PERMISSIONS 4589 // ========================================================= 4590 4591 static class PermissionController extends IPermissionController.Stub { 4592 ActivityManagerService mActivityManagerService; 4593 PermissionController(ActivityManagerService activityManagerService) { 4594 mActivityManagerService = activityManagerService; 4595 } 4596 4597 public boolean checkPermission(String permission, int pid, int uid) { 4598 return mActivityManagerService.checkPermission(permission, pid, 4599 uid) == PackageManager.PERMISSION_GRANTED; 4600 } 4601 } 4602 4603 /** 4604 * This can be called with or without the global lock held. 4605 */ 4606 int checkComponentPermission(String permission, int pid, int uid, 4607 int owningUid, boolean exported) { 4608 // We might be performing an operation on behalf of an indirect binder 4609 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4610 // client identity accordingly before proceeding. 4611 Identity tlsIdentity = sCallerIdentity.get(); 4612 if (tlsIdentity != null) { 4613 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4614 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4615 uid = tlsIdentity.uid; 4616 pid = tlsIdentity.pid; 4617 } 4618 4619 if (pid == MY_PID) { 4620 return PackageManager.PERMISSION_GRANTED; 4621 } 4622 4623 return ActivityManager.checkComponentPermission(permission, uid, 4624 owningUid, exported); 4625 } 4626 4627 /** 4628 * As the only public entry point for permissions checking, this method 4629 * can enforce the semantic that requesting a check on a null global 4630 * permission is automatically denied. (Internally a null permission 4631 * string is used when calling {@link #checkComponentPermission} in cases 4632 * when only uid-based security is needed.) 4633 * 4634 * This can be called with or without the global lock held. 4635 */ 4636 public int checkPermission(String permission, int pid, int uid) { 4637 if (permission == null) { 4638 return PackageManager.PERMISSION_DENIED; 4639 } 4640 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4641 } 4642 4643 /** 4644 * Binder IPC calls go through the public entry point. 4645 * This can be called with or without the global lock held. 4646 */ 4647 int checkCallingPermission(String permission) { 4648 return checkPermission(permission, 4649 Binder.getCallingPid(), 4650 UserId.getAppId(Binder.getCallingUid())); 4651 } 4652 4653 /** 4654 * This can be called with or without the global lock held. 4655 */ 4656 void enforceCallingPermission(String permission, String func) { 4657 if (checkCallingPermission(permission) 4658 == PackageManager.PERMISSION_GRANTED) { 4659 return; 4660 } 4661 4662 String msg = "Permission Denial: " + func + " from pid=" 4663 + Binder.getCallingPid() 4664 + ", uid=" + Binder.getCallingUid() 4665 + " requires " + permission; 4666 Slog.w(TAG, msg); 4667 throw new SecurityException(msg); 4668 } 4669 4670 /** 4671 * Determine if UID is holding permissions required to access {@link Uri} in 4672 * the given {@link ProviderInfo}. Final permission checking is always done 4673 * in {@link ContentProvider}. 4674 */ 4675 private final boolean checkHoldingPermissionsLocked( 4676 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4677 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4678 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4679 4680 if (pi.applicationInfo.uid == uid) { 4681 return true; 4682 } else if (!pi.exported) { 4683 return false; 4684 } 4685 4686 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4687 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4688 try { 4689 // check if target holds top-level <provider> permissions 4690 if (!readMet && pi.readPermission != null 4691 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4692 readMet = true; 4693 } 4694 if (!writeMet && pi.writePermission != null 4695 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4696 writeMet = true; 4697 } 4698 4699 // track if unprotected read/write is allowed; any denied 4700 // <path-permission> below removes this ability 4701 boolean allowDefaultRead = pi.readPermission == null; 4702 boolean allowDefaultWrite = pi.writePermission == null; 4703 4704 // check if target holds any <path-permission> that match uri 4705 final PathPermission[] pps = pi.pathPermissions; 4706 if (pps != null) { 4707 final String path = uri.getPath(); 4708 int i = pps.length; 4709 while (i > 0 && (!readMet || !writeMet)) { 4710 i--; 4711 PathPermission pp = pps[i]; 4712 if (pp.match(path)) { 4713 if (!readMet) { 4714 final String pprperm = pp.getReadPermission(); 4715 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4716 + pprperm + " for " + pp.getPath() 4717 + ": match=" + pp.match(path) 4718 + " check=" + pm.checkUidPermission(pprperm, uid)); 4719 if (pprperm != null) { 4720 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4721 readMet = true; 4722 } else { 4723 allowDefaultRead = false; 4724 } 4725 } 4726 } 4727 if (!writeMet) { 4728 final String ppwperm = pp.getWritePermission(); 4729 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4730 + ppwperm + " for " + pp.getPath() 4731 + ": match=" + pp.match(path) 4732 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4733 if (ppwperm != null) { 4734 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4735 writeMet = true; 4736 } else { 4737 allowDefaultWrite = false; 4738 } 4739 } 4740 } 4741 } 4742 } 4743 } 4744 4745 // grant unprotected <provider> read/write, if not blocked by 4746 // <path-permission> above 4747 if (allowDefaultRead) readMet = true; 4748 if (allowDefaultWrite) writeMet = true; 4749 4750 } catch (RemoteException e) { 4751 return false; 4752 } 4753 4754 return readMet && writeMet; 4755 } 4756 4757 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4758 int modeFlags) { 4759 // Root gets to do everything. 4760 if (uid == 0) { 4761 return true; 4762 } 4763 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4764 if (perms == null) return false; 4765 UriPermission perm = perms.get(uri); 4766 if (perm == null) return false; 4767 return (modeFlags&perm.modeFlags) == modeFlags; 4768 } 4769 4770 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4771 enforceNotIsolatedCaller("checkUriPermission"); 4772 4773 // Another redirected-binder-call permissions check as in 4774 // {@link checkComponentPermission}. 4775 Identity tlsIdentity = sCallerIdentity.get(); 4776 if (tlsIdentity != null) { 4777 uid = tlsIdentity.uid; 4778 pid = tlsIdentity.pid; 4779 } 4780 4781 uid = UserId.getAppId(uid); 4782 // Our own process gets to do everything. 4783 if (pid == MY_PID) { 4784 return PackageManager.PERMISSION_GRANTED; 4785 } 4786 synchronized(this) { 4787 return checkUriPermissionLocked(uri, uid, modeFlags) 4788 ? PackageManager.PERMISSION_GRANTED 4789 : PackageManager.PERMISSION_DENIED; 4790 } 4791 } 4792 4793 /** 4794 * Check if the targetPkg can be granted permission to access uri by 4795 * the callingUid using the given modeFlags. Throws a security exception 4796 * if callingUid is not allowed to do this. Returns the uid of the target 4797 * if the URI permission grant should be performed; returns -1 if it is not 4798 * needed (for example targetPkg already has permission to access the URI). 4799 * If you already know the uid of the target, you can supply it in 4800 * lastTargetUid else set that to -1. 4801 */ 4802 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4803 Uri uri, int modeFlags, int lastTargetUid) { 4804 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4805 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4806 if (modeFlags == 0) { 4807 return -1; 4808 } 4809 4810 if (targetPkg != null) { 4811 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4812 "Checking grant " + targetPkg + " permission to " + uri); 4813 } 4814 4815 final IPackageManager pm = AppGlobals.getPackageManager(); 4816 4817 // If this is not a content: uri, we can't do anything with it. 4818 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4819 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4820 "Can't grant URI permission for non-content URI: " + uri); 4821 return -1; 4822 } 4823 4824 String name = uri.getAuthority(); 4825 ProviderInfo pi = null; 4826 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4827 UserId.getUserId(callingUid)); 4828 if (cpr != null) { 4829 pi = cpr.info; 4830 } else { 4831 try { 4832 pi = pm.resolveContentProvider(name, 4833 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4834 } catch (RemoteException ex) { 4835 } 4836 } 4837 if (pi == null) { 4838 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4839 return -1; 4840 } 4841 4842 int targetUid = lastTargetUid; 4843 if (targetUid < 0 && targetPkg != null) { 4844 try { 4845 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4846 if (targetUid < 0) { 4847 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4848 "Can't grant URI permission no uid for: " + targetPkg); 4849 return -1; 4850 } 4851 } catch (RemoteException ex) { 4852 return -1; 4853 } 4854 } 4855 4856 if (targetUid >= 0) { 4857 // First... does the target actually need this permission? 4858 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4859 // No need to grant the target this permission. 4860 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4861 "Target " + targetPkg + " already has full permission to " + uri); 4862 return -1; 4863 } 4864 } else { 4865 // First... there is no target package, so can anyone access it? 4866 boolean allowed = pi.exported; 4867 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4868 if (pi.readPermission != null) { 4869 allowed = false; 4870 } 4871 } 4872 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4873 if (pi.writePermission != null) { 4874 allowed = false; 4875 } 4876 } 4877 if (allowed) { 4878 return -1; 4879 } 4880 } 4881 4882 // Second... is the provider allowing granting of URI permissions? 4883 if (!pi.grantUriPermissions) { 4884 throw new SecurityException("Provider " + pi.packageName 4885 + "/" + pi.name 4886 + " does not allow granting of Uri permissions (uri " 4887 + uri + ")"); 4888 } 4889 if (pi.uriPermissionPatterns != null) { 4890 final int N = pi.uriPermissionPatterns.length; 4891 boolean allowed = false; 4892 for (int i=0; i<N; i++) { 4893 if (pi.uriPermissionPatterns[i] != null 4894 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4895 allowed = true; 4896 break; 4897 } 4898 } 4899 if (!allowed) { 4900 throw new SecurityException("Provider " + pi.packageName 4901 + "/" + pi.name 4902 + " does not allow granting of permission to path of Uri " 4903 + uri); 4904 } 4905 } 4906 4907 // Third... does the caller itself have permission to access 4908 // this uri? 4909 if (callingUid != Process.myUid()) { 4910 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4911 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4912 throw new SecurityException("Uid " + callingUid 4913 + " does not have permission to uri " + uri); 4914 } 4915 } 4916 } 4917 4918 return targetUid; 4919 } 4920 4921 public int checkGrantUriPermission(int callingUid, String targetPkg, 4922 Uri uri, int modeFlags) { 4923 enforceNotIsolatedCaller("checkGrantUriPermission"); 4924 synchronized(this) { 4925 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4926 } 4927 } 4928 4929 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4930 Uri uri, int modeFlags, UriPermissionOwner owner) { 4931 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4932 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4933 if (modeFlags == 0) { 4934 return; 4935 } 4936 4937 // So here we are: the caller has the assumed permission 4938 // to the uri, and the target doesn't. Let's now give this to 4939 // the target. 4940 4941 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4942 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4943 4944 HashMap<Uri, UriPermission> targetUris 4945 = mGrantedUriPermissions.get(targetUid); 4946 if (targetUris == null) { 4947 targetUris = new HashMap<Uri, UriPermission>(); 4948 mGrantedUriPermissions.put(targetUid, targetUris); 4949 } 4950 4951 UriPermission perm = targetUris.get(uri); 4952 if (perm == null) { 4953 perm = new UriPermission(targetUid, uri); 4954 targetUris.put(uri, perm); 4955 } 4956 4957 perm.modeFlags |= modeFlags; 4958 if (owner == null) { 4959 perm.globalModeFlags |= modeFlags; 4960 } else { 4961 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4962 perm.readOwners.add(owner); 4963 owner.addReadPermission(perm); 4964 } 4965 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4966 perm.writeOwners.add(owner); 4967 owner.addWritePermission(perm); 4968 } 4969 } 4970 } 4971 4972 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 4973 int modeFlags, UriPermissionOwner owner) { 4974 if (targetPkg == null) { 4975 throw new NullPointerException("targetPkg"); 4976 } 4977 4978 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4979 if (targetUid < 0) { 4980 return; 4981 } 4982 4983 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 4984 } 4985 4986 static class NeededUriGrants extends ArrayList<Uri> { 4987 final String targetPkg; 4988 final int targetUid; 4989 final int flags; 4990 4991 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 4992 targetPkg = _targetPkg; 4993 targetUid = _targetUid; 4994 flags = _flags; 4995 } 4996 } 4997 4998 /** 4999 * Like checkGrantUriPermissionLocked, but takes an Intent. 5000 */ 5001 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5002 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5003 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5004 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5005 + " clip=" + (intent != null ? intent.getClipData() : null) 5006 + " from " + intent + "; flags=0x" 5007 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5008 5009 if (targetPkg == null) { 5010 throw new NullPointerException("targetPkg"); 5011 } 5012 5013 if (intent == null) { 5014 return null; 5015 } 5016 Uri data = intent.getData(); 5017 ClipData clip = intent.getClipData(); 5018 if (data == null && clip == null) { 5019 return null; 5020 } 5021 if (data != null) { 5022 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5023 mode, needed != null ? needed.targetUid : -1); 5024 if (target > 0) { 5025 if (needed == null) { 5026 needed = new NeededUriGrants(targetPkg, target, mode); 5027 } 5028 needed.add(data); 5029 } 5030 } 5031 if (clip != null) { 5032 for (int i=0; i<clip.getItemCount(); i++) { 5033 Uri uri = clip.getItemAt(i).getUri(); 5034 if (uri != null) { 5035 int target = -1; 5036 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5037 mode, needed != null ? needed.targetUid : -1); 5038 if (target > 0) { 5039 if (needed == null) { 5040 needed = new NeededUriGrants(targetPkg, target, mode); 5041 } 5042 needed.add(uri); 5043 } 5044 } else { 5045 Intent clipIntent = clip.getItemAt(i).getIntent(); 5046 if (clipIntent != null) { 5047 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5048 callingUid, targetPkg, clipIntent, mode, needed); 5049 if (newNeeded != null) { 5050 needed = newNeeded; 5051 } 5052 } 5053 } 5054 } 5055 } 5056 5057 return needed; 5058 } 5059 5060 /** 5061 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5062 */ 5063 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5064 UriPermissionOwner owner) { 5065 if (needed != null) { 5066 for (int i=0; i<needed.size(); i++) { 5067 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5068 needed.get(i), needed.flags, owner); 5069 } 5070 } 5071 } 5072 5073 void grantUriPermissionFromIntentLocked(int callingUid, 5074 String targetPkg, Intent intent, UriPermissionOwner owner) { 5075 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5076 intent, intent != null ? intent.getFlags() : 0, null); 5077 if (needed == null) { 5078 return; 5079 } 5080 5081 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5082 } 5083 5084 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5085 Uri uri, int modeFlags) { 5086 enforceNotIsolatedCaller("grantUriPermission"); 5087 synchronized(this) { 5088 final ProcessRecord r = getRecordForAppLocked(caller); 5089 if (r == null) { 5090 throw new SecurityException("Unable to find app for caller " 5091 + caller 5092 + " when granting permission to uri " + uri); 5093 } 5094 if (targetPkg == null) { 5095 throw new IllegalArgumentException("null target"); 5096 } 5097 if (uri == null) { 5098 throw new IllegalArgumentException("null uri"); 5099 } 5100 5101 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5102 null); 5103 } 5104 } 5105 5106 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5107 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5108 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5109 HashMap<Uri, UriPermission> perms 5110 = mGrantedUriPermissions.get(perm.uid); 5111 if (perms != null) { 5112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5113 "Removing " + perm.uid + " permission to " + perm.uri); 5114 perms.remove(perm.uri); 5115 if (perms.size() == 0) { 5116 mGrantedUriPermissions.remove(perm.uid); 5117 } 5118 } 5119 } 5120 } 5121 5122 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5123 int modeFlags) { 5124 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5125 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5126 if (modeFlags == 0) { 5127 return; 5128 } 5129 5130 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5131 "Revoking all granted permissions to " + uri); 5132 5133 final IPackageManager pm = AppGlobals.getPackageManager(); 5134 5135 final String authority = uri.getAuthority(); 5136 ProviderInfo pi = null; 5137 int userId = UserId.getUserId(callingUid); 5138 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5139 if (cpr != null) { 5140 pi = cpr.info; 5141 } else { 5142 try { 5143 pi = pm.resolveContentProvider(authority, 5144 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5145 } catch (RemoteException ex) { 5146 } 5147 } 5148 if (pi == null) { 5149 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5150 return; 5151 } 5152 5153 // Does the caller have this permission on the URI? 5154 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5155 // Right now, if you are not the original owner of the permission, 5156 // you are not allowed to revoke it. 5157 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5158 throw new SecurityException("Uid " + callingUid 5159 + " does not have permission to uri " + uri); 5160 //} 5161 } 5162 5163 // Go through all of the permissions and remove any that match. 5164 final List<String> SEGMENTS = uri.getPathSegments(); 5165 if (SEGMENTS != null) { 5166 final int NS = SEGMENTS.size(); 5167 int N = mGrantedUriPermissions.size(); 5168 for (int i=0; i<N; i++) { 5169 HashMap<Uri, UriPermission> perms 5170 = mGrantedUriPermissions.valueAt(i); 5171 Iterator<UriPermission> it = perms.values().iterator(); 5172 toploop: 5173 while (it.hasNext()) { 5174 UriPermission perm = it.next(); 5175 Uri targetUri = perm.uri; 5176 if (!authority.equals(targetUri.getAuthority())) { 5177 continue; 5178 } 5179 List<String> targetSegments = targetUri.getPathSegments(); 5180 if (targetSegments == null) { 5181 continue; 5182 } 5183 if (targetSegments.size() < NS) { 5184 continue; 5185 } 5186 for (int j=0; j<NS; j++) { 5187 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5188 continue toploop; 5189 } 5190 } 5191 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5192 "Revoking " + perm.uid + " permission to " + perm.uri); 5193 perm.clearModes(modeFlags); 5194 if (perm.modeFlags == 0) { 5195 it.remove(); 5196 } 5197 } 5198 if (perms.size() == 0) { 5199 mGrantedUriPermissions.remove( 5200 mGrantedUriPermissions.keyAt(i)); 5201 N--; 5202 i--; 5203 } 5204 } 5205 } 5206 } 5207 5208 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5209 int modeFlags) { 5210 enforceNotIsolatedCaller("revokeUriPermission"); 5211 synchronized(this) { 5212 final ProcessRecord r = getRecordForAppLocked(caller); 5213 if (r == null) { 5214 throw new SecurityException("Unable to find app for caller " 5215 + caller 5216 + " when revoking permission to uri " + uri); 5217 } 5218 if (uri == null) { 5219 Slog.w(TAG, "revokeUriPermission: null uri"); 5220 return; 5221 } 5222 5223 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5224 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5225 if (modeFlags == 0) { 5226 return; 5227 } 5228 5229 final IPackageManager pm = AppGlobals.getPackageManager(); 5230 5231 final String authority = uri.getAuthority(); 5232 ProviderInfo pi = null; 5233 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5234 if (cpr != null) { 5235 pi = cpr.info; 5236 } else { 5237 try { 5238 pi = pm.resolveContentProvider(authority, 5239 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5240 } catch (RemoteException ex) { 5241 } 5242 } 5243 if (pi == null) { 5244 Slog.w(TAG, "No content provider found for permission revoke: " 5245 + uri.toSafeString()); 5246 return; 5247 } 5248 5249 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5250 } 5251 } 5252 5253 @Override 5254 public IBinder newUriPermissionOwner(String name) { 5255 enforceNotIsolatedCaller("newUriPermissionOwner"); 5256 synchronized(this) { 5257 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5258 return owner.getExternalTokenLocked(); 5259 } 5260 } 5261 5262 @Override 5263 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5264 Uri uri, int modeFlags) { 5265 synchronized(this) { 5266 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5267 if (owner == null) { 5268 throw new IllegalArgumentException("Unknown owner: " + token); 5269 } 5270 if (fromUid != Binder.getCallingUid()) { 5271 if (Binder.getCallingUid() != Process.myUid()) { 5272 // Only system code can grant URI permissions on behalf 5273 // of other users. 5274 throw new SecurityException("nice try"); 5275 } 5276 } 5277 if (targetPkg == null) { 5278 throw new IllegalArgumentException("null target"); 5279 } 5280 if (uri == null) { 5281 throw new IllegalArgumentException("null uri"); 5282 } 5283 5284 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5285 } 5286 } 5287 5288 @Override 5289 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5290 synchronized(this) { 5291 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5292 if (owner == null) { 5293 throw new IllegalArgumentException("Unknown owner: " + token); 5294 } 5295 5296 if (uri == null) { 5297 owner.removeUriPermissionsLocked(mode); 5298 } else { 5299 owner.removeUriPermissionLocked(uri, mode); 5300 } 5301 } 5302 } 5303 5304 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5305 synchronized (this) { 5306 ProcessRecord app = 5307 who != null ? getRecordForAppLocked(who) : null; 5308 if (app == null) return; 5309 5310 Message msg = Message.obtain(); 5311 msg.what = WAIT_FOR_DEBUGGER_MSG; 5312 msg.obj = app; 5313 msg.arg1 = waiting ? 1 : 0; 5314 mHandler.sendMessage(msg); 5315 } 5316 } 5317 5318 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5319 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5320 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5321 outInfo.availMem = Process.getFreeMemory(); 5322 outInfo.totalMem = Process.getTotalMemory(); 5323 outInfo.threshold = homeAppMem; 5324 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5325 outInfo.hiddenAppThreshold = hiddenAppMem; 5326 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5327 ProcessList.SERVICE_ADJ); 5328 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5329 ProcessList.VISIBLE_APP_ADJ); 5330 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5331 ProcessList.FOREGROUND_APP_ADJ); 5332 } 5333 5334 // ========================================================= 5335 // TASK MANAGEMENT 5336 // ========================================================= 5337 5338 public List getTasks(int maxNum, int flags, 5339 IThumbnailReceiver receiver) { 5340 ArrayList list = new ArrayList(); 5341 5342 PendingThumbnailsRecord pending = null; 5343 IApplicationThread topThumbnail = null; 5344 ActivityRecord topRecord = null; 5345 5346 synchronized(this) { 5347 if (localLOGV) Slog.v( 5348 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5349 + ", receiver=" + receiver); 5350 5351 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5352 != PackageManager.PERMISSION_GRANTED) { 5353 if (receiver != null) { 5354 // If the caller wants to wait for pending thumbnails, 5355 // it ain't gonna get them. 5356 try { 5357 receiver.finished(); 5358 } catch (RemoteException ex) { 5359 } 5360 } 5361 String msg = "Permission Denial: getTasks() from pid=" 5362 + Binder.getCallingPid() 5363 + ", uid=" + Binder.getCallingUid() 5364 + " requires " + android.Manifest.permission.GET_TASKS; 5365 Slog.w(TAG, msg); 5366 throw new SecurityException(msg); 5367 } 5368 5369 int pos = mMainStack.mHistory.size()-1; 5370 ActivityRecord next = 5371 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5372 ActivityRecord top = null; 5373 TaskRecord curTask = null; 5374 int numActivities = 0; 5375 int numRunning = 0; 5376 while (pos >= 0 && maxNum > 0) { 5377 final ActivityRecord r = next; 5378 pos--; 5379 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5380 5381 // Initialize state for next task if needed. 5382 if (top == null || 5383 (top.state == ActivityState.INITIALIZING 5384 && top.task == r.task)) { 5385 top = r; 5386 curTask = r.task; 5387 numActivities = numRunning = 0; 5388 } 5389 5390 // Add 'r' into the current task. 5391 numActivities++; 5392 if (r.app != null && r.app.thread != null) { 5393 numRunning++; 5394 } 5395 5396 if (localLOGV) Slog.v( 5397 TAG, r.intent.getComponent().flattenToShortString() 5398 + ": task=" + r.task); 5399 5400 // If the next one is a different task, generate a new 5401 // TaskInfo entry for what we have. 5402 if (next == null || next.task != curTask) { 5403 ActivityManager.RunningTaskInfo ci 5404 = new ActivityManager.RunningTaskInfo(); 5405 ci.id = curTask.taskId; 5406 ci.baseActivity = r.intent.getComponent(); 5407 ci.topActivity = top.intent.getComponent(); 5408 if (top.thumbHolder != null) { 5409 ci.description = top.thumbHolder.lastDescription; 5410 } 5411 ci.numActivities = numActivities; 5412 ci.numRunning = numRunning; 5413 //System.out.println( 5414 // "#" + maxNum + ": " + " descr=" + ci.description); 5415 if (ci.thumbnail == null && receiver != null) { 5416 if (localLOGV) Slog.v( 5417 TAG, "State=" + top.state + "Idle=" + top.idle 5418 + " app=" + top.app 5419 + " thr=" + (top.app != null ? top.app.thread : null)); 5420 if (top.state == ActivityState.RESUMED 5421 || top.state == ActivityState.PAUSING) { 5422 if (top.idle && top.app != null 5423 && top.app.thread != null) { 5424 topRecord = top; 5425 topThumbnail = top.app.thread; 5426 } else { 5427 top.thumbnailNeeded = true; 5428 } 5429 } 5430 if (pending == null) { 5431 pending = new PendingThumbnailsRecord(receiver); 5432 } 5433 pending.pendingRecords.add(top); 5434 } 5435 list.add(ci); 5436 maxNum--; 5437 top = null; 5438 } 5439 } 5440 5441 if (pending != null) { 5442 mPendingThumbnails.add(pending); 5443 } 5444 } 5445 5446 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5447 5448 if (topThumbnail != null) { 5449 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5450 try { 5451 topThumbnail.requestThumbnail(topRecord.appToken); 5452 } catch (Exception e) { 5453 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5454 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5455 } 5456 } 5457 5458 if (pending == null && receiver != null) { 5459 // In this case all thumbnails were available and the client 5460 // is being asked to be told when the remaining ones come in... 5461 // which is unusually, since the top-most currently running 5462 // activity should never have a canned thumbnail! Oh well. 5463 try { 5464 receiver.finished(); 5465 } catch (RemoteException ex) { 5466 } 5467 } 5468 5469 return list; 5470 } 5471 5472 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5473 int flags) { 5474 final int callingUid = Binder.getCallingUid(); 5475 // If it's the system uid asking, then use the current user id. 5476 // TODO: Make sure that there aren't any other legitimate calls from the system uid that 5477 // require the entire list. 5478 final int callingUserId = callingUid == Process.SYSTEM_UID 5479 ? mCurrentUserId : UserId.getUserId(callingUid); 5480 synchronized (this) { 5481 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5482 "getRecentTasks()"); 5483 final boolean detailed = checkCallingPermission( 5484 android.Manifest.permission.GET_DETAILED_TASKS) 5485 == PackageManager.PERMISSION_GRANTED; 5486 5487 IPackageManager pm = AppGlobals.getPackageManager(); 5488 5489 final int N = mRecentTasks.size(); 5490 ArrayList<ActivityManager.RecentTaskInfo> res 5491 = new ArrayList<ActivityManager.RecentTaskInfo>( 5492 maxNum < N ? maxNum : N); 5493 for (int i=0; i<N && maxNum > 0; i++) { 5494 TaskRecord tr = mRecentTasks.get(i); 5495 // Only add calling user's recent tasks 5496 if (tr.userId != callingUserId) continue; 5497 // Return the entry if desired by the caller. We always return 5498 // the first entry, because callers always expect this to be the 5499 // foreground app. We may filter others if the caller has 5500 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5501 // we should exclude the entry. 5502 5503 if (i == 0 5504 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5505 || (tr.intent == null) 5506 || ((tr.intent.getFlags() 5507 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5508 ActivityManager.RecentTaskInfo rti 5509 = new ActivityManager.RecentTaskInfo(); 5510 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5511 rti.persistentId = tr.taskId; 5512 rti.baseIntent = new Intent( 5513 tr.intent != null ? tr.intent : tr.affinityIntent); 5514 if (!detailed) { 5515 rti.baseIntent.replaceExtras((Bundle)null); 5516 } 5517 rti.origActivity = tr.origActivity; 5518 rti.description = tr.lastDescription; 5519 5520 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5521 // Check whether this activity is currently available. 5522 try { 5523 if (rti.origActivity != null) { 5524 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId) 5525 == null) { 5526 continue; 5527 } 5528 } else if (rti.baseIntent != null) { 5529 if (pm.queryIntentActivities(rti.baseIntent, 5530 null, 0, callingUserId) == null) { 5531 continue; 5532 } 5533 } 5534 } catch (RemoteException e) { 5535 // Will never happen. 5536 } 5537 } 5538 5539 res.add(rti); 5540 maxNum--; 5541 } 5542 } 5543 return res; 5544 } 5545 } 5546 5547 private TaskRecord taskForIdLocked(int id) { 5548 final int N = mRecentTasks.size(); 5549 for (int i=0; i<N; i++) { 5550 TaskRecord tr = mRecentTasks.get(i); 5551 if (tr.taskId == id) { 5552 return tr; 5553 } 5554 } 5555 return null; 5556 } 5557 5558 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5559 synchronized (this) { 5560 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5561 "getTaskThumbnails()"); 5562 TaskRecord tr = taskForIdLocked(id); 5563 if (tr != null) { 5564 return mMainStack.getTaskThumbnailsLocked(tr); 5565 } 5566 } 5567 return null; 5568 } 5569 5570 public boolean removeSubTask(int taskId, int subTaskIndex) { 5571 synchronized (this) { 5572 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5573 "removeSubTask()"); 5574 long ident = Binder.clearCallingIdentity(); 5575 try { 5576 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5577 true) != null; 5578 } finally { 5579 Binder.restoreCallingIdentity(ident); 5580 } 5581 } 5582 } 5583 5584 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5585 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5586 Intent baseIntent = new Intent( 5587 tr.intent != null ? tr.intent : tr.affinityIntent); 5588 ComponentName component = baseIntent.getComponent(); 5589 if (component == null) { 5590 Slog.w(TAG, "Now component for base intent of task: " + tr); 5591 return; 5592 } 5593 5594 // Find any running services associated with this app. 5595 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5596 5597 if (killProcesses) { 5598 // Find any running processes associated with this app. 5599 final String pkg = component.getPackageName(); 5600 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5601 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5602 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5603 for (int i=0; i<uids.size(); i++) { 5604 ProcessRecord proc = uids.valueAt(i); 5605 if (proc.userId != tr.userId) { 5606 continue; 5607 } 5608 if (!proc.pkgList.contains(pkg)) { 5609 continue; 5610 } 5611 procs.add(proc); 5612 } 5613 } 5614 5615 // Kill the running processes. 5616 for (int i=0; i<procs.size(); i++) { 5617 ProcessRecord pr = procs.get(i); 5618 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5619 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5620 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5621 pr.processName, pr.setAdj, "remove task"); 5622 pr.killedBackground = true; 5623 Process.killProcessQuiet(pr.pid); 5624 } else { 5625 pr.waitingToKill = "remove task"; 5626 } 5627 } 5628 } 5629 } 5630 5631 public boolean removeTask(int taskId, int flags) { 5632 synchronized (this) { 5633 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5634 "removeTask()"); 5635 long ident = Binder.clearCallingIdentity(); 5636 try { 5637 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5638 false); 5639 if (r != null) { 5640 mRecentTasks.remove(r.task); 5641 cleanUpRemovedTaskLocked(r.task, flags); 5642 return true; 5643 } else { 5644 TaskRecord tr = null; 5645 int i=0; 5646 while (i < mRecentTasks.size()) { 5647 TaskRecord t = mRecentTasks.get(i); 5648 if (t.taskId == taskId) { 5649 tr = t; 5650 break; 5651 } 5652 i++; 5653 } 5654 if (tr != null) { 5655 if (tr.numActivities <= 0) { 5656 // Caller is just removing a recent task that is 5657 // not actively running. That is easy! 5658 mRecentTasks.remove(i); 5659 cleanUpRemovedTaskLocked(tr, flags); 5660 return true; 5661 } else { 5662 Slog.w(TAG, "removeTask: task " + taskId 5663 + " does not have activities to remove, " 5664 + " but numActivities=" + tr.numActivities 5665 + ": " + tr); 5666 } 5667 } 5668 } 5669 } finally { 5670 Binder.restoreCallingIdentity(ident); 5671 } 5672 } 5673 return false; 5674 } 5675 5676 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5677 int j; 5678 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5679 TaskRecord jt = startTask; 5680 5681 // First look backwards 5682 for (j=startIndex-1; j>=0; j--) { 5683 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5684 if (r.task != jt) { 5685 jt = r.task; 5686 if (affinity.equals(jt.affinity)) { 5687 return j; 5688 } 5689 } 5690 } 5691 5692 // Now look forwards 5693 final int N = mMainStack.mHistory.size(); 5694 jt = startTask; 5695 for (j=startIndex+1; j<N; j++) { 5696 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5697 if (r.task != jt) { 5698 if (affinity.equals(jt.affinity)) { 5699 return j; 5700 } 5701 jt = r.task; 5702 } 5703 } 5704 5705 // Might it be at the top? 5706 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5707 return N-1; 5708 } 5709 5710 return -1; 5711 } 5712 5713 /** 5714 * TODO: Add mController hook 5715 */ 5716 public void moveTaskToFront(int task, int flags, Bundle options) { 5717 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5718 "moveTaskToFront()"); 5719 5720 synchronized(this) { 5721 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5722 Binder.getCallingUid(), "Task to front")) { 5723 ActivityOptions.abort(options); 5724 return; 5725 } 5726 final long origId = Binder.clearCallingIdentity(); 5727 try { 5728 TaskRecord tr = taskForIdLocked(task); 5729 if (tr != null) { 5730 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5731 mMainStack.mUserLeaving = true; 5732 } 5733 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5734 // Caller wants the home activity moved with it. To accomplish this, 5735 // we'll just move the home task to the top first. 5736 mMainStack.moveHomeToFrontLocked(); 5737 } 5738 mMainStack.moveTaskToFrontLocked(tr, null, options); 5739 return; 5740 } 5741 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5742 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5743 if (hr.task.taskId == task) { 5744 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5745 mMainStack.mUserLeaving = true; 5746 } 5747 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5748 // Caller wants the home activity moved with it. To accomplish this, 5749 // we'll just move the home task to the top first. 5750 mMainStack.moveHomeToFrontLocked(); 5751 } 5752 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5753 return; 5754 } 5755 } 5756 } finally { 5757 Binder.restoreCallingIdentity(origId); 5758 } 5759 ActivityOptions.abort(options); 5760 } 5761 } 5762 5763 public void moveTaskToBack(int task) { 5764 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5765 "moveTaskToBack()"); 5766 5767 synchronized(this) { 5768 if (mMainStack.mResumedActivity != null 5769 && mMainStack.mResumedActivity.task.taskId == task) { 5770 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5771 Binder.getCallingUid(), "Task to back")) { 5772 return; 5773 } 5774 } 5775 final long origId = Binder.clearCallingIdentity(); 5776 mMainStack.moveTaskToBackLocked(task, null); 5777 Binder.restoreCallingIdentity(origId); 5778 } 5779 } 5780 5781 /** 5782 * Moves an activity, and all of the other activities within the same task, to the bottom 5783 * of the history stack. The activity's order within the task is unchanged. 5784 * 5785 * @param token A reference to the activity we wish to move 5786 * @param nonRoot If false then this only works if the activity is the root 5787 * of a task; if true it will work for any activity in a task. 5788 * @return Returns true if the move completed, false if not. 5789 */ 5790 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5791 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5792 synchronized(this) { 5793 final long origId = Binder.clearCallingIdentity(); 5794 int taskId = getTaskForActivityLocked(token, !nonRoot); 5795 if (taskId >= 0) { 5796 return mMainStack.moveTaskToBackLocked(taskId, null); 5797 } 5798 Binder.restoreCallingIdentity(origId); 5799 } 5800 return false; 5801 } 5802 5803 public void moveTaskBackwards(int task) { 5804 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5805 "moveTaskBackwards()"); 5806 5807 synchronized(this) { 5808 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5809 Binder.getCallingUid(), "Task backwards")) { 5810 return; 5811 } 5812 final long origId = Binder.clearCallingIdentity(); 5813 moveTaskBackwardsLocked(task); 5814 Binder.restoreCallingIdentity(origId); 5815 } 5816 } 5817 5818 private final void moveTaskBackwardsLocked(int task) { 5819 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5820 } 5821 5822 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5823 synchronized(this) { 5824 return getTaskForActivityLocked(token, onlyRoot); 5825 } 5826 } 5827 5828 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5829 final int N = mMainStack.mHistory.size(); 5830 TaskRecord lastTask = null; 5831 for (int i=0; i<N; i++) { 5832 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5833 if (r.appToken == token) { 5834 if (!onlyRoot || lastTask != r.task) { 5835 return r.task.taskId; 5836 } 5837 return -1; 5838 } 5839 lastTask = r.task; 5840 } 5841 5842 return -1; 5843 } 5844 5845 // ========================================================= 5846 // THUMBNAILS 5847 // ========================================================= 5848 5849 public void reportThumbnail(IBinder token, 5850 Bitmap thumbnail, CharSequence description) { 5851 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5852 final long origId = Binder.clearCallingIdentity(); 5853 sendPendingThumbnail(null, token, thumbnail, description, true); 5854 Binder.restoreCallingIdentity(origId); 5855 } 5856 5857 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5858 Bitmap thumbnail, CharSequence description, boolean always) { 5859 TaskRecord task = null; 5860 ArrayList receivers = null; 5861 5862 //System.out.println("Send pending thumbnail: " + r); 5863 5864 synchronized(this) { 5865 if (r == null) { 5866 r = mMainStack.isInStackLocked(token); 5867 if (r == null) { 5868 return; 5869 } 5870 } 5871 if (thumbnail == null && r.thumbHolder != null) { 5872 thumbnail = r.thumbHolder.lastThumbnail; 5873 description = r.thumbHolder.lastDescription; 5874 } 5875 if (thumbnail == null && !always) { 5876 // If there is no thumbnail, and this entry is not actually 5877 // going away, then abort for now and pick up the next 5878 // thumbnail we get. 5879 return; 5880 } 5881 task = r.task; 5882 5883 int N = mPendingThumbnails.size(); 5884 int i=0; 5885 while (i<N) { 5886 PendingThumbnailsRecord pr = 5887 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5888 //System.out.println("Looking in " + pr.pendingRecords); 5889 if (pr.pendingRecords.remove(r)) { 5890 if (receivers == null) { 5891 receivers = new ArrayList(); 5892 } 5893 receivers.add(pr); 5894 if (pr.pendingRecords.size() == 0) { 5895 pr.finished = true; 5896 mPendingThumbnails.remove(i); 5897 N--; 5898 continue; 5899 } 5900 } 5901 i++; 5902 } 5903 } 5904 5905 if (receivers != null) { 5906 final int N = receivers.size(); 5907 for (int i=0; i<N; i++) { 5908 try { 5909 PendingThumbnailsRecord pr = 5910 (PendingThumbnailsRecord)receivers.get(i); 5911 pr.receiver.newThumbnail( 5912 task != null ? task.taskId : -1, thumbnail, description); 5913 if (pr.finished) { 5914 pr.receiver.finished(); 5915 } 5916 } catch (Exception e) { 5917 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5918 } 5919 } 5920 } 5921 } 5922 5923 // ========================================================= 5924 // CONTENT PROVIDERS 5925 // ========================================================= 5926 5927 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5928 List<ProviderInfo> providers = null; 5929 try { 5930 providers = AppGlobals.getPackageManager(). 5931 queryContentProviders(app.processName, app.uid, 5932 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5933 } catch (RemoteException ex) { 5934 } 5935 if (DEBUG_MU) 5936 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 5937 int userId = app.userId; 5938 if (providers != null) { 5939 int N = providers.size(); 5940 for (int i=0; i<N; i++) { 5941 ProviderInfo cpi = 5942 (ProviderInfo)providers.get(i); 5943 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 5944 cpi.name, cpi.flags); 5945 if (singleton && UserId.getUserId(app.uid) != 0) { 5946 // This is a singleton provider, but a user besides the 5947 // default user is asking to initialize a process it runs 5948 // in... well, no, it doesn't actually run in this process, 5949 // it runs in the process of the default user. Get rid of it. 5950 providers.remove(i); 5951 N--; 5952 continue; 5953 } 5954 5955 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5956 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 5957 if (cpr == null) { 5958 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 5959 mProviderMap.putProviderByClass(comp, cpr); 5960 } 5961 if (DEBUG_MU) 5962 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 5963 app.pubProviders.put(cpi.name, cpr); 5964 app.addPackage(cpi.applicationInfo.packageName); 5965 ensurePackageDexOpt(cpi.applicationInfo.packageName); 5966 } 5967 } 5968 return providers; 5969 } 5970 5971 /** 5972 * Check if {@link ProcessRecord} has a possible chance at accessing the 5973 * given {@link ProviderInfo}. Final permission checking is always done 5974 * in {@link ContentProvider}. 5975 */ 5976 private final String checkContentProviderPermissionLocked( 5977 ProviderInfo cpi, ProcessRecord r) { 5978 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 5979 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 5980 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 5981 cpi.applicationInfo.uid, cpi.exported) 5982 == PackageManager.PERMISSION_GRANTED) { 5983 return null; 5984 } 5985 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 5986 cpi.applicationInfo.uid, cpi.exported) 5987 == PackageManager.PERMISSION_GRANTED) { 5988 return null; 5989 } 5990 5991 PathPermission[] pps = cpi.pathPermissions; 5992 if (pps != null) { 5993 int i = pps.length; 5994 while (i > 0) { 5995 i--; 5996 PathPermission pp = pps[i]; 5997 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 5998 cpi.applicationInfo.uid, cpi.exported) 5999 == PackageManager.PERMISSION_GRANTED) { 6000 return null; 6001 } 6002 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6003 cpi.applicationInfo.uid, cpi.exported) 6004 == PackageManager.PERMISSION_GRANTED) { 6005 return null; 6006 } 6007 } 6008 } 6009 6010 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6011 if (perms != null) { 6012 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6013 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6014 return null; 6015 } 6016 } 6017 } 6018 6019 String msg; 6020 if (!cpi.exported) { 6021 msg = "Permission Denial: opening provider " + cpi.name 6022 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6023 + ", uid=" + callingUid + ") that is not exported from uid " 6024 + cpi.applicationInfo.uid; 6025 } else { 6026 msg = "Permission Denial: opening provider " + cpi.name 6027 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6028 + ", uid=" + callingUid + ") requires " 6029 + cpi.readPermission + " or " + cpi.writePermission; 6030 } 6031 Slog.w(TAG, msg); 6032 return msg; 6033 } 6034 6035 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6036 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6037 if (r != null) { 6038 for (int i=0; i<r.conProviders.size(); i++) { 6039 ContentProviderConnection conn = r.conProviders.get(i); 6040 if (conn.provider == cpr) { 6041 if (DEBUG_PROVIDER) Slog.v(TAG, 6042 "Adding provider requested by " 6043 + r.processName + " from process " 6044 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6045 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6046 if (stable) { 6047 conn.stableCount++; 6048 conn.numStableIncs++; 6049 } else { 6050 conn.unstableCount++; 6051 conn.numUnstableIncs++; 6052 } 6053 return conn; 6054 } 6055 } 6056 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6057 if (stable) { 6058 conn.stableCount = 1; 6059 conn.numStableIncs = 1; 6060 } else { 6061 conn.unstableCount = 1; 6062 conn.numUnstableIncs = 1; 6063 } 6064 cpr.connections.add(conn); 6065 r.conProviders.add(conn); 6066 return conn; 6067 } 6068 cpr.addExternalProcessHandleLocked(externalProcessToken); 6069 return null; 6070 } 6071 6072 boolean decProviderCountLocked(ContentProviderConnection conn, 6073 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6074 if (conn != null) { 6075 cpr = conn.provider; 6076 if (DEBUG_PROVIDER) Slog.v(TAG, 6077 "Removing provider requested by " 6078 + conn.client.processName + " from process " 6079 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6080 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6081 if (stable) { 6082 conn.stableCount--; 6083 } else { 6084 conn.unstableCount--; 6085 } 6086 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6087 cpr.connections.remove(conn); 6088 conn.client.conProviders.remove(conn); 6089 return true; 6090 } 6091 return false; 6092 } 6093 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6094 return false; 6095 } 6096 6097 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6098 String name, IBinder token, boolean stable) { 6099 ContentProviderRecord cpr; 6100 ContentProviderConnection conn = null; 6101 ProviderInfo cpi = null; 6102 6103 synchronized(this) { 6104 ProcessRecord r = null; 6105 if (caller != null) { 6106 r = getRecordForAppLocked(caller); 6107 if (r == null) { 6108 throw new SecurityException( 6109 "Unable to find app for caller " + caller 6110 + " (pid=" + Binder.getCallingPid() 6111 + ") when getting content provider " + name); 6112 } 6113 } 6114 6115 // First check if this content provider has been published... 6116 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6117 cpr = mProviderMap.getProviderByName(name, userId); 6118 boolean providerRunning = cpr != null; 6119 if (providerRunning) { 6120 cpi = cpr.info; 6121 String msg; 6122 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6123 throw new SecurityException(msg); 6124 } 6125 6126 if (r != null && cpr.canRunHere(r)) { 6127 // This provider has been published or is in the process 6128 // of being published... but it is also allowed to run 6129 // in the caller's process, so don't make a connection 6130 // and just let the caller instantiate its own instance. 6131 ContentProviderHolder holder = cpr.newHolder(null); 6132 // don't give caller the provider object, it needs 6133 // to make its own. 6134 holder.provider = null; 6135 return holder; 6136 } 6137 6138 final long origId = Binder.clearCallingIdentity(); 6139 6140 // In this case the provider instance already exists, so we can 6141 // return it right away. 6142 conn = incProviderCountLocked(r, cpr, token, stable); 6143 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6144 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6145 // If this is a perceptible app accessing the provider, 6146 // make sure to count it as being accessed and thus 6147 // back up on the LRU list. This is good because 6148 // content providers are often expensive to start. 6149 updateLruProcessLocked(cpr.proc, false, true); 6150 } 6151 } 6152 6153 if (cpr.proc != null) { 6154 if (false) { 6155 if (cpr.name.flattenToShortString().equals( 6156 "com.android.providers.calendar/.CalendarProvider2")) { 6157 Slog.v(TAG, "****************** KILLING " 6158 + cpr.name.flattenToShortString()); 6159 Process.killProcess(cpr.proc.pid); 6160 } 6161 } 6162 boolean success = updateOomAdjLocked(cpr.proc); 6163 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6164 // NOTE: there is still a race here where a signal could be 6165 // pending on the process even though we managed to update its 6166 // adj level. Not sure what to do about this, but at least 6167 // the race is now smaller. 6168 if (!success) { 6169 // Uh oh... it looks like the provider's process 6170 // has been killed on us. We need to wait for a new 6171 // process to be started, and make sure its death 6172 // doesn't kill our process. 6173 Slog.i(TAG, 6174 "Existing provider " + cpr.name.flattenToShortString() 6175 + " is crashing; detaching " + r); 6176 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6177 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6178 if (!lastRef) { 6179 // This wasn't the last ref our process had on 6180 // the provider... we have now been killed, bail. 6181 return null; 6182 } 6183 providerRunning = false; 6184 conn = null; 6185 } 6186 } 6187 6188 Binder.restoreCallingIdentity(origId); 6189 } 6190 6191 boolean singleton; 6192 if (!providerRunning) { 6193 try { 6194 cpi = AppGlobals.getPackageManager(). 6195 resolveContentProvider(name, 6196 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6197 } catch (RemoteException ex) { 6198 } 6199 if (cpi == null) { 6200 return null; 6201 } 6202 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6203 cpi.name, cpi.flags); 6204 if (singleton) { 6205 userId = 0; 6206 } 6207 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6208 6209 String msg; 6210 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6211 throw new SecurityException(msg); 6212 } 6213 6214 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6215 && !cpi.processName.equals("system")) { 6216 // If this content provider does not run in the system 6217 // process, and the system is not yet ready to run other 6218 // processes, then fail fast instead of hanging. 6219 throw new IllegalArgumentException( 6220 "Attempt to launch content provider before system ready"); 6221 } 6222 6223 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6224 cpr = mProviderMap.getProviderByClass(comp, userId); 6225 final boolean firstClass = cpr == null; 6226 if (firstClass) { 6227 try { 6228 ApplicationInfo ai = 6229 AppGlobals.getPackageManager(). 6230 getApplicationInfo( 6231 cpi.applicationInfo.packageName, 6232 STOCK_PM_FLAGS, userId); 6233 if (ai == null) { 6234 Slog.w(TAG, "No package info for content provider " 6235 + cpi.name); 6236 return null; 6237 } 6238 ai = getAppInfoForUser(ai, userId); 6239 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6240 } catch (RemoteException ex) { 6241 // pm is in same process, this will never happen. 6242 } 6243 } 6244 6245 if (r != null && cpr.canRunHere(r)) { 6246 // If this is a multiprocess provider, then just return its 6247 // info and allow the caller to instantiate it. Only do 6248 // this if the provider is the same user as the caller's 6249 // process, or can run as root (so can be in any process). 6250 return cpr.newHolder(null); 6251 } 6252 6253 if (DEBUG_PROVIDER) { 6254 RuntimeException e = new RuntimeException("here"); 6255 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6256 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6257 } 6258 6259 // This is single process, and our app is now connecting to it. 6260 // See if we are already in the process of launching this 6261 // provider. 6262 final int N = mLaunchingProviders.size(); 6263 int i; 6264 for (i=0; i<N; i++) { 6265 if (mLaunchingProviders.get(i) == cpr) { 6266 break; 6267 } 6268 } 6269 6270 // If the provider is not already being launched, then get it 6271 // started. 6272 if (i >= N) { 6273 final long origId = Binder.clearCallingIdentity(); 6274 6275 try { 6276 // Content provider is now in use, its package can't be stopped. 6277 try { 6278 AppGlobals.getPackageManager().setPackageStoppedState( 6279 cpr.appInfo.packageName, false, userId); 6280 } catch (RemoteException e) { 6281 } catch (IllegalArgumentException e) { 6282 Slog.w(TAG, "Failed trying to unstop package " 6283 + cpr.appInfo.packageName + ": " + e); 6284 } 6285 6286 ProcessRecord proc = startProcessLocked(cpi.processName, 6287 cpr.appInfo, false, 0, "content provider", 6288 new ComponentName(cpi.applicationInfo.packageName, 6289 cpi.name), false, false); 6290 if (proc == null) { 6291 Slog.w(TAG, "Unable to launch app " 6292 + cpi.applicationInfo.packageName + "/" 6293 + cpi.applicationInfo.uid + " for provider " 6294 + name + ": process is bad"); 6295 return null; 6296 } 6297 cpr.launchingApp = proc; 6298 mLaunchingProviders.add(cpr); 6299 } finally { 6300 Binder.restoreCallingIdentity(origId); 6301 } 6302 } 6303 6304 // Make sure the provider is published (the same provider class 6305 // may be published under multiple names). 6306 if (firstClass) { 6307 mProviderMap.putProviderByClass(comp, cpr); 6308 } 6309 6310 mProviderMap.putProviderByName(name, cpr); 6311 conn = incProviderCountLocked(r, cpr, token, stable); 6312 if (conn != null) { 6313 conn.waiting = true; 6314 } 6315 } 6316 } 6317 6318 // Wait for the provider to be published... 6319 synchronized (cpr) { 6320 while (cpr.provider == null) { 6321 if (cpr.launchingApp == null) { 6322 Slog.w(TAG, "Unable to launch app " 6323 + cpi.applicationInfo.packageName + "/" 6324 + cpi.applicationInfo.uid + " for provider " 6325 + name + ": launching app became null"); 6326 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6327 cpi.applicationInfo.packageName, 6328 cpi.applicationInfo.uid, name); 6329 return null; 6330 } 6331 try { 6332 if (DEBUG_MU) { 6333 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6334 + cpr.launchingApp); 6335 } 6336 if (conn != null) { 6337 conn.waiting = true; 6338 } 6339 cpr.wait(); 6340 } catch (InterruptedException ex) { 6341 } finally { 6342 if (conn != null) { 6343 conn.waiting = false; 6344 } 6345 } 6346 } 6347 } 6348 return cpr != null ? cpr.newHolder(conn) : null; 6349 } 6350 6351 public final ContentProviderHolder getContentProvider( 6352 IApplicationThread caller, String name, boolean stable) { 6353 enforceNotIsolatedCaller("getContentProvider"); 6354 if (caller == null) { 6355 String msg = "null IApplicationThread when getting content provider " 6356 + name; 6357 Slog.w(TAG, msg); 6358 throw new SecurityException(msg); 6359 } 6360 6361 return getContentProviderImpl(caller, name, null, stable); 6362 } 6363 6364 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6365 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6366 "Do not have permission in call getContentProviderExternal()"); 6367 return getContentProviderExternalUnchecked(name, token); 6368 } 6369 6370 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6371 return getContentProviderImpl(null, name, token, true); 6372 } 6373 6374 /** 6375 * Drop a content provider from a ProcessRecord's bookkeeping 6376 * @param cpr 6377 */ 6378 public void removeContentProvider(IBinder connection, boolean stable) { 6379 enforceNotIsolatedCaller("removeContentProvider"); 6380 synchronized (this) { 6381 ContentProviderConnection conn; 6382 try { 6383 conn = (ContentProviderConnection)connection; 6384 } catch (ClassCastException e) { 6385 String msg ="removeContentProvider: " + connection 6386 + " not a ContentProviderConnection"; 6387 Slog.w(TAG, msg); 6388 throw new IllegalArgumentException(msg); 6389 } 6390 if (conn == null) { 6391 throw new NullPointerException("connection is null"); 6392 } 6393 if (decProviderCountLocked(conn, null, null, stable)) { 6394 updateOomAdjLocked(); 6395 } 6396 } 6397 } 6398 6399 public void removeContentProviderExternal(String name, IBinder token) { 6400 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6401 "Do not have permission in call removeContentProviderExternal()"); 6402 removeContentProviderExternalUnchecked(name, token); 6403 } 6404 6405 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6406 synchronized (this) { 6407 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6408 Binder.getOrigCallingUser()); 6409 if(cpr == null) { 6410 //remove from mProvidersByClass 6411 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6412 return; 6413 } 6414 6415 //update content provider record entry info 6416 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6417 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6418 Binder.getOrigCallingUser()); 6419 if (localCpr.hasExternalProcessHandles()) { 6420 if (localCpr.removeExternalProcessHandleLocked(token)) { 6421 updateOomAdjLocked(); 6422 } else { 6423 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6424 + " with no external reference for token: " 6425 + token + "."); 6426 } 6427 } else { 6428 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6429 + " with no external references."); 6430 } 6431 } 6432 } 6433 6434 public final void publishContentProviders(IApplicationThread caller, 6435 List<ContentProviderHolder> providers) { 6436 if (providers == null) { 6437 return; 6438 } 6439 6440 enforceNotIsolatedCaller("publishContentProviders"); 6441 synchronized (this) { 6442 final ProcessRecord r = getRecordForAppLocked(caller); 6443 if (DEBUG_MU) 6444 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6445 if (r == null) { 6446 throw new SecurityException( 6447 "Unable to find app for caller " + caller 6448 + " (pid=" + Binder.getCallingPid() 6449 + ") when publishing content providers"); 6450 } 6451 6452 final long origId = Binder.clearCallingIdentity(); 6453 6454 final int N = providers.size(); 6455 for (int i=0; i<N; i++) { 6456 ContentProviderHolder src = providers.get(i); 6457 if (src == null || src.info == null || src.provider == null) { 6458 continue; 6459 } 6460 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6461 if (DEBUG_MU) 6462 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6463 if (dst != null) { 6464 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6465 mProviderMap.putProviderByClass(comp, dst); 6466 String names[] = dst.info.authority.split(";"); 6467 for (int j = 0; j < names.length; j++) { 6468 mProviderMap.putProviderByName(names[j], dst); 6469 } 6470 6471 int NL = mLaunchingProviders.size(); 6472 int j; 6473 for (j=0; j<NL; j++) { 6474 if (mLaunchingProviders.get(j) == dst) { 6475 mLaunchingProviders.remove(j); 6476 j--; 6477 NL--; 6478 } 6479 } 6480 synchronized (dst) { 6481 dst.provider = src.provider; 6482 dst.proc = r; 6483 dst.notifyAll(); 6484 } 6485 updateOomAdjLocked(r); 6486 } 6487 } 6488 6489 Binder.restoreCallingIdentity(origId); 6490 } 6491 } 6492 6493 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6494 ContentProviderConnection conn; 6495 try { 6496 conn = (ContentProviderConnection)connection; 6497 } catch (ClassCastException e) { 6498 String msg ="refContentProvider: " + connection 6499 + " not a ContentProviderConnection"; 6500 Slog.w(TAG, msg); 6501 throw new IllegalArgumentException(msg); 6502 } 6503 if (conn == null) { 6504 throw new NullPointerException("connection is null"); 6505 } 6506 6507 synchronized (this) { 6508 if (stable > 0) { 6509 conn.numStableIncs += stable; 6510 } 6511 stable = conn.stableCount + stable; 6512 if (stable < 0) { 6513 throw new IllegalStateException("stableCount < 0: " + stable); 6514 } 6515 6516 if (unstable > 0) { 6517 conn.numUnstableIncs += unstable; 6518 } 6519 unstable = conn.unstableCount + unstable; 6520 if (unstable < 0) { 6521 throw new IllegalStateException("unstableCount < 0: " + unstable); 6522 } 6523 6524 if ((stable+unstable) <= 0) { 6525 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6526 + stable + " unstable=" + unstable); 6527 } 6528 conn.stableCount = stable; 6529 conn.unstableCount = unstable; 6530 return !conn.dead; 6531 } 6532 } 6533 6534 public void unstableProviderDied(IBinder connection) { 6535 ContentProviderConnection conn; 6536 try { 6537 conn = (ContentProviderConnection)connection; 6538 } catch (ClassCastException e) { 6539 String msg ="refContentProvider: " + connection 6540 + " not a ContentProviderConnection"; 6541 Slog.w(TAG, msg); 6542 throw new IllegalArgumentException(msg); 6543 } 6544 if (conn == null) { 6545 throw new NullPointerException("connection is null"); 6546 } 6547 6548 // Safely retrieve the content provider associated with the connection. 6549 IContentProvider provider; 6550 synchronized (this) { 6551 provider = conn.provider.provider; 6552 } 6553 6554 if (provider == null) { 6555 // Um, yeah, we're way ahead of you. 6556 return; 6557 } 6558 6559 // Make sure the caller is being honest with us. 6560 if (provider.asBinder().pingBinder()) { 6561 // Er, no, still looks good to us. 6562 synchronized (this) { 6563 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6564 + " says " + conn + " died, but we don't agree"); 6565 return; 6566 } 6567 } 6568 6569 // Well look at that! It's dead! 6570 synchronized (this) { 6571 if (conn.provider.provider != provider) { 6572 // But something changed... good enough. 6573 return; 6574 } 6575 6576 ProcessRecord proc = conn.provider.proc; 6577 if (proc == null || proc.thread == null) { 6578 // Seems like the process is already cleaned up. 6579 return; 6580 } 6581 6582 // As far as we're concerned, this is just like receiving a 6583 // death notification... just a bit prematurely. 6584 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6585 + ") early provider death"); 6586 final long ident = Binder.clearCallingIdentity(); 6587 try { 6588 appDiedLocked(proc, proc.pid, proc.thread); 6589 } finally { 6590 Binder.restoreCallingIdentity(ident); 6591 } 6592 } 6593 } 6594 6595 public static final void installSystemProviders() { 6596 List<ProviderInfo> providers; 6597 synchronized (mSelf) { 6598 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6599 providers = mSelf.generateApplicationProvidersLocked(app); 6600 if (providers != null) { 6601 for (int i=providers.size()-1; i>=0; i--) { 6602 ProviderInfo pi = (ProviderInfo)providers.get(i); 6603 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6604 Slog.w(TAG, "Not installing system proc provider " + pi.name 6605 + ": not system .apk"); 6606 providers.remove(i); 6607 } 6608 } 6609 } 6610 } 6611 if (providers != null) { 6612 mSystemThread.installSystemProviders(providers); 6613 } 6614 6615 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6616 6617 mSelf.mUsageStatsService.monitorPackages(); 6618 } 6619 6620 /** 6621 * Allows app to retrieve the MIME type of a URI without having permission 6622 * to access its content provider. 6623 * 6624 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6625 * 6626 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6627 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6628 */ 6629 public String getProviderMimeType(Uri uri) { 6630 enforceNotIsolatedCaller("getProviderMimeType"); 6631 final String name = uri.getAuthority(); 6632 final long ident = Binder.clearCallingIdentity(); 6633 ContentProviderHolder holder = null; 6634 6635 try { 6636 holder = getContentProviderExternalUnchecked(name, null); 6637 if (holder != null) { 6638 return holder.provider.getType(uri); 6639 } 6640 } catch (RemoteException e) { 6641 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6642 return null; 6643 } finally { 6644 if (holder != null) { 6645 removeContentProviderExternalUnchecked(name, null); 6646 } 6647 Binder.restoreCallingIdentity(ident); 6648 } 6649 6650 return null; 6651 } 6652 6653 // ========================================================= 6654 // GLOBAL MANAGEMENT 6655 // ========================================================= 6656 6657 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6658 ApplicationInfo info, String customProcess, boolean isolated) { 6659 String proc = customProcess != null ? customProcess : info.processName; 6660 BatteryStatsImpl.Uid.Proc ps = null; 6661 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6662 int uid = info.uid; 6663 if (isolated) { 6664 int userId = UserId.getUserId(uid); 6665 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6666 uid = 0; 6667 while (true) { 6668 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6669 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6670 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6671 } 6672 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6673 mNextIsolatedProcessUid++; 6674 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6675 // No process for this uid, use it. 6676 break; 6677 } 6678 stepsLeft--; 6679 if (stepsLeft <= 0) { 6680 return null; 6681 } 6682 } 6683 } 6684 synchronized (stats) { 6685 ps = stats.getProcessStatsLocked(info.uid, proc); 6686 } 6687 return new ProcessRecord(ps, thread, info, proc, uid); 6688 } 6689 6690 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6691 ProcessRecord app; 6692 if (!isolated) { 6693 app = getProcessRecordLocked(info.processName, info.uid); 6694 } else { 6695 app = null; 6696 } 6697 6698 if (app == null) { 6699 app = newProcessRecordLocked(null, info, null, isolated); 6700 mProcessNames.put(info.processName, app.uid, app); 6701 if (isolated) { 6702 mIsolatedProcesses.put(app.uid, app); 6703 } 6704 updateLruProcessLocked(app, true, true); 6705 } 6706 6707 // This package really, really can not be stopped. 6708 try { 6709 AppGlobals.getPackageManager().setPackageStoppedState( 6710 info.packageName, false, UserId.getUserId(app.uid)); 6711 } catch (RemoteException e) { 6712 } catch (IllegalArgumentException e) { 6713 Slog.w(TAG, "Failed trying to unstop package " 6714 + info.packageName + ": " + e); 6715 } 6716 6717 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6718 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6719 app.persistent = true; 6720 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6721 } 6722 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6723 mPersistentStartingProcesses.add(app); 6724 startProcessLocked(app, "added application", app.processName); 6725 } 6726 6727 return app; 6728 } 6729 6730 public void unhandledBack() { 6731 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6732 "unhandledBack()"); 6733 6734 synchronized(this) { 6735 int count = mMainStack.mHistory.size(); 6736 if (DEBUG_SWITCH) Slog.d( 6737 TAG, "Performing unhandledBack(): stack size = " + count); 6738 if (count > 1) { 6739 final long origId = Binder.clearCallingIdentity(); 6740 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6741 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6742 Binder.restoreCallingIdentity(origId); 6743 } 6744 } 6745 } 6746 6747 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6748 enforceNotIsolatedCaller("openContentUri"); 6749 String name = uri.getAuthority(); 6750 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6751 ParcelFileDescriptor pfd = null; 6752 if (cph != null) { 6753 // We record the binder invoker's uid in thread-local storage before 6754 // going to the content provider to open the file. Later, in the code 6755 // that handles all permissions checks, we look for this uid and use 6756 // that rather than the Activity Manager's own uid. The effect is that 6757 // we do the check against the caller's permissions even though it looks 6758 // to the content provider like the Activity Manager itself is making 6759 // the request. 6760 sCallerIdentity.set(new Identity( 6761 Binder.getCallingPid(), Binder.getCallingUid())); 6762 try { 6763 pfd = cph.provider.openFile(uri, "r"); 6764 } catch (FileNotFoundException e) { 6765 // do nothing; pfd will be returned null 6766 } finally { 6767 // Ensure that whatever happens, we clean up the identity state 6768 sCallerIdentity.remove(); 6769 } 6770 6771 // We've got the fd now, so we're done with the provider. 6772 removeContentProviderExternalUnchecked(name, null); 6773 } else { 6774 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6775 } 6776 return pfd; 6777 } 6778 6779 // Actually is sleeping or shutting down or whatever else in the future 6780 // is an inactive state. 6781 public boolean isSleeping() { 6782 return mSleeping || mShuttingDown; 6783 } 6784 6785 public void goingToSleep() { 6786 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6787 != PackageManager.PERMISSION_GRANTED) { 6788 throw new SecurityException("Requires permission " 6789 + android.Manifest.permission.DEVICE_POWER); 6790 } 6791 6792 synchronized(this) { 6793 mWentToSleep = true; 6794 updateEventDispatchingLocked(); 6795 6796 if (!mSleeping) { 6797 mSleeping = true; 6798 mMainStack.stopIfSleepingLocked(); 6799 6800 // Initialize the wake times of all processes. 6801 checkExcessivePowerUsageLocked(false); 6802 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6803 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6804 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6805 } 6806 } 6807 } 6808 6809 public boolean shutdown(int timeout) { 6810 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6811 != PackageManager.PERMISSION_GRANTED) { 6812 throw new SecurityException("Requires permission " 6813 + android.Manifest.permission.SHUTDOWN); 6814 } 6815 6816 boolean timedout = false; 6817 6818 synchronized(this) { 6819 mShuttingDown = true; 6820 updateEventDispatchingLocked(); 6821 6822 if (mMainStack.mResumedActivity != null) { 6823 mMainStack.stopIfSleepingLocked(); 6824 final long endTime = System.currentTimeMillis() + timeout; 6825 while (mMainStack.mResumedActivity != null 6826 || mMainStack.mPausingActivity != null) { 6827 long delay = endTime - System.currentTimeMillis(); 6828 if (delay <= 0) { 6829 Slog.w(TAG, "Activity manager shutdown timed out"); 6830 timedout = true; 6831 break; 6832 } 6833 try { 6834 this.wait(); 6835 } catch (InterruptedException e) { 6836 } 6837 } 6838 } 6839 } 6840 6841 mUsageStatsService.shutdown(); 6842 mBatteryStatsService.shutdown(); 6843 6844 return timedout; 6845 } 6846 6847 public final void activitySlept(IBinder token) { 6848 if (localLOGV) Slog.v( 6849 TAG, "Activity slept: token=" + token); 6850 6851 ActivityRecord r = null; 6852 6853 final long origId = Binder.clearCallingIdentity(); 6854 6855 synchronized (this) { 6856 r = mMainStack.isInStackLocked(token); 6857 if (r != null) { 6858 mMainStack.activitySleptLocked(r); 6859 } 6860 } 6861 6862 Binder.restoreCallingIdentity(origId); 6863 } 6864 6865 private void comeOutOfSleepIfNeededLocked() { 6866 if (!mWentToSleep && !mLockScreenShown) { 6867 if (mSleeping) { 6868 mSleeping = false; 6869 mMainStack.awakeFromSleepingLocked(); 6870 mMainStack.resumeTopActivityLocked(null); 6871 } 6872 } 6873 } 6874 6875 public void wakingUp() { 6876 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6877 != PackageManager.PERMISSION_GRANTED) { 6878 throw new SecurityException("Requires permission " 6879 + android.Manifest.permission.DEVICE_POWER); 6880 } 6881 6882 synchronized(this) { 6883 mWentToSleep = false; 6884 updateEventDispatchingLocked(); 6885 comeOutOfSleepIfNeededLocked(); 6886 } 6887 } 6888 6889 private void updateEventDispatchingLocked() { 6890 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6891 } 6892 6893 public void setLockScreenShown(boolean shown) { 6894 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6895 != PackageManager.PERMISSION_GRANTED) { 6896 throw new SecurityException("Requires permission " 6897 + android.Manifest.permission.DEVICE_POWER); 6898 } 6899 6900 synchronized(this) { 6901 mLockScreenShown = shown; 6902 comeOutOfSleepIfNeededLocked(); 6903 } 6904 } 6905 6906 public void stopAppSwitches() { 6907 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6908 != PackageManager.PERMISSION_GRANTED) { 6909 throw new SecurityException("Requires permission " 6910 + android.Manifest.permission.STOP_APP_SWITCHES); 6911 } 6912 6913 synchronized(this) { 6914 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6915 + APP_SWITCH_DELAY_TIME; 6916 mDidAppSwitch = false; 6917 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6918 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6919 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6920 } 6921 } 6922 6923 public void resumeAppSwitches() { 6924 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6925 != PackageManager.PERMISSION_GRANTED) { 6926 throw new SecurityException("Requires permission " 6927 + android.Manifest.permission.STOP_APP_SWITCHES); 6928 } 6929 6930 synchronized(this) { 6931 // Note that we don't execute any pending app switches... we will 6932 // let those wait until either the timeout, or the next start 6933 // activity request. 6934 mAppSwitchesAllowedTime = 0; 6935 } 6936 } 6937 6938 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6939 String name) { 6940 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6941 return true; 6942 } 6943 6944 final int perm = checkComponentPermission( 6945 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6946 callingUid, -1, true); 6947 if (perm == PackageManager.PERMISSION_GRANTED) { 6948 return true; 6949 } 6950 6951 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6952 return false; 6953 } 6954 6955 public void setDebugApp(String packageName, boolean waitForDebugger, 6956 boolean persistent) { 6957 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 6958 "setDebugApp()"); 6959 6960 // Note that this is not really thread safe if there are multiple 6961 // callers into it at the same time, but that's not a situation we 6962 // care about. 6963 if (persistent) { 6964 final ContentResolver resolver = mContext.getContentResolver(); 6965 Settings.System.putString( 6966 resolver, Settings.System.DEBUG_APP, 6967 packageName); 6968 Settings.System.putInt( 6969 resolver, Settings.System.WAIT_FOR_DEBUGGER, 6970 waitForDebugger ? 1 : 0); 6971 } 6972 6973 synchronized (this) { 6974 if (!persistent) { 6975 mOrigDebugApp = mDebugApp; 6976 mOrigWaitForDebugger = mWaitForDebugger; 6977 } 6978 mDebugApp = packageName; 6979 mWaitForDebugger = waitForDebugger; 6980 mDebugTransient = !persistent; 6981 if (packageName != null) { 6982 final long origId = Binder.clearCallingIdentity(); 6983 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 6984 Binder.restoreCallingIdentity(origId); 6985 } 6986 } 6987 } 6988 6989 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 6990 synchronized (this) { 6991 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6992 if (!isDebuggable) { 6993 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 6994 throw new SecurityException("Process not debuggable: " + app.packageName); 6995 } 6996 } 6997 6998 mOpenGlTraceApp = processName; 6999 } 7000 } 7001 7002 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7003 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7004 synchronized (this) { 7005 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7006 if (!isDebuggable) { 7007 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7008 throw new SecurityException("Process not debuggable: " + app.packageName); 7009 } 7010 } 7011 mProfileApp = processName; 7012 mProfileFile = profileFile; 7013 if (mProfileFd != null) { 7014 try { 7015 mProfileFd.close(); 7016 } catch (IOException e) { 7017 } 7018 mProfileFd = null; 7019 } 7020 mProfileFd = profileFd; 7021 mProfileType = 0; 7022 mAutoStopProfiler = autoStopProfiler; 7023 } 7024 } 7025 7026 public void setAlwaysFinish(boolean enabled) { 7027 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7028 "setAlwaysFinish()"); 7029 7030 Settings.System.putInt( 7031 mContext.getContentResolver(), 7032 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7033 7034 synchronized (this) { 7035 mAlwaysFinishActivities = enabled; 7036 } 7037 } 7038 7039 public void setActivityController(IActivityController controller) { 7040 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7041 "setActivityController()"); 7042 synchronized (this) { 7043 mController = controller; 7044 } 7045 } 7046 7047 public boolean isUserAMonkey() { 7048 // For now the fact that there is a controller implies 7049 // we have a monkey. 7050 synchronized (this) { 7051 return mController != null; 7052 } 7053 } 7054 7055 public void registerProcessObserver(IProcessObserver observer) { 7056 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7057 "registerProcessObserver()"); 7058 synchronized (this) { 7059 mProcessObservers.register(observer); 7060 } 7061 } 7062 7063 public void unregisterProcessObserver(IProcessObserver observer) { 7064 synchronized (this) { 7065 mProcessObservers.unregister(observer); 7066 } 7067 } 7068 7069 public void setImmersive(IBinder token, boolean immersive) { 7070 synchronized(this) { 7071 ActivityRecord r = mMainStack.isInStackLocked(token); 7072 if (r == null) { 7073 throw new IllegalArgumentException(); 7074 } 7075 r.immersive = immersive; 7076 } 7077 } 7078 7079 public boolean isImmersive(IBinder token) { 7080 synchronized (this) { 7081 ActivityRecord r = mMainStack.isInStackLocked(token); 7082 if (r == null) { 7083 throw new IllegalArgumentException(); 7084 } 7085 return r.immersive; 7086 } 7087 } 7088 7089 public boolean isTopActivityImmersive() { 7090 enforceNotIsolatedCaller("startActivity"); 7091 synchronized (this) { 7092 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7093 return (r != null) ? r.immersive : false; 7094 } 7095 } 7096 7097 public final void enterSafeMode() { 7098 synchronized(this) { 7099 // It only makes sense to do this before the system is ready 7100 // and started launching other packages. 7101 if (!mSystemReady) { 7102 try { 7103 AppGlobals.getPackageManager().enterSafeMode(); 7104 } catch (RemoteException e) { 7105 } 7106 } 7107 } 7108 } 7109 7110 public final void showSafeModeOverlay() { 7111 View v = LayoutInflater.from(mContext).inflate( 7112 com.android.internal.R.layout.safe_mode, null); 7113 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7114 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7115 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7116 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7117 lp.gravity = Gravity.BOTTOM | Gravity.START; 7118 lp.format = v.getBackground().getOpacity(); 7119 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7120 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7121 ((WindowManager)mContext.getSystemService( 7122 Context.WINDOW_SERVICE)).addView(v, lp); 7123 } 7124 7125 public void noteWakeupAlarm(IIntentSender sender) { 7126 if (!(sender instanceof PendingIntentRecord)) { 7127 return; 7128 } 7129 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7130 synchronized (stats) { 7131 if (mBatteryStatsService.isOnBattery()) { 7132 mBatteryStatsService.enforceCallingPermission(); 7133 PendingIntentRecord rec = (PendingIntentRecord)sender; 7134 int MY_UID = Binder.getCallingUid(); 7135 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7136 BatteryStatsImpl.Uid.Pkg pkg = 7137 stats.getPackageStatsLocked(uid, rec.key.packageName); 7138 pkg.incWakeupsLocked(); 7139 } 7140 } 7141 } 7142 7143 public boolean killPids(int[] pids, String pReason, boolean secure) { 7144 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7145 throw new SecurityException("killPids only available to the system"); 7146 } 7147 String reason = (pReason == null) ? "Unknown" : pReason; 7148 // XXX Note: don't acquire main activity lock here, because the window 7149 // manager calls in with its locks held. 7150 7151 boolean killed = false; 7152 synchronized (mPidsSelfLocked) { 7153 int[] types = new int[pids.length]; 7154 int worstType = 0; 7155 for (int i=0; i<pids.length; i++) { 7156 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7157 if (proc != null) { 7158 int type = proc.setAdj; 7159 types[i] = type; 7160 if (type > worstType) { 7161 worstType = type; 7162 } 7163 } 7164 } 7165 7166 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7167 // then constrain it so we will kill all hidden procs. 7168 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7169 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7170 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7171 } 7172 7173 // If this is not a secure call, don't let it kill processes that 7174 // are important. 7175 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7176 worstType = ProcessList.SERVICE_ADJ; 7177 } 7178 7179 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7180 for (int i=0; i<pids.length; i++) { 7181 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7182 if (proc == null) { 7183 continue; 7184 } 7185 int adj = proc.setAdj; 7186 if (adj >= worstType && !proc.killedBackground) { 7187 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7188 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7189 proc.processName, adj, reason); 7190 killed = true; 7191 proc.killedBackground = true; 7192 Process.killProcessQuiet(pids[i]); 7193 } 7194 } 7195 } 7196 return killed; 7197 } 7198 7199 @Override 7200 public boolean killProcessesBelowForeground(String reason) { 7201 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7202 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7203 } 7204 7205 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7206 } 7207 7208 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7209 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7210 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7211 } 7212 7213 boolean killed = false; 7214 synchronized (mPidsSelfLocked) { 7215 final int size = mPidsSelfLocked.size(); 7216 for (int i = 0; i < size; i++) { 7217 final int pid = mPidsSelfLocked.keyAt(i); 7218 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7219 if (proc == null) continue; 7220 7221 final int adj = proc.setAdj; 7222 if (adj > belowAdj && !proc.killedBackground) { 7223 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7224 EventLog.writeEvent( 7225 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7226 killed = true; 7227 proc.killedBackground = true; 7228 Process.killProcessQuiet(pid); 7229 } 7230 } 7231 } 7232 return killed; 7233 } 7234 7235 public final void startRunning(String pkg, String cls, String action, 7236 String data) { 7237 synchronized(this) { 7238 if (mStartRunning) { 7239 return; 7240 } 7241 mStartRunning = true; 7242 mTopComponent = pkg != null && cls != null 7243 ? new ComponentName(pkg, cls) : null; 7244 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7245 mTopData = data; 7246 if (!mSystemReady) { 7247 return; 7248 } 7249 } 7250 7251 systemReady(null); 7252 } 7253 7254 private void retrieveSettings() { 7255 final ContentResolver resolver = mContext.getContentResolver(); 7256 String debugApp = Settings.System.getString( 7257 resolver, Settings.System.DEBUG_APP); 7258 boolean waitForDebugger = Settings.System.getInt( 7259 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7260 boolean alwaysFinishActivities = Settings.System.getInt( 7261 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7262 7263 Configuration configuration = new Configuration(); 7264 Settings.System.getConfiguration(resolver, configuration); 7265 7266 synchronized (this) { 7267 mDebugApp = mOrigDebugApp = debugApp; 7268 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7269 mAlwaysFinishActivities = alwaysFinishActivities; 7270 // This happens before any activities are started, so we can 7271 // change mConfiguration in-place. 7272 updateConfigurationLocked(configuration, null, false, true); 7273 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7274 } 7275 } 7276 7277 public boolean testIsSystemReady() { 7278 // no need to synchronize(this) just to read & return the value 7279 return mSystemReady; 7280 } 7281 7282 private static File getCalledPreBootReceiversFile() { 7283 File dataDir = Environment.getDataDirectory(); 7284 File systemDir = new File(dataDir, "system"); 7285 File fname = new File(systemDir, "called_pre_boots.dat"); 7286 return fname; 7287 } 7288 7289 static final int LAST_DONE_VERSION = 10000; 7290 7291 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7292 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7293 File file = getCalledPreBootReceiversFile(); 7294 FileInputStream fis = null; 7295 try { 7296 fis = new FileInputStream(file); 7297 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7298 int fvers = dis.readInt(); 7299 if (fvers == LAST_DONE_VERSION) { 7300 String vers = dis.readUTF(); 7301 String codename = dis.readUTF(); 7302 String build = dis.readUTF(); 7303 if (android.os.Build.VERSION.RELEASE.equals(vers) 7304 && android.os.Build.VERSION.CODENAME.equals(codename) 7305 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7306 int num = dis.readInt(); 7307 while (num > 0) { 7308 num--; 7309 String pkg = dis.readUTF(); 7310 String cls = dis.readUTF(); 7311 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7312 } 7313 } 7314 } 7315 } catch (FileNotFoundException e) { 7316 } catch (IOException e) { 7317 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7318 } finally { 7319 if (fis != null) { 7320 try { 7321 fis.close(); 7322 } catch (IOException e) { 7323 } 7324 } 7325 } 7326 return lastDoneReceivers; 7327 } 7328 7329 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7330 File file = getCalledPreBootReceiversFile(); 7331 FileOutputStream fos = null; 7332 DataOutputStream dos = null; 7333 try { 7334 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7335 fos = new FileOutputStream(file); 7336 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7337 dos.writeInt(LAST_DONE_VERSION); 7338 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7339 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7340 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7341 dos.writeInt(list.size()); 7342 for (int i=0; i<list.size(); i++) { 7343 dos.writeUTF(list.get(i).getPackageName()); 7344 dos.writeUTF(list.get(i).getClassName()); 7345 } 7346 } catch (IOException e) { 7347 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7348 file.delete(); 7349 } finally { 7350 FileUtils.sync(fos); 7351 if (dos != null) { 7352 try { 7353 dos.close(); 7354 } catch (IOException e) { 7355 // TODO Auto-generated catch block 7356 e.printStackTrace(); 7357 } 7358 } 7359 } 7360 } 7361 7362 public void systemReady(final Runnable goingCallback) { 7363 synchronized(this) { 7364 if (mSystemReady) { 7365 if (goingCallback != null) goingCallback.run(); 7366 return; 7367 } 7368 7369 // Check to see if there are any update receivers to run. 7370 if (!mDidUpdate) { 7371 if (mWaitingUpdate) { 7372 return; 7373 } 7374 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7375 List<ResolveInfo> ris = null; 7376 try { 7377 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7378 intent, null, 0, 0); 7379 } catch (RemoteException e) { 7380 } 7381 if (ris != null) { 7382 for (int i=ris.size()-1; i>=0; i--) { 7383 if ((ris.get(i).activityInfo.applicationInfo.flags 7384 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7385 ris.remove(i); 7386 } 7387 } 7388 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7389 7390 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7391 7392 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7393 for (int i=0; i<ris.size(); i++) { 7394 ActivityInfo ai = ris.get(i).activityInfo; 7395 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7396 if (lastDoneReceivers.contains(comp)) { 7397 ris.remove(i); 7398 i--; 7399 } 7400 } 7401 7402 for (int i=0; i<ris.size(); i++) { 7403 ActivityInfo ai = ris.get(i).activityInfo; 7404 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7405 doneReceivers.add(comp); 7406 intent.setComponent(comp); 7407 IIntentReceiver finisher = null; 7408 if (i == ris.size()-1) { 7409 finisher = new IIntentReceiver.Stub() { 7410 public void performReceive(Intent intent, int resultCode, 7411 String data, Bundle extras, boolean ordered, 7412 boolean sticky) { 7413 // The raw IIntentReceiver interface is called 7414 // with the AM lock held, so redispatch to 7415 // execute our code without the lock. 7416 mHandler.post(new Runnable() { 7417 public void run() { 7418 synchronized (ActivityManagerService.this) { 7419 mDidUpdate = true; 7420 } 7421 writeLastDonePreBootReceivers(doneReceivers); 7422 showBootMessage(mContext.getText( 7423 R.string.android_upgrading_complete), 7424 false); 7425 systemReady(goingCallback); 7426 } 7427 }); 7428 } 7429 }; 7430 } 7431 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7432 /* TODO: Send this to all users */ 7433 broadcastIntentLocked(null, null, intent, null, finisher, 7434 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7435 0 /* UserId zero */); 7436 if (finisher != null) { 7437 mWaitingUpdate = true; 7438 } 7439 } 7440 } 7441 if (mWaitingUpdate) { 7442 return; 7443 } 7444 mDidUpdate = true; 7445 } 7446 7447 mSystemReady = true; 7448 if (!mStartRunning) { 7449 return; 7450 } 7451 } 7452 7453 ArrayList<ProcessRecord> procsToKill = null; 7454 synchronized(mPidsSelfLocked) { 7455 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7456 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7457 if (!isAllowedWhileBooting(proc.info)){ 7458 if (procsToKill == null) { 7459 procsToKill = new ArrayList<ProcessRecord>(); 7460 } 7461 procsToKill.add(proc); 7462 } 7463 } 7464 } 7465 7466 synchronized(this) { 7467 if (procsToKill != null) { 7468 for (int i=procsToKill.size()-1; i>=0; i--) { 7469 ProcessRecord proc = procsToKill.get(i); 7470 Slog.i(TAG, "Removing system update proc: " + proc); 7471 removeProcessLocked(proc, true, false, "system update done"); 7472 } 7473 } 7474 7475 // Now that we have cleaned up any update processes, we 7476 // are ready to start launching real processes and know that 7477 // we won't trample on them any more. 7478 mProcessesReady = true; 7479 } 7480 7481 Slog.i(TAG, "System now ready"); 7482 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7483 SystemClock.uptimeMillis()); 7484 7485 synchronized(this) { 7486 // Make sure we have no pre-ready processes sitting around. 7487 7488 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7489 ResolveInfo ri = mContext.getPackageManager() 7490 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7491 STOCK_PM_FLAGS); 7492 CharSequence errorMsg = null; 7493 if (ri != null) { 7494 ActivityInfo ai = ri.activityInfo; 7495 ApplicationInfo app = ai.applicationInfo; 7496 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7497 mTopAction = Intent.ACTION_FACTORY_TEST; 7498 mTopData = null; 7499 mTopComponent = new ComponentName(app.packageName, 7500 ai.name); 7501 } else { 7502 errorMsg = mContext.getResources().getText( 7503 com.android.internal.R.string.factorytest_not_system); 7504 } 7505 } else { 7506 errorMsg = mContext.getResources().getText( 7507 com.android.internal.R.string.factorytest_no_action); 7508 } 7509 if (errorMsg != null) { 7510 mTopAction = null; 7511 mTopData = null; 7512 mTopComponent = null; 7513 Message msg = Message.obtain(); 7514 msg.what = SHOW_FACTORY_ERROR_MSG; 7515 msg.getData().putCharSequence("msg", errorMsg); 7516 mHandler.sendMessage(msg); 7517 } 7518 } 7519 } 7520 7521 retrieveSettings(); 7522 7523 if (goingCallback != null) goingCallback.run(); 7524 7525 synchronized (this) { 7526 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7527 try { 7528 List apps = AppGlobals.getPackageManager(). 7529 getPersistentApplications(STOCK_PM_FLAGS); 7530 if (apps != null) { 7531 int N = apps.size(); 7532 int i; 7533 for (i=0; i<N; i++) { 7534 ApplicationInfo info 7535 = (ApplicationInfo)apps.get(i); 7536 if (info != null && 7537 !info.packageName.equals("android")) { 7538 addAppLocked(info, false); 7539 } 7540 } 7541 } 7542 } catch (RemoteException ex) { 7543 // pm is in same process, this will never happen. 7544 } 7545 } 7546 7547 // Start up initial activity. 7548 mBooting = true; 7549 7550 try { 7551 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7552 Message msg = Message.obtain(); 7553 msg.what = SHOW_UID_ERROR_MSG; 7554 mHandler.sendMessage(msg); 7555 } 7556 } catch (RemoteException e) { 7557 } 7558 7559 mMainStack.resumeTopActivityLocked(null); 7560 } 7561 } 7562 7563 private boolean makeAppCrashingLocked(ProcessRecord app, 7564 String shortMsg, String longMsg, String stackTrace) { 7565 app.crashing = true; 7566 app.crashingReport = generateProcessError(app, 7567 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7568 startAppProblemLocked(app); 7569 app.stopFreezingAllLocked(); 7570 return handleAppCrashLocked(app); 7571 } 7572 7573 private void makeAppNotRespondingLocked(ProcessRecord app, 7574 String activity, String shortMsg, String longMsg) { 7575 app.notResponding = true; 7576 app.notRespondingReport = generateProcessError(app, 7577 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7578 activity, shortMsg, longMsg, null); 7579 startAppProblemLocked(app); 7580 app.stopFreezingAllLocked(); 7581 } 7582 7583 /** 7584 * Generate a process error record, suitable for attachment to a ProcessRecord. 7585 * 7586 * @param app The ProcessRecord in which the error occurred. 7587 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7588 * ActivityManager.AppErrorStateInfo 7589 * @param activity The activity associated with the crash, if known. 7590 * @param shortMsg Short message describing the crash. 7591 * @param longMsg Long message describing the crash. 7592 * @param stackTrace Full crash stack trace, may be null. 7593 * 7594 * @return Returns a fully-formed AppErrorStateInfo record. 7595 */ 7596 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7597 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7598 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7599 7600 report.condition = condition; 7601 report.processName = app.processName; 7602 report.pid = app.pid; 7603 report.uid = app.info.uid; 7604 report.tag = activity; 7605 report.shortMsg = shortMsg; 7606 report.longMsg = longMsg; 7607 report.stackTrace = stackTrace; 7608 7609 return report; 7610 } 7611 7612 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7613 synchronized (this) { 7614 app.crashing = false; 7615 app.crashingReport = null; 7616 app.notResponding = false; 7617 app.notRespondingReport = null; 7618 if (app.anrDialog == fromDialog) { 7619 app.anrDialog = null; 7620 } 7621 if (app.waitDialog == fromDialog) { 7622 app.waitDialog = null; 7623 } 7624 if (app.pid > 0 && app.pid != MY_PID) { 7625 handleAppCrashLocked(app); 7626 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7627 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7628 app.processName, app.setAdj, "user's request after error"); 7629 Process.killProcessQuiet(app.pid); 7630 } 7631 } 7632 } 7633 7634 private boolean handleAppCrashLocked(ProcessRecord app) { 7635 if (mHeadless) { 7636 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7637 return false; 7638 } 7639 long now = SystemClock.uptimeMillis(); 7640 7641 Long crashTime; 7642 if (!app.isolated) { 7643 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7644 } else { 7645 crashTime = null; 7646 } 7647 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7648 // This process loses! 7649 Slog.w(TAG, "Process " + app.info.processName 7650 + " has crashed too many times: killing!"); 7651 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7652 app.info.processName, app.uid); 7653 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7654 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7655 if (r.app == app) { 7656 Slog.w(TAG, " Force finishing activity " 7657 + r.intent.getComponent().flattenToShortString()); 7658 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7659 } 7660 } 7661 if (!app.persistent) { 7662 // We don't want to start this process again until the user 7663 // explicitly does so... but for persistent process, we really 7664 // need to keep it running. If a persistent process is actually 7665 // repeatedly crashing, then badness for everyone. 7666 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7667 app.info.processName); 7668 if (!app.isolated) { 7669 // XXX We don't have a way to mark isolated processes 7670 // as bad, since they don't have a peristent identity. 7671 mBadProcesses.put(app.info.processName, app.uid, now); 7672 mProcessCrashTimes.remove(app.info.processName, app.uid); 7673 } 7674 app.bad = true; 7675 app.removed = true; 7676 // Don't let services in this process be restarted and potentially 7677 // annoy the user repeatedly. Unless it is persistent, since those 7678 // processes run critical code. 7679 removeProcessLocked(app, false, false, "crash"); 7680 mMainStack.resumeTopActivityLocked(null); 7681 return false; 7682 } 7683 mMainStack.resumeTopActivityLocked(null); 7684 } else { 7685 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7686 if (r != null && r.app == app) { 7687 // If the top running activity is from this crashing 7688 // process, then terminate it to avoid getting in a loop. 7689 Slog.w(TAG, " Force finishing activity " 7690 + r.intent.getComponent().flattenToShortString()); 7691 int index = mMainStack.indexOfActivityLocked(r); 7692 r.stack.finishActivityLocked(r, index, 7693 Activity.RESULT_CANCELED, null, "crashed"); 7694 // Also terminate any activities below it that aren't yet 7695 // stopped, to avoid a situation where one will get 7696 // re-start our crashing activity once it gets resumed again. 7697 index--; 7698 if (index >= 0) { 7699 r = (ActivityRecord)mMainStack.mHistory.get(index); 7700 if (r.state == ActivityState.RESUMED 7701 || r.state == ActivityState.PAUSING 7702 || r.state == ActivityState.PAUSED) { 7703 if (!r.isHomeActivity || mHomeProcess != r.app) { 7704 Slog.w(TAG, " Force finishing activity " 7705 + r.intent.getComponent().flattenToShortString()); 7706 r.stack.finishActivityLocked(r, index, 7707 Activity.RESULT_CANCELED, null, "crashed"); 7708 } 7709 } 7710 } 7711 } 7712 } 7713 7714 // Bump up the crash count of any services currently running in the proc. 7715 if (app.services.size() != 0) { 7716 // Any services running in the application need to be placed 7717 // back in the pending list. 7718 Iterator<ServiceRecord> it = app.services.iterator(); 7719 while (it.hasNext()) { 7720 ServiceRecord sr = it.next(); 7721 sr.crashCount++; 7722 } 7723 } 7724 7725 // If the crashing process is what we consider to be the "home process" and it has been 7726 // replaced by a third-party app, clear the package preferred activities from packages 7727 // with a home activity running in the process to prevent a repeatedly crashing app 7728 // from blocking the user to manually clear the list. 7729 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7730 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7731 Iterator it = mHomeProcess.activities.iterator(); 7732 while (it.hasNext()) { 7733 ActivityRecord r = (ActivityRecord)it.next(); 7734 if (r.isHomeActivity) { 7735 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7736 try { 7737 ActivityThread.getPackageManager() 7738 .clearPackagePreferredActivities(r.packageName); 7739 } catch (RemoteException c) { 7740 // pm is in same process, this will never happen. 7741 } 7742 } 7743 } 7744 } 7745 7746 if (!app.isolated) { 7747 // XXX Can't keep track of crash times for isolated processes, 7748 // because they don't have a perisistent identity. 7749 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7750 } 7751 7752 return true; 7753 } 7754 7755 void startAppProblemLocked(ProcessRecord app) { 7756 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7757 mContext, app.info.packageName, app.info.flags); 7758 skipCurrentReceiverLocked(app); 7759 } 7760 7761 void skipCurrentReceiverLocked(ProcessRecord app) { 7762 for (BroadcastQueue queue : mBroadcastQueues) { 7763 queue.skipCurrentReceiverLocked(app); 7764 } 7765 } 7766 7767 /** 7768 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7769 * The application process will exit immediately after this call returns. 7770 * @param app object of the crashing app, null for the system server 7771 * @param crashInfo describing the exception 7772 */ 7773 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7774 ProcessRecord r = findAppProcess(app, "Crash"); 7775 final String processName = app == null ? "system_server" 7776 : (r == null ? "unknown" : r.processName); 7777 7778 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7779 processName, 7780 r == null ? -1 : r.info.flags, 7781 crashInfo.exceptionClassName, 7782 crashInfo.exceptionMessage, 7783 crashInfo.throwFileName, 7784 crashInfo.throwLineNumber); 7785 7786 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7787 7788 crashApplication(r, crashInfo); 7789 } 7790 7791 public void handleApplicationStrictModeViolation( 7792 IBinder app, 7793 int violationMask, 7794 StrictMode.ViolationInfo info) { 7795 ProcessRecord r = findAppProcess(app, "StrictMode"); 7796 if (r == null) { 7797 return; 7798 } 7799 7800 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7801 Integer stackFingerprint = info.hashCode(); 7802 boolean logIt = true; 7803 synchronized (mAlreadyLoggedViolatedStacks) { 7804 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7805 logIt = false; 7806 // TODO: sub-sample into EventLog for these, with 7807 // the info.durationMillis? Then we'd get 7808 // the relative pain numbers, without logging all 7809 // the stack traces repeatedly. We'd want to do 7810 // likewise in the client code, which also does 7811 // dup suppression, before the Binder call. 7812 } else { 7813 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7814 mAlreadyLoggedViolatedStacks.clear(); 7815 } 7816 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7817 } 7818 } 7819 if (logIt) { 7820 logStrictModeViolationToDropBox(r, info); 7821 } 7822 } 7823 7824 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7825 AppErrorResult result = new AppErrorResult(); 7826 synchronized (this) { 7827 final long origId = Binder.clearCallingIdentity(); 7828 7829 Message msg = Message.obtain(); 7830 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7831 HashMap<String, Object> data = new HashMap<String, Object>(); 7832 data.put("result", result); 7833 data.put("app", r); 7834 data.put("violationMask", violationMask); 7835 data.put("info", info); 7836 msg.obj = data; 7837 mHandler.sendMessage(msg); 7838 7839 Binder.restoreCallingIdentity(origId); 7840 } 7841 int res = result.get(); 7842 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7843 } 7844 } 7845 7846 // Depending on the policy in effect, there could be a bunch of 7847 // these in quick succession so we try to batch these together to 7848 // minimize disk writes, number of dropbox entries, and maximize 7849 // compression, by having more fewer, larger records. 7850 private void logStrictModeViolationToDropBox( 7851 ProcessRecord process, 7852 StrictMode.ViolationInfo info) { 7853 if (info == null) { 7854 return; 7855 } 7856 final boolean isSystemApp = process == null || 7857 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7858 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7859 final String processName = process == null ? "unknown" : process.processName; 7860 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7861 final DropBoxManager dbox = (DropBoxManager) 7862 mContext.getSystemService(Context.DROPBOX_SERVICE); 7863 7864 // Exit early if the dropbox isn't configured to accept this report type. 7865 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7866 7867 boolean bufferWasEmpty; 7868 boolean needsFlush; 7869 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7870 synchronized (sb) { 7871 bufferWasEmpty = sb.length() == 0; 7872 appendDropBoxProcessHeaders(process, processName, sb); 7873 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7874 sb.append("System-App: ").append(isSystemApp).append("\n"); 7875 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7876 if (info.violationNumThisLoop != 0) { 7877 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7878 } 7879 if (info.numAnimationsRunning != 0) { 7880 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7881 } 7882 if (info.broadcastIntentAction != null) { 7883 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7884 } 7885 if (info.durationMillis != -1) { 7886 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7887 } 7888 if (info.numInstances != -1) { 7889 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7890 } 7891 if (info.tags != null) { 7892 for (String tag : info.tags) { 7893 sb.append("Span-Tag: ").append(tag).append("\n"); 7894 } 7895 } 7896 sb.append("\n"); 7897 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7898 sb.append(info.crashInfo.stackTrace); 7899 } 7900 sb.append("\n"); 7901 7902 // Only buffer up to ~64k. Various logging bits truncate 7903 // things at 128k. 7904 needsFlush = (sb.length() > 64 * 1024); 7905 } 7906 7907 // Flush immediately if the buffer's grown too large, or this 7908 // is a non-system app. Non-system apps are isolated with a 7909 // different tag & policy and not batched. 7910 // 7911 // Batching is useful during internal testing with 7912 // StrictMode settings turned up high. Without batching, 7913 // thousands of separate files could be created on boot. 7914 if (!isSystemApp || needsFlush) { 7915 new Thread("Error dump: " + dropboxTag) { 7916 @Override 7917 public void run() { 7918 String report; 7919 synchronized (sb) { 7920 report = sb.toString(); 7921 sb.delete(0, sb.length()); 7922 sb.trimToSize(); 7923 } 7924 if (report.length() != 0) { 7925 dbox.addText(dropboxTag, report); 7926 } 7927 } 7928 }.start(); 7929 return; 7930 } 7931 7932 // System app batching: 7933 if (!bufferWasEmpty) { 7934 // An existing dropbox-writing thread is outstanding, so 7935 // we don't need to start it up. The existing thread will 7936 // catch the buffer appends we just did. 7937 return; 7938 } 7939 7940 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7941 // (After this point, we shouldn't access AMS internal data structures.) 7942 new Thread("Error dump: " + dropboxTag) { 7943 @Override 7944 public void run() { 7945 // 5 second sleep to let stacks arrive and be batched together 7946 try { 7947 Thread.sleep(5000); // 5 seconds 7948 } catch (InterruptedException e) {} 7949 7950 String errorReport; 7951 synchronized (mStrictModeBuffer) { 7952 errorReport = mStrictModeBuffer.toString(); 7953 if (errorReport.length() == 0) { 7954 return; 7955 } 7956 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 7957 mStrictModeBuffer.trimToSize(); 7958 } 7959 dbox.addText(dropboxTag, errorReport); 7960 } 7961 }.start(); 7962 } 7963 7964 /** 7965 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 7966 * @param app object of the crashing app, null for the system server 7967 * @param tag reported by the caller 7968 * @param crashInfo describing the context of the error 7969 * @return true if the process should exit immediately (WTF is fatal) 7970 */ 7971 public boolean handleApplicationWtf(IBinder app, String tag, 7972 ApplicationErrorReport.CrashInfo crashInfo) { 7973 ProcessRecord r = findAppProcess(app, "WTF"); 7974 final String processName = app == null ? "system_server" 7975 : (r == null ? "unknown" : r.processName); 7976 7977 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 7978 processName, 7979 r == null ? -1 : r.info.flags, 7980 tag, crashInfo.exceptionMessage); 7981 7982 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 7983 7984 if (r != null && r.pid != Process.myPid() && 7985 Settings.Secure.getInt(mContext.getContentResolver(), 7986 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 7987 crashApplication(r, crashInfo); 7988 return true; 7989 } else { 7990 return false; 7991 } 7992 } 7993 7994 /** 7995 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 7996 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 7997 */ 7998 private ProcessRecord findAppProcess(IBinder app, String reason) { 7999 if (app == null) { 8000 return null; 8001 } 8002 8003 synchronized (this) { 8004 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8005 final int NA = apps.size(); 8006 for (int ia=0; ia<NA; ia++) { 8007 ProcessRecord p = apps.valueAt(ia); 8008 if (p.thread != null && p.thread.asBinder() == app) { 8009 return p; 8010 } 8011 } 8012 } 8013 8014 Slog.w(TAG, "Can't find mystery application for " + reason 8015 + " from pid=" + Binder.getCallingPid() 8016 + " uid=" + Binder.getCallingUid() + ": " + app); 8017 return null; 8018 } 8019 } 8020 8021 /** 8022 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8023 * to append various headers to the dropbox log text. 8024 */ 8025 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8026 StringBuilder sb) { 8027 // Watchdog thread ends up invoking this function (with 8028 // a null ProcessRecord) to add the stack file to dropbox. 8029 // Do not acquire a lock on this (am) in such cases, as it 8030 // could cause a potential deadlock, if and when watchdog 8031 // is invoked due to unavailability of lock on am and it 8032 // would prevent watchdog from killing system_server. 8033 if (process == null) { 8034 sb.append("Process: ").append(processName).append("\n"); 8035 return; 8036 } 8037 // Note: ProcessRecord 'process' is guarded by the service 8038 // instance. (notably process.pkgList, which could otherwise change 8039 // concurrently during execution of this method) 8040 synchronized (this) { 8041 sb.append("Process: ").append(processName).append("\n"); 8042 int flags = process.info.flags; 8043 IPackageManager pm = AppGlobals.getPackageManager(); 8044 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8045 for (String pkg : process.pkgList) { 8046 sb.append("Package: ").append(pkg); 8047 try { 8048 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8049 if (pi != null) { 8050 sb.append(" v").append(pi.versionCode); 8051 if (pi.versionName != null) { 8052 sb.append(" (").append(pi.versionName).append(")"); 8053 } 8054 } 8055 } catch (RemoteException e) { 8056 Slog.e(TAG, "Error getting package info: " + pkg, e); 8057 } 8058 sb.append("\n"); 8059 } 8060 } 8061 } 8062 8063 private static String processClass(ProcessRecord process) { 8064 if (process == null || process.pid == MY_PID) { 8065 return "system_server"; 8066 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8067 return "system_app"; 8068 } else { 8069 return "data_app"; 8070 } 8071 } 8072 8073 /** 8074 * Write a description of an error (crash, WTF, ANR) to the drop box. 8075 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8076 * @param process which caused the error, null means the system server 8077 * @param activity which triggered the error, null if unknown 8078 * @param parent activity related to the error, null if unknown 8079 * @param subject line related to the error, null if absent 8080 * @param report in long form describing the error, null if absent 8081 * @param logFile to include in the report, null if none 8082 * @param crashInfo giving an application stack trace, null if absent 8083 */ 8084 public void addErrorToDropBox(String eventType, 8085 ProcessRecord process, String processName, ActivityRecord activity, 8086 ActivityRecord parent, String subject, 8087 final String report, final File logFile, 8088 final ApplicationErrorReport.CrashInfo crashInfo) { 8089 // NOTE -- this must never acquire the ActivityManagerService lock, 8090 // otherwise the watchdog may be prevented from resetting the system. 8091 8092 final String dropboxTag = processClass(process) + "_" + eventType; 8093 final DropBoxManager dbox = (DropBoxManager) 8094 mContext.getSystemService(Context.DROPBOX_SERVICE); 8095 8096 // Exit early if the dropbox isn't configured to accept this report type. 8097 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8098 8099 final StringBuilder sb = new StringBuilder(1024); 8100 appendDropBoxProcessHeaders(process, processName, sb); 8101 if (activity != null) { 8102 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8103 } 8104 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8105 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8106 } 8107 if (parent != null && parent != activity) { 8108 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8109 } 8110 if (subject != null) { 8111 sb.append("Subject: ").append(subject).append("\n"); 8112 } 8113 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8114 if (Debug.isDebuggerConnected()) { 8115 sb.append("Debugger: Connected\n"); 8116 } 8117 sb.append("\n"); 8118 8119 // Do the rest in a worker thread to avoid blocking the caller on I/O 8120 // (After this point, we shouldn't access AMS internal data structures.) 8121 Thread worker = new Thread("Error dump: " + dropboxTag) { 8122 @Override 8123 public void run() { 8124 if (report != null) { 8125 sb.append(report); 8126 } 8127 if (logFile != null) { 8128 try { 8129 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8130 } catch (IOException e) { 8131 Slog.e(TAG, "Error reading " + logFile, e); 8132 } 8133 } 8134 if (crashInfo != null && crashInfo.stackTrace != null) { 8135 sb.append(crashInfo.stackTrace); 8136 } 8137 8138 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8139 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8140 if (lines > 0) { 8141 sb.append("\n"); 8142 8143 // Merge several logcat streams, and take the last N lines 8144 InputStreamReader input = null; 8145 try { 8146 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8147 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8148 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8149 8150 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8151 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8152 input = new InputStreamReader(logcat.getInputStream()); 8153 8154 int num; 8155 char[] buf = new char[8192]; 8156 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8157 } catch (IOException e) { 8158 Slog.e(TAG, "Error running logcat", e); 8159 } finally { 8160 if (input != null) try { input.close(); } catch (IOException e) {} 8161 } 8162 } 8163 8164 dbox.addText(dropboxTag, sb.toString()); 8165 } 8166 }; 8167 8168 if (process == null) { 8169 // If process is null, we are being called from some internal code 8170 // and may be about to die -- run this synchronously. 8171 worker.run(); 8172 } else { 8173 worker.start(); 8174 } 8175 } 8176 8177 /** 8178 * Bring up the "unexpected error" dialog box for a crashing app. 8179 * Deal with edge cases (intercepts from instrumented applications, 8180 * ActivityController, error intent receivers, that sort of thing). 8181 * @param r the application crashing 8182 * @param crashInfo describing the failure 8183 */ 8184 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8185 long timeMillis = System.currentTimeMillis(); 8186 String shortMsg = crashInfo.exceptionClassName; 8187 String longMsg = crashInfo.exceptionMessage; 8188 String stackTrace = crashInfo.stackTrace; 8189 if (shortMsg != null && longMsg != null) { 8190 longMsg = shortMsg + ": " + longMsg; 8191 } else if (shortMsg != null) { 8192 longMsg = shortMsg; 8193 } 8194 8195 AppErrorResult result = new AppErrorResult(); 8196 synchronized (this) { 8197 if (mController != null) { 8198 try { 8199 String name = r != null ? r.processName : null; 8200 int pid = r != null ? r.pid : Binder.getCallingPid(); 8201 if (!mController.appCrashed(name, pid, 8202 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8203 Slog.w(TAG, "Force-killing crashed app " + name 8204 + " at watcher's request"); 8205 Process.killProcess(pid); 8206 return; 8207 } 8208 } catch (RemoteException e) { 8209 mController = null; 8210 } 8211 } 8212 8213 final long origId = Binder.clearCallingIdentity(); 8214 8215 // If this process is running instrumentation, finish it. 8216 if (r != null && r.instrumentationClass != null) { 8217 Slog.w(TAG, "Error in app " + r.processName 8218 + " running instrumentation " + r.instrumentationClass + ":"); 8219 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8220 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8221 Bundle info = new Bundle(); 8222 info.putString("shortMsg", shortMsg); 8223 info.putString("longMsg", longMsg); 8224 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8225 Binder.restoreCallingIdentity(origId); 8226 return; 8227 } 8228 8229 // If we can't identify the process or it's already exceeded its crash quota, 8230 // quit right away without showing a crash dialog. 8231 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8232 Binder.restoreCallingIdentity(origId); 8233 return; 8234 } 8235 8236 Message msg = Message.obtain(); 8237 msg.what = SHOW_ERROR_MSG; 8238 HashMap data = new HashMap(); 8239 data.put("result", result); 8240 data.put("app", r); 8241 msg.obj = data; 8242 mHandler.sendMessage(msg); 8243 8244 Binder.restoreCallingIdentity(origId); 8245 } 8246 8247 int res = result.get(); 8248 8249 Intent appErrorIntent = null; 8250 synchronized (this) { 8251 if (r != null && !r.isolated) { 8252 // XXX Can't keep track of crash time for isolated processes, 8253 // since they don't have a persistent identity. 8254 mProcessCrashTimes.put(r.info.processName, r.uid, 8255 SystemClock.uptimeMillis()); 8256 } 8257 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8258 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8259 } 8260 } 8261 8262 if (appErrorIntent != null) { 8263 try { 8264 mContext.startActivity(appErrorIntent); 8265 } catch (ActivityNotFoundException e) { 8266 Slog.w(TAG, "bug report receiver dissappeared", e); 8267 } 8268 } 8269 } 8270 8271 Intent createAppErrorIntentLocked(ProcessRecord r, 8272 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8273 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8274 if (report == null) { 8275 return null; 8276 } 8277 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8278 result.setComponent(r.errorReportReceiver); 8279 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8280 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8281 return result; 8282 } 8283 8284 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8285 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8286 if (r.errorReportReceiver == null) { 8287 return null; 8288 } 8289 8290 if (!r.crashing && !r.notResponding) { 8291 return null; 8292 } 8293 8294 ApplicationErrorReport report = new ApplicationErrorReport(); 8295 report.packageName = r.info.packageName; 8296 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8297 report.processName = r.processName; 8298 report.time = timeMillis; 8299 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8300 8301 if (r.crashing) { 8302 report.type = ApplicationErrorReport.TYPE_CRASH; 8303 report.crashInfo = crashInfo; 8304 } else if (r.notResponding) { 8305 report.type = ApplicationErrorReport.TYPE_ANR; 8306 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8307 8308 report.anrInfo.activity = r.notRespondingReport.tag; 8309 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8310 report.anrInfo.info = r.notRespondingReport.longMsg; 8311 } 8312 8313 return report; 8314 } 8315 8316 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8317 enforceNotIsolatedCaller("getProcessesInErrorState"); 8318 // assume our apps are happy - lazy create the list 8319 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8320 8321 synchronized (this) { 8322 8323 // iterate across all processes 8324 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8325 ProcessRecord app = mLruProcesses.get(i); 8326 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8327 // This one's in trouble, so we'll generate a report for it 8328 // crashes are higher priority (in case there's a crash *and* an anr) 8329 ActivityManager.ProcessErrorStateInfo report = null; 8330 if (app.crashing) { 8331 report = app.crashingReport; 8332 } else if (app.notResponding) { 8333 report = app.notRespondingReport; 8334 } 8335 8336 if (report != null) { 8337 if (errList == null) { 8338 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8339 } 8340 errList.add(report); 8341 } else { 8342 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8343 " crashing = " + app.crashing + 8344 " notResponding = " + app.notResponding); 8345 } 8346 } 8347 } 8348 } 8349 8350 return errList; 8351 } 8352 8353 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8354 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8355 if (currApp != null) { 8356 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8357 } 8358 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8359 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8360 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8361 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8362 if (currApp != null) { 8363 currApp.lru = 0; 8364 } 8365 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8366 } else if (adj >= ProcessList.SERVICE_ADJ) { 8367 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8368 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8369 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8370 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8371 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8372 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8373 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8374 } else { 8375 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8376 } 8377 } 8378 8379 private void fillInProcMemInfo(ProcessRecord app, 8380 ActivityManager.RunningAppProcessInfo outInfo) { 8381 outInfo.pid = app.pid; 8382 outInfo.uid = app.info.uid; 8383 if (mHeavyWeightProcess == app) { 8384 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8385 } 8386 if (app.persistent) { 8387 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8388 } 8389 outInfo.lastTrimLevel = app.trimMemoryLevel; 8390 int adj = app.curAdj; 8391 outInfo.importance = oomAdjToImportance(adj, outInfo); 8392 outInfo.importanceReasonCode = app.adjTypeCode; 8393 } 8394 8395 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8396 enforceNotIsolatedCaller("getRunningAppProcesses"); 8397 // Lazy instantiation of list 8398 List<ActivityManager.RunningAppProcessInfo> runList = null; 8399 synchronized (this) { 8400 // Iterate across all processes 8401 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8402 ProcessRecord app = mLruProcesses.get(i); 8403 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8404 // Generate process state info for running application 8405 ActivityManager.RunningAppProcessInfo currApp = 8406 new ActivityManager.RunningAppProcessInfo(app.processName, 8407 app.pid, app.getPackageList()); 8408 fillInProcMemInfo(app, currApp); 8409 if (app.adjSource instanceof ProcessRecord) { 8410 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8411 currApp.importanceReasonImportance = oomAdjToImportance( 8412 app.adjSourceOom, null); 8413 } else if (app.adjSource instanceof ActivityRecord) { 8414 ActivityRecord r = (ActivityRecord)app.adjSource; 8415 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8416 } 8417 if (app.adjTarget instanceof ComponentName) { 8418 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8419 } 8420 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8421 // + " lru=" + currApp.lru); 8422 if (runList == null) { 8423 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8424 } 8425 runList.add(currApp); 8426 } 8427 } 8428 } 8429 return runList; 8430 } 8431 8432 public List<ApplicationInfo> getRunningExternalApplications() { 8433 enforceNotIsolatedCaller("getRunningExternalApplications"); 8434 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8435 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8436 if (runningApps != null && runningApps.size() > 0) { 8437 Set<String> extList = new HashSet<String>(); 8438 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8439 if (app.pkgList != null) { 8440 for (String pkg : app.pkgList) { 8441 extList.add(pkg); 8442 } 8443 } 8444 } 8445 IPackageManager pm = AppGlobals.getPackageManager(); 8446 for (String pkg : extList) { 8447 try { 8448 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8449 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8450 retList.add(info); 8451 } 8452 } catch (RemoteException e) { 8453 } 8454 } 8455 } 8456 return retList; 8457 } 8458 8459 @Override 8460 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8461 enforceNotIsolatedCaller("getMyMemoryState"); 8462 synchronized (this) { 8463 ProcessRecord proc; 8464 synchronized (mPidsSelfLocked) { 8465 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8466 } 8467 fillInProcMemInfo(proc, outInfo); 8468 } 8469 } 8470 8471 @Override 8472 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8473 if (checkCallingPermission(android.Manifest.permission.DUMP) 8474 != PackageManager.PERMISSION_GRANTED) { 8475 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8476 + Binder.getCallingPid() 8477 + ", uid=" + Binder.getCallingUid() 8478 + " without permission " 8479 + android.Manifest.permission.DUMP); 8480 return; 8481 } 8482 8483 boolean dumpAll = false; 8484 boolean dumpClient = false; 8485 String dumpPackage = null; 8486 8487 int opti = 0; 8488 while (opti < args.length) { 8489 String opt = args[opti]; 8490 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8491 break; 8492 } 8493 opti++; 8494 if ("-a".equals(opt)) { 8495 dumpAll = true; 8496 } else if ("-c".equals(opt)) { 8497 dumpClient = true; 8498 } else if ("-h".equals(opt)) { 8499 pw.println("Activity manager dump options:"); 8500 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8501 pw.println(" cmd may be one of:"); 8502 pw.println(" a[ctivities]: activity stack state"); 8503 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8504 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8505 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8506 pw.println(" o[om]: out of memory management"); 8507 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8508 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8509 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8510 pw.println(" service [COMP_SPEC]: service client-side state"); 8511 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8512 pw.println(" all: dump all activities"); 8513 pw.println(" top: dump the top activity"); 8514 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8515 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8516 pw.println(" a partial substring in a component name, a"); 8517 pw.println(" hex object identifier."); 8518 pw.println(" -a: include all available server state."); 8519 pw.println(" -c: include client state."); 8520 return; 8521 } else { 8522 pw.println("Unknown argument: " + opt + "; use -h for help"); 8523 } 8524 } 8525 8526 long origId = Binder.clearCallingIdentity(); 8527 boolean more = false; 8528 // Is the caller requesting to dump a particular piece of data? 8529 if (opti < args.length) { 8530 String cmd = args[opti]; 8531 opti++; 8532 if ("activities".equals(cmd) || "a".equals(cmd)) { 8533 synchronized (this) { 8534 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8535 } 8536 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8537 String[] newArgs; 8538 String name; 8539 if (opti >= args.length) { 8540 name = null; 8541 newArgs = EMPTY_STRING_ARRAY; 8542 } else { 8543 name = args[opti]; 8544 opti++; 8545 newArgs = new String[args.length - opti]; 8546 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8547 args.length - opti); 8548 } 8549 synchronized (this) { 8550 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8551 } 8552 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8553 String[] newArgs; 8554 String name; 8555 if (opti >= args.length) { 8556 name = null; 8557 newArgs = EMPTY_STRING_ARRAY; 8558 } else { 8559 name = args[opti]; 8560 opti++; 8561 newArgs = new String[args.length - opti]; 8562 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8563 args.length - opti); 8564 } 8565 synchronized (this) { 8566 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8567 } 8568 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8569 String[] newArgs; 8570 String name; 8571 if (opti >= args.length) { 8572 name = null; 8573 newArgs = EMPTY_STRING_ARRAY; 8574 } else { 8575 name = args[opti]; 8576 opti++; 8577 newArgs = new String[args.length - opti]; 8578 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8579 args.length - opti); 8580 } 8581 synchronized (this) { 8582 dumpProcessesLocked(fd, pw, args, opti, true, name); 8583 } 8584 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8585 synchronized (this) { 8586 dumpOomLocked(fd, pw, args, opti, true); 8587 } 8588 } else if ("provider".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, args.length - opti); 8599 } 8600 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8601 pw.println("No providers match: " + name); 8602 pw.println("Use -h for help."); 8603 } 8604 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8605 synchronized (this) { 8606 dumpProvidersLocked(fd, pw, args, opti, true, null); 8607 } 8608 } else if ("service".equals(cmd)) { 8609 String[] newArgs; 8610 String name; 8611 if (opti >= args.length) { 8612 name = null; 8613 newArgs = EMPTY_STRING_ARRAY; 8614 } else { 8615 name = args[opti]; 8616 opti++; 8617 newArgs = new String[args.length - opti]; 8618 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8619 args.length - opti); 8620 } 8621 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8622 pw.println("No services match: " + name); 8623 pw.println("Use -h for help."); 8624 } 8625 } else if ("package".equals(cmd)) { 8626 String[] newArgs; 8627 if (opti >= args.length) { 8628 pw.println("package: no package name specified"); 8629 pw.println("Use -h for help."); 8630 } else { 8631 dumpPackage = args[opti]; 8632 opti++; 8633 newArgs = new String[args.length - opti]; 8634 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8635 args.length - opti); 8636 args = newArgs; 8637 opti = 0; 8638 more = true; 8639 } 8640 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8641 synchronized (this) { 8642 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8643 } 8644 } else { 8645 // Dumping a single activity? 8646 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8647 pw.println("Bad activity command, or no activities match: " + cmd); 8648 pw.println("Use -h for help."); 8649 } 8650 } 8651 if (!more) { 8652 Binder.restoreCallingIdentity(origId); 8653 return; 8654 } 8655 } 8656 8657 // No piece of data specified, dump everything. 8658 synchronized (this) { 8659 boolean needSep; 8660 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8661 if (needSep) { 8662 pw.println(" "); 8663 } 8664 if (dumpAll) { 8665 pw.println("-------------------------------------------------------------------------------"); 8666 } 8667 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8668 if (needSep) { 8669 pw.println(" "); 8670 } 8671 if (dumpAll) { 8672 pw.println("-------------------------------------------------------------------------------"); 8673 } 8674 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8675 if (needSep) { 8676 pw.println(" "); 8677 } 8678 if (dumpAll) { 8679 pw.println("-------------------------------------------------------------------------------"); 8680 } 8681 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8682 if (needSep) { 8683 pw.println(" "); 8684 } 8685 if (dumpAll) { 8686 pw.println("-------------------------------------------------------------------------------"); 8687 } 8688 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8689 if (needSep) { 8690 pw.println(" "); 8691 } 8692 if (dumpAll) { 8693 pw.println("-------------------------------------------------------------------------------"); 8694 } 8695 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8696 } 8697 Binder.restoreCallingIdentity(origId); 8698 } 8699 8700 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8701 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8702 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8703 pw.println(" Main stack:"); 8704 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8705 dumpPackage); 8706 pw.println(" "); 8707 pw.println(" Running activities (most recent first):"); 8708 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8709 dumpPackage); 8710 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8711 pw.println(" "); 8712 pw.println(" Activities waiting for another to become visible:"); 8713 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8714 !dumpAll, false, dumpPackage); 8715 } 8716 if (mMainStack.mStoppingActivities.size() > 0) { 8717 pw.println(" "); 8718 pw.println(" Activities waiting to stop:"); 8719 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8720 !dumpAll, false, dumpPackage); 8721 } 8722 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8723 pw.println(" "); 8724 pw.println(" Activities waiting to sleep:"); 8725 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8726 !dumpAll, false, dumpPackage); 8727 } 8728 if (mMainStack.mFinishingActivities.size() > 0) { 8729 pw.println(" "); 8730 pw.println(" Activities waiting to finish:"); 8731 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8732 !dumpAll, false, dumpPackage); 8733 } 8734 8735 pw.println(" "); 8736 if (mMainStack.mPausingActivity != null) { 8737 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8738 } 8739 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8740 pw.println(" mFocusedActivity: " + mFocusedActivity); 8741 if (dumpAll) { 8742 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8743 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8744 pw.println(" mDismissKeyguardOnNextActivity: " 8745 + mMainStack.mDismissKeyguardOnNextActivity); 8746 } 8747 8748 if (mRecentTasks.size() > 0) { 8749 pw.println(); 8750 pw.println(" Recent tasks:"); 8751 8752 final int N = mRecentTasks.size(); 8753 for (int i=0; i<N; i++) { 8754 TaskRecord tr = mRecentTasks.get(i); 8755 if (dumpPackage != null) { 8756 if (tr.realActivity == null || 8757 !dumpPackage.equals(tr.realActivity)) { 8758 continue; 8759 } 8760 } 8761 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8762 pw.println(tr); 8763 if (dumpAll) { 8764 mRecentTasks.get(i).dump(pw, " "); 8765 } 8766 } 8767 } 8768 8769 if (dumpAll) { 8770 pw.println(" "); 8771 pw.println(" mCurTask: " + mCurTask); 8772 } 8773 8774 return true; 8775 } 8776 8777 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8778 int opti, boolean dumpAll, String dumpPackage) { 8779 boolean needSep = false; 8780 int numPers = 0; 8781 8782 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8783 8784 if (dumpAll) { 8785 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8786 final int NA = procs.size(); 8787 for (int ia=0; ia<NA; ia++) { 8788 ProcessRecord r = procs.valueAt(ia); 8789 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8790 continue; 8791 } 8792 if (!needSep) { 8793 pw.println(" All known processes:"); 8794 needSep = true; 8795 } 8796 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8797 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8798 pw.print(" "); pw.println(r); 8799 r.dump(pw, " "); 8800 if (r.persistent) { 8801 numPers++; 8802 } 8803 } 8804 } 8805 } 8806 8807 if (mIsolatedProcesses.size() > 0) { 8808 if (needSep) pw.println(" "); 8809 needSep = true; 8810 pw.println(" Isolated process list (sorted by uid):"); 8811 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8812 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8813 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8814 continue; 8815 } 8816 pw.println(String.format("%sIsolated #%2d: %s", 8817 " ", i, r.toString())); 8818 } 8819 } 8820 8821 if (mLruProcesses.size() > 0) { 8822 if (needSep) pw.println(" "); 8823 needSep = true; 8824 pw.println(" Process LRU list (sorted by oom_adj):"); 8825 dumpProcessOomList(pw, this, mLruProcesses, " ", 8826 "Proc", "PERS", false, dumpPackage); 8827 needSep = true; 8828 } 8829 8830 if (dumpAll) { 8831 synchronized (mPidsSelfLocked) { 8832 boolean printed = false; 8833 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8834 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8835 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8836 continue; 8837 } 8838 if (!printed) { 8839 if (needSep) pw.println(" "); 8840 needSep = true; 8841 pw.println(" PID mappings:"); 8842 printed = true; 8843 } 8844 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8845 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8846 } 8847 } 8848 } 8849 8850 if (mForegroundProcesses.size() > 0) { 8851 synchronized (mPidsSelfLocked) { 8852 boolean printed = false; 8853 for (int i=0; i<mForegroundProcesses.size(); i++) { 8854 ProcessRecord r = mPidsSelfLocked.get( 8855 mForegroundProcesses.valueAt(i).pid); 8856 if (dumpPackage != null && (r == null 8857 || !dumpPackage.equals(r.info.packageName))) { 8858 continue; 8859 } 8860 if (!printed) { 8861 if (needSep) pw.println(" "); 8862 needSep = true; 8863 pw.println(" Foreground Processes:"); 8864 printed = true; 8865 } 8866 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8867 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8868 } 8869 } 8870 } 8871 8872 if (mPersistentStartingProcesses.size() > 0) { 8873 if (needSep) pw.println(" "); 8874 needSep = true; 8875 pw.println(" Persisent processes that are starting:"); 8876 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8877 "Starting Norm", "Restarting PERS", dumpPackage); 8878 } 8879 8880 if (mRemovedProcesses.size() > 0) { 8881 if (needSep) pw.println(" "); 8882 needSep = true; 8883 pw.println(" Processes that are being removed:"); 8884 dumpProcessList(pw, this, mRemovedProcesses, " ", 8885 "Removed Norm", "Removed PERS", dumpPackage); 8886 } 8887 8888 if (mProcessesOnHold.size() > 0) { 8889 if (needSep) pw.println(" "); 8890 needSep = true; 8891 pw.println(" Processes that are on old until the system is ready:"); 8892 dumpProcessList(pw, this, mProcessesOnHold, " ", 8893 "OnHold Norm", "OnHold PERS", dumpPackage); 8894 } 8895 8896 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8897 8898 if (mProcessCrashTimes.getMap().size() > 0) { 8899 boolean printed = false; 8900 long now = SystemClock.uptimeMillis(); 8901 for (Map.Entry<String, SparseArray<Long>> procs 8902 : mProcessCrashTimes.getMap().entrySet()) { 8903 String pname = procs.getKey(); 8904 SparseArray<Long> uids = procs.getValue(); 8905 final int N = uids.size(); 8906 for (int i=0; i<N; i++) { 8907 int puid = uids.keyAt(i); 8908 ProcessRecord r = mProcessNames.get(pname, puid); 8909 if (dumpPackage != null && (r == null 8910 || !dumpPackage.equals(r.info.packageName))) { 8911 continue; 8912 } 8913 if (!printed) { 8914 if (needSep) pw.println(" "); 8915 needSep = true; 8916 pw.println(" Time since processes crashed:"); 8917 printed = true; 8918 } 8919 pw.print(" Process "); pw.print(pname); 8920 pw.print(" uid "); pw.print(puid); 8921 pw.print(": last crashed "); 8922 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8923 pw.println(" ago"); 8924 } 8925 } 8926 } 8927 8928 if (mBadProcesses.getMap().size() > 0) { 8929 boolean printed = false; 8930 for (Map.Entry<String, SparseArray<Long>> procs 8931 : mBadProcesses.getMap().entrySet()) { 8932 String pname = procs.getKey(); 8933 SparseArray<Long> uids = procs.getValue(); 8934 final int N = uids.size(); 8935 for (int i=0; i<N; i++) { 8936 int puid = uids.keyAt(i); 8937 ProcessRecord r = mProcessNames.get(pname, puid); 8938 if (dumpPackage != null && (r == null 8939 || !dumpPackage.equals(r.info.packageName))) { 8940 continue; 8941 } 8942 if (!printed) { 8943 if (needSep) pw.println(" "); 8944 needSep = true; 8945 pw.println(" Bad processes:"); 8946 } 8947 pw.print(" Bad process "); pw.print(pname); 8948 pw.print(" uid "); pw.print(puid); 8949 pw.print(": crashed at time "); 8950 pw.println(uids.valueAt(i)); 8951 } 8952 } 8953 } 8954 8955 pw.println(); 8956 pw.println(" mHomeProcess: " + mHomeProcess); 8957 pw.println(" mPreviousProcess: " + mPreviousProcess); 8958 if (dumpAll) { 8959 StringBuilder sb = new StringBuilder(128); 8960 sb.append(" mPreviousProcessVisibleTime: "); 8961 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 8962 pw.println(sb); 8963 } 8964 if (mHeavyWeightProcess != null) { 8965 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8966 } 8967 pw.println(" mConfiguration: " + mConfiguration); 8968 if (dumpAll) { 8969 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 8970 if (mCompatModePackages.getPackages().size() > 0) { 8971 boolean printed = false; 8972 for (Map.Entry<String, Integer> entry 8973 : mCompatModePackages.getPackages().entrySet()) { 8974 String pkg = entry.getKey(); 8975 int mode = entry.getValue(); 8976 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 8977 continue; 8978 } 8979 if (!printed) { 8980 pw.println(" mScreenCompatPackages:"); 8981 printed = true; 8982 } 8983 pw.print(" "); pw.print(pkg); pw.print(": "); 8984 pw.print(mode); pw.println(); 8985 } 8986 } 8987 } 8988 if (mSleeping || mWentToSleep || mLockScreenShown) { 8989 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 8990 + " mLockScreenShown " + mLockScreenShown); 8991 } 8992 if (mShuttingDown) { 8993 pw.println(" mShuttingDown=" + mShuttingDown); 8994 } 8995 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 8996 || mOrigWaitForDebugger) { 8997 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 8998 + " mDebugTransient=" + mDebugTransient 8999 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9000 } 9001 if (mOpenGlTraceApp != null) { 9002 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9003 } 9004 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9005 || mProfileFd != null) { 9006 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9007 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9008 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9009 + mAutoStopProfiler); 9010 } 9011 if (mAlwaysFinishActivities || mController != null) { 9012 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9013 + " mController=" + mController); 9014 } 9015 if (dumpAll) { 9016 pw.println(" Total persistent processes: " + numPers); 9017 pw.println(" mStartRunning=" + mStartRunning 9018 + " mProcessesReady=" + mProcessesReady 9019 + " mSystemReady=" + mSystemReady); 9020 pw.println(" mBooting=" + mBooting 9021 + " mBooted=" + mBooted 9022 + " mFactoryTest=" + mFactoryTest); 9023 pw.print(" mLastPowerCheckRealtime="); 9024 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9025 pw.println(""); 9026 pw.print(" mLastPowerCheckUptime="); 9027 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9028 pw.println(""); 9029 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9030 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9031 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9032 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9033 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9034 } 9035 9036 return true; 9037 } 9038 9039 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9040 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9041 if (mProcessesToGc.size() > 0) { 9042 boolean printed = false; 9043 long now = SystemClock.uptimeMillis(); 9044 for (int i=0; i<mProcessesToGc.size(); i++) { 9045 ProcessRecord proc = mProcessesToGc.get(i); 9046 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9047 continue; 9048 } 9049 if (!printed) { 9050 if (needSep) pw.println(" "); 9051 needSep = true; 9052 pw.println(" Processes that are waiting to GC:"); 9053 printed = true; 9054 } 9055 pw.print(" Process "); pw.println(proc); 9056 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9057 pw.print(", last gced="); 9058 pw.print(now-proc.lastRequestedGc); 9059 pw.print(" ms ago, last lowMem="); 9060 pw.print(now-proc.lastLowMemory); 9061 pw.println(" ms ago"); 9062 9063 } 9064 } 9065 return needSep; 9066 } 9067 9068 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9069 int opti, boolean dumpAll) { 9070 boolean needSep = false; 9071 9072 if (mLruProcesses.size() > 0) { 9073 if (needSep) pw.println(" "); 9074 needSep = true; 9075 pw.println(" OOM levels:"); 9076 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9077 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9078 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9079 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9080 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9081 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9082 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9083 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9084 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9085 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9086 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9087 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9088 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9089 9090 if (needSep) pw.println(" "); 9091 needSep = true; 9092 pw.println(" Process OOM control:"); 9093 dumpProcessOomList(pw, this, mLruProcesses, " ", 9094 "Proc", "PERS", true, null); 9095 needSep = true; 9096 } 9097 9098 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9099 9100 pw.println(); 9101 pw.println(" mHomeProcess: " + mHomeProcess); 9102 pw.println(" mPreviousProcess: " + mPreviousProcess); 9103 if (mHeavyWeightProcess != null) { 9104 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9105 } 9106 9107 return true; 9108 } 9109 9110 /** 9111 * There are three ways to call this: 9112 * - no provider specified: dump all the providers 9113 * - a flattened component name that matched an existing provider was specified as the 9114 * first arg: dump that one provider 9115 * - the first arg isn't the flattened component name of an existing provider: 9116 * dump all providers whose component contains the first arg as a substring 9117 */ 9118 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9119 int opti, boolean dumpAll) { 9120 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9121 } 9122 9123 static class ItemMatcher { 9124 ArrayList<ComponentName> components; 9125 ArrayList<String> strings; 9126 ArrayList<Integer> objects; 9127 boolean all; 9128 9129 ItemMatcher() { 9130 all = true; 9131 } 9132 9133 void build(String name) { 9134 ComponentName componentName = ComponentName.unflattenFromString(name); 9135 if (componentName != null) { 9136 if (components == null) { 9137 components = new ArrayList<ComponentName>(); 9138 } 9139 components.add(componentName); 9140 all = false; 9141 } else { 9142 int objectId = 0; 9143 // Not a '/' separated full component name; maybe an object ID? 9144 try { 9145 objectId = Integer.parseInt(name, 16); 9146 if (objects == null) { 9147 objects = new ArrayList<Integer>(); 9148 } 9149 objects.add(objectId); 9150 all = false; 9151 } catch (RuntimeException e) { 9152 // Not an integer; just do string match. 9153 if (strings == null) { 9154 strings = new ArrayList<String>(); 9155 } 9156 strings.add(name); 9157 all = false; 9158 } 9159 } 9160 } 9161 9162 int build(String[] args, int opti) { 9163 for (; opti<args.length; opti++) { 9164 String name = args[opti]; 9165 if ("--".equals(name)) { 9166 return opti+1; 9167 } 9168 build(name); 9169 } 9170 return opti; 9171 } 9172 9173 boolean match(Object object, ComponentName comp) { 9174 if (all) { 9175 return true; 9176 } 9177 if (components != null) { 9178 for (int i=0; i<components.size(); i++) { 9179 if (components.get(i).equals(comp)) { 9180 return true; 9181 } 9182 } 9183 } 9184 if (objects != null) { 9185 for (int i=0; i<objects.size(); i++) { 9186 if (System.identityHashCode(object) == objects.get(i)) { 9187 return true; 9188 } 9189 } 9190 } 9191 if (strings != null) { 9192 String flat = comp.flattenToString(); 9193 for (int i=0; i<strings.size(); i++) { 9194 if (flat.contains(strings.get(i))) { 9195 return true; 9196 } 9197 } 9198 } 9199 return false; 9200 } 9201 } 9202 9203 /** 9204 * There are three things that cmd can be: 9205 * - a flattened component name that matches an existing activity 9206 * - the cmd arg isn't the flattened component name of an existing activity: 9207 * dump all activity whose component contains the cmd as a substring 9208 * - A hex number of the ActivityRecord object instance. 9209 */ 9210 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9211 int opti, boolean dumpAll) { 9212 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9213 9214 if ("all".equals(name)) { 9215 synchronized (this) { 9216 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9217 activities.add(r1); 9218 } 9219 } 9220 } else if ("top".equals(name)) { 9221 synchronized (this) { 9222 final int N = mMainStack.mHistory.size(); 9223 if (N > 0) { 9224 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9225 } 9226 } 9227 } else { 9228 ItemMatcher matcher = new ItemMatcher(); 9229 matcher.build(name); 9230 9231 synchronized (this) { 9232 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9233 if (matcher.match(r1, r1.intent.getComponent())) { 9234 activities.add(r1); 9235 } 9236 } 9237 } 9238 } 9239 9240 if (activities.size() <= 0) { 9241 return false; 9242 } 9243 9244 String[] newArgs = new String[args.length - opti]; 9245 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9246 9247 TaskRecord lastTask = null; 9248 boolean needSep = false; 9249 for (int i=activities.size()-1; i>=0; i--) { 9250 ActivityRecord r = (ActivityRecord)activities.get(i); 9251 if (needSep) { 9252 pw.println(); 9253 } 9254 needSep = true; 9255 synchronized (this) { 9256 if (lastTask != r.task) { 9257 lastTask = r.task; 9258 pw.print("TASK "); pw.print(lastTask.affinity); 9259 pw.print(" id="); pw.println(lastTask.taskId); 9260 if (dumpAll) { 9261 lastTask.dump(pw, " "); 9262 } 9263 } 9264 } 9265 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9266 } 9267 return true; 9268 } 9269 9270 /** 9271 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9272 * there is a thread associated with the activity. 9273 */ 9274 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9275 final ActivityRecord r, String[] args, boolean dumpAll) { 9276 String innerPrefix = prefix + " "; 9277 synchronized (this) { 9278 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9279 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9280 pw.print(" pid="); 9281 if (r.app != null) pw.println(r.app.pid); 9282 else pw.println("(not running)"); 9283 if (dumpAll) { 9284 r.dump(pw, innerPrefix); 9285 } 9286 } 9287 if (r.app != null && r.app.thread != null) { 9288 // flush anything that is already in the PrintWriter since the thread is going 9289 // to write to the file descriptor directly 9290 pw.flush(); 9291 try { 9292 TransferPipe tp = new TransferPipe(); 9293 try { 9294 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9295 r.appToken, innerPrefix, args); 9296 tp.go(fd); 9297 } finally { 9298 tp.kill(); 9299 } 9300 } catch (IOException e) { 9301 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9302 } catch (RemoteException e) { 9303 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9304 } 9305 } 9306 } 9307 9308 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9309 int opti, boolean dumpAll, String dumpPackage) { 9310 boolean needSep = false; 9311 9312 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9313 if (dumpAll) { 9314 if (mRegisteredReceivers.size() > 0) { 9315 boolean printed = false; 9316 Iterator it = mRegisteredReceivers.values().iterator(); 9317 while (it.hasNext()) { 9318 ReceiverList r = (ReceiverList)it.next(); 9319 if (dumpPackage != null && (r.app == null || 9320 !dumpPackage.equals(r.app.info.packageName))) { 9321 continue; 9322 } 9323 if (!printed) { 9324 pw.println(" Registered Receivers:"); 9325 needSep = true; 9326 printed = true; 9327 } 9328 pw.print(" * "); pw.println(r); 9329 r.dump(pw, " "); 9330 } 9331 } 9332 9333 if (mReceiverResolver.dump(pw, needSep ? 9334 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9335 " ", dumpPackage, false)) { 9336 needSep = true; 9337 } 9338 } 9339 9340 for (BroadcastQueue q : mBroadcastQueues) { 9341 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9342 } 9343 9344 needSep = true; 9345 9346 if (mStickyBroadcasts != null && dumpPackage == null) { 9347 if (needSep) { 9348 pw.println(); 9349 } 9350 needSep = true; 9351 pw.println(" Sticky broadcasts:"); 9352 StringBuilder sb = new StringBuilder(128); 9353 for (Map.Entry<String, ArrayList<Intent>> ent 9354 : mStickyBroadcasts.entrySet()) { 9355 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9356 if (dumpAll) { 9357 pw.println(":"); 9358 ArrayList<Intent> intents = ent.getValue(); 9359 final int N = intents.size(); 9360 for (int i=0; i<N; i++) { 9361 sb.setLength(0); 9362 sb.append(" Intent: "); 9363 intents.get(i).toShortString(sb, false, true, false, false); 9364 pw.println(sb.toString()); 9365 Bundle bundle = intents.get(i).getExtras(); 9366 if (bundle != null) { 9367 pw.print(" "); 9368 pw.println(bundle.toString()); 9369 } 9370 } 9371 } else { 9372 pw.println(""); 9373 } 9374 } 9375 needSep = true; 9376 } 9377 9378 if (dumpAll) { 9379 pw.println(); 9380 for (BroadcastQueue queue : mBroadcastQueues) { 9381 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9382 + queue.mBroadcastsScheduled); 9383 } 9384 pw.println(" mHandler:"); 9385 mHandler.dump(new PrintWriterPrinter(pw), " "); 9386 needSep = true; 9387 } 9388 9389 return needSep; 9390 } 9391 9392 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9393 int opti, boolean dumpAll, String dumpPackage) { 9394 boolean needSep = true; 9395 9396 ItemMatcher matcher = new ItemMatcher(); 9397 matcher.build(args, opti); 9398 9399 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9400 9401 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9402 9403 if (mLaunchingProviders.size() > 0) { 9404 boolean printed = false; 9405 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9406 ContentProviderRecord r = mLaunchingProviders.get(i); 9407 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9408 continue; 9409 } 9410 if (!printed) { 9411 if (needSep) pw.println(" "); 9412 needSep = true; 9413 pw.println(" Launching content providers:"); 9414 printed = true; 9415 } 9416 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9417 pw.println(r); 9418 } 9419 } 9420 9421 if (mGrantedUriPermissions.size() > 0) { 9422 if (needSep) pw.println(); 9423 needSep = true; 9424 pw.println("Granted Uri Permissions:"); 9425 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9426 int uid = mGrantedUriPermissions.keyAt(i); 9427 HashMap<Uri, UriPermission> perms 9428 = mGrantedUriPermissions.valueAt(i); 9429 pw.print(" * UID "); pw.print(uid); 9430 pw.println(" holds:"); 9431 for (UriPermission perm : perms.values()) { 9432 pw.print(" "); pw.println(perm); 9433 if (dumpAll) { 9434 perm.dump(pw, " "); 9435 } 9436 } 9437 } 9438 needSep = true; 9439 } 9440 9441 return needSep; 9442 } 9443 9444 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9445 int opti, boolean dumpAll, String dumpPackage) { 9446 boolean needSep = false; 9447 9448 if (mIntentSenderRecords.size() > 0) { 9449 boolean printed = false; 9450 Iterator<WeakReference<PendingIntentRecord>> it 9451 = mIntentSenderRecords.values().iterator(); 9452 while (it.hasNext()) { 9453 WeakReference<PendingIntentRecord> ref = it.next(); 9454 PendingIntentRecord rec = ref != null ? ref.get(): null; 9455 if (dumpPackage != null && (rec == null 9456 || !dumpPackage.equals(rec.key.packageName))) { 9457 continue; 9458 } 9459 if (!printed) { 9460 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9461 printed = true; 9462 } 9463 needSep = true; 9464 if (rec != null) { 9465 pw.print(" * "); pw.println(rec); 9466 if (dumpAll) { 9467 rec.dump(pw, " "); 9468 } 9469 } else { 9470 pw.print(" * "); pw.println(ref); 9471 } 9472 } 9473 } 9474 9475 return needSep; 9476 } 9477 9478 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9479 String prefix, String label, boolean complete, boolean brief, boolean client, 9480 String dumpPackage) { 9481 TaskRecord lastTask = null; 9482 boolean needNL = false; 9483 final String innerPrefix = prefix + " "; 9484 final String[] args = new String[0]; 9485 for (int i=list.size()-1; i>=0; i--) { 9486 final ActivityRecord r = (ActivityRecord)list.get(i); 9487 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9488 continue; 9489 } 9490 final boolean full = !brief && (complete || !r.isInHistory()); 9491 if (needNL) { 9492 pw.println(" "); 9493 needNL = false; 9494 } 9495 if (lastTask != r.task) { 9496 lastTask = r.task; 9497 pw.print(prefix); 9498 pw.print(full ? "* " : " "); 9499 pw.println(lastTask); 9500 if (full) { 9501 lastTask.dump(pw, prefix + " "); 9502 } else if (complete) { 9503 // Complete + brief == give a summary. Isn't that obvious?!? 9504 if (lastTask.intent != null) { 9505 pw.print(prefix); pw.print(" "); 9506 pw.println(lastTask.intent.toInsecureStringWithClip()); 9507 } 9508 } 9509 } 9510 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9511 pw.print(" #"); pw.print(i); pw.print(": "); 9512 pw.println(r); 9513 if (full) { 9514 r.dump(pw, innerPrefix); 9515 } else if (complete) { 9516 // Complete + brief == give a summary. Isn't that obvious?!? 9517 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9518 if (r.app != null) { 9519 pw.print(innerPrefix); pw.println(r.app); 9520 } 9521 } 9522 if (client && r.app != null && r.app.thread != null) { 9523 // flush anything that is already in the PrintWriter since the thread is going 9524 // to write to the file descriptor directly 9525 pw.flush(); 9526 try { 9527 TransferPipe tp = new TransferPipe(); 9528 try { 9529 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9530 r.appToken, innerPrefix, args); 9531 // Short timeout, since blocking here can 9532 // deadlock with the application. 9533 tp.go(fd, 2000); 9534 } finally { 9535 tp.kill(); 9536 } 9537 } catch (IOException e) { 9538 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9539 } catch (RemoteException e) { 9540 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9541 } 9542 needNL = true; 9543 } 9544 } 9545 } 9546 9547 private static String buildOomTag(String prefix, String space, int val, int base) { 9548 if (val == base) { 9549 if (space == null) return prefix; 9550 return prefix + " "; 9551 } 9552 return prefix + "+" + Integer.toString(val-base); 9553 } 9554 9555 private static final int dumpProcessList(PrintWriter pw, 9556 ActivityManagerService service, List list, 9557 String prefix, String normalLabel, String persistentLabel, 9558 String dumpPackage) { 9559 int numPers = 0; 9560 final int N = list.size()-1; 9561 for (int i=N; i>=0; i--) { 9562 ProcessRecord r = (ProcessRecord)list.get(i); 9563 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9564 continue; 9565 } 9566 pw.println(String.format("%s%s #%2d: %s", 9567 prefix, (r.persistent ? persistentLabel : normalLabel), 9568 i, r.toString())); 9569 if (r.persistent) { 9570 numPers++; 9571 } 9572 } 9573 return numPers; 9574 } 9575 9576 private static final boolean dumpProcessOomList(PrintWriter pw, 9577 ActivityManagerService service, List<ProcessRecord> origList, 9578 String prefix, String normalLabel, String persistentLabel, 9579 boolean inclDetails, String dumpPackage) { 9580 9581 ArrayList<Pair<ProcessRecord, Integer>> list 9582 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9583 for (int i=0; i<origList.size(); i++) { 9584 ProcessRecord r = origList.get(i); 9585 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9586 continue; 9587 } 9588 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9589 } 9590 9591 if (list.size() <= 0) { 9592 return false; 9593 } 9594 9595 Comparator<Pair<ProcessRecord, Integer>> comparator 9596 = new Comparator<Pair<ProcessRecord, Integer>>() { 9597 @Override 9598 public int compare(Pair<ProcessRecord, Integer> object1, 9599 Pair<ProcessRecord, Integer> object2) { 9600 if (object1.first.setAdj != object2.first.setAdj) { 9601 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9602 } 9603 if (object1.second.intValue() != object2.second.intValue()) { 9604 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9605 } 9606 return 0; 9607 } 9608 }; 9609 9610 Collections.sort(list, comparator); 9611 9612 final long curRealtime = SystemClock.elapsedRealtime(); 9613 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9614 final long curUptime = SystemClock.uptimeMillis(); 9615 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9616 9617 for (int i=list.size()-1; i>=0; i--) { 9618 ProcessRecord r = list.get(i).first; 9619 String oomAdj; 9620 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9621 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9622 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9623 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9624 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9625 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9626 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9627 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9628 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9629 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9630 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9631 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9632 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9633 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9634 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9635 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9636 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9637 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9638 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9639 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9640 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9641 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9642 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9643 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9644 } else { 9645 oomAdj = Integer.toString(r.setAdj); 9646 } 9647 String schedGroup; 9648 switch (r.setSchedGroup) { 9649 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9650 schedGroup = "B"; 9651 break; 9652 case Process.THREAD_GROUP_DEFAULT: 9653 schedGroup = "F"; 9654 break; 9655 default: 9656 schedGroup = Integer.toString(r.setSchedGroup); 9657 break; 9658 } 9659 String foreground; 9660 if (r.foregroundActivities) { 9661 foreground = "A"; 9662 } else if (r.foregroundServices) { 9663 foreground = "S"; 9664 } else { 9665 foreground = " "; 9666 } 9667 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9668 prefix, (r.persistent ? persistentLabel : normalLabel), 9669 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9670 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9671 if (r.adjSource != null || r.adjTarget != null) { 9672 pw.print(prefix); 9673 pw.print(" "); 9674 if (r.adjTarget instanceof ComponentName) { 9675 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9676 } else if (r.adjTarget != null) { 9677 pw.print(r.adjTarget.toString()); 9678 } else { 9679 pw.print("{null}"); 9680 } 9681 pw.print("<="); 9682 if (r.adjSource instanceof ProcessRecord) { 9683 pw.print("Proc{"); 9684 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9685 pw.println("}"); 9686 } else if (r.adjSource != null) { 9687 pw.println(r.adjSource.toString()); 9688 } else { 9689 pw.println("{null}"); 9690 } 9691 } 9692 if (inclDetails) { 9693 pw.print(prefix); 9694 pw.print(" "); 9695 pw.print("oom: max="); pw.print(r.maxAdj); 9696 pw.print(" hidden="); pw.print(r.hiddenAdj); 9697 pw.print(" curRaw="); pw.print(r.curRawAdj); 9698 pw.print(" setRaw="); pw.print(r.setRawAdj); 9699 pw.print(" cur="); pw.print(r.curAdj); 9700 pw.print(" set="); pw.println(r.setAdj); 9701 pw.print(prefix); 9702 pw.print(" "); 9703 pw.print("keeping="); pw.print(r.keeping); 9704 pw.print(" hidden="); pw.print(r.hidden); 9705 pw.print(" empty="); pw.print(r.empty); 9706 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9707 9708 if (!r.keeping) { 9709 if (r.lastWakeTime != 0) { 9710 long wtime; 9711 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9712 synchronized (stats) { 9713 wtime = stats.getProcessWakeTime(r.info.uid, 9714 r.pid, curRealtime); 9715 } 9716 long timeUsed = wtime - r.lastWakeTime; 9717 pw.print(prefix); 9718 pw.print(" "); 9719 pw.print("keep awake over "); 9720 TimeUtils.formatDuration(realtimeSince, pw); 9721 pw.print(" used "); 9722 TimeUtils.formatDuration(timeUsed, pw); 9723 pw.print(" ("); 9724 pw.print((timeUsed*100)/realtimeSince); 9725 pw.println("%)"); 9726 } 9727 if (r.lastCpuTime != 0) { 9728 long timeUsed = r.curCpuTime - r.lastCpuTime; 9729 pw.print(prefix); 9730 pw.print(" "); 9731 pw.print("run cpu over "); 9732 TimeUtils.formatDuration(uptimeSince, pw); 9733 pw.print(" used "); 9734 TimeUtils.formatDuration(timeUsed, pw); 9735 pw.print(" ("); 9736 pw.print((timeUsed*100)/uptimeSince); 9737 pw.println("%)"); 9738 } 9739 } 9740 } 9741 } 9742 return true; 9743 } 9744 9745 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9746 ArrayList<ProcessRecord> procs; 9747 synchronized (this) { 9748 if (args != null && args.length > start 9749 && args[start].charAt(0) != '-') { 9750 procs = new ArrayList<ProcessRecord>(); 9751 int pid = -1; 9752 try { 9753 pid = Integer.parseInt(args[start]); 9754 } catch (NumberFormatException e) { 9755 9756 } 9757 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9758 ProcessRecord proc = mLruProcesses.get(i); 9759 if (proc.pid == pid) { 9760 procs.add(proc); 9761 } else if (proc.processName.equals(args[start])) { 9762 procs.add(proc); 9763 } 9764 } 9765 if (procs.size() <= 0) { 9766 pw.println("No process found for: " + args[start]); 9767 return null; 9768 } 9769 } else { 9770 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9771 } 9772 } 9773 return procs; 9774 } 9775 9776 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9777 PrintWriter pw, String[] args) { 9778 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9779 if (procs == null) { 9780 return; 9781 } 9782 9783 long uptime = SystemClock.uptimeMillis(); 9784 long realtime = SystemClock.elapsedRealtime(); 9785 pw.println("Applications Graphics Acceleration Info:"); 9786 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9787 9788 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9789 ProcessRecord r = procs.get(i); 9790 if (r.thread != null) { 9791 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9792 pw.flush(); 9793 try { 9794 TransferPipe tp = new TransferPipe(); 9795 try { 9796 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9797 tp.go(fd); 9798 } finally { 9799 tp.kill(); 9800 } 9801 } catch (IOException e) { 9802 pw.println("Failure while dumping the app: " + r); 9803 pw.flush(); 9804 } catch (RemoteException e) { 9805 pw.println("Got a RemoteException while dumping the app " + r); 9806 pw.flush(); 9807 } 9808 } 9809 } 9810 } 9811 9812 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9813 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9814 if (procs == null) { 9815 return; 9816 } 9817 9818 pw.println("Applications Database Info:"); 9819 9820 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9821 ProcessRecord r = procs.get(i); 9822 if (r.thread != null) { 9823 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9824 pw.flush(); 9825 try { 9826 TransferPipe tp = new TransferPipe(); 9827 try { 9828 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9829 tp.go(fd); 9830 } finally { 9831 tp.kill(); 9832 } 9833 } catch (IOException e) { 9834 pw.println("Failure while dumping the app: " + r); 9835 pw.flush(); 9836 } catch (RemoteException e) { 9837 pw.println("Got a RemoteException while dumping the app " + r); 9838 pw.flush(); 9839 } 9840 } 9841 } 9842 } 9843 9844 final static class MemItem { 9845 final String label; 9846 final String shortLabel; 9847 final long pss; 9848 final int id; 9849 ArrayList<MemItem> subitems; 9850 9851 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9852 label = _label; 9853 shortLabel = _shortLabel; 9854 pss = _pss; 9855 id = _id; 9856 } 9857 } 9858 9859 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9860 boolean sort) { 9861 if (sort) { 9862 Collections.sort(items, new Comparator<MemItem>() { 9863 @Override 9864 public int compare(MemItem lhs, MemItem rhs) { 9865 if (lhs.pss < rhs.pss) { 9866 return 1; 9867 } else if (lhs.pss > rhs.pss) { 9868 return -1; 9869 } 9870 return 0; 9871 } 9872 }); 9873 } 9874 9875 for (int i=0; i<items.size(); i++) { 9876 MemItem mi = items.get(i); 9877 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9878 if (mi.subitems != null) { 9879 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9880 } 9881 } 9882 } 9883 9884 // These are in KB. 9885 static final long[] DUMP_MEM_BUCKETS = new long[] { 9886 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9887 120*1024, 160*1024, 200*1024, 9888 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9889 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9890 }; 9891 9892 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9893 boolean stackLike) { 9894 int start = label.lastIndexOf('.'); 9895 if (start >= 0) start++; 9896 else start = 0; 9897 int end = label.length(); 9898 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9899 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9900 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9901 out.append(bucket); 9902 out.append(stackLike ? "MB." : "MB "); 9903 out.append(label, start, end); 9904 return; 9905 } 9906 } 9907 out.append(memKB/1024); 9908 out.append(stackLike ? "MB." : "MB "); 9909 out.append(label, start, end); 9910 } 9911 9912 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9913 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9914 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9915 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9916 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9917 }; 9918 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9919 "System", "Persistent", "Foreground", 9920 "Visible", "Perceptible", "Heavy Weight", 9921 "Backup", "A Services", "Home", "Previous", 9922 "B Services", "Background" 9923 }; 9924 9925 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9926 PrintWriter pw, String prefix, String[] args, boolean brief, 9927 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9928 boolean dumpAll = false; 9929 boolean oomOnly = false; 9930 9931 int opti = 0; 9932 while (opti < args.length) { 9933 String opt = args[opti]; 9934 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9935 break; 9936 } 9937 opti++; 9938 if ("-a".equals(opt)) { 9939 dumpAll = true; 9940 } else if ("--oom".equals(opt)) { 9941 oomOnly = true; 9942 } else if ("-h".equals(opt)) { 9943 pw.println("meminfo dump options: [-a] [--oom] [process]"); 9944 pw.println(" -a: include all available information for each process."); 9945 pw.println(" --oom: only show processes organized by oom adj."); 9946 pw.println("If [process] is specified it can be the name or "); 9947 pw.println("pid of a specific process to dump."); 9948 return; 9949 } else { 9950 pw.println("Unknown argument: " + opt + "; use -h for help"); 9951 } 9952 } 9953 9954 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 9955 if (procs == null) { 9956 return; 9957 } 9958 9959 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9960 long uptime = SystemClock.uptimeMillis(); 9961 long realtime = SystemClock.elapsedRealtime(); 9962 9963 if (procs.size() == 1 || isCheckinRequest) { 9964 dumpAll = true; 9965 } 9966 9967 if (isCheckinRequest) { 9968 // short checkin version 9969 pw.println(uptime + "," + realtime); 9970 pw.flush(); 9971 } else { 9972 pw.println("Applications Memory Usage (kB):"); 9973 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9974 } 9975 9976 String[] innerArgs = new String[args.length-opti]; 9977 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 9978 9979 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 9980 long nativePss=0, dalvikPss=0, otherPss=0; 9981 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 9982 9983 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 9984 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 9985 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 9986 9987 long totalPss = 0; 9988 9989 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9990 ProcessRecord r = procs.get(i); 9991 if (r.thread != null) { 9992 if (!isCheckinRequest && dumpAll) { 9993 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9994 pw.flush(); 9995 } 9996 Debug.MemoryInfo mi = null; 9997 if (dumpAll) { 9998 try { 9999 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10000 } catch (RemoteException e) { 10001 if (!isCheckinRequest) { 10002 pw.println("Got RemoteException!"); 10003 pw.flush(); 10004 } 10005 } 10006 } else { 10007 mi = new Debug.MemoryInfo(); 10008 Debug.getMemoryInfo(r.pid, mi); 10009 } 10010 10011 if (!isCheckinRequest && mi != null) { 10012 long myTotalPss = mi.getTotalPss(); 10013 totalPss += myTotalPss; 10014 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10015 r.processName, myTotalPss, 0); 10016 procMems.add(pssItem); 10017 10018 nativePss += mi.nativePss; 10019 dalvikPss += mi.dalvikPss; 10020 otherPss += mi.otherPss; 10021 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10022 long mem = mi.getOtherPss(j); 10023 miscPss[j] += mem; 10024 otherPss -= mem; 10025 } 10026 10027 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10028 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10029 || oomIndex == (oomPss.length-1)) { 10030 oomPss[oomIndex] += myTotalPss; 10031 if (oomProcs[oomIndex] == null) { 10032 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10033 } 10034 oomProcs[oomIndex].add(pssItem); 10035 break; 10036 } 10037 } 10038 } 10039 } 10040 } 10041 10042 if (!isCheckinRequest && procs.size() > 1) { 10043 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10044 10045 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10046 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10047 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10048 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10049 String label = Debug.MemoryInfo.getOtherLabel(j); 10050 catMems.add(new MemItem(label, label, miscPss[j], j)); 10051 } 10052 10053 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10054 for (int j=0; j<oomPss.length; j++) { 10055 if (oomPss[j] != 0) { 10056 String label = DUMP_MEM_OOM_LABEL[j]; 10057 MemItem item = new MemItem(label, label, oomPss[j], 10058 DUMP_MEM_OOM_ADJ[j]); 10059 item.subitems = oomProcs[j]; 10060 oomMems.add(item); 10061 } 10062 } 10063 10064 if (outTag != null || outStack != null) { 10065 if (outTag != null) { 10066 appendMemBucket(outTag, totalPss, "total", false); 10067 } 10068 if (outStack != null) { 10069 appendMemBucket(outStack, totalPss, "total", true); 10070 } 10071 boolean firstLine = true; 10072 for (int i=0; i<oomMems.size(); i++) { 10073 MemItem miCat = oomMems.get(i); 10074 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10075 continue; 10076 } 10077 if (miCat.id < ProcessList.SERVICE_ADJ 10078 || miCat.id == ProcessList.HOME_APP_ADJ 10079 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10080 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10081 outTag.append(" / "); 10082 } 10083 if (outStack != null) { 10084 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10085 if (firstLine) { 10086 outStack.append(":"); 10087 firstLine = false; 10088 } 10089 outStack.append("\n\t at "); 10090 } else { 10091 outStack.append("$"); 10092 } 10093 } 10094 for (int j=0; j<miCat.subitems.size(); j++) { 10095 MemItem mi = miCat.subitems.get(j); 10096 if (j > 0) { 10097 if (outTag != null) { 10098 outTag.append(" "); 10099 } 10100 if (outStack != null) { 10101 outStack.append("$"); 10102 } 10103 } 10104 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10105 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10106 } 10107 if (outStack != null) { 10108 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10109 } 10110 } 10111 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10112 outStack.append("("); 10113 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10114 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10115 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10116 outStack.append(":"); 10117 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10118 } 10119 } 10120 outStack.append(")"); 10121 } 10122 } 10123 } 10124 } 10125 10126 if (!brief && !oomOnly) { 10127 pw.println(); 10128 pw.println("Total PSS by process:"); 10129 dumpMemItems(pw, " ", procMems, true); 10130 pw.println(); 10131 } 10132 pw.println("Total PSS by OOM adjustment:"); 10133 dumpMemItems(pw, " ", oomMems, false); 10134 if (!oomOnly) { 10135 PrintWriter out = categoryPw != null ? categoryPw : pw; 10136 out.println(); 10137 out.println("Total PSS by category:"); 10138 dumpMemItems(out, " ", catMems, true); 10139 } 10140 pw.println(); 10141 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10142 final int[] SINGLE_LONG_FORMAT = new int[] { 10143 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10144 }; 10145 long[] longOut = new long[1]; 10146 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10147 SINGLE_LONG_FORMAT, null, longOut, null); 10148 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10149 longOut[0] = 0; 10150 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10151 SINGLE_LONG_FORMAT, null, longOut, null); 10152 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10153 longOut[0] = 0; 10154 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10155 SINGLE_LONG_FORMAT, null, longOut, null); 10156 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10157 longOut[0] = 0; 10158 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10159 SINGLE_LONG_FORMAT, null, longOut, null); 10160 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10161 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10162 pw.print(shared); pw.println(" kB"); 10163 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10164 pw.print(voltile); pw.println(" kB volatile"); 10165 } 10166 } 10167 10168 /** 10169 * Searches array of arguments for the specified string 10170 * @param args array of argument strings 10171 * @param value value to search for 10172 * @return true if the value is contained in the array 10173 */ 10174 private static boolean scanArgs(String[] args, String value) { 10175 if (args != null) { 10176 for (String arg : args) { 10177 if (value.equals(arg)) { 10178 return true; 10179 } 10180 } 10181 } 10182 return false; 10183 } 10184 10185 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10186 ContentProviderRecord cpr, boolean always) { 10187 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10188 10189 if (!inLaunching || always) { 10190 synchronized (cpr) { 10191 cpr.launchingApp = null; 10192 cpr.notifyAll(); 10193 } 10194 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10195 String names[] = cpr.info.authority.split(";"); 10196 for (int j = 0; j < names.length; j++) { 10197 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10198 } 10199 } 10200 10201 for (int i=0; i<cpr.connections.size(); i++) { 10202 ContentProviderConnection conn = cpr.connections.get(i); 10203 if (conn.waiting) { 10204 // If this connection is waiting for the provider, then we don't 10205 // need to mess with its process unless we are always removing 10206 // or for some reason the provider is not currently launching. 10207 if (inLaunching && !always) { 10208 continue; 10209 } 10210 } 10211 ProcessRecord capp = conn.client; 10212 conn.dead = true; 10213 if (conn.stableCount > 0) { 10214 if (!capp.persistent && capp.thread != null 10215 && capp.pid != 0 10216 && capp.pid != MY_PID) { 10217 Slog.i(TAG, "Kill " + capp.processName 10218 + " (pid " + capp.pid + "): provider " + cpr.info.name 10219 + " in dying process " + (proc != null ? proc.processName : "??")); 10220 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10221 capp.processName, capp.setAdj, "dying provider " 10222 + cpr.name.toShortString()); 10223 Process.killProcessQuiet(capp.pid); 10224 } 10225 } else if (capp.thread != null && conn.provider.provider != null) { 10226 try { 10227 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10228 } catch (RemoteException e) { 10229 } 10230 // In the protocol here, we don't expect the client to correctly 10231 // clean up this connection, we'll just remove it. 10232 cpr.connections.remove(i); 10233 conn.client.conProviders.remove(conn); 10234 } 10235 } 10236 10237 if (inLaunching && always) { 10238 mLaunchingProviders.remove(cpr); 10239 } 10240 return inLaunching; 10241 } 10242 10243 /** 10244 * Main code for cleaning up a process when it has gone away. This is 10245 * called both as a result of the process dying, or directly when stopping 10246 * a process when running in single process mode. 10247 */ 10248 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10249 boolean restarting, boolean allowRestart, int index) { 10250 if (index >= 0) { 10251 mLruProcesses.remove(index); 10252 } 10253 10254 mProcessesToGc.remove(app); 10255 10256 // Dismiss any open dialogs. 10257 if (app.crashDialog != null) { 10258 app.crashDialog.dismiss(); 10259 app.crashDialog = null; 10260 } 10261 if (app.anrDialog != null) { 10262 app.anrDialog.dismiss(); 10263 app.anrDialog = null; 10264 } 10265 if (app.waitDialog != null) { 10266 app.waitDialog.dismiss(); 10267 app.waitDialog = null; 10268 } 10269 10270 app.crashing = false; 10271 app.notResponding = false; 10272 10273 app.resetPackageList(); 10274 app.unlinkDeathRecipient(); 10275 app.thread = null; 10276 app.forcingToForeground = null; 10277 app.foregroundServices = false; 10278 app.foregroundActivities = false; 10279 app.hasShownUi = false; 10280 app.hasAboveClient = false; 10281 10282 mServices.killServicesLocked(app, allowRestart); 10283 10284 boolean restart = false; 10285 10286 // Remove published content providers. 10287 if (!app.pubProviders.isEmpty()) { 10288 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10289 while (it.hasNext()) { 10290 ContentProviderRecord cpr = it.next(); 10291 10292 final boolean always = app.bad || !allowRestart; 10293 if (removeDyingProviderLocked(app, cpr, always) || always) { 10294 // We left the provider in the launching list, need to 10295 // restart it. 10296 restart = true; 10297 } 10298 10299 cpr.provider = null; 10300 cpr.proc = null; 10301 } 10302 app.pubProviders.clear(); 10303 } 10304 10305 // Take care of any launching providers waiting for this process. 10306 if (checkAppInLaunchingProvidersLocked(app, false)) { 10307 restart = true; 10308 } 10309 10310 // Unregister from connected content providers. 10311 if (!app.conProviders.isEmpty()) { 10312 for (int i=0; i<app.conProviders.size(); i++) { 10313 ContentProviderConnection conn = app.conProviders.get(i); 10314 conn.provider.connections.remove(conn); 10315 } 10316 app.conProviders.clear(); 10317 } 10318 10319 // At this point there may be remaining entries in mLaunchingProviders 10320 // where we were the only one waiting, so they are no longer of use. 10321 // Look for these and clean up if found. 10322 // XXX Commented out for now. Trying to figure out a way to reproduce 10323 // the actual situation to identify what is actually going on. 10324 if (false) { 10325 for (int i=0; i<mLaunchingProviders.size(); i++) { 10326 ContentProviderRecord cpr = (ContentProviderRecord) 10327 mLaunchingProviders.get(i); 10328 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10329 synchronized (cpr) { 10330 cpr.launchingApp = null; 10331 cpr.notifyAll(); 10332 } 10333 } 10334 } 10335 } 10336 10337 skipCurrentReceiverLocked(app); 10338 10339 // Unregister any receivers. 10340 if (app.receivers.size() > 0) { 10341 Iterator<ReceiverList> it = app.receivers.iterator(); 10342 while (it.hasNext()) { 10343 removeReceiverLocked(it.next()); 10344 } 10345 app.receivers.clear(); 10346 } 10347 10348 // If the app is undergoing backup, tell the backup manager about it 10349 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10350 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10351 try { 10352 IBackupManager bm = IBackupManager.Stub.asInterface( 10353 ServiceManager.getService(Context.BACKUP_SERVICE)); 10354 bm.agentDisconnected(app.info.packageName); 10355 } catch (RemoteException e) { 10356 // can't happen; backup manager is local 10357 } 10358 } 10359 10360 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10361 ProcessChangeItem item = mPendingProcessChanges.get(i); 10362 if (item.pid == app.pid) { 10363 mPendingProcessChanges.remove(i); 10364 mAvailProcessChanges.add(item); 10365 } 10366 } 10367 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10368 10369 // If the caller is restarting this app, then leave it in its 10370 // current lists and let the caller take care of it. 10371 if (restarting) { 10372 return; 10373 } 10374 10375 if (!app.persistent || app.isolated) { 10376 if (DEBUG_PROCESSES) Slog.v(TAG, 10377 "Removing non-persistent process during cleanup: " + app); 10378 mProcessNames.remove(app.processName, app.uid); 10379 mIsolatedProcesses.remove(app.uid); 10380 if (mHeavyWeightProcess == app) { 10381 mHeavyWeightProcess = null; 10382 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10383 } 10384 } else if (!app.removed) { 10385 // This app is persistent, so we need to keep its record around. 10386 // If it is not already on the pending app list, add it there 10387 // and start a new process for it. 10388 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10389 mPersistentStartingProcesses.add(app); 10390 restart = true; 10391 } 10392 } 10393 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10394 "Clean-up removing on hold: " + app); 10395 mProcessesOnHold.remove(app); 10396 10397 if (app == mHomeProcess) { 10398 mHomeProcess = null; 10399 } 10400 if (app == mPreviousProcess) { 10401 mPreviousProcess = null; 10402 } 10403 10404 if (restart && !app.isolated) { 10405 // We have components that still need to be running in the 10406 // process, so re-launch it. 10407 mProcessNames.put(app.processName, app.uid, app); 10408 startProcessLocked(app, "restart", app.processName); 10409 } else if (app.pid > 0 && app.pid != MY_PID) { 10410 // Goodbye! 10411 synchronized (mPidsSelfLocked) { 10412 mPidsSelfLocked.remove(app.pid); 10413 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10414 } 10415 app.setPid(0); 10416 } 10417 } 10418 10419 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10420 // Look through the content providers we are waiting to have launched, 10421 // and if any run in this process then either schedule a restart of 10422 // the process or kill the client waiting for it if this process has 10423 // gone bad. 10424 int NL = mLaunchingProviders.size(); 10425 boolean restart = false; 10426 for (int i=0; i<NL; i++) { 10427 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10428 if (cpr.launchingApp == app) { 10429 if (!alwaysBad && !app.bad) { 10430 restart = true; 10431 } else { 10432 removeDyingProviderLocked(app, cpr, true); 10433 NL = mLaunchingProviders.size(); 10434 } 10435 } 10436 } 10437 return restart; 10438 } 10439 10440 // ========================================================= 10441 // SERVICES 10442 // ========================================================= 10443 10444 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10445 int flags) { 10446 enforceNotIsolatedCaller("getServices"); 10447 synchronized (this) { 10448 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10449 } 10450 } 10451 10452 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10453 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10454 synchronized (this) { 10455 return mServices.getRunningServiceControlPanelLocked(name); 10456 } 10457 } 10458 10459 public ComponentName startService(IApplicationThread caller, Intent service, 10460 String resolvedType) { 10461 enforceNotIsolatedCaller("startService"); 10462 // Refuse possible leaked file descriptors 10463 if (service != null && service.hasFileDescriptors() == true) { 10464 throw new IllegalArgumentException("File descriptors passed in Intent"); 10465 } 10466 10467 if (DEBUG_SERVICE) 10468 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10469 synchronized(this) { 10470 final int callingPid = Binder.getCallingPid(); 10471 final int callingUid = Binder.getCallingUid(); 10472 final long origId = Binder.clearCallingIdentity(); 10473 ComponentName res = mServices.startServiceLocked(caller, service, 10474 resolvedType, callingPid, callingUid); 10475 Binder.restoreCallingIdentity(origId); 10476 return res; 10477 } 10478 } 10479 10480 ComponentName startServiceInPackage(int uid, 10481 Intent service, String resolvedType) { 10482 synchronized(this) { 10483 if (DEBUG_SERVICE) 10484 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10485 final long origId = Binder.clearCallingIdentity(); 10486 ComponentName res = mServices.startServiceLocked(null, service, 10487 resolvedType, -1, uid); 10488 Binder.restoreCallingIdentity(origId); 10489 return res; 10490 } 10491 } 10492 10493 public int stopService(IApplicationThread caller, Intent service, 10494 String resolvedType) { 10495 enforceNotIsolatedCaller("stopService"); 10496 // Refuse possible leaked file descriptors 10497 if (service != null && service.hasFileDescriptors() == true) { 10498 throw new IllegalArgumentException("File descriptors passed in Intent"); 10499 } 10500 10501 synchronized(this) { 10502 return mServices.stopServiceLocked(caller, service, resolvedType); 10503 } 10504 } 10505 10506 public IBinder peekService(Intent service, String resolvedType) { 10507 enforceNotIsolatedCaller("peekService"); 10508 // Refuse possible leaked file descriptors 10509 if (service != null && service.hasFileDescriptors() == true) { 10510 throw new IllegalArgumentException("File descriptors passed in Intent"); 10511 } 10512 synchronized(this) { 10513 return mServices.peekServiceLocked(service, resolvedType); 10514 } 10515 } 10516 10517 public boolean stopServiceToken(ComponentName className, IBinder token, 10518 int startId) { 10519 synchronized(this) { 10520 return mServices.stopServiceTokenLocked(className, token, startId); 10521 } 10522 } 10523 10524 public void setServiceForeground(ComponentName className, IBinder token, 10525 int id, Notification notification, boolean removeNotification) { 10526 synchronized(this) { 10527 mServices.setServiceForegroundLocked(className, token, id, notification, 10528 removeNotification); 10529 } 10530 } 10531 10532 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10533 String className, int flags) { 10534 boolean result = false; 10535 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10536 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10537 if (ActivityManager.checkUidPermission( 10538 android.Manifest.permission.INTERACT_ACROSS_USERS, 10539 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10540 ComponentName comp = new ComponentName(aInfo.packageName, className); 10541 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10542 + " requests FLAG_SINGLE_USER, but app does not hold " 10543 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10544 Slog.w(TAG, msg); 10545 throw new SecurityException(msg); 10546 } 10547 result = true; 10548 } 10549 } else if (componentProcessName == aInfo.packageName) { 10550 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10551 } else if ("system".equals(componentProcessName)) { 10552 result = true; 10553 } 10554 if (DEBUG_MU) { 10555 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10556 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10557 } 10558 return result; 10559 } 10560 10561 public int bindService(IApplicationThread caller, IBinder token, 10562 Intent service, String resolvedType, 10563 IServiceConnection connection, int flags, int userId) { 10564 enforceNotIsolatedCaller("bindService"); 10565 // Refuse possible leaked file descriptors 10566 if (service != null && service.hasFileDescriptors() == true) { 10567 throw new IllegalArgumentException("File descriptors passed in Intent"); 10568 } 10569 10570 checkValidCaller(Binder.getCallingUid(), userId); 10571 10572 synchronized(this) { 10573 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10574 connection, flags, userId); 10575 } 10576 } 10577 10578 public boolean unbindService(IServiceConnection connection) { 10579 synchronized (this) { 10580 return mServices.unbindServiceLocked(connection); 10581 } 10582 } 10583 10584 public void publishService(IBinder token, Intent intent, IBinder service) { 10585 // Refuse possible leaked file descriptors 10586 if (intent != null && intent.hasFileDescriptors() == true) { 10587 throw new IllegalArgumentException("File descriptors passed in Intent"); 10588 } 10589 10590 synchronized(this) { 10591 if (!(token instanceof ServiceRecord)) { 10592 throw new IllegalArgumentException("Invalid service token"); 10593 } 10594 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10595 } 10596 } 10597 10598 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10599 // Refuse possible leaked file descriptors 10600 if (intent != null && intent.hasFileDescriptors() == true) { 10601 throw new IllegalArgumentException("File descriptors passed in Intent"); 10602 } 10603 10604 synchronized(this) { 10605 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10606 } 10607 } 10608 10609 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10610 synchronized(this) { 10611 if (!(token instanceof ServiceRecord)) { 10612 throw new IllegalArgumentException("Invalid service token"); 10613 } 10614 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10615 } 10616 } 10617 10618 // ========================================================= 10619 // BACKUP AND RESTORE 10620 // ========================================================= 10621 10622 // Cause the target app to be launched if necessary and its backup agent 10623 // instantiated. The backup agent will invoke backupAgentCreated() on the 10624 // activity manager to announce its creation. 10625 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10626 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10627 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10628 10629 synchronized(this) { 10630 // !!! TODO: currently no check here that we're already bound 10631 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10632 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10633 synchronized (stats) { 10634 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10635 } 10636 10637 // Backup agent is now in use, its package can't be stopped. 10638 try { 10639 AppGlobals.getPackageManager().setPackageStoppedState( 10640 app.packageName, false, UserId.getUserId(app.uid)); 10641 } catch (RemoteException e) { 10642 } catch (IllegalArgumentException e) { 10643 Slog.w(TAG, "Failed trying to unstop package " 10644 + app.packageName + ": " + e); 10645 } 10646 10647 BackupRecord r = new BackupRecord(ss, app, backupMode); 10648 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10649 ? new ComponentName(app.packageName, app.backupAgentName) 10650 : new ComponentName("android", "FullBackupAgent"); 10651 // startProcessLocked() returns existing proc's record if it's already running 10652 ProcessRecord proc = startProcessLocked(app.processName, app, 10653 false, 0, "backup", hostingName, false, false); 10654 if (proc == null) { 10655 Slog.e(TAG, "Unable to start backup agent process " + r); 10656 return false; 10657 } 10658 10659 r.app = proc; 10660 mBackupTarget = r; 10661 mBackupAppName = app.packageName; 10662 10663 // Try not to kill the process during backup 10664 updateOomAdjLocked(proc); 10665 10666 // If the process is already attached, schedule the creation of the backup agent now. 10667 // If it is not yet live, this will be done when it attaches to the framework. 10668 if (proc.thread != null) { 10669 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10670 try { 10671 proc.thread.scheduleCreateBackupAgent(app, 10672 compatibilityInfoForPackageLocked(app), backupMode); 10673 } catch (RemoteException e) { 10674 // Will time out on the backup manager side 10675 } 10676 } else { 10677 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10678 } 10679 // Invariants: at this point, the target app process exists and the application 10680 // is either already running or in the process of coming up. mBackupTarget and 10681 // mBackupAppName describe the app, so that when it binds back to the AM we 10682 // know that it's scheduled for a backup-agent operation. 10683 } 10684 10685 return true; 10686 } 10687 10688 // A backup agent has just come up 10689 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10690 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10691 + " = " + agent); 10692 10693 synchronized(this) { 10694 if (!agentPackageName.equals(mBackupAppName)) { 10695 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10696 return; 10697 } 10698 } 10699 10700 long oldIdent = Binder.clearCallingIdentity(); 10701 try { 10702 IBackupManager bm = IBackupManager.Stub.asInterface( 10703 ServiceManager.getService(Context.BACKUP_SERVICE)); 10704 bm.agentConnected(agentPackageName, agent); 10705 } catch (RemoteException e) { 10706 // can't happen; the backup manager service is local 10707 } catch (Exception e) { 10708 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10709 e.printStackTrace(); 10710 } finally { 10711 Binder.restoreCallingIdentity(oldIdent); 10712 } 10713 } 10714 10715 // done with this agent 10716 public void unbindBackupAgent(ApplicationInfo appInfo) { 10717 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10718 if (appInfo == null) { 10719 Slog.w(TAG, "unbind backup agent for null app"); 10720 return; 10721 } 10722 10723 synchronized(this) { 10724 if (mBackupAppName == null) { 10725 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10726 return; 10727 } 10728 10729 if (!mBackupAppName.equals(appInfo.packageName)) { 10730 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10731 return; 10732 } 10733 10734 ProcessRecord proc = mBackupTarget.app; 10735 mBackupTarget = null; 10736 mBackupAppName = null; 10737 10738 // Not backing this app up any more; reset its OOM adjustment 10739 updateOomAdjLocked(proc); 10740 10741 // If the app crashed during backup, 'thread' will be null here 10742 if (proc.thread != null) { 10743 try { 10744 proc.thread.scheduleDestroyBackupAgent(appInfo, 10745 compatibilityInfoForPackageLocked(appInfo)); 10746 } catch (Exception e) { 10747 Slog.e(TAG, "Exception when unbinding backup agent:"); 10748 e.printStackTrace(); 10749 } 10750 } 10751 } 10752 } 10753 // ========================================================= 10754 // BROADCASTS 10755 // ========================================================= 10756 10757 private final List getStickiesLocked(String action, IntentFilter filter, 10758 List cur) { 10759 final ContentResolver resolver = mContext.getContentResolver(); 10760 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10761 if (list == null) { 10762 return cur; 10763 } 10764 int N = list.size(); 10765 for (int i=0; i<N; i++) { 10766 Intent intent = list.get(i); 10767 if (filter.match(resolver, intent, true, TAG) >= 0) { 10768 if (cur == null) { 10769 cur = new ArrayList<Intent>(); 10770 } 10771 cur.add(intent); 10772 } 10773 } 10774 return cur; 10775 } 10776 10777 boolean isPendingBroadcastProcessLocked(int pid) { 10778 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10779 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10780 } 10781 10782 void skipPendingBroadcastLocked(int pid) { 10783 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10784 for (BroadcastQueue queue : mBroadcastQueues) { 10785 queue.skipPendingBroadcastLocked(pid); 10786 } 10787 } 10788 10789 // The app just attached; send any pending broadcasts that it should receive 10790 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10791 boolean didSomething = false; 10792 for (BroadcastQueue queue : mBroadcastQueues) { 10793 didSomething |= queue.sendPendingBroadcastsLocked(app); 10794 } 10795 return didSomething; 10796 } 10797 10798 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10799 IIntentReceiver receiver, IntentFilter filter, String permission) { 10800 enforceNotIsolatedCaller("registerReceiver"); 10801 int callingUid; 10802 synchronized(this) { 10803 ProcessRecord callerApp = null; 10804 if (caller != null) { 10805 callerApp = getRecordForAppLocked(caller); 10806 if (callerApp == null) { 10807 throw new SecurityException( 10808 "Unable to find app for caller " + caller 10809 + " (pid=" + Binder.getCallingPid() 10810 + ") when registering receiver " + receiver); 10811 } 10812 if (callerApp.info.uid != Process.SYSTEM_UID && 10813 !callerApp.pkgList.contains(callerPackage)) { 10814 throw new SecurityException("Given caller package " + callerPackage 10815 + " is not running in process " + callerApp); 10816 } 10817 callingUid = callerApp.info.uid; 10818 } else { 10819 callerPackage = null; 10820 callingUid = Binder.getCallingUid(); 10821 } 10822 10823 List allSticky = null; 10824 10825 // Look for any matching sticky broadcasts... 10826 Iterator actions = filter.actionsIterator(); 10827 if (actions != null) { 10828 while (actions.hasNext()) { 10829 String action = (String)actions.next(); 10830 allSticky = getStickiesLocked(action, filter, allSticky); 10831 } 10832 } else { 10833 allSticky = getStickiesLocked(null, filter, allSticky); 10834 } 10835 10836 // The first sticky in the list is returned directly back to 10837 // the client. 10838 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10839 10840 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10841 + ": " + sticky); 10842 10843 if (receiver == null) { 10844 return sticky; 10845 } 10846 10847 ReceiverList rl 10848 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10849 if (rl == null) { 10850 rl = new ReceiverList(this, callerApp, 10851 Binder.getCallingPid(), 10852 Binder.getCallingUid(), receiver); 10853 if (rl.app != null) { 10854 rl.app.receivers.add(rl); 10855 } else { 10856 try { 10857 receiver.asBinder().linkToDeath(rl, 0); 10858 } catch (RemoteException e) { 10859 return sticky; 10860 } 10861 rl.linkedToDeath = true; 10862 } 10863 mRegisteredReceivers.put(receiver.asBinder(), rl); 10864 } 10865 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10866 permission, callingUid); 10867 rl.add(bf); 10868 if (!bf.debugCheck()) { 10869 Slog.w(TAG, "==> For Dynamic broadast"); 10870 } 10871 mReceiverResolver.addFilter(bf); 10872 10873 // Enqueue broadcasts for all existing stickies that match 10874 // this filter. 10875 if (allSticky != null) { 10876 ArrayList receivers = new ArrayList(); 10877 receivers.add(bf); 10878 10879 int N = allSticky.size(); 10880 for (int i=0; i<N; i++) { 10881 Intent intent = (Intent)allSticky.get(i); 10882 BroadcastQueue queue = broadcastQueueForIntent(intent); 10883 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10884 null, -1, -1, null, receivers, null, 0, null, null, 10885 false, true, true, false); 10886 queue.enqueueParallelBroadcastLocked(r); 10887 queue.scheduleBroadcastsLocked(); 10888 } 10889 } 10890 10891 return sticky; 10892 } 10893 } 10894 10895 public void unregisterReceiver(IIntentReceiver receiver) { 10896 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10897 10898 final long origId = Binder.clearCallingIdentity(); 10899 try { 10900 boolean doTrim = false; 10901 10902 synchronized(this) { 10903 ReceiverList rl 10904 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10905 if (rl != null) { 10906 if (rl.curBroadcast != null) { 10907 BroadcastRecord r = rl.curBroadcast; 10908 final boolean doNext = finishReceiverLocked( 10909 receiver.asBinder(), r.resultCode, r.resultData, 10910 r.resultExtras, r.resultAbort, true); 10911 if (doNext) { 10912 doTrim = true; 10913 r.queue.processNextBroadcast(false); 10914 } 10915 } 10916 10917 if (rl.app != null) { 10918 rl.app.receivers.remove(rl); 10919 } 10920 removeReceiverLocked(rl); 10921 if (rl.linkedToDeath) { 10922 rl.linkedToDeath = false; 10923 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10924 } 10925 } 10926 } 10927 10928 // If we actually concluded any broadcasts, we might now be able 10929 // to trim the recipients' apps from our working set 10930 if (doTrim) { 10931 trimApplications(); 10932 return; 10933 } 10934 10935 } finally { 10936 Binder.restoreCallingIdentity(origId); 10937 } 10938 } 10939 10940 void removeReceiverLocked(ReceiverList rl) { 10941 mRegisteredReceivers.remove(rl.receiver.asBinder()); 10942 int N = rl.size(); 10943 for (int i=0; i<N; i++) { 10944 mReceiverResolver.removeFilter(rl.get(i)); 10945 } 10946 } 10947 10948 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 10949 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10950 ProcessRecord r = mLruProcesses.get(i); 10951 if (r.thread != null) { 10952 try { 10953 r.thread.dispatchPackageBroadcast(cmd, packages); 10954 } catch (RemoteException ex) { 10955 } 10956 } 10957 } 10958 } 10959 10960 private final int broadcastIntentLocked(ProcessRecord callerApp, 10961 String callerPackage, Intent intent, String resolvedType, 10962 IIntentReceiver resultTo, int resultCode, String resultData, 10963 Bundle map, String requiredPermission, 10964 boolean ordered, boolean sticky, int callingPid, int callingUid, 10965 int userId) { 10966 intent = new Intent(intent); 10967 10968 // By default broadcasts do not go to stopped apps. 10969 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 10970 10971 if (DEBUG_BROADCAST_LIGHT) Slog.v( 10972 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 10973 + " ordered=" + ordered + " userid=" + userId); 10974 if ((resultTo != null) && !ordered) { 10975 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 10976 } 10977 10978 boolean onlySendToCaller = false; 10979 10980 // If the caller is trying to send this broadcast to a different 10981 // user, verify that is allowed. 10982 if (UserId.getUserId(callingUid) != userId) { 10983 if (checkComponentPermission( 10984 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10985 callingPid, callingUid, -1, true) 10986 != PackageManager.PERMISSION_GRANTED) { 10987 if (checkComponentPermission( 10988 android.Manifest.permission.INTERACT_ACROSS_USERS, 10989 callingPid, callingUid, -1, true) 10990 == PackageManager.PERMISSION_GRANTED) { 10991 onlySendToCaller = true; 10992 } else { 10993 String msg = "Permission Denial: " + intent.getAction() 10994 + " broadcast from " + callerPackage 10995 + " asks to send as user " + userId 10996 + " but is calling from user " + UserId.getUserId(callingUid) 10997 + "; this requires " 10998 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10999 Slog.w(TAG, msg); 11000 throw new SecurityException(msg); 11001 } 11002 } 11003 } 11004 11005 // Handle special intents: if this broadcast is from the package 11006 // manager about a package being removed, we need to remove all of 11007 // its activities from the history stack. 11008 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11009 intent.getAction()); 11010 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11011 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11012 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11013 || uidRemoved) { 11014 if (checkComponentPermission( 11015 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11016 callingPid, callingUid, -1, true) 11017 == PackageManager.PERMISSION_GRANTED) { 11018 if (uidRemoved) { 11019 final Bundle intentExtras = intent.getExtras(); 11020 final int uid = intentExtras != null 11021 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11022 if (uid >= 0) { 11023 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11024 synchronized (bs) { 11025 bs.removeUidStatsLocked(uid); 11026 } 11027 } 11028 } else { 11029 // If resources are unvailble just force stop all 11030 // those packages and flush the attribute cache as well. 11031 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11032 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11033 if (list != null && (list.length > 0)) { 11034 for (String pkg : list) { 11035 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11036 } 11037 sendPackageBroadcastLocked( 11038 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11039 } 11040 } else { 11041 Uri data = intent.getData(); 11042 String ssp; 11043 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11044 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11045 forceStopPackageLocked(ssp, 11046 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11047 false, userId); 11048 } 11049 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11050 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11051 new String[] {ssp}); 11052 } 11053 } 11054 } 11055 } 11056 } else { 11057 String msg = "Permission Denial: " + intent.getAction() 11058 + " broadcast from " + callerPackage + " (pid=" + callingPid 11059 + ", uid=" + callingUid + ")" 11060 + " requires " 11061 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11062 Slog.w(TAG, msg); 11063 throw new SecurityException(msg); 11064 } 11065 11066 // Special case for adding a package: by default turn on compatibility 11067 // mode. 11068 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11069 Uri data = intent.getData(); 11070 String ssp; 11071 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11072 mCompatModePackages.handlePackageAddedLocked(ssp, 11073 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11074 } 11075 } 11076 11077 /* 11078 * If this is the time zone changed action, queue up a message that will reset the timezone 11079 * of all currently running processes. This message will get queued up before the broadcast 11080 * happens. 11081 */ 11082 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11083 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11084 } 11085 11086 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11087 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11088 } 11089 11090 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11091 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11092 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11093 } 11094 11095 /* 11096 * Prevent non-system code (defined here to be non-persistent 11097 * processes) from sending protected broadcasts. 11098 */ 11099 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11100 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11101 callingUid == 0) { 11102 // Always okay. 11103 } else if (callerApp == null || !callerApp.persistent) { 11104 try { 11105 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11106 intent.getAction())) { 11107 String msg = "Permission Denial: not allowed to send broadcast " 11108 + intent.getAction() + " from pid=" 11109 + callingPid + ", uid=" + callingUid; 11110 Slog.w(TAG, msg); 11111 throw new SecurityException(msg); 11112 } 11113 } catch (RemoteException e) { 11114 Slog.w(TAG, "Remote exception", e); 11115 return ActivityManager.BROADCAST_SUCCESS; 11116 } 11117 } 11118 11119 // Add to the sticky list if requested. 11120 if (sticky) { 11121 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11122 callingPid, callingUid) 11123 != PackageManager.PERMISSION_GRANTED) { 11124 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11125 + callingPid + ", uid=" + callingUid 11126 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11127 Slog.w(TAG, msg); 11128 throw new SecurityException(msg); 11129 } 11130 if (requiredPermission != null) { 11131 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11132 + " and enforce permission " + requiredPermission); 11133 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11134 } 11135 if (intent.getComponent() != null) { 11136 throw new SecurityException( 11137 "Sticky broadcasts can't target a specific component"); 11138 } 11139 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11140 if (list == null) { 11141 list = new ArrayList<Intent>(); 11142 mStickyBroadcasts.put(intent.getAction(), list); 11143 } 11144 int N = list.size(); 11145 int i; 11146 for (i=0; i<N; i++) { 11147 if (intent.filterEquals(list.get(i))) { 11148 // This sticky already exists, replace it. 11149 list.set(i, new Intent(intent)); 11150 break; 11151 } 11152 } 11153 if (i >= N) { 11154 list.add(new Intent(intent)); 11155 } 11156 } 11157 11158 // Figure out who all will receive this broadcast. 11159 List receivers = null; 11160 List<BroadcastFilter> registeredReceivers = null; 11161 try { 11162 // Need to resolve the intent to interested receivers... 11163 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11164 == 0) { 11165 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11166 intent, resolvedType, STOCK_PM_FLAGS, userId); 11167 } 11168 if (intent.getComponent() == null) { 11169 registeredReceivers = mReceiverResolver.queryIntent(intent, 11170 resolvedType, false, userId); 11171 } 11172 } catch (RemoteException ex) { 11173 // pm is in same process, this will never happen. 11174 } 11175 11176 final boolean replacePending = 11177 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11178 11179 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11180 + " replacePending=" + replacePending); 11181 11182 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11183 if (!ordered && NR > 0) { 11184 // If we are not serializing this broadcast, then send the 11185 // registered receivers separately so they don't wait for the 11186 // components to be launched. 11187 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11188 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11189 callerPackage, callingPid, callingUid, requiredPermission, 11190 registeredReceivers, resultTo, resultCode, resultData, map, 11191 ordered, sticky, false, onlySendToCaller); 11192 if (DEBUG_BROADCAST) Slog.v( 11193 TAG, "Enqueueing parallel broadcast " + r); 11194 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11195 if (!replaced) { 11196 queue.enqueueParallelBroadcastLocked(r); 11197 queue.scheduleBroadcastsLocked(); 11198 } 11199 registeredReceivers = null; 11200 NR = 0; 11201 } 11202 11203 // Merge into one list. 11204 int ir = 0; 11205 if (receivers != null) { 11206 // A special case for PACKAGE_ADDED: do not allow the package 11207 // being added to see this broadcast. This prevents them from 11208 // using this as a back door to get run as soon as they are 11209 // installed. Maybe in the future we want to have a special install 11210 // broadcast or such for apps, but we'd like to deliberately make 11211 // this decision. 11212 String skipPackages[] = null; 11213 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11214 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11215 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11216 Uri data = intent.getData(); 11217 if (data != null) { 11218 String pkgName = data.getSchemeSpecificPart(); 11219 if (pkgName != null) { 11220 skipPackages = new String[] { pkgName }; 11221 } 11222 } 11223 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11224 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11225 } 11226 if (skipPackages != null && (skipPackages.length > 0)) { 11227 for (String skipPackage : skipPackages) { 11228 if (skipPackage != null) { 11229 int NT = receivers.size(); 11230 for (int it=0; it<NT; it++) { 11231 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11232 if (curt.activityInfo.packageName.equals(skipPackage)) { 11233 receivers.remove(it); 11234 it--; 11235 NT--; 11236 } 11237 } 11238 } 11239 } 11240 } 11241 11242 int NT = receivers != null ? receivers.size() : 0; 11243 int it = 0; 11244 ResolveInfo curt = null; 11245 BroadcastFilter curr = null; 11246 while (it < NT && ir < NR) { 11247 if (curt == null) { 11248 curt = (ResolveInfo)receivers.get(it); 11249 } 11250 if (curr == null) { 11251 curr = registeredReceivers.get(ir); 11252 } 11253 if (curr.getPriority() >= curt.priority) { 11254 // Insert this broadcast record into the final list. 11255 receivers.add(it, curr); 11256 ir++; 11257 curr = null; 11258 it++; 11259 NT++; 11260 } else { 11261 // Skip to the next ResolveInfo in the final list. 11262 it++; 11263 curt = null; 11264 } 11265 } 11266 } 11267 while (ir < NR) { 11268 if (receivers == null) { 11269 receivers = new ArrayList(); 11270 } 11271 receivers.add(registeredReceivers.get(ir)); 11272 ir++; 11273 } 11274 11275 if ((receivers != null && receivers.size() > 0) 11276 || resultTo != null) { 11277 BroadcastQueue queue = broadcastQueueForIntent(intent); 11278 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11279 callerPackage, callingPid, callingUid, requiredPermission, 11280 receivers, resultTo, resultCode, resultData, map, ordered, 11281 sticky, false, onlySendToCaller); 11282 if (DEBUG_BROADCAST) Slog.v( 11283 TAG, "Enqueueing ordered broadcast " + r 11284 + ": prev had " + queue.mOrderedBroadcasts.size()); 11285 if (DEBUG_BROADCAST) { 11286 int seq = r.intent.getIntExtra("seq", -1); 11287 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11288 } 11289 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11290 if (!replaced) { 11291 queue.enqueueOrderedBroadcastLocked(r); 11292 queue.scheduleBroadcastsLocked(); 11293 } 11294 } 11295 11296 return ActivityManager.BROADCAST_SUCCESS; 11297 } 11298 11299 final Intent verifyBroadcastLocked(Intent intent) { 11300 // Refuse possible leaked file descriptors 11301 if (intent != null && intent.hasFileDescriptors() == true) { 11302 throw new IllegalArgumentException("File descriptors passed in Intent"); 11303 } 11304 11305 int flags = intent.getFlags(); 11306 11307 if (!mProcessesReady) { 11308 // if the caller really truly claims to know what they're doing, go 11309 // ahead and allow the broadcast without launching any receivers 11310 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11311 intent = new Intent(intent); 11312 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11313 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11314 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11315 + " before boot completion"); 11316 throw new IllegalStateException("Cannot broadcast before boot completed"); 11317 } 11318 } 11319 11320 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11321 throw new IllegalArgumentException( 11322 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11323 } 11324 11325 return intent; 11326 } 11327 11328 public final int broadcastIntent(IApplicationThread caller, 11329 Intent intent, String resolvedType, IIntentReceiver resultTo, 11330 int resultCode, String resultData, Bundle map, 11331 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11332 enforceNotIsolatedCaller("broadcastIntent"); 11333 synchronized(this) { 11334 intent = verifyBroadcastLocked(intent); 11335 11336 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11337 final int callingPid = Binder.getCallingPid(); 11338 final int callingUid = Binder.getCallingUid(); 11339 final long origId = Binder.clearCallingIdentity(); 11340 int res = broadcastIntentLocked(callerApp, 11341 callerApp != null ? callerApp.info.packageName : null, 11342 intent, resolvedType, resultTo, 11343 resultCode, resultData, map, requiredPermission, serialized, sticky, 11344 callingPid, callingUid, userId); 11345 Binder.restoreCallingIdentity(origId); 11346 return res; 11347 } 11348 } 11349 11350 int broadcastIntentInPackage(String packageName, int uid, 11351 Intent intent, String resolvedType, IIntentReceiver resultTo, 11352 int resultCode, String resultData, Bundle map, 11353 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11354 synchronized(this) { 11355 intent = verifyBroadcastLocked(intent); 11356 11357 final long origId = Binder.clearCallingIdentity(); 11358 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11359 resultTo, resultCode, resultData, map, requiredPermission, 11360 serialized, sticky, -1, uid, userId); 11361 Binder.restoreCallingIdentity(origId); 11362 return res; 11363 } 11364 } 11365 11366 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11367 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11368 // Refuse possible leaked file descriptors 11369 if (intent != null && intent.hasFileDescriptors() == true) { 11370 throw new IllegalArgumentException("File descriptors passed in Intent"); 11371 } 11372 11373 synchronized(this) { 11374 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11375 != PackageManager.PERMISSION_GRANTED) { 11376 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11377 + Binder.getCallingPid() 11378 + ", uid=" + Binder.getCallingUid() 11379 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11380 Slog.w(TAG, msg); 11381 throw new SecurityException(msg); 11382 } 11383 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11384 if (list != null) { 11385 int N = list.size(); 11386 int i; 11387 for (i=0; i<N; i++) { 11388 if (intent.filterEquals(list.get(i))) { 11389 list.remove(i); 11390 break; 11391 } 11392 } 11393 } 11394 } 11395 } 11396 11397 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11398 String resultData, Bundle resultExtras, boolean resultAbort, 11399 boolean explicit) { 11400 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11401 if (r == null) { 11402 Slog.w(TAG, "finishReceiver called but not found on queue"); 11403 return false; 11404 } 11405 11406 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11407 explicit); 11408 } 11409 11410 public void finishReceiver(IBinder who, int resultCode, String resultData, 11411 Bundle resultExtras, boolean resultAbort) { 11412 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11413 11414 // Refuse possible leaked file descriptors 11415 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11416 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11417 } 11418 11419 final long origId = Binder.clearCallingIdentity(); 11420 try { 11421 boolean doNext = false; 11422 BroadcastRecord r = null; 11423 11424 synchronized(this) { 11425 r = broadcastRecordForReceiverLocked(who); 11426 if (r != null) { 11427 doNext = r.queue.finishReceiverLocked(r, resultCode, 11428 resultData, resultExtras, resultAbort, true); 11429 } 11430 } 11431 11432 if (doNext) { 11433 r.queue.processNextBroadcast(false); 11434 } 11435 trimApplications(); 11436 } finally { 11437 Binder.restoreCallingIdentity(origId); 11438 } 11439 } 11440 11441 // ========================================================= 11442 // INSTRUMENTATION 11443 // ========================================================= 11444 11445 public boolean startInstrumentation(ComponentName className, 11446 String profileFile, int flags, Bundle arguments, 11447 IInstrumentationWatcher watcher) { 11448 enforceNotIsolatedCaller("startInstrumentation"); 11449 // Refuse possible leaked file descriptors 11450 if (arguments != null && arguments.hasFileDescriptors()) { 11451 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11452 } 11453 11454 synchronized(this) { 11455 InstrumentationInfo ii = null; 11456 ApplicationInfo ai = null; 11457 try { 11458 ii = mContext.getPackageManager().getInstrumentationInfo( 11459 className, STOCK_PM_FLAGS); 11460 ai = mContext.getPackageManager().getApplicationInfo( 11461 ii.targetPackage, STOCK_PM_FLAGS); 11462 } catch (PackageManager.NameNotFoundException e) { 11463 } 11464 if (ii == null) { 11465 reportStartInstrumentationFailure(watcher, className, 11466 "Unable to find instrumentation info for: " + className); 11467 return false; 11468 } 11469 if (ai == null) { 11470 reportStartInstrumentationFailure(watcher, className, 11471 "Unable to find instrumentation target package: " + ii.targetPackage); 11472 return false; 11473 } 11474 11475 int match = mContext.getPackageManager().checkSignatures( 11476 ii.targetPackage, ii.packageName); 11477 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11478 String msg = "Permission Denial: starting instrumentation " 11479 + className + " from pid=" 11480 + Binder.getCallingPid() 11481 + ", uid=" + Binder.getCallingPid() 11482 + " not allowed because package " + ii.packageName 11483 + " does not have a signature matching the target " 11484 + ii.targetPackage; 11485 reportStartInstrumentationFailure(watcher, className, msg); 11486 throw new SecurityException(msg); 11487 } 11488 11489 int userId = UserId.getCallingUserId(); 11490 final long origId = Binder.clearCallingIdentity(); 11491 // Instrumentation can kill and relaunch even persistent processes 11492 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11493 ProcessRecord app = addAppLocked(ai, false); 11494 app.instrumentationClass = className; 11495 app.instrumentationInfo = ai; 11496 app.instrumentationProfileFile = profileFile; 11497 app.instrumentationArguments = arguments; 11498 app.instrumentationWatcher = watcher; 11499 app.instrumentationResultClass = className; 11500 Binder.restoreCallingIdentity(origId); 11501 } 11502 11503 return true; 11504 } 11505 11506 /** 11507 * Report errors that occur while attempting to start Instrumentation. Always writes the 11508 * error to the logs, but if somebody is watching, send the report there too. This enables 11509 * the "am" command to report errors with more information. 11510 * 11511 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11512 * @param cn The component name of the instrumentation. 11513 * @param report The error report. 11514 */ 11515 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11516 ComponentName cn, String report) { 11517 Slog.w(TAG, report); 11518 try { 11519 if (watcher != null) { 11520 Bundle results = new Bundle(); 11521 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11522 results.putString("Error", report); 11523 watcher.instrumentationStatus(cn, -1, results); 11524 } 11525 } catch (RemoteException e) { 11526 Slog.w(TAG, e); 11527 } 11528 } 11529 11530 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11531 if (app.instrumentationWatcher != null) { 11532 try { 11533 // NOTE: IInstrumentationWatcher *must* be oneway here 11534 app.instrumentationWatcher.instrumentationFinished( 11535 app.instrumentationClass, 11536 resultCode, 11537 results); 11538 } catch (RemoteException e) { 11539 } 11540 } 11541 app.instrumentationWatcher = null; 11542 app.instrumentationClass = null; 11543 app.instrumentationInfo = null; 11544 app.instrumentationProfileFile = null; 11545 app.instrumentationArguments = null; 11546 11547 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11548 } 11549 11550 public void finishInstrumentation(IApplicationThread target, 11551 int resultCode, Bundle results) { 11552 int userId = UserId.getCallingUserId(); 11553 // Refuse possible leaked file descriptors 11554 if (results != null && results.hasFileDescriptors()) { 11555 throw new IllegalArgumentException("File descriptors passed in Intent"); 11556 } 11557 11558 synchronized(this) { 11559 ProcessRecord app = getRecordForAppLocked(target); 11560 if (app == null) { 11561 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11562 return; 11563 } 11564 final long origId = Binder.clearCallingIdentity(); 11565 finishInstrumentationLocked(app, resultCode, results); 11566 Binder.restoreCallingIdentity(origId); 11567 } 11568 } 11569 11570 // ========================================================= 11571 // CONFIGURATION 11572 // ========================================================= 11573 11574 public ConfigurationInfo getDeviceConfigurationInfo() { 11575 ConfigurationInfo config = new ConfigurationInfo(); 11576 synchronized (this) { 11577 config.reqTouchScreen = mConfiguration.touchscreen; 11578 config.reqKeyboardType = mConfiguration.keyboard; 11579 config.reqNavigation = mConfiguration.navigation; 11580 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11581 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11582 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11583 } 11584 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11585 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11586 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11587 } 11588 config.reqGlEsVersion = GL_ES_VERSION; 11589 } 11590 return config; 11591 } 11592 11593 public Configuration getConfiguration() { 11594 Configuration ci; 11595 synchronized(this) { 11596 ci = new Configuration(mConfiguration); 11597 } 11598 return ci; 11599 } 11600 11601 public void updatePersistentConfiguration(Configuration values) { 11602 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11603 "updateConfiguration()"); 11604 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11605 "updateConfiguration()"); 11606 if (values == null) { 11607 throw new NullPointerException("Configuration must not be null"); 11608 } 11609 11610 synchronized(this) { 11611 final long origId = Binder.clearCallingIdentity(); 11612 updateConfigurationLocked(values, null, true, false); 11613 Binder.restoreCallingIdentity(origId); 11614 } 11615 } 11616 11617 public void updateConfiguration(Configuration values) { 11618 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11619 "updateConfiguration()"); 11620 11621 synchronized(this) { 11622 if (values == null && mWindowManager != null) { 11623 // sentinel: fetch the current configuration from the window manager 11624 values = mWindowManager.computeNewConfiguration(); 11625 } 11626 11627 if (mWindowManager != null) { 11628 mProcessList.applyDisplaySize(mWindowManager); 11629 } 11630 11631 final long origId = Binder.clearCallingIdentity(); 11632 if (values != null) { 11633 Settings.System.clearConfiguration(values); 11634 } 11635 updateConfigurationLocked(values, null, false, false); 11636 Binder.restoreCallingIdentity(origId); 11637 } 11638 } 11639 11640 /** 11641 * Do either or both things: (1) change the current configuration, and (2) 11642 * make sure the given activity is running with the (now) current 11643 * configuration. Returns true if the activity has been left running, or 11644 * false if <var>starting</var> is being destroyed to match the new 11645 * configuration. 11646 * @param persistent TODO 11647 */ 11648 boolean updateConfigurationLocked(Configuration values, 11649 ActivityRecord starting, boolean persistent, boolean initLocale) { 11650 // do nothing if we are headless 11651 if (mHeadless) return true; 11652 11653 int changes = 0; 11654 11655 boolean kept = true; 11656 11657 if (values != null) { 11658 Configuration newConfig = new Configuration(mConfiguration); 11659 changes = newConfig.updateFrom(values); 11660 if (changes != 0) { 11661 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11662 Slog.i(TAG, "Updating configuration to: " + values); 11663 } 11664 11665 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11666 11667 if (values.locale != null && !initLocale) { 11668 saveLocaleLocked(values.locale, 11669 !values.locale.equals(mConfiguration.locale), 11670 values.userSetLocale); 11671 } 11672 11673 mConfigurationSeq++; 11674 if (mConfigurationSeq <= 0) { 11675 mConfigurationSeq = 1; 11676 } 11677 newConfig.seq = mConfigurationSeq; 11678 mConfiguration = newConfig; 11679 Slog.i(TAG, "Config changed: " + newConfig); 11680 11681 final Configuration configCopy = new Configuration(mConfiguration); 11682 11683 // TODO: If our config changes, should we auto dismiss any currently 11684 // showing dialogs? 11685 mShowDialogs = shouldShowDialogs(newConfig); 11686 11687 AttributeCache ac = AttributeCache.instance(); 11688 if (ac != null) { 11689 ac.updateConfiguration(configCopy); 11690 } 11691 11692 // Make sure all resources in our process are updated 11693 // right now, so that anyone who is going to retrieve 11694 // resource values after we return will be sure to get 11695 // the new ones. This is especially important during 11696 // boot, where the first config change needs to guarantee 11697 // all resources have that config before following boot 11698 // code is executed. 11699 mSystemThread.applyConfigurationToResources(configCopy); 11700 11701 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11702 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11703 msg.obj = new Configuration(configCopy); 11704 mHandler.sendMessage(msg); 11705 } 11706 11707 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11708 ProcessRecord app = mLruProcesses.get(i); 11709 try { 11710 if (app.thread != null) { 11711 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11712 + app.processName + " new config " + mConfiguration); 11713 app.thread.scheduleConfigurationChanged(configCopy); 11714 } 11715 } catch (Exception e) { 11716 } 11717 } 11718 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11719 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11720 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11721 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11722 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11723 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11724 broadcastIntentLocked(null, null, 11725 new Intent(Intent.ACTION_LOCALE_CHANGED), 11726 null, null, 0, null, null, 11727 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11728 } 11729 } 11730 } 11731 11732 if (changes != 0 && starting == null) { 11733 // If the configuration changed, and the caller is not already 11734 // in the process of starting an activity, then find the top 11735 // activity to check if its configuration needs to change. 11736 starting = mMainStack.topRunningActivityLocked(null); 11737 } 11738 11739 if (starting != null) { 11740 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11741 // And we need to make sure at this point that all other activities 11742 // are made visible with the correct configuration. 11743 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11744 } 11745 11746 if (values != null && mWindowManager != null) { 11747 mWindowManager.setNewConfiguration(mConfiguration); 11748 } 11749 11750 return kept; 11751 } 11752 11753 /** 11754 * Decide based on the configuration whether we should shouw the ANR, 11755 * crash, etc dialogs. The idea is that if there is no affordnace to 11756 * press the on-screen buttons, we shouldn't show the dialog. 11757 * 11758 * A thought: SystemUI might also want to get told about this, the Power 11759 * dialog / global actions also might want different behaviors. 11760 */ 11761 private static final boolean shouldShowDialogs(Configuration config) { 11762 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11763 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11764 } 11765 11766 /** 11767 * Save the locale. You must be inside a synchronized (this) block. 11768 */ 11769 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11770 if(isDiff) { 11771 SystemProperties.set("user.language", l.getLanguage()); 11772 SystemProperties.set("user.region", l.getCountry()); 11773 } 11774 11775 if(isPersist) { 11776 SystemProperties.set("persist.sys.language", l.getLanguage()); 11777 SystemProperties.set("persist.sys.country", l.getCountry()); 11778 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11779 } 11780 } 11781 11782 @Override 11783 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11784 ActivityRecord srec = ActivityRecord.forToken(token); 11785 return srec != null && srec.task.affinity != null && 11786 srec.task.affinity.equals(destAffinity); 11787 } 11788 11789 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11790 Intent resultData) { 11791 ComponentName dest = destIntent.getComponent(); 11792 11793 synchronized (this) { 11794 ActivityRecord srec = ActivityRecord.forToken(token); 11795 if (srec == null) { 11796 return false; 11797 } 11798 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11799 final int start = history.indexOf(srec); 11800 if (start < 0) { 11801 // Current activity is not in history stack; do nothing. 11802 return false; 11803 } 11804 int finishTo = start - 1; 11805 ActivityRecord parent = null; 11806 boolean foundParentInTask = false; 11807 if (dest != null) { 11808 TaskRecord tr = srec.task; 11809 for (int i = start - 1; i >= 0; i--) { 11810 ActivityRecord r = history.get(i); 11811 if (tr != r.task) { 11812 // Couldn't find parent in the same task; stop at the one above this. 11813 // (Root of current task; in-app "home" behavior) 11814 // Always at least finish the current activity. 11815 finishTo = Math.min(start - 1, i + 1); 11816 parent = history.get(finishTo); 11817 break; 11818 } else if (r.info.packageName.equals(dest.getPackageName()) && 11819 r.info.name.equals(dest.getClassName())) { 11820 finishTo = i; 11821 parent = r; 11822 foundParentInTask = true; 11823 break; 11824 } 11825 } 11826 } 11827 11828 if (mController != null) { 11829 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11830 if (next != null) { 11831 // ask watcher if this is allowed 11832 boolean resumeOK = true; 11833 try { 11834 resumeOK = mController.activityResuming(next.packageName); 11835 } catch (RemoteException e) { 11836 mController = null; 11837 } 11838 11839 if (!resumeOK) { 11840 return false; 11841 } 11842 } 11843 } 11844 final long origId = Binder.clearCallingIdentity(); 11845 for (int i = start; i > finishTo; i--) { 11846 ActivityRecord r = history.get(i); 11847 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11848 "navigate-up"); 11849 // Only return the supplied result for the first activity finished 11850 resultCode = Activity.RESULT_CANCELED; 11851 resultData = null; 11852 } 11853 11854 if (parent != null && foundParentInTask) { 11855 final int parentLaunchMode = parent.info.launchMode; 11856 final int destIntentFlags = destIntent.getFlags(); 11857 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11858 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11859 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11860 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11861 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11862 } else { 11863 try { 11864 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11865 destIntent.getComponent(), 0, UserId.getCallingUserId()); 11866 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11867 null, aInfo, parent.appToken, null, 11868 0, -1, parent.launchedFromUid, 0, null, true, null); 11869 foundParentInTask = res == ActivityManager.START_SUCCESS; 11870 } catch (RemoteException e) { 11871 foundParentInTask = false; 11872 } 11873 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11874 resultData, "navigate-up"); 11875 } 11876 } 11877 Binder.restoreCallingIdentity(origId); 11878 return foundParentInTask; 11879 } 11880 } 11881 11882 public int getLaunchedFromUid(IBinder activityToken) { 11883 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11884 if (srec == null) { 11885 return -1; 11886 } 11887 return srec.launchedFromUid; 11888 } 11889 11890 // ========================================================= 11891 // LIFETIME MANAGEMENT 11892 // ========================================================= 11893 11894 // Returns which broadcast queue the app is the current [or imminent] receiver 11895 // on, or 'null' if the app is not an active broadcast recipient. 11896 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11897 BroadcastRecord r = app.curReceiver; 11898 if (r != null) { 11899 return r.queue; 11900 } 11901 11902 // It's not the current receiver, but it might be starting up to become one 11903 synchronized (this) { 11904 for (BroadcastQueue queue : mBroadcastQueues) { 11905 r = queue.mPendingBroadcast; 11906 if (r != null && r.curApp == app) { 11907 // found it; report which queue it's in 11908 return queue; 11909 } 11910 } 11911 } 11912 11913 return null; 11914 } 11915 11916 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11917 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11918 if (mAdjSeq == app.adjSeq) { 11919 // This adjustment has already been computed. If we are calling 11920 // from the top, we may have already computed our adjustment with 11921 // an earlier hidden adjustment that isn't really for us... if 11922 // so, use the new hidden adjustment. 11923 if (!recursed && app.hidden) { 11924 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 11925 } 11926 return app.curRawAdj; 11927 } 11928 11929 if (app.thread == null) { 11930 app.adjSeq = mAdjSeq; 11931 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 11932 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 11933 } 11934 11935 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 11936 app.adjSource = null; 11937 app.adjTarget = null; 11938 app.empty = false; 11939 app.hidden = false; 11940 11941 final int activitiesSize = app.activities.size(); 11942 11943 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 11944 // The max adjustment doesn't allow this app to be anything 11945 // below foreground, so it is not worth doing work for it. 11946 app.adjType = "fixed"; 11947 app.adjSeq = mAdjSeq; 11948 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 11949 app.foregroundActivities = false; 11950 app.keeping = true; 11951 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 11952 // System process can do UI, and when they do we want to have 11953 // them trim their memory after the user leaves the UI. To 11954 // facilitate this, here we need to determine whether or not it 11955 // is currently showing UI. 11956 app.systemNoUi = true; 11957 if (app == TOP_APP) { 11958 app.systemNoUi = false; 11959 } else if (activitiesSize > 0) { 11960 for (int j = 0; j < activitiesSize; j++) { 11961 final ActivityRecord r = app.activities.get(j); 11962 if (r.visible) { 11963 app.systemNoUi = false; 11964 break; 11965 } 11966 } 11967 } 11968 return (app.curAdj=app.maxAdj); 11969 } 11970 11971 app.keeping = false; 11972 app.systemNoUi = false; 11973 11974 // Determine the importance of the process, starting with most 11975 // important to least, and assign an appropriate OOM adjustment. 11976 int adj; 11977 int schedGroup; 11978 boolean foregroundActivities = false; 11979 boolean interesting = false; 11980 BroadcastQueue queue; 11981 if (app == TOP_APP) { 11982 // The last app on the list is the foreground app. 11983 adj = ProcessList.FOREGROUND_APP_ADJ; 11984 schedGroup = Process.THREAD_GROUP_DEFAULT; 11985 app.adjType = "top-activity"; 11986 foregroundActivities = true; 11987 interesting = true; 11988 } else if (app.instrumentationClass != null) { 11989 // Don't want to kill running instrumentation. 11990 adj = ProcessList.FOREGROUND_APP_ADJ; 11991 schedGroup = Process.THREAD_GROUP_DEFAULT; 11992 app.adjType = "instrumentation"; 11993 interesting = true; 11994 } else if ((queue = isReceivingBroadcast(app)) != null) { 11995 // An app that is currently receiving a broadcast also 11996 // counts as being in the foreground for OOM killer purposes. 11997 // It's placed in a sched group based on the nature of the 11998 // broadcast as reflected by which queue it's active in. 11999 adj = ProcessList.FOREGROUND_APP_ADJ; 12000 schedGroup = (queue == mFgBroadcastQueue) 12001 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12002 app.adjType = "broadcast"; 12003 } else if (app.executingServices.size() > 0) { 12004 // An app that is currently executing a service callback also 12005 // counts as being in the foreground. 12006 adj = ProcessList.FOREGROUND_APP_ADJ; 12007 schedGroup = Process.THREAD_GROUP_DEFAULT; 12008 app.adjType = "exec-service"; 12009 } else if (activitiesSize > 0) { 12010 // This app is in the background with paused activities. 12011 // We inspect activities to potentially upgrade adjustment further below. 12012 adj = hiddenAdj; 12013 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12014 app.hidden = true; 12015 app.adjType = "bg-activities"; 12016 } else { 12017 // A very not-needed process. If this is lower in the lru list, 12018 // we will push it in to the empty bucket. 12019 adj = hiddenAdj; 12020 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12021 app.hidden = true; 12022 app.empty = true; 12023 app.adjType = "bg-empty"; 12024 } 12025 12026 boolean hasStoppingActivities = false; 12027 12028 // Examine all activities if not already foreground. 12029 if (!foregroundActivities && activitiesSize > 0) { 12030 for (int j = 0; j < activitiesSize; j++) { 12031 final ActivityRecord r = app.activities.get(j); 12032 if (r.visible) { 12033 // App has a visible activity; only upgrade adjustment. 12034 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12035 adj = ProcessList.VISIBLE_APP_ADJ; 12036 app.adjType = "visible"; 12037 } 12038 schedGroup = Process.THREAD_GROUP_DEFAULT; 12039 app.hidden = false; 12040 foregroundActivities = true; 12041 break; 12042 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12043 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12044 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12045 app.adjType = "pausing"; 12046 } 12047 app.hidden = false; 12048 foregroundActivities = true; 12049 } else if (r.state == ActivityState.STOPPING) { 12050 // We will apply the actual adjustment later, because 12051 // we want to allow this process to immediately go through 12052 // any memory trimming that is in effect. 12053 app.hidden = false; 12054 foregroundActivities = true; 12055 hasStoppingActivities = true; 12056 } 12057 } 12058 } 12059 12060 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12061 if (app.foregroundServices) { 12062 // The user is aware of this app, so make it visible. 12063 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12064 app.hidden = false; 12065 app.adjType = "foreground-service"; 12066 schedGroup = Process.THREAD_GROUP_DEFAULT; 12067 } else if (app.forcingToForeground != null) { 12068 // The user is aware of this app, so make it visible. 12069 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12070 app.hidden = false; 12071 app.adjType = "force-foreground"; 12072 app.adjSource = app.forcingToForeground; 12073 schedGroup = Process.THREAD_GROUP_DEFAULT; 12074 } 12075 } 12076 12077 if (app.foregroundServices) { 12078 interesting = true; 12079 } 12080 12081 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12082 // We don't want to kill the current heavy-weight process. 12083 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12084 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12085 app.hidden = false; 12086 app.adjType = "heavy"; 12087 } 12088 12089 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12090 // This process is hosting what we currently consider to be the 12091 // home app, so we don't want to let it go into the background. 12092 adj = ProcessList.HOME_APP_ADJ; 12093 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12094 app.hidden = false; 12095 app.adjType = "home"; 12096 } 12097 12098 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12099 && app.activities.size() > 0) { 12100 // This was the previous process that showed UI to the user. 12101 // We want to try to keep it around more aggressively, to give 12102 // a good experience around switching between two apps. 12103 adj = ProcessList.PREVIOUS_APP_ADJ; 12104 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12105 app.hidden = false; 12106 app.adjType = "previous"; 12107 } 12108 12109 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12110 + " reason=" + app.adjType); 12111 12112 // By default, we use the computed adjustment. It may be changed if 12113 // there are applications dependent on our services or providers, but 12114 // this gives us a baseline and makes sure we don't get into an 12115 // infinite recursion. 12116 app.adjSeq = mAdjSeq; 12117 app.curRawAdj = app.nonStoppingAdj = adj; 12118 12119 if (mBackupTarget != null && app == mBackupTarget.app) { 12120 // If possible we want to avoid killing apps while they're being backed up 12121 if (adj > ProcessList.BACKUP_APP_ADJ) { 12122 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12123 adj = ProcessList.BACKUP_APP_ADJ; 12124 app.adjType = "backup"; 12125 app.hidden = false; 12126 } 12127 } 12128 12129 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12130 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12131 final long now = SystemClock.uptimeMillis(); 12132 // This process is more important if the top activity is 12133 // bound to the service. 12134 Iterator<ServiceRecord> jt = app.services.iterator(); 12135 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12136 ServiceRecord s = jt.next(); 12137 if (s.startRequested) { 12138 if (app.hasShownUi && app != mHomeProcess) { 12139 // If this process has shown some UI, let it immediately 12140 // go to the LRU list because it may be pretty heavy with 12141 // UI stuff. We'll tag it with a label just to help 12142 // debug and understand what is going on. 12143 if (adj > ProcessList.SERVICE_ADJ) { 12144 app.adjType = "started-bg-ui-services"; 12145 } 12146 } else { 12147 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12148 // This service has seen some activity within 12149 // recent memory, so we will keep its process ahead 12150 // of the background processes. 12151 if (adj > ProcessList.SERVICE_ADJ) { 12152 adj = ProcessList.SERVICE_ADJ; 12153 app.adjType = "started-services"; 12154 app.hidden = false; 12155 } 12156 } 12157 // If we have let the service slide into the background 12158 // state, still have some text describing what it is doing 12159 // even though the service no longer has an impact. 12160 if (adj > ProcessList.SERVICE_ADJ) { 12161 app.adjType = "started-bg-services"; 12162 } 12163 } 12164 // Don't kill this process because it is doing work; it 12165 // has said it is doing work. 12166 app.keeping = true; 12167 } 12168 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12169 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12170 Iterator<ArrayList<ConnectionRecord>> kt 12171 = s.connections.values().iterator(); 12172 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12173 ArrayList<ConnectionRecord> clist = kt.next(); 12174 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12175 // XXX should compute this based on the max of 12176 // all connected clients. 12177 ConnectionRecord cr = clist.get(i); 12178 if (cr.binding.client == app) { 12179 // Binding to ourself is not interesting. 12180 continue; 12181 } 12182 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12183 ProcessRecord client = cr.binding.client; 12184 int clientAdj = adj; 12185 int myHiddenAdj = hiddenAdj; 12186 if (myHiddenAdj > client.hiddenAdj) { 12187 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12188 myHiddenAdj = client.hiddenAdj; 12189 } else { 12190 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12191 } 12192 } 12193 clientAdj = computeOomAdjLocked( 12194 client, myHiddenAdj, TOP_APP, true, doingAll); 12195 String adjType = null; 12196 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12197 // Not doing bind OOM management, so treat 12198 // this guy more like a started service. 12199 if (app.hasShownUi && app != mHomeProcess) { 12200 // If this process has shown some UI, let it immediately 12201 // go to the LRU list because it may be pretty heavy with 12202 // UI stuff. We'll tag it with a label just to help 12203 // debug and understand what is going on. 12204 if (adj > clientAdj) { 12205 adjType = "bound-bg-ui-services"; 12206 } 12207 app.hidden = false; 12208 clientAdj = adj; 12209 } else { 12210 if (now >= (s.lastActivity 12211 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12212 // This service has not seen activity within 12213 // recent memory, so allow it to drop to the 12214 // LRU list if there is no other reason to keep 12215 // it around. We'll also tag it with a label just 12216 // to help debug and undertand what is going on. 12217 if (adj > clientAdj) { 12218 adjType = "bound-bg-services"; 12219 } 12220 clientAdj = adj; 12221 } 12222 } 12223 } 12224 if (adj > clientAdj) { 12225 // If this process has recently shown UI, and 12226 // the process that is binding to it is less 12227 // important than being visible, then we don't 12228 // care about the binding as much as we care 12229 // about letting this process get into the LRU 12230 // list to be killed and restarted if needed for 12231 // memory. 12232 if (app.hasShownUi && app != mHomeProcess 12233 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12234 adjType = "bound-bg-ui-services"; 12235 } else { 12236 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12237 |Context.BIND_IMPORTANT)) != 0) { 12238 adj = clientAdj; 12239 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12240 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12241 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12242 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12243 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12244 adj = clientAdj; 12245 } else { 12246 app.pendingUiClean = true; 12247 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12248 adj = ProcessList.VISIBLE_APP_ADJ; 12249 } 12250 } 12251 if (!client.hidden) { 12252 app.hidden = false; 12253 } 12254 if (client.keeping) { 12255 app.keeping = true; 12256 } 12257 adjType = "service"; 12258 } 12259 } 12260 if (adjType != null) { 12261 app.adjType = adjType; 12262 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12263 .REASON_SERVICE_IN_USE; 12264 app.adjSource = cr.binding.client; 12265 app.adjSourceOom = clientAdj; 12266 app.adjTarget = s.name; 12267 } 12268 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12269 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12270 schedGroup = Process.THREAD_GROUP_DEFAULT; 12271 } 12272 } 12273 } 12274 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12275 ActivityRecord a = cr.activity; 12276 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12277 (a.visible || a.state == ActivityState.RESUMED 12278 || a.state == ActivityState.PAUSING)) { 12279 adj = ProcessList.FOREGROUND_APP_ADJ; 12280 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12281 schedGroup = Process.THREAD_GROUP_DEFAULT; 12282 } 12283 app.hidden = false; 12284 app.adjType = "service"; 12285 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12286 .REASON_SERVICE_IN_USE; 12287 app.adjSource = a; 12288 app.adjSourceOom = adj; 12289 app.adjTarget = s.name; 12290 } 12291 } 12292 } 12293 } 12294 } 12295 } 12296 12297 // Finally, if this process has active services running in it, we 12298 // would like to avoid killing it unless it would prevent the current 12299 // application from running. By default we put the process in 12300 // with the rest of the background processes; as we scan through 12301 // its services we may bump it up from there. 12302 if (adj > hiddenAdj) { 12303 adj = hiddenAdj; 12304 app.hidden = false; 12305 app.adjType = "bg-services"; 12306 } 12307 } 12308 12309 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12310 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12311 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12312 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12313 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12314 ContentProviderRecord cpr = jt.next(); 12315 for (int i = cpr.connections.size()-1; 12316 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12317 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12318 i--) { 12319 ContentProviderConnection conn = cpr.connections.get(i); 12320 ProcessRecord client = conn.client; 12321 if (client == app) { 12322 // Being our own client is not interesting. 12323 continue; 12324 } 12325 int myHiddenAdj = hiddenAdj; 12326 if (myHiddenAdj > client.hiddenAdj) { 12327 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12328 myHiddenAdj = client.hiddenAdj; 12329 } else { 12330 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12331 } 12332 } 12333 int clientAdj = computeOomAdjLocked( 12334 client, myHiddenAdj, TOP_APP, true, doingAll); 12335 if (adj > clientAdj) { 12336 if (app.hasShownUi && app != mHomeProcess 12337 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12338 app.adjType = "bg-ui-provider"; 12339 } else { 12340 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12341 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12342 app.adjType = "provider"; 12343 } 12344 if (!client.hidden) { 12345 app.hidden = false; 12346 } 12347 if (client.keeping) { 12348 app.keeping = true; 12349 } 12350 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12351 .REASON_PROVIDER_IN_USE; 12352 app.adjSource = client; 12353 app.adjSourceOom = clientAdj; 12354 app.adjTarget = cpr.name; 12355 } 12356 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12357 schedGroup = Process.THREAD_GROUP_DEFAULT; 12358 } 12359 } 12360 // If the provider has external (non-framework) process 12361 // dependencies, ensure that its adjustment is at least 12362 // FOREGROUND_APP_ADJ. 12363 if (cpr.hasExternalProcessHandles()) { 12364 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12365 adj = ProcessList.FOREGROUND_APP_ADJ; 12366 schedGroup = Process.THREAD_GROUP_DEFAULT; 12367 app.hidden = false; 12368 app.keeping = true; 12369 app.adjType = "provider"; 12370 app.adjTarget = cpr.name; 12371 } 12372 } 12373 } 12374 } 12375 12376 if (adj == ProcessList.SERVICE_ADJ) { 12377 if (doingAll) { 12378 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12379 mNewNumServiceProcs++; 12380 } 12381 if (app.serviceb) { 12382 adj = ProcessList.SERVICE_B_ADJ; 12383 } 12384 } else { 12385 app.serviceb = false; 12386 } 12387 12388 app.nonStoppingAdj = adj; 12389 12390 if (hasStoppingActivities) { 12391 // Only upgrade adjustment. 12392 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12393 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12394 app.adjType = "stopping"; 12395 } 12396 } 12397 12398 app.curRawAdj = adj; 12399 12400 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12401 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12402 if (adj > app.maxAdj) { 12403 adj = app.maxAdj; 12404 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12405 schedGroup = Process.THREAD_GROUP_DEFAULT; 12406 } 12407 } 12408 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12409 app.keeping = true; 12410 } 12411 12412 if (app.hasAboveClient) { 12413 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12414 // then we need to drop its adjustment to be lower than the service's 12415 // in order to honor the request. We want to drop it by one adjustment 12416 // level... but there is special meaning applied to various levels so 12417 // we will skip some of them. 12418 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12419 // System process will not get dropped, ever 12420 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12421 adj = ProcessList.VISIBLE_APP_ADJ; 12422 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12423 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12424 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12425 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12426 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12427 adj++; 12428 } 12429 } 12430 12431 int importance = app.memImportance; 12432 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12433 app.curAdj = adj; 12434 app.curSchedGroup = schedGroup; 12435 if (!interesting) { 12436 // For this reporting, if there is not something explicitly 12437 // interesting in this process then we will push it to the 12438 // background importance. 12439 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12440 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12441 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12442 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12443 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12444 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12445 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12446 } else if (adj >= ProcessList.SERVICE_ADJ) { 12447 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12448 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12449 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12450 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12451 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12452 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12453 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12454 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12455 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12456 } else { 12457 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12458 } 12459 } 12460 12461 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12462 if (foregroundActivities != app.foregroundActivities) { 12463 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12464 } 12465 if (changes != 0) { 12466 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12467 app.memImportance = importance; 12468 app.foregroundActivities = foregroundActivities; 12469 int i = mPendingProcessChanges.size()-1; 12470 ProcessChangeItem item = null; 12471 while (i >= 0) { 12472 item = mPendingProcessChanges.get(i); 12473 if (item.pid == app.pid) { 12474 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12475 break; 12476 } 12477 i--; 12478 } 12479 if (i < 0) { 12480 // No existing item in pending changes; need a new one. 12481 final int NA = mAvailProcessChanges.size(); 12482 if (NA > 0) { 12483 item = mAvailProcessChanges.remove(NA-1); 12484 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12485 } else { 12486 item = new ProcessChangeItem(); 12487 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12488 } 12489 item.changes = 0; 12490 item.pid = app.pid; 12491 item.uid = app.info.uid; 12492 if (mPendingProcessChanges.size() == 0) { 12493 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12494 "*** Enqueueing dispatch processes changed!"); 12495 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12496 } 12497 mPendingProcessChanges.add(item); 12498 } 12499 item.changes |= changes; 12500 item.importance = importance; 12501 item.foregroundActivities = foregroundActivities; 12502 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12503 + Integer.toHexString(System.identityHashCode(item)) 12504 + " " + app.toShortString() + ": changes=" + item.changes 12505 + " importance=" + item.importance 12506 + " foreground=" + item.foregroundActivities 12507 + " type=" + app.adjType + " source=" + app.adjSource 12508 + " target=" + app.adjTarget); 12509 } 12510 12511 return app.curRawAdj; 12512 } 12513 12514 /** 12515 * Ask a given process to GC right now. 12516 */ 12517 final void performAppGcLocked(ProcessRecord app) { 12518 try { 12519 app.lastRequestedGc = SystemClock.uptimeMillis(); 12520 if (app.thread != null) { 12521 if (app.reportLowMemory) { 12522 app.reportLowMemory = false; 12523 app.thread.scheduleLowMemory(); 12524 } else { 12525 app.thread.processInBackground(); 12526 } 12527 } 12528 } catch (Exception e) { 12529 // whatever. 12530 } 12531 } 12532 12533 /** 12534 * Returns true if things are idle enough to perform GCs. 12535 */ 12536 private final boolean canGcNowLocked() { 12537 boolean processingBroadcasts = false; 12538 for (BroadcastQueue q : mBroadcastQueues) { 12539 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12540 processingBroadcasts = true; 12541 } 12542 } 12543 return !processingBroadcasts 12544 && (mSleeping || (mMainStack.mResumedActivity != null && 12545 mMainStack.mResumedActivity.idle)); 12546 } 12547 12548 /** 12549 * Perform GCs on all processes that are waiting for it, but only 12550 * if things are idle. 12551 */ 12552 final void performAppGcsLocked() { 12553 final int N = mProcessesToGc.size(); 12554 if (N <= 0) { 12555 return; 12556 } 12557 if (canGcNowLocked()) { 12558 while (mProcessesToGc.size() > 0) { 12559 ProcessRecord proc = mProcessesToGc.remove(0); 12560 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12561 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12562 <= SystemClock.uptimeMillis()) { 12563 // To avoid spamming the system, we will GC processes one 12564 // at a time, waiting a few seconds between each. 12565 performAppGcLocked(proc); 12566 scheduleAppGcsLocked(); 12567 return; 12568 } else { 12569 // It hasn't been long enough since we last GCed this 12570 // process... put it in the list to wait for its time. 12571 addProcessToGcListLocked(proc); 12572 break; 12573 } 12574 } 12575 } 12576 12577 scheduleAppGcsLocked(); 12578 } 12579 } 12580 12581 /** 12582 * If all looks good, perform GCs on all processes waiting for them. 12583 */ 12584 final void performAppGcsIfAppropriateLocked() { 12585 if (canGcNowLocked()) { 12586 performAppGcsLocked(); 12587 return; 12588 } 12589 // Still not idle, wait some more. 12590 scheduleAppGcsLocked(); 12591 } 12592 12593 /** 12594 * Schedule the execution of all pending app GCs. 12595 */ 12596 final void scheduleAppGcsLocked() { 12597 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12598 12599 if (mProcessesToGc.size() > 0) { 12600 // Schedule a GC for the time to the next process. 12601 ProcessRecord proc = mProcessesToGc.get(0); 12602 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12603 12604 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12605 long now = SystemClock.uptimeMillis(); 12606 if (when < (now+GC_TIMEOUT)) { 12607 when = now + GC_TIMEOUT; 12608 } 12609 mHandler.sendMessageAtTime(msg, when); 12610 } 12611 } 12612 12613 /** 12614 * Add a process to the array of processes waiting to be GCed. Keeps the 12615 * list in sorted order by the last GC time. The process can't already be 12616 * on the list. 12617 */ 12618 final void addProcessToGcListLocked(ProcessRecord proc) { 12619 boolean added = false; 12620 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12621 if (mProcessesToGc.get(i).lastRequestedGc < 12622 proc.lastRequestedGc) { 12623 added = true; 12624 mProcessesToGc.add(i+1, proc); 12625 break; 12626 } 12627 } 12628 if (!added) { 12629 mProcessesToGc.add(0, proc); 12630 } 12631 } 12632 12633 /** 12634 * Set up to ask a process to GC itself. This will either do it 12635 * immediately, or put it on the list of processes to gc the next 12636 * time things are idle. 12637 */ 12638 final void scheduleAppGcLocked(ProcessRecord app) { 12639 long now = SystemClock.uptimeMillis(); 12640 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12641 return; 12642 } 12643 if (!mProcessesToGc.contains(app)) { 12644 addProcessToGcListLocked(app); 12645 scheduleAppGcsLocked(); 12646 } 12647 } 12648 12649 final void checkExcessivePowerUsageLocked(boolean doKills) { 12650 updateCpuStatsNow(); 12651 12652 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12653 boolean doWakeKills = doKills; 12654 boolean doCpuKills = doKills; 12655 if (mLastPowerCheckRealtime == 0) { 12656 doWakeKills = false; 12657 } 12658 if (mLastPowerCheckUptime == 0) { 12659 doCpuKills = false; 12660 } 12661 if (stats.isScreenOn()) { 12662 doWakeKills = false; 12663 } 12664 final long curRealtime = SystemClock.elapsedRealtime(); 12665 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12666 final long curUptime = SystemClock.uptimeMillis(); 12667 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12668 mLastPowerCheckRealtime = curRealtime; 12669 mLastPowerCheckUptime = curUptime; 12670 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12671 doWakeKills = false; 12672 } 12673 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12674 doCpuKills = false; 12675 } 12676 int i = mLruProcesses.size(); 12677 while (i > 0) { 12678 i--; 12679 ProcessRecord app = mLruProcesses.get(i); 12680 if (!app.keeping) { 12681 long wtime; 12682 synchronized (stats) { 12683 wtime = stats.getProcessWakeTime(app.info.uid, 12684 app.pid, curRealtime); 12685 } 12686 long wtimeUsed = wtime - app.lastWakeTime; 12687 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12688 if (DEBUG_POWER) { 12689 StringBuilder sb = new StringBuilder(128); 12690 sb.append("Wake for "); 12691 app.toShortString(sb); 12692 sb.append(": over "); 12693 TimeUtils.formatDuration(realtimeSince, sb); 12694 sb.append(" used "); 12695 TimeUtils.formatDuration(wtimeUsed, sb); 12696 sb.append(" ("); 12697 sb.append((wtimeUsed*100)/realtimeSince); 12698 sb.append("%)"); 12699 Slog.i(TAG, sb.toString()); 12700 sb.setLength(0); 12701 sb.append("CPU for "); 12702 app.toShortString(sb); 12703 sb.append(": over "); 12704 TimeUtils.formatDuration(uptimeSince, sb); 12705 sb.append(" used "); 12706 TimeUtils.formatDuration(cputimeUsed, sb); 12707 sb.append(" ("); 12708 sb.append((cputimeUsed*100)/uptimeSince); 12709 sb.append("%)"); 12710 Slog.i(TAG, sb.toString()); 12711 } 12712 // If a process has held a wake lock for more 12713 // than 50% of the time during this period, 12714 // that sounds bad. Kill! 12715 if (doWakeKills && realtimeSince > 0 12716 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12717 synchronized (stats) { 12718 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12719 realtimeSince, wtimeUsed); 12720 } 12721 Slog.w(TAG, "Excessive wake lock in " + app.processName 12722 + " (pid " + app.pid + "): held " + wtimeUsed 12723 + " during " + realtimeSince); 12724 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12725 app.processName, app.setAdj, "excessive wake lock"); 12726 Process.killProcessQuiet(app.pid); 12727 } else if (doCpuKills && uptimeSince > 0 12728 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12729 synchronized (stats) { 12730 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12731 uptimeSince, cputimeUsed); 12732 } 12733 Slog.w(TAG, "Excessive CPU in " + app.processName 12734 + " (pid " + app.pid + "): used " + cputimeUsed 12735 + " during " + uptimeSince); 12736 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12737 app.processName, app.setAdj, "excessive cpu"); 12738 Process.killProcessQuiet(app.pid); 12739 } else { 12740 app.lastWakeTime = wtime; 12741 app.lastCpuTime = app.curCpuTime; 12742 } 12743 } 12744 } 12745 } 12746 12747 private final boolean updateOomAdjLocked( 12748 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 12749 app.hiddenAdj = hiddenAdj; 12750 12751 if (app.thread == null) { 12752 return false; 12753 } 12754 12755 final boolean wasKeeping = app.keeping; 12756 12757 boolean success = true; 12758 12759 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 12760 12761 if (app.curRawAdj != app.setRawAdj) { 12762 if (wasKeeping && !app.keeping) { 12763 // This app is no longer something we want to keep. Note 12764 // its current wake lock time to later know to kill it if 12765 // it is not behaving well. 12766 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12767 synchronized (stats) { 12768 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12769 app.pid, SystemClock.elapsedRealtime()); 12770 } 12771 app.lastCpuTime = app.curCpuTime; 12772 } 12773 12774 app.setRawAdj = app.curRawAdj; 12775 } 12776 12777 if (app.curAdj != app.setAdj) { 12778 if (Process.setOomAdj(app.pid, app.curAdj)) { 12779 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12780 TAG, "Set " + app.pid + " " + app.processName + 12781 " adj " + app.curAdj + ": " + app.adjType); 12782 app.setAdj = app.curAdj; 12783 } else { 12784 success = false; 12785 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12786 } 12787 } 12788 if (app.setSchedGroup != app.curSchedGroup) { 12789 app.setSchedGroup = app.curSchedGroup; 12790 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12791 "Setting process group of " + app.processName 12792 + " to " + app.curSchedGroup); 12793 if (app.waitingToKill != null && 12794 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12795 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12796 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12797 app.processName, app.setAdj, app.waitingToKill); 12798 app.killedBackground = true; 12799 Process.killProcessQuiet(app.pid); 12800 success = false; 12801 } else { 12802 if (true) { 12803 long oldId = Binder.clearCallingIdentity(); 12804 try { 12805 Process.setProcessGroup(app.pid, app.curSchedGroup); 12806 } catch (Exception e) { 12807 Slog.w(TAG, "Failed setting process group of " + app.pid 12808 + " to " + app.curSchedGroup); 12809 e.printStackTrace(); 12810 } finally { 12811 Binder.restoreCallingIdentity(oldId); 12812 } 12813 } else { 12814 if (app.thread != null) { 12815 try { 12816 app.thread.setSchedulingGroup(app.curSchedGroup); 12817 } catch (RemoteException e) { 12818 } 12819 } 12820 } 12821 } 12822 } 12823 return success; 12824 } 12825 12826 private final ActivityRecord resumedAppLocked() { 12827 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12828 if (resumedActivity == null || resumedActivity.app == null) { 12829 resumedActivity = mMainStack.mPausingActivity; 12830 if (resumedActivity == null || resumedActivity.app == null) { 12831 resumedActivity = mMainStack.topRunningActivityLocked(null); 12832 } 12833 } 12834 return resumedActivity; 12835 } 12836 12837 final boolean updateOomAdjLocked(ProcessRecord app) { 12838 final ActivityRecord TOP_ACT = resumedAppLocked(); 12839 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12840 int curAdj = app.curAdj; 12841 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12842 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12843 12844 mAdjSeq++; 12845 12846 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 12847 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12848 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12849 if (nowHidden != wasHidden) { 12850 // Changed to/from hidden state, so apps after it in the LRU 12851 // list may also be changed. 12852 updateOomAdjLocked(); 12853 } 12854 return success; 12855 } 12856 12857 final void updateOomAdjLocked() { 12858 final ActivityRecord TOP_ACT = resumedAppLocked(); 12859 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12860 12861 if (false) { 12862 RuntimeException e = new RuntimeException(); 12863 e.fillInStackTrace(); 12864 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12865 } 12866 12867 mAdjSeq++; 12868 mNewNumServiceProcs = 0; 12869 12870 // Let's determine how many processes we have running vs. 12871 // how many slots we have for background processes; we may want 12872 // to put multiple processes in a slot of there are enough of 12873 // them. 12874 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 12875 int factor = (mLruProcesses.size()-4)/numSlots; 12876 if (factor < 1) factor = 1; 12877 int step = 0; 12878 int numHidden = 0; 12879 int numTrimming = 0; 12880 12881 // First update the OOM adjustment for each of the 12882 // application processes based on their current state. 12883 int i = mLruProcesses.size(); 12884 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12885 while (i > 0) { 12886 i--; 12887 ProcessRecord app = mLruProcesses.get(i); 12888 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 12889 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 12890 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 12891 && app.curAdj == curHiddenAdj) { 12892 step++; 12893 if (step >= factor) { 12894 step = 0; 12895 curHiddenAdj++; 12896 } 12897 } 12898 if (!app.killedBackground) { 12899 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12900 numHidden++; 12901 if (numHidden > mProcessLimit) { 12902 Slog.i(TAG, "No longer want " + app.processName 12903 + " (pid " + app.pid + "): hidden #" + numHidden); 12904 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12905 app.processName, app.setAdj, "too many background"); 12906 app.killedBackground = true; 12907 Process.killProcessQuiet(app.pid); 12908 } 12909 } 12910 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 12911 // If this is an isolated process, and there are no 12912 // services running in it, then the process is no longer 12913 // needed. We agressively kill these because we can by 12914 // definition not re-use the same process again, and it is 12915 // good to avoid having whatever code was running in them 12916 // left sitting around after no longer needed. 12917 Slog.i(TAG, "Isolated process " + app.processName 12918 + " (pid " + app.pid + ") no longer needed"); 12919 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12920 app.processName, app.setAdj, "isolated not needed"); 12921 app.killedBackground = true; 12922 Process.killProcessQuiet(app.pid); 12923 } 12924 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12925 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12926 && !app.killedBackground) { 12927 numTrimming++; 12928 } 12929 } 12930 } 12931 12932 mNumServiceProcs = mNewNumServiceProcs; 12933 12934 // Now determine the memory trimming level of background processes. 12935 // Unfortunately we need to start at the back of the list to do this 12936 // properly. We only do this if the number of background apps we 12937 // are managing to keep around is less than half the maximum we desire; 12938 // if we are keeping a good number around, we'll let them use whatever 12939 // memory they want. 12940 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 12941 final int N = mLruProcesses.size(); 12942 factor = numTrimming/3; 12943 int minFactor = 2; 12944 if (mHomeProcess != null) minFactor++; 12945 if (mPreviousProcess != null) minFactor++; 12946 if (factor < minFactor) factor = minFactor; 12947 step = 0; 12948 int fgTrimLevel; 12949 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 12950 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 12951 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 12952 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 12953 } else { 12954 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 12955 } 12956 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 12957 for (i=0; i<N; i++) { 12958 ProcessRecord app = mLruProcesses.get(i); 12959 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12960 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12961 && !app.killedBackground) { 12962 if (app.trimMemoryLevel < curLevel && app.thread != null) { 12963 try { 12964 app.thread.scheduleTrimMemory(curLevel); 12965 } catch (RemoteException e) { 12966 } 12967 if (false) { 12968 // For now we won't do this; our memory trimming seems 12969 // to be good enough at this point that destroying 12970 // activities causes more harm than good. 12971 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 12972 && app != mHomeProcess && app != mPreviousProcess) { 12973 // Need to do this on its own message because the stack may not 12974 // be in a consistent state at this point. 12975 // For these apps we will also finish their activities 12976 // to help them free memory. 12977 mMainStack.scheduleDestroyActivities(app, false, "trim"); 12978 } 12979 } 12980 } 12981 app.trimMemoryLevel = curLevel; 12982 step++; 12983 if (step >= factor) { 12984 step = 0; 12985 switch (curLevel) { 12986 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 12987 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 12988 break; 12989 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 12990 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 12991 break; 12992 } 12993 } 12994 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12995 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 12996 && app.thread != null) { 12997 try { 12998 app.thread.scheduleTrimMemory( 12999 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13000 } catch (RemoteException e) { 13001 } 13002 } 13003 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13004 } else { 13005 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13006 && app.pendingUiClean) { 13007 // If this application is now in the background and it 13008 // had done UI, then give it the special trim level to 13009 // have it free UI resources. 13010 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13011 if (app.trimMemoryLevel < level && app.thread != null) { 13012 try { 13013 app.thread.scheduleTrimMemory(level); 13014 } catch (RemoteException e) { 13015 } 13016 } 13017 app.pendingUiClean = false; 13018 } 13019 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13020 try { 13021 app.thread.scheduleTrimMemory(fgTrimLevel); 13022 } catch (RemoteException e) { 13023 } 13024 } 13025 app.trimMemoryLevel = fgTrimLevel; 13026 } 13027 } 13028 } else { 13029 final int N = mLruProcesses.size(); 13030 for (i=0; i<N; i++) { 13031 ProcessRecord app = mLruProcesses.get(i); 13032 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13033 && app.pendingUiClean) { 13034 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13035 && app.thread != null) { 13036 try { 13037 app.thread.scheduleTrimMemory( 13038 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13039 } catch (RemoteException e) { 13040 } 13041 } 13042 app.pendingUiClean = false; 13043 } 13044 app.trimMemoryLevel = 0; 13045 } 13046 } 13047 13048 if (mAlwaysFinishActivities) { 13049 // Need to do this on its own message because the stack may not 13050 // be in a consistent state at this point. 13051 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13052 } 13053 } 13054 13055 final void trimApplications() { 13056 synchronized (this) { 13057 int i; 13058 13059 // First remove any unused application processes whose package 13060 // has been removed. 13061 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13062 final ProcessRecord app = mRemovedProcesses.get(i); 13063 if (app.activities.size() == 0 13064 && app.curReceiver == null && app.services.size() == 0) { 13065 Slog.i( 13066 TAG, "Exiting empty application process " 13067 + app.processName + " (" 13068 + (app.thread != null ? app.thread.asBinder() : null) 13069 + ")\n"); 13070 if (app.pid > 0 && app.pid != MY_PID) { 13071 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13072 app.processName, app.setAdj, "empty"); 13073 Process.killProcessQuiet(app.pid); 13074 } else { 13075 try { 13076 app.thread.scheduleExit(); 13077 } catch (Exception e) { 13078 // Ignore exceptions. 13079 } 13080 } 13081 cleanUpApplicationRecordLocked(app, false, true, -1); 13082 mRemovedProcesses.remove(i); 13083 13084 if (app.persistent) { 13085 if (app.persistent) { 13086 addAppLocked(app.info, false); 13087 } 13088 } 13089 } 13090 } 13091 13092 // Now update the oom adj for all processes. 13093 updateOomAdjLocked(); 13094 } 13095 } 13096 13097 /** This method sends the specified signal to each of the persistent apps */ 13098 public void signalPersistentProcesses(int sig) throws RemoteException { 13099 if (sig != Process.SIGNAL_USR1) { 13100 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13101 } 13102 13103 synchronized (this) { 13104 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13105 != PackageManager.PERMISSION_GRANTED) { 13106 throw new SecurityException("Requires permission " 13107 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13108 } 13109 13110 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13111 ProcessRecord r = mLruProcesses.get(i); 13112 if (r.thread != null && r.persistent) { 13113 Process.sendSignal(r.pid, sig); 13114 } 13115 } 13116 } 13117 } 13118 13119 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13120 if (proc == null || proc == mProfileProc) { 13121 proc = mProfileProc; 13122 path = mProfileFile; 13123 profileType = mProfileType; 13124 clearProfilerLocked(); 13125 } 13126 if (proc == null) { 13127 return; 13128 } 13129 try { 13130 proc.thread.profilerControl(false, path, null, profileType); 13131 } catch (RemoteException e) { 13132 throw new IllegalStateException("Process disappeared"); 13133 } 13134 } 13135 13136 private void clearProfilerLocked() { 13137 if (mProfileFd != null) { 13138 try { 13139 mProfileFd.close(); 13140 } catch (IOException e) { 13141 } 13142 } 13143 mProfileApp = null; 13144 mProfileProc = null; 13145 mProfileFile = null; 13146 mProfileType = 0; 13147 mAutoStopProfiler = false; 13148 } 13149 13150 public boolean profileControl(String process, boolean start, 13151 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13152 13153 try { 13154 synchronized (this) { 13155 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13156 // its own permission. 13157 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13158 != PackageManager.PERMISSION_GRANTED) { 13159 throw new SecurityException("Requires permission " 13160 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13161 } 13162 13163 if (start && fd == null) { 13164 throw new IllegalArgumentException("null fd"); 13165 } 13166 13167 ProcessRecord proc = null; 13168 if (process != null) { 13169 try { 13170 int pid = Integer.parseInt(process); 13171 synchronized (mPidsSelfLocked) { 13172 proc = mPidsSelfLocked.get(pid); 13173 } 13174 } catch (NumberFormatException e) { 13175 } 13176 13177 if (proc == null) { 13178 HashMap<String, SparseArray<ProcessRecord>> all 13179 = mProcessNames.getMap(); 13180 SparseArray<ProcessRecord> procs = all.get(process); 13181 if (procs != null && procs.size() > 0) { 13182 proc = procs.valueAt(0); 13183 } 13184 } 13185 } 13186 13187 if (start && (proc == null || proc.thread == null)) { 13188 throw new IllegalArgumentException("Unknown process: " + process); 13189 } 13190 13191 if (start) { 13192 stopProfilerLocked(null, null, 0); 13193 setProfileApp(proc.info, proc.processName, path, fd, false); 13194 mProfileProc = proc; 13195 mProfileType = profileType; 13196 try { 13197 fd = fd.dup(); 13198 } catch (IOException e) { 13199 fd = null; 13200 } 13201 proc.thread.profilerControl(start, path, fd, profileType); 13202 fd = null; 13203 mProfileFd = null; 13204 } else { 13205 stopProfilerLocked(proc, path, profileType); 13206 if (fd != null) { 13207 try { 13208 fd.close(); 13209 } catch (IOException e) { 13210 } 13211 } 13212 } 13213 13214 return true; 13215 } 13216 } catch (RemoteException e) { 13217 throw new IllegalStateException("Process disappeared"); 13218 } finally { 13219 if (fd != null) { 13220 try { 13221 fd.close(); 13222 } catch (IOException e) { 13223 } 13224 } 13225 } 13226 } 13227 13228 public boolean dumpHeap(String process, boolean managed, 13229 String path, ParcelFileDescriptor fd) throws RemoteException { 13230 13231 try { 13232 synchronized (this) { 13233 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13234 // its own permission (same as profileControl). 13235 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13236 != PackageManager.PERMISSION_GRANTED) { 13237 throw new SecurityException("Requires permission " 13238 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13239 } 13240 13241 if (fd == null) { 13242 throw new IllegalArgumentException("null fd"); 13243 } 13244 13245 ProcessRecord proc = null; 13246 try { 13247 int pid = Integer.parseInt(process); 13248 synchronized (mPidsSelfLocked) { 13249 proc = mPidsSelfLocked.get(pid); 13250 } 13251 } catch (NumberFormatException e) { 13252 } 13253 13254 if (proc == null) { 13255 HashMap<String, SparseArray<ProcessRecord>> all 13256 = mProcessNames.getMap(); 13257 SparseArray<ProcessRecord> procs = all.get(process); 13258 if (procs != null && procs.size() > 0) { 13259 proc = procs.valueAt(0); 13260 } 13261 } 13262 13263 if (proc == null || proc.thread == null) { 13264 throw new IllegalArgumentException("Unknown process: " + process); 13265 } 13266 13267 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13268 if (!isDebuggable) { 13269 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13270 throw new SecurityException("Process not debuggable: " + proc); 13271 } 13272 } 13273 13274 proc.thread.dumpHeap(managed, path, fd); 13275 fd = null; 13276 return true; 13277 } 13278 } catch (RemoteException e) { 13279 throw new IllegalStateException("Process disappeared"); 13280 } finally { 13281 if (fd != null) { 13282 try { 13283 fd.close(); 13284 } catch (IOException e) { 13285 } 13286 } 13287 } 13288 } 13289 13290 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13291 public void monitor() { 13292 synchronized (this) { } 13293 } 13294 13295 void onCoreSettingsChange(Bundle settings) { 13296 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13297 ProcessRecord processRecord = mLruProcesses.get(i); 13298 try { 13299 if (processRecord.thread != null) { 13300 processRecord.thread.setCoreSettings(settings); 13301 } 13302 } catch (RemoteException re) { 13303 /* ignore */ 13304 } 13305 } 13306 } 13307 13308 // Multi-user methods 13309 13310 private int mCurrentUserId; 13311 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 13312 13313 public boolean switchUser(int userId) { 13314 final int callingUid = Binder.getCallingUid(); 13315 if (callingUid != 0 && callingUid != Process.myUid()) { 13316 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13317 return false; 13318 } 13319 if (mCurrentUserId == userId) 13320 return true; 13321 13322 synchronized (this) { 13323 // Check if user is already logged in, otherwise check if user exists first before 13324 // adding to the list of logged in users. 13325 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13326 if (!userExists(userId)) { 13327 return false; 13328 } 13329 mLoggedInUsers.append(userId, userId); 13330 } 13331 13332 mCurrentUserId = userId; 13333 boolean haveActivities = mMainStack.switchUser(userId); 13334 if (!haveActivities) { 13335 startHomeActivityLocked(userId); 13336 } 13337 13338 } 13339 13340 // Inform of user switch 13341 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13342 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 13343 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13344 13345 return true; 13346 } 13347 13348 @Override 13349 public UserInfo getCurrentUser() throws RemoteException { 13350 final int callingUid = Binder.getCallingUid(); 13351 if (callingUid != 0 && callingUid != Process.myUid()) { 13352 Slog.e(TAG, "Trying to get user from unauthorized app"); 13353 return null; 13354 } 13355 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 13356 } 13357 13358 private void onUserRemoved(Intent intent) { 13359 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 13360 if (extraUserId < 1) return; 13361 13362 // Kill all the processes for the user 13363 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13364 synchronized (this) { 13365 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13366 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13367 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13368 for (int i = 0; i < uids.size(); i++) { 13369 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 13370 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13371 } 13372 } 13373 } 13374 13375 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13376 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13377 false, false, true, true, extraUserId); 13378 } 13379 } 13380 } 13381 13382 private boolean userExists(int userId) { 13383 try { 13384 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 13385 return user != null; 13386 } catch (RemoteException re) { 13387 // Won't happen, in same process 13388 } 13389 13390 return false; 13391 } 13392 13393 private void checkValidCaller(int uid, int userId) { 13394 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13395 13396 throw new SecurityException("Caller uid=" + uid 13397 + " is not privileged to communicate with user=" + userId); 13398 } 13399 13400 private int applyUserId(int uid, int userId) { 13401 return UserId.getUid(userId, uid); 13402 } 13403 13404 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13405 if (info == null) return null; 13406 ApplicationInfo newInfo = new ApplicationInfo(info); 13407 newInfo.uid = applyUserId(info.uid, userId); 13408 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13409 + info.packageName; 13410 return newInfo; 13411 } 13412 13413 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13414 if (aInfo == null 13415 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 13416 return aInfo; 13417 } 13418 13419 ActivityInfo info = new ActivityInfo(aInfo); 13420 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13421 return info; 13422 } 13423} 13424