ActivityManagerService.java revision 4860cfc68464ebdcc391324518772c79f047597f
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 try { 4172 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 4173 for (UserInfo user : users) { 4174 broadcastIntentLocked(null, null, 4175 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4176 null, null, 0, null, null, 4177 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4178 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4179 } 4180 } catch (RemoteException re) { 4181 // Won't happen, in same process 4182 } 4183 4184 } 4185 } 4186 } 4187 4188 final void ensureBootCompleted() { 4189 boolean booting; 4190 boolean enableScreen; 4191 synchronized (this) { 4192 booting = mBooting; 4193 mBooting = false; 4194 enableScreen = !mBooted; 4195 mBooted = true; 4196 } 4197 4198 if (booting) { 4199 finishBooting(); 4200 } 4201 4202 if (enableScreen) { 4203 enableScreenAfterBoot(); 4204 } 4205 } 4206 4207 public final void activityPaused(IBinder token) { 4208 final long origId = Binder.clearCallingIdentity(); 4209 mMainStack.activityPaused(token, false); 4210 Binder.restoreCallingIdentity(origId); 4211 } 4212 4213 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4214 CharSequence description) { 4215 if (localLOGV) Slog.v( 4216 TAG, "Activity stopped: token=" + token); 4217 4218 // Refuse possible leaked file descriptors 4219 if (icicle != null && icicle.hasFileDescriptors()) { 4220 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4221 } 4222 4223 ActivityRecord r = null; 4224 4225 final long origId = Binder.clearCallingIdentity(); 4226 4227 synchronized (this) { 4228 r = mMainStack.isInStackLocked(token); 4229 if (r != null) { 4230 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4231 } 4232 } 4233 4234 if (r != null) { 4235 sendPendingThumbnail(r, null, null, null, false); 4236 } 4237 4238 trimApplications(); 4239 4240 Binder.restoreCallingIdentity(origId); 4241 } 4242 4243 public final void activityDestroyed(IBinder token) { 4244 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4245 mMainStack.activityDestroyed(token); 4246 } 4247 4248 public String getCallingPackage(IBinder token) { 4249 synchronized (this) { 4250 ActivityRecord r = getCallingRecordLocked(token); 4251 return r != null && r.app != null ? r.info.packageName : null; 4252 } 4253 } 4254 4255 public ComponentName getCallingActivity(IBinder token) { 4256 synchronized (this) { 4257 ActivityRecord r = getCallingRecordLocked(token); 4258 return r != null ? r.intent.getComponent() : null; 4259 } 4260 } 4261 4262 private ActivityRecord getCallingRecordLocked(IBinder token) { 4263 ActivityRecord r = mMainStack.isInStackLocked(token); 4264 if (r == null) { 4265 return null; 4266 } 4267 return r.resultTo; 4268 } 4269 4270 public ComponentName getActivityClassForToken(IBinder token) { 4271 synchronized(this) { 4272 ActivityRecord r = mMainStack.isInStackLocked(token); 4273 if (r == null) { 4274 return null; 4275 } 4276 return r.intent.getComponent(); 4277 } 4278 } 4279 4280 public String getPackageForToken(IBinder token) { 4281 synchronized(this) { 4282 ActivityRecord r = mMainStack.isInStackLocked(token); 4283 if (r == null) { 4284 return null; 4285 } 4286 return r.packageName; 4287 } 4288 } 4289 4290 public IIntentSender getIntentSender(int type, 4291 String packageName, IBinder token, String resultWho, 4292 int requestCode, Intent[] intents, String[] resolvedTypes, 4293 int flags, Bundle options) { 4294 enforceNotIsolatedCaller("getIntentSender"); 4295 // Refuse possible leaked file descriptors 4296 if (intents != null) { 4297 if (intents.length < 1) { 4298 throw new IllegalArgumentException("Intents array length must be >= 1"); 4299 } 4300 for (int i=0; i<intents.length; i++) { 4301 Intent intent = intents[i]; 4302 if (intent != null) { 4303 if (intent.hasFileDescriptors()) { 4304 throw new IllegalArgumentException("File descriptors passed in Intent"); 4305 } 4306 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4307 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4308 throw new IllegalArgumentException( 4309 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4310 } 4311 intents[i] = new Intent(intent); 4312 } 4313 } 4314 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4315 throw new IllegalArgumentException( 4316 "Intent array length does not match resolvedTypes length"); 4317 } 4318 } 4319 if (options != null) { 4320 if (options.hasFileDescriptors()) { 4321 throw new IllegalArgumentException("File descriptors passed in options"); 4322 } 4323 } 4324 4325 synchronized(this) { 4326 int callingUid = Binder.getCallingUid(); 4327 try { 4328 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4329 int uid = AppGlobals.getPackageManager() 4330 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4331 if (!UserId.isSameApp(callingUid, uid)) { 4332 String msg = "Permission Denial: getIntentSender() from pid=" 4333 + Binder.getCallingPid() 4334 + ", uid=" + Binder.getCallingUid() 4335 + ", (need uid=" + uid + ")" 4336 + " is not allowed to send as package " + packageName; 4337 Slog.w(TAG, msg); 4338 throw new SecurityException(msg); 4339 } 4340 } 4341 4342 if (DEBUG_MU) 4343 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4344 + Binder.getOrigCallingUid()); 4345 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4346 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4347 4348 } catch (RemoteException e) { 4349 throw new SecurityException(e); 4350 } 4351 } 4352 } 4353 4354 IIntentSender getIntentSenderLocked(int type, 4355 String packageName, int callingUid, IBinder token, String resultWho, 4356 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4357 Bundle options) { 4358 if (DEBUG_MU) 4359 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4360 ActivityRecord activity = null; 4361 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4362 activity = mMainStack.isInStackLocked(token); 4363 if (activity == null) { 4364 return null; 4365 } 4366 if (activity.finishing) { 4367 return null; 4368 } 4369 } 4370 4371 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4372 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4373 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4374 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4375 |PendingIntent.FLAG_UPDATE_CURRENT); 4376 4377 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4378 type, packageName, activity, resultWho, 4379 requestCode, intents, resolvedTypes, flags, options); 4380 WeakReference<PendingIntentRecord> ref; 4381 ref = mIntentSenderRecords.get(key); 4382 PendingIntentRecord rec = ref != null ? ref.get() : null; 4383 if (rec != null) { 4384 if (!cancelCurrent) { 4385 if (updateCurrent) { 4386 if (rec.key.requestIntent != null) { 4387 rec.key.requestIntent.replaceExtras(intents != null ? 4388 intents[intents.length - 1] : null); 4389 } 4390 if (intents != null) { 4391 intents[intents.length-1] = rec.key.requestIntent; 4392 rec.key.allIntents = intents; 4393 rec.key.allResolvedTypes = resolvedTypes; 4394 } else { 4395 rec.key.allIntents = null; 4396 rec.key.allResolvedTypes = null; 4397 } 4398 } 4399 return rec; 4400 } 4401 rec.canceled = true; 4402 mIntentSenderRecords.remove(key); 4403 } 4404 if (noCreate) { 4405 return rec; 4406 } 4407 rec = new PendingIntentRecord(this, key, callingUid); 4408 mIntentSenderRecords.put(key, rec.ref); 4409 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4410 if (activity.pendingResults == null) { 4411 activity.pendingResults 4412 = new HashSet<WeakReference<PendingIntentRecord>>(); 4413 } 4414 activity.pendingResults.add(rec.ref); 4415 } 4416 return rec; 4417 } 4418 4419 public void cancelIntentSender(IIntentSender sender) { 4420 if (!(sender instanceof PendingIntentRecord)) { 4421 return; 4422 } 4423 synchronized(this) { 4424 PendingIntentRecord rec = (PendingIntentRecord)sender; 4425 try { 4426 int uid = AppGlobals.getPackageManager() 4427 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4428 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4429 String msg = "Permission Denial: cancelIntentSender() from pid=" 4430 + Binder.getCallingPid() 4431 + ", uid=" + Binder.getCallingUid() 4432 + " is not allowed to cancel packges " 4433 + rec.key.packageName; 4434 Slog.w(TAG, msg); 4435 throw new SecurityException(msg); 4436 } 4437 } catch (RemoteException e) { 4438 throw new SecurityException(e); 4439 } 4440 cancelIntentSenderLocked(rec, true); 4441 } 4442 } 4443 4444 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4445 rec.canceled = true; 4446 mIntentSenderRecords.remove(rec.key); 4447 if (cleanActivity && rec.key.activity != null) { 4448 rec.key.activity.pendingResults.remove(rec.ref); 4449 } 4450 } 4451 4452 public String getPackageForIntentSender(IIntentSender pendingResult) { 4453 if (!(pendingResult instanceof PendingIntentRecord)) { 4454 return null; 4455 } 4456 try { 4457 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4458 return res.key.packageName; 4459 } catch (ClassCastException e) { 4460 } 4461 return null; 4462 } 4463 4464 public int getUidForIntentSender(IIntentSender sender) { 4465 if (sender instanceof PendingIntentRecord) { 4466 try { 4467 PendingIntentRecord res = (PendingIntentRecord)sender; 4468 return res.uid; 4469 } catch (ClassCastException e) { 4470 } 4471 } 4472 return -1; 4473 } 4474 4475 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4476 if (!(pendingResult instanceof PendingIntentRecord)) { 4477 return false; 4478 } 4479 try { 4480 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4481 if (res.key.allIntents == null) { 4482 return false; 4483 } 4484 for (int i=0; i<res.key.allIntents.length; i++) { 4485 Intent intent = res.key.allIntents[i]; 4486 if (intent.getPackage() != null && intent.getComponent() != null) { 4487 return false; 4488 } 4489 } 4490 return true; 4491 } catch (ClassCastException e) { 4492 } 4493 return false; 4494 } 4495 4496 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4497 if (!(pendingResult instanceof PendingIntentRecord)) { 4498 return false; 4499 } 4500 try { 4501 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4502 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4503 return true; 4504 } 4505 return false; 4506 } catch (ClassCastException e) { 4507 } 4508 return false; 4509 } 4510 4511 public void setProcessLimit(int max) { 4512 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4513 "setProcessLimit()"); 4514 synchronized (this) { 4515 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4516 mProcessLimitOverride = max; 4517 } 4518 trimApplications(); 4519 } 4520 4521 public int getProcessLimit() { 4522 synchronized (this) { 4523 return mProcessLimitOverride; 4524 } 4525 } 4526 4527 void foregroundTokenDied(ForegroundToken token) { 4528 synchronized (ActivityManagerService.this) { 4529 synchronized (mPidsSelfLocked) { 4530 ForegroundToken cur 4531 = mForegroundProcesses.get(token.pid); 4532 if (cur != token) { 4533 return; 4534 } 4535 mForegroundProcesses.remove(token.pid); 4536 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4537 if (pr == null) { 4538 return; 4539 } 4540 pr.forcingToForeground = null; 4541 pr.foregroundServices = false; 4542 } 4543 updateOomAdjLocked(); 4544 } 4545 } 4546 4547 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4548 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4549 "setProcessForeground()"); 4550 synchronized(this) { 4551 boolean changed = false; 4552 4553 synchronized (mPidsSelfLocked) { 4554 ProcessRecord pr = mPidsSelfLocked.get(pid); 4555 if (pr == null && isForeground) { 4556 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4557 return; 4558 } 4559 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4560 if (oldToken != null) { 4561 oldToken.token.unlinkToDeath(oldToken, 0); 4562 mForegroundProcesses.remove(pid); 4563 if (pr != null) { 4564 pr.forcingToForeground = null; 4565 } 4566 changed = true; 4567 } 4568 if (isForeground && token != null) { 4569 ForegroundToken newToken = new ForegroundToken() { 4570 public void binderDied() { 4571 foregroundTokenDied(this); 4572 } 4573 }; 4574 newToken.pid = pid; 4575 newToken.token = token; 4576 try { 4577 token.linkToDeath(newToken, 0); 4578 mForegroundProcesses.put(pid, newToken); 4579 pr.forcingToForeground = token; 4580 changed = true; 4581 } catch (RemoteException e) { 4582 // If the process died while doing this, we will later 4583 // do the cleanup with the process death link. 4584 } 4585 } 4586 } 4587 4588 if (changed) { 4589 updateOomAdjLocked(); 4590 } 4591 } 4592 } 4593 4594 // ========================================================= 4595 // PERMISSIONS 4596 // ========================================================= 4597 4598 static class PermissionController extends IPermissionController.Stub { 4599 ActivityManagerService mActivityManagerService; 4600 PermissionController(ActivityManagerService activityManagerService) { 4601 mActivityManagerService = activityManagerService; 4602 } 4603 4604 public boolean checkPermission(String permission, int pid, int uid) { 4605 return mActivityManagerService.checkPermission(permission, pid, 4606 uid) == PackageManager.PERMISSION_GRANTED; 4607 } 4608 } 4609 4610 /** 4611 * This can be called with or without the global lock held. 4612 */ 4613 int checkComponentPermission(String permission, int pid, int uid, 4614 int owningUid, boolean exported) { 4615 // We might be performing an operation on behalf of an indirect binder 4616 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4617 // client identity accordingly before proceeding. 4618 Identity tlsIdentity = sCallerIdentity.get(); 4619 if (tlsIdentity != null) { 4620 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4621 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4622 uid = tlsIdentity.uid; 4623 pid = tlsIdentity.pid; 4624 } 4625 4626 if (pid == MY_PID) { 4627 return PackageManager.PERMISSION_GRANTED; 4628 } 4629 4630 return ActivityManager.checkComponentPermission(permission, uid, 4631 owningUid, exported); 4632 } 4633 4634 /** 4635 * As the only public entry point for permissions checking, this method 4636 * can enforce the semantic that requesting a check on a null global 4637 * permission is automatically denied. (Internally a null permission 4638 * string is used when calling {@link #checkComponentPermission} in cases 4639 * when only uid-based security is needed.) 4640 * 4641 * This can be called with or without the global lock held. 4642 */ 4643 public int checkPermission(String permission, int pid, int uid) { 4644 if (permission == null) { 4645 return PackageManager.PERMISSION_DENIED; 4646 } 4647 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4648 } 4649 4650 /** 4651 * Binder IPC calls go through the public entry point. 4652 * This can be called with or without the global lock held. 4653 */ 4654 int checkCallingPermission(String permission) { 4655 return checkPermission(permission, 4656 Binder.getCallingPid(), 4657 UserId.getAppId(Binder.getCallingUid())); 4658 } 4659 4660 /** 4661 * This can be called with or without the global lock held. 4662 */ 4663 void enforceCallingPermission(String permission, String func) { 4664 if (checkCallingPermission(permission) 4665 == PackageManager.PERMISSION_GRANTED) { 4666 return; 4667 } 4668 4669 String msg = "Permission Denial: " + func + " from pid=" 4670 + Binder.getCallingPid() 4671 + ", uid=" + Binder.getCallingUid() 4672 + " requires " + permission; 4673 Slog.w(TAG, msg); 4674 throw new SecurityException(msg); 4675 } 4676 4677 /** 4678 * Determine if UID is holding permissions required to access {@link Uri} in 4679 * the given {@link ProviderInfo}. Final permission checking is always done 4680 * in {@link ContentProvider}. 4681 */ 4682 private final boolean checkHoldingPermissionsLocked( 4683 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4684 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4685 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4686 4687 if (pi.applicationInfo.uid == uid) { 4688 return true; 4689 } else if (!pi.exported) { 4690 return false; 4691 } 4692 4693 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4694 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4695 try { 4696 // check if target holds top-level <provider> permissions 4697 if (!readMet && pi.readPermission != null 4698 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4699 readMet = true; 4700 } 4701 if (!writeMet && pi.writePermission != null 4702 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4703 writeMet = true; 4704 } 4705 4706 // track if unprotected read/write is allowed; any denied 4707 // <path-permission> below removes this ability 4708 boolean allowDefaultRead = pi.readPermission == null; 4709 boolean allowDefaultWrite = pi.writePermission == null; 4710 4711 // check if target holds any <path-permission> that match uri 4712 final PathPermission[] pps = pi.pathPermissions; 4713 if (pps != null) { 4714 final String path = uri.getPath(); 4715 int i = pps.length; 4716 while (i > 0 && (!readMet || !writeMet)) { 4717 i--; 4718 PathPermission pp = pps[i]; 4719 if (pp.match(path)) { 4720 if (!readMet) { 4721 final String pprperm = pp.getReadPermission(); 4722 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4723 + pprperm + " for " + pp.getPath() 4724 + ": match=" + pp.match(path) 4725 + " check=" + pm.checkUidPermission(pprperm, uid)); 4726 if (pprperm != null) { 4727 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4728 readMet = true; 4729 } else { 4730 allowDefaultRead = false; 4731 } 4732 } 4733 } 4734 if (!writeMet) { 4735 final String ppwperm = pp.getWritePermission(); 4736 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4737 + ppwperm + " for " + pp.getPath() 4738 + ": match=" + pp.match(path) 4739 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4740 if (ppwperm != null) { 4741 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4742 writeMet = true; 4743 } else { 4744 allowDefaultWrite = false; 4745 } 4746 } 4747 } 4748 } 4749 } 4750 } 4751 4752 // grant unprotected <provider> read/write, if not blocked by 4753 // <path-permission> above 4754 if (allowDefaultRead) readMet = true; 4755 if (allowDefaultWrite) writeMet = true; 4756 4757 } catch (RemoteException e) { 4758 return false; 4759 } 4760 4761 return readMet && writeMet; 4762 } 4763 4764 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4765 int modeFlags) { 4766 // Root gets to do everything. 4767 if (uid == 0) { 4768 return true; 4769 } 4770 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4771 if (perms == null) return false; 4772 UriPermission perm = perms.get(uri); 4773 if (perm == null) return false; 4774 return (modeFlags&perm.modeFlags) == modeFlags; 4775 } 4776 4777 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4778 enforceNotIsolatedCaller("checkUriPermission"); 4779 4780 // Another redirected-binder-call permissions check as in 4781 // {@link checkComponentPermission}. 4782 Identity tlsIdentity = sCallerIdentity.get(); 4783 if (tlsIdentity != null) { 4784 uid = tlsIdentity.uid; 4785 pid = tlsIdentity.pid; 4786 } 4787 4788 uid = UserId.getAppId(uid); 4789 // Our own process gets to do everything. 4790 if (pid == MY_PID) { 4791 return PackageManager.PERMISSION_GRANTED; 4792 } 4793 synchronized(this) { 4794 return checkUriPermissionLocked(uri, uid, modeFlags) 4795 ? PackageManager.PERMISSION_GRANTED 4796 : PackageManager.PERMISSION_DENIED; 4797 } 4798 } 4799 4800 /** 4801 * Check if the targetPkg can be granted permission to access uri by 4802 * the callingUid using the given modeFlags. Throws a security exception 4803 * if callingUid is not allowed to do this. Returns the uid of the target 4804 * if the URI permission grant should be performed; returns -1 if it is not 4805 * needed (for example targetPkg already has permission to access the URI). 4806 * If you already know the uid of the target, you can supply it in 4807 * lastTargetUid else set that to -1. 4808 */ 4809 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4810 Uri uri, int modeFlags, int lastTargetUid) { 4811 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4812 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4813 if (modeFlags == 0) { 4814 return -1; 4815 } 4816 4817 if (targetPkg != null) { 4818 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4819 "Checking grant " + targetPkg + " permission to " + uri); 4820 } 4821 4822 final IPackageManager pm = AppGlobals.getPackageManager(); 4823 4824 // If this is not a content: uri, we can't do anything with it. 4825 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4826 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4827 "Can't grant URI permission for non-content URI: " + uri); 4828 return -1; 4829 } 4830 4831 String name = uri.getAuthority(); 4832 ProviderInfo pi = null; 4833 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4834 UserId.getUserId(callingUid)); 4835 if (cpr != null) { 4836 pi = cpr.info; 4837 } else { 4838 try { 4839 pi = pm.resolveContentProvider(name, 4840 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4841 } catch (RemoteException ex) { 4842 } 4843 } 4844 if (pi == null) { 4845 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4846 return -1; 4847 } 4848 4849 int targetUid = lastTargetUid; 4850 if (targetUid < 0 && targetPkg != null) { 4851 try { 4852 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4853 if (targetUid < 0) { 4854 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4855 "Can't grant URI permission no uid for: " + targetPkg); 4856 return -1; 4857 } 4858 } catch (RemoteException ex) { 4859 return -1; 4860 } 4861 } 4862 4863 if (targetUid >= 0) { 4864 // First... does the target actually need this permission? 4865 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4866 // No need to grant the target this permission. 4867 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4868 "Target " + targetPkg + " already has full permission to " + uri); 4869 return -1; 4870 } 4871 } else { 4872 // First... there is no target package, so can anyone access it? 4873 boolean allowed = pi.exported; 4874 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4875 if (pi.readPermission != null) { 4876 allowed = false; 4877 } 4878 } 4879 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4880 if (pi.writePermission != null) { 4881 allowed = false; 4882 } 4883 } 4884 if (allowed) { 4885 return -1; 4886 } 4887 } 4888 4889 // Second... is the provider allowing granting of URI permissions? 4890 if (!pi.grantUriPermissions) { 4891 throw new SecurityException("Provider " + pi.packageName 4892 + "/" + pi.name 4893 + " does not allow granting of Uri permissions (uri " 4894 + uri + ")"); 4895 } 4896 if (pi.uriPermissionPatterns != null) { 4897 final int N = pi.uriPermissionPatterns.length; 4898 boolean allowed = false; 4899 for (int i=0; i<N; i++) { 4900 if (pi.uriPermissionPatterns[i] != null 4901 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4902 allowed = true; 4903 break; 4904 } 4905 } 4906 if (!allowed) { 4907 throw new SecurityException("Provider " + pi.packageName 4908 + "/" + pi.name 4909 + " does not allow granting of permission to path of Uri " 4910 + uri); 4911 } 4912 } 4913 4914 // Third... does the caller itself have permission to access 4915 // this uri? 4916 if (callingUid != Process.myUid()) { 4917 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4918 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4919 throw new SecurityException("Uid " + callingUid 4920 + " does not have permission to uri " + uri); 4921 } 4922 } 4923 } 4924 4925 return targetUid; 4926 } 4927 4928 public int checkGrantUriPermission(int callingUid, String targetPkg, 4929 Uri uri, int modeFlags) { 4930 enforceNotIsolatedCaller("checkGrantUriPermission"); 4931 synchronized(this) { 4932 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4933 } 4934 } 4935 4936 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4937 Uri uri, int modeFlags, UriPermissionOwner owner) { 4938 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4939 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4940 if (modeFlags == 0) { 4941 return; 4942 } 4943 4944 // So here we are: the caller has the assumed permission 4945 // to the uri, and the target doesn't. Let's now give this to 4946 // the target. 4947 4948 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4949 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4950 4951 HashMap<Uri, UriPermission> targetUris 4952 = mGrantedUriPermissions.get(targetUid); 4953 if (targetUris == null) { 4954 targetUris = new HashMap<Uri, UriPermission>(); 4955 mGrantedUriPermissions.put(targetUid, targetUris); 4956 } 4957 4958 UriPermission perm = targetUris.get(uri); 4959 if (perm == null) { 4960 perm = new UriPermission(targetUid, uri); 4961 targetUris.put(uri, perm); 4962 } 4963 4964 perm.modeFlags |= modeFlags; 4965 if (owner == null) { 4966 perm.globalModeFlags |= modeFlags; 4967 } else { 4968 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4969 perm.readOwners.add(owner); 4970 owner.addReadPermission(perm); 4971 } 4972 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4973 perm.writeOwners.add(owner); 4974 owner.addWritePermission(perm); 4975 } 4976 } 4977 } 4978 4979 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 4980 int modeFlags, UriPermissionOwner owner) { 4981 if (targetPkg == null) { 4982 throw new NullPointerException("targetPkg"); 4983 } 4984 4985 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4986 if (targetUid < 0) { 4987 return; 4988 } 4989 4990 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 4991 } 4992 4993 static class NeededUriGrants extends ArrayList<Uri> { 4994 final String targetPkg; 4995 final int targetUid; 4996 final int flags; 4997 4998 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 4999 targetPkg = _targetPkg; 5000 targetUid = _targetUid; 5001 flags = _flags; 5002 } 5003 } 5004 5005 /** 5006 * Like checkGrantUriPermissionLocked, but takes an Intent. 5007 */ 5008 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5009 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5010 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5011 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5012 + " clip=" + (intent != null ? intent.getClipData() : null) 5013 + " from " + intent + "; flags=0x" 5014 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5015 5016 if (targetPkg == null) { 5017 throw new NullPointerException("targetPkg"); 5018 } 5019 5020 if (intent == null) { 5021 return null; 5022 } 5023 Uri data = intent.getData(); 5024 ClipData clip = intent.getClipData(); 5025 if (data == null && clip == null) { 5026 return null; 5027 } 5028 if (data != null) { 5029 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5030 mode, needed != null ? needed.targetUid : -1); 5031 if (target > 0) { 5032 if (needed == null) { 5033 needed = new NeededUriGrants(targetPkg, target, mode); 5034 } 5035 needed.add(data); 5036 } 5037 } 5038 if (clip != null) { 5039 for (int i=0; i<clip.getItemCount(); i++) { 5040 Uri uri = clip.getItemAt(i).getUri(); 5041 if (uri != null) { 5042 int target = -1; 5043 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5044 mode, needed != null ? needed.targetUid : -1); 5045 if (target > 0) { 5046 if (needed == null) { 5047 needed = new NeededUriGrants(targetPkg, target, mode); 5048 } 5049 needed.add(uri); 5050 } 5051 } else { 5052 Intent clipIntent = clip.getItemAt(i).getIntent(); 5053 if (clipIntent != null) { 5054 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5055 callingUid, targetPkg, clipIntent, mode, needed); 5056 if (newNeeded != null) { 5057 needed = newNeeded; 5058 } 5059 } 5060 } 5061 } 5062 } 5063 5064 return needed; 5065 } 5066 5067 /** 5068 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5069 */ 5070 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5071 UriPermissionOwner owner) { 5072 if (needed != null) { 5073 for (int i=0; i<needed.size(); i++) { 5074 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5075 needed.get(i), needed.flags, owner); 5076 } 5077 } 5078 } 5079 5080 void grantUriPermissionFromIntentLocked(int callingUid, 5081 String targetPkg, Intent intent, UriPermissionOwner owner) { 5082 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5083 intent, intent != null ? intent.getFlags() : 0, null); 5084 if (needed == null) { 5085 return; 5086 } 5087 5088 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5089 } 5090 5091 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5092 Uri uri, int modeFlags) { 5093 enforceNotIsolatedCaller("grantUriPermission"); 5094 synchronized(this) { 5095 final ProcessRecord r = getRecordForAppLocked(caller); 5096 if (r == null) { 5097 throw new SecurityException("Unable to find app for caller " 5098 + caller 5099 + " when granting permission to uri " + uri); 5100 } 5101 if (targetPkg == null) { 5102 throw new IllegalArgumentException("null target"); 5103 } 5104 if (uri == null) { 5105 throw new IllegalArgumentException("null uri"); 5106 } 5107 5108 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5109 null); 5110 } 5111 } 5112 5113 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5114 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5115 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5116 HashMap<Uri, UriPermission> perms 5117 = mGrantedUriPermissions.get(perm.uid); 5118 if (perms != null) { 5119 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5120 "Removing " + perm.uid + " permission to " + perm.uri); 5121 perms.remove(perm.uri); 5122 if (perms.size() == 0) { 5123 mGrantedUriPermissions.remove(perm.uid); 5124 } 5125 } 5126 } 5127 } 5128 5129 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5130 int modeFlags) { 5131 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5132 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5133 if (modeFlags == 0) { 5134 return; 5135 } 5136 5137 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5138 "Revoking all granted permissions to " + uri); 5139 5140 final IPackageManager pm = AppGlobals.getPackageManager(); 5141 5142 final String authority = uri.getAuthority(); 5143 ProviderInfo pi = null; 5144 int userId = UserId.getUserId(callingUid); 5145 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5146 if (cpr != null) { 5147 pi = cpr.info; 5148 } else { 5149 try { 5150 pi = pm.resolveContentProvider(authority, 5151 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5152 } catch (RemoteException ex) { 5153 } 5154 } 5155 if (pi == null) { 5156 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5157 return; 5158 } 5159 5160 // Does the caller have this permission on the URI? 5161 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5162 // Right now, if you are not the original owner of the permission, 5163 // you are not allowed to revoke it. 5164 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5165 throw new SecurityException("Uid " + callingUid 5166 + " does not have permission to uri " + uri); 5167 //} 5168 } 5169 5170 // Go through all of the permissions and remove any that match. 5171 final List<String> SEGMENTS = uri.getPathSegments(); 5172 if (SEGMENTS != null) { 5173 final int NS = SEGMENTS.size(); 5174 int N = mGrantedUriPermissions.size(); 5175 for (int i=0; i<N; i++) { 5176 HashMap<Uri, UriPermission> perms 5177 = mGrantedUriPermissions.valueAt(i); 5178 Iterator<UriPermission> it = perms.values().iterator(); 5179 toploop: 5180 while (it.hasNext()) { 5181 UriPermission perm = it.next(); 5182 Uri targetUri = perm.uri; 5183 if (!authority.equals(targetUri.getAuthority())) { 5184 continue; 5185 } 5186 List<String> targetSegments = targetUri.getPathSegments(); 5187 if (targetSegments == null) { 5188 continue; 5189 } 5190 if (targetSegments.size() < NS) { 5191 continue; 5192 } 5193 for (int j=0; j<NS; j++) { 5194 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5195 continue toploop; 5196 } 5197 } 5198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5199 "Revoking " + perm.uid + " permission to " + perm.uri); 5200 perm.clearModes(modeFlags); 5201 if (perm.modeFlags == 0) { 5202 it.remove(); 5203 } 5204 } 5205 if (perms.size() == 0) { 5206 mGrantedUriPermissions.remove( 5207 mGrantedUriPermissions.keyAt(i)); 5208 N--; 5209 i--; 5210 } 5211 } 5212 } 5213 } 5214 5215 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5216 int modeFlags) { 5217 enforceNotIsolatedCaller("revokeUriPermission"); 5218 synchronized(this) { 5219 final ProcessRecord r = getRecordForAppLocked(caller); 5220 if (r == null) { 5221 throw new SecurityException("Unable to find app for caller " 5222 + caller 5223 + " when revoking permission to uri " + uri); 5224 } 5225 if (uri == null) { 5226 Slog.w(TAG, "revokeUriPermission: null uri"); 5227 return; 5228 } 5229 5230 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5231 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5232 if (modeFlags == 0) { 5233 return; 5234 } 5235 5236 final IPackageManager pm = AppGlobals.getPackageManager(); 5237 5238 final String authority = uri.getAuthority(); 5239 ProviderInfo pi = null; 5240 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5241 if (cpr != null) { 5242 pi = cpr.info; 5243 } else { 5244 try { 5245 pi = pm.resolveContentProvider(authority, 5246 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5247 } catch (RemoteException ex) { 5248 } 5249 } 5250 if (pi == null) { 5251 Slog.w(TAG, "No content provider found for permission revoke: " 5252 + uri.toSafeString()); 5253 return; 5254 } 5255 5256 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5257 } 5258 } 5259 5260 @Override 5261 public IBinder newUriPermissionOwner(String name) { 5262 enforceNotIsolatedCaller("newUriPermissionOwner"); 5263 synchronized(this) { 5264 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5265 return owner.getExternalTokenLocked(); 5266 } 5267 } 5268 5269 @Override 5270 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5271 Uri uri, int modeFlags) { 5272 synchronized(this) { 5273 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5274 if (owner == null) { 5275 throw new IllegalArgumentException("Unknown owner: " + token); 5276 } 5277 if (fromUid != Binder.getCallingUid()) { 5278 if (Binder.getCallingUid() != Process.myUid()) { 5279 // Only system code can grant URI permissions on behalf 5280 // of other users. 5281 throw new SecurityException("nice try"); 5282 } 5283 } 5284 if (targetPkg == null) { 5285 throw new IllegalArgumentException("null target"); 5286 } 5287 if (uri == null) { 5288 throw new IllegalArgumentException("null uri"); 5289 } 5290 5291 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5292 } 5293 } 5294 5295 @Override 5296 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5297 synchronized(this) { 5298 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5299 if (owner == null) { 5300 throw new IllegalArgumentException("Unknown owner: " + token); 5301 } 5302 5303 if (uri == null) { 5304 owner.removeUriPermissionsLocked(mode); 5305 } else { 5306 owner.removeUriPermissionLocked(uri, mode); 5307 } 5308 } 5309 } 5310 5311 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5312 synchronized (this) { 5313 ProcessRecord app = 5314 who != null ? getRecordForAppLocked(who) : null; 5315 if (app == null) return; 5316 5317 Message msg = Message.obtain(); 5318 msg.what = WAIT_FOR_DEBUGGER_MSG; 5319 msg.obj = app; 5320 msg.arg1 = waiting ? 1 : 0; 5321 mHandler.sendMessage(msg); 5322 } 5323 } 5324 5325 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5326 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5327 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5328 outInfo.availMem = Process.getFreeMemory(); 5329 outInfo.totalMem = Process.getTotalMemory(); 5330 outInfo.threshold = homeAppMem; 5331 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5332 outInfo.hiddenAppThreshold = hiddenAppMem; 5333 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5334 ProcessList.SERVICE_ADJ); 5335 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5336 ProcessList.VISIBLE_APP_ADJ); 5337 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5338 ProcessList.FOREGROUND_APP_ADJ); 5339 } 5340 5341 // ========================================================= 5342 // TASK MANAGEMENT 5343 // ========================================================= 5344 5345 public List getTasks(int maxNum, int flags, 5346 IThumbnailReceiver receiver) { 5347 ArrayList list = new ArrayList(); 5348 5349 PendingThumbnailsRecord pending = null; 5350 IApplicationThread topThumbnail = null; 5351 ActivityRecord topRecord = null; 5352 5353 synchronized(this) { 5354 if (localLOGV) Slog.v( 5355 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5356 + ", receiver=" + receiver); 5357 5358 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5359 != PackageManager.PERMISSION_GRANTED) { 5360 if (receiver != null) { 5361 // If the caller wants to wait for pending thumbnails, 5362 // it ain't gonna get them. 5363 try { 5364 receiver.finished(); 5365 } catch (RemoteException ex) { 5366 } 5367 } 5368 String msg = "Permission Denial: getTasks() from pid=" 5369 + Binder.getCallingPid() 5370 + ", uid=" + Binder.getCallingUid() 5371 + " requires " + android.Manifest.permission.GET_TASKS; 5372 Slog.w(TAG, msg); 5373 throw new SecurityException(msg); 5374 } 5375 5376 int pos = mMainStack.mHistory.size()-1; 5377 ActivityRecord next = 5378 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5379 ActivityRecord top = null; 5380 TaskRecord curTask = null; 5381 int numActivities = 0; 5382 int numRunning = 0; 5383 while (pos >= 0 && maxNum > 0) { 5384 final ActivityRecord r = next; 5385 pos--; 5386 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5387 5388 // Initialize state for next task if needed. 5389 if (top == null || 5390 (top.state == ActivityState.INITIALIZING 5391 && top.task == r.task)) { 5392 top = r; 5393 curTask = r.task; 5394 numActivities = numRunning = 0; 5395 } 5396 5397 // Add 'r' into the current task. 5398 numActivities++; 5399 if (r.app != null && r.app.thread != null) { 5400 numRunning++; 5401 } 5402 5403 if (localLOGV) Slog.v( 5404 TAG, r.intent.getComponent().flattenToShortString() 5405 + ": task=" + r.task); 5406 5407 // If the next one is a different task, generate a new 5408 // TaskInfo entry for what we have. 5409 if (next == null || next.task != curTask) { 5410 ActivityManager.RunningTaskInfo ci 5411 = new ActivityManager.RunningTaskInfo(); 5412 ci.id = curTask.taskId; 5413 ci.baseActivity = r.intent.getComponent(); 5414 ci.topActivity = top.intent.getComponent(); 5415 if (top.thumbHolder != null) { 5416 ci.description = top.thumbHolder.lastDescription; 5417 } 5418 ci.numActivities = numActivities; 5419 ci.numRunning = numRunning; 5420 //System.out.println( 5421 // "#" + maxNum + ": " + " descr=" + ci.description); 5422 if (ci.thumbnail == null && receiver != null) { 5423 if (localLOGV) Slog.v( 5424 TAG, "State=" + top.state + "Idle=" + top.idle 5425 + " app=" + top.app 5426 + " thr=" + (top.app != null ? top.app.thread : null)); 5427 if (top.state == ActivityState.RESUMED 5428 || top.state == ActivityState.PAUSING) { 5429 if (top.idle && top.app != null 5430 && top.app.thread != null) { 5431 topRecord = top; 5432 topThumbnail = top.app.thread; 5433 } else { 5434 top.thumbnailNeeded = true; 5435 } 5436 } 5437 if (pending == null) { 5438 pending = new PendingThumbnailsRecord(receiver); 5439 } 5440 pending.pendingRecords.add(top); 5441 } 5442 list.add(ci); 5443 maxNum--; 5444 top = null; 5445 } 5446 } 5447 5448 if (pending != null) { 5449 mPendingThumbnails.add(pending); 5450 } 5451 } 5452 5453 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5454 5455 if (topThumbnail != null) { 5456 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5457 try { 5458 topThumbnail.requestThumbnail(topRecord.appToken); 5459 } catch (Exception e) { 5460 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5461 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5462 } 5463 } 5464 5465 if (pending == null && receiver != null) { 5466 // In this case all thumbnails were available and the client 5467 // is being asked to be told when the remaining ones come in... 5468 // which is unusually, since the top-most currently running 5469 // activity should never have a canned thumbnail! Oh well. 5470 try { 5471 receiver.finished(); 5472 } catch (RemoteException ex) { 5473 } 5474 } 5475 5476 return list; 5477 } 5478 5479 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5480 int flags) { 5481 final int callingUid = Binder.getCallingUid(); 5482 // If it's the system uid asking, then use the current user id. 5483 // TODO: Make sure that there aren't any other legitimate calls from the system uid that 5484 // require the entire list. 5485 final int callingUserId = callingUid == Process.SYSTEM_UID 5486 ? mCurrentUserId : UserId.getUserId(callingUid); 5487 synchronized (this) { 5488 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5489 "getRecentTasks()"); 5490 final boolean detailed = checkCallingPermission( 5491 android.Manifest.permission.GET_DETAILED_TASKS) 5492 == PackageManager.PERMISSION_GRANTED; 5493 5494 IPackageManager pm = AppGlobals.getPackageManager(); 5495 5496 final int N = mRecentTasks.size(); 5497 ArrayList<ActivityManager.RecentTaskInfo> res 5498 = new ArrayList<ActivityManager.RecentTaskInfo>( 5499 maxNum < N ? maxNum : N); 5500 for (int i=0; i<N && maxNum > 0; i++) { 5501 TaskRecord tr = mRecentTasks.get(i); 5502 // Only add calling user's recent tasks 5503 if (tr.userId != callingUserId) continue; 5504 // Return the entry if desired by the caller. We always return 5505 // the first entry, because callers always expect this to be the 5506 // foreground app. We may filter others if the caller has 5507 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5508 // we should exclude the entry. 5509 5510 if (i == 0 5511 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5512 || (tr.intent == null) 5513 || ((tr.intent.getFlags() 5514 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5515 ActivityManager.RecentTaskInfo rti 5516 = new ActivityManager.RecentTaskInfo(); 5517 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5518 rti.persistentId = tr.taskId; 5519 rti.baseIntent = new Intent( 5520 tr.intent != null ? tr.intent : tr.affinityIntent); 5521 if (!detailed) { 5522 rti.baseIntent.replaceExtras((Bundle)null); 5523 } 5524 rti.origActivity = tr.origActivity; 5525 rti.description = tr.lastDescription; 5526 5527 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5528 // Check whether this activity is currently available. 5529 try { 5530 if (rti.origActivity != null) { 5531 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId) 5532 == null) { 5533 continue; 5534 } 5535 } else if (rti.baseIntent != null) { 5536 if (pm.queryIntentActivities(rti.baseIntent, 5537 null, 0, callingUserId) == null) { 5538 continue; 5539 } 5540 } 5541 } catch (RemoteException e) { 5542 // Will never happen. 5543 } 5544 } 5545 5546 res.add(rti); 5547 maxNum--; 5548 } 5549 } 5550 return res; 5551 } 5552 } 5553 5554 private TaskRecord taskForIdLocked(int id) { 5555 final int N = mRecentTasks.size(); 5556 for (int i=0; i<N; i++) { 5557 TaskRecord tr = mRecentTasks.get(i); 5558 if (tr.taskId == id) { 5559 return tr; 5560 } 5561 } 5562 return null; 5563 } 5564 5565 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5566 synchronized (this) { 5567 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5568 "getTaskThumbnails()"); 5569 TaskRecord tr = taskForIdLocked(id); 5570 if (tr != null) { 5571 return mMainStack.getTaskThumbnailsLocked(tr); 5572 } 5573 } 5574 return null; 5575 } 5576 5577 public boolean removeSubTask(int taskId, int subTaskIndex) { 5578 synchronized (this) { 5579 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5580 "removeSubTask()"); 5581 long ident = Binder.clearCallingIdentity(); 5582 try { 5583 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5584 true) != null; 5585 } finally { 5586 Binder.restoreCallingIdentity(ident); 5587 } 5588 } 5589 } 5590 5591 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5592 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5593 Intent baseIntent = new Intent( 5594 tr.intent != null ? tr.intent : tr.affinityIntent); 5595 ComponentName component = baseIntent.getComponent(); 5596 if (component == null) { 5597 Slog.w(TAG, "Now component for base intent of task: " + tr); 5598 return; 5599 } 5600 5601 // Find any running services associated with this app. 5602 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5603 5604 if (killProcesses) { 5605 // Find any running processes associated with this app. 5606 final String pkg = component.getPackageName(); 5607 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5608 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5609 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5610 for (int i=0; i<uids.size(); i++) { 5611 ProcessRecord proc = uids.valueAt(i); 5612 if (proc.userId != tr.userId) { 5613 continue; 5614 } 5615 if (!proc.pkgList.contains(pkg)) { 5616 continue; 5617 } 5618 procs.add(proc); 5619 } 5620 } 5621 5622 // Kill the running processes. 5623 for (int i=0; i<procs.size(); i++) { 5624 ProcessRecord pr = procs.get(i); 5625 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5626 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5627 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5628 pr.processName, pr.setAdj, "remove task"); 5629 pr.killedBackground = true; 5630 Process.killProcessQuiet(pr.pid); 5631 } else { 5632 pr.waitingToKill = "remove task"; 5633 } 5634 } 5635 } 5636 } 5637 5638 public boolean removeTask(int taskId, int flags) { 5639 synchronized (this) { 5640 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5641 "removeTask()"); 5642 long ident = Binder.clearCallingIdentity(); 5643 try { 5644 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5645 false); 5646 if (r != null) { 5647 mRecentTasks.remove(r.task); 5648 cleanUpRemovedTaskLocked(r.task, flags); 5649 return true; 5650 } else { 5651 TaskRecord tr = null; 5652 int i=0; 5653 while (i < mRecentTasks.size()) { 5654 TaskRecord t = mRecentTasks.get(i); 5655 if (t.taskId == taskId) { 5656 tr = t; 5657 break; 5658 } 5659 i++; 5660 } 5661 if (tr != null) { 5662 if (tr.numActivities <= 0) { 5663 // Caller is just removing a recent task that is 5664 // not actively running. That is easy! 5665 mRecentTasks.remove(i); 5666 cleanUpRemovedTaskLocked(tr, flags); 5667 return true; 5668 } else { 5669 Slog.w(TAG, "removeTask: task " + taskId 5670 + " does not have activities to remove, " 5671 + " but numActivities=" + tr.numActivities 5672 + ": " + tr); 5673 } 5674 } 5675 } 5676 } finally { 5677 Binder.restoreCallingIdentity(ident); 5678 } 5679 } 5680 return false; 5681 } 5682 5683 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5684 int j; 5685 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5686 TaskRecord jt = startTask; 5687 5688 // First look backwards 5689 for (j=startIndex-1; j>=0; j--) { 5690 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5691 if (r.task != jt) { 5692 jt = r.task; 5693 if (affinity.equals(jt.affinity)) { 5694 return j; 5695 } 5696 } 5697 } 5698 5699 // Now look forwards 5700 final int N = mMainStack.mHistory.size(); 5701 jt = startTask; 5702 for (j=startIndex+1; j<N; j++) { 5703 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5704 if (r.task != jt) { 5705 if (affinity.equals(jt.affinity)) { 5706 return j; 5707 } 5708 jt = r.task; 5709 } 5710 } 5711 5712 // Might it be at the top? 5713 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5714 return N-1; 5715 } 5716 5717 return -1; 5718 } 5719 5720 /** 5721 * TODO: Add mController hook 5722 */ 5723 public void moveTaskToFront(int task, int flags, Bundle options) { 5724 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5725 "moveTaskToFront()"); 5726 5727 synchronized(this) { 5728 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5729 Binder.getCallingUid(), "Task to front")) { 5730 ActivityOptions.abort(options); 5731 return; 5732 } 5733 final long origId = Binder.clearCallingIdentity(); 5734 try { 5735 TaskRecord tr = taskForIdLocked(task); 5736 if (tr != null) { 5737 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5738 mMainStack.mUserLeaving = true; 5739 } 5740 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5741 // Caller wants the home activity moved with it. To accomplish this, 5742 // we'll just move the home task to the top first. 5743 mMainStack.moveHomeToFrontLocked(); 5744 } 5745 mMainStack.moveTaskToFrontLocked(tr, null, options); 5746 return; 5747 } 5748 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5749 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5750 if (hr.task.taskId == task) { 5751 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5752 mMainStack.mUserLeaving = true; 5753 } 5754 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5755 // Caller wants the home activity moved with it. To accomplish this, 5756 // we'll just move the home task to the top first. 5757 mMainStack.moveHomeToFrontLocked(); 5758 } 5759 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5760 return; 5761 } 5762 } 5763 } finally { 5764 Binder.restoreCallingIdentity(origId); 5765 } 5766 ActivityOptions.abort(options); 5767 } 5768 } 5769 5770 public void moveTaskToBack(int task) { 5771 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5772 "moveTaskToBack()"); 5773 5774 synchronized(this) { 5775 if (mMainStack.mResumedActivity != null 5776 && mMainStack.mResumedActivity.task.taskId == task) { 5777 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5778 Binder.getCallingUid(), "Task to back")) { 5779 return; 5780 } 5781 } 5782 final long origId = Binder.clearCallingIdentity(); 5783 mMainStack.moveTaskToBackLocked(task, null); 5784 Binder.restoreCallingIdentity(origId); 5785 } 5786 } 5787 5788 /** 5789 * Moves an activity, and all of the other activities within the same task, to the bottom 5790 * of the history stack. The activity's order within the task is unchanged. 5791 * 5792 * @param token A reference to the activity we wish to move 5793 * @param nonRoot If false then this only works if the activity is the root 5794 * of a task; if true it will work for any activity in a task. 5795 * @return Returns true if the move completed, false if not. 5796 */ 5797 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5798 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5799 synchronized(this) { 5800 final long origId = Binder.clearCallingIdentity(); 5801 int taskId = getTaskForActivityLocked(token, !nonRoot); 5802 if (taskId >= 0) { 5803 return mMainStack.moveTaskToBackLocked(taskId, null); 5804 } 5805 Binder.restoreCallingIdentity(origId); 5806 } 5807 return false; 5808 } 5809 5810 public void moveTaskBackwards(int task) { 5811 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5812 "moveTaskBackwards()"); 5813 5814 synchronized(this) { 5815 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5816 Binder.getCallingUid(), "Task backwards")) { 5817 return; 5818 } 5819 final long origId = Binder.clearCallingIdentity(); 5820 moveTaskBackwardsLocked(task); 5821 Binder.restoreCallingIdentity(origId); 5822 } 5823 } 5824 5825 private final void moveTaskBackwardsLocked(int task) { 5826 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5827 } 5828 5829 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5830 synchronized(this) { 5831 return getTaskForActivityLocked(token, onlyRoot); 5832 } 5833 } 5834 5835 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5836 final int N = mMainStack.mHistory.size(); 5837 TaskRecord lastTask = null; 5838 for (int i=0; i<N; i++) { 5839 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5840 if (r.appToken == token) { 5841 if (!onlyRoot || lastTask != r.task) { 5842 return r.task.taskId; 5843 } 5844 return -1; 5845 } 5846 lastTask = r.task; 5847 } 5848 5849 return -1; 5850 } 5851 5852 // ========================================================= 5853 // THUMBNAILS 5854 // ========================================================= 5855 5856 public void reportThumbnail(IBinder token, 5857 Bitmap thumbnail, CharSequence description) { 5858 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5859 final long origId = Binder.clearCallingIdentity(); 5860 sendPendingThumbnail(null, token, thumbnail, description, true); 5861 Binder.restoreCallingIdentity(origId); 5862 } 5863 5864 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5865 Bitmap thumbnail, CharSequence description, boolean always) { 5866 TaskRecord task = null; 5867 ArrayList receivers = null; 5868 5869 //System.out.println("Send pending thumbnail: " + r); 5870 5871 synchronized(this) { 5872 if (r == null) { 5873 r = mMainStack.isInStackLocked(token); 5874 if (r == null) { 5875 return; 5876 } 5877 } 5878 if (thumbnail == null && r.thumbHolder != null) { 5879 thumbnail = r.thumbHolder.lastThumbnail; 5880 description = r.thumbHolder.lastDescription; 5881 } 5882 if (thumbnail == null && !always) { 5883 // If there is no thumbnail, and this entry is not actually 5884 // going away, then abort for now and pick up the next 5885 // thumbnail we get. 5886 return; 5887 } 5888 task = r.task; 5889 5890 int N = mPendingThumbnails.size(); 5891 int i=0; 5892 while (i<N) { 5893 PendingThumbnailsRecord pr = 5894 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5895 //System.out.println("Looking in " + pr.pendingRecords); 5896 if (pr.pendingRecords.remove(r)) { 5897 if (receivers == null) { 5898 receivers = new ArrayList(); 5899 } 5900 receivers.add(pr); 5901 if (pr.pendingRecords.size() == 0) { 5902 pr.finished = true; 5903 mPendingThumbnails.remove(i); 5904 N--; 5905 continue; 5906 } 5907 } 5908 i++; 5909 } 5910 } 5911 5912 if (receivers != null) { 5913 final int N = receivers.size(); 5914 for (int i=0; i<N; i++) { 5915 try { 5916 PendingThumbnailsRecord pr = 5917 (PendingThumbnailsRecord)receivers.get(i); 5918 pr.receiver.newThumbnail( 5919 task != null ? task.taskId : -1, thumbnail, description); 5920 if (pr.finished) { 5921 pr.receiver.finished(); 5922 } 5923 } catch (Exception e) { 5924 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5925 } 5926 } 5927 } 5928 } 5929 5930 // ========================================================= 5931 // CONTENT PROVIDERS 5932 // ========================================================= 5933 5934 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5935 List<ProviderInfo> providers = null; 5936 try { 5937 providers = AppGlobals.getPackageManager(). 5938 queryContentProviders(app.processName, app.uid, 5939 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5940 } catch (RemoteException ex) { 5941 } 5942 if (DEBUG_MU) 5943 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 5944 int userId = app.userId; 5945 if (providers != null) { 5946 int N = providers.size(); 5947 for (int i=0; i<N; i++) { 5948 ProviderInfo cpi = 5949 (ProviderInfo)providers.get(i); 5950 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 5951 cpi.name, cpi.flags); 5952 if (singleton && UserId.getUserId(app.uid) != 0) { 5953 // This is a singleton provider, but a user besides the 5954 // default user is asking to initialize a process it runs 5955 // in... well, no, it doesn't actually run in this process, 5956 // it runs in the process of the default user. Get rid of it. 5957 providers.remove(i); 5958 N--; 5959 continue; 5960 } 5961 5962 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 5963 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 5964 if (cpr == null) { 5965 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 5966 mProviderMap.putProviderByClass(comp, cpr); 5967 } 5968 if (DEBUG_MU) 5969 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 5970 app.pubProviders.put(cpi.name, cpr); 5971 app.addPackage(cpi.applicationInfo.packageName); 5972 ensurePackageDexOpt(cpi.applicationInfo.packageName); 5973 } 5974 } 5975 return providers; 5976 } 5977 5978 /** 5979 * Check if {@link ProcessRecord} has a possible chance at accessing the 5980 * given {@link ProviderInfo}. Final permission checking is always done 5981 * in {@link ContentProvider}. 5982 */ 5983 private final String checkContentProviderPermissionLocked( 5984 ProviderInfo cpi, ProcessRecord r) { 5985 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 5986 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 5987 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 5988 cpi.applicationInfo.uid, cpi.exported) 5989 == PackageManager.PERMISSION_GRANTED) { 5990 return null; 5991 } 5992 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 5993 cpi.applicationInfo.uid, cpi.exported) 5994 == PackageManager.PERMISSION_GRANTED) { 5995 return null; 5996 } 5997 5998 PathPermission[] pps = cpi.pathPermissions; 5999 if (pps != null) { 6000 int i = pps.length; 6001 while (i > 0) { 6002 i--; 6003 PathPermission pp = pps[i]; 6004 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6005 cpi.applicationInfo.uid, cpi.exported) 6006 == PackageManager.PERMISSION_GRANTED) { 6007 return null; 6008 } 6009 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6010 cpi.applicationInfo.uid, cpi.exported) 6011 == PackageManager.PERMISSION_GRANTED) { 6012 return null; 6013 } 6014 } 6015 } 6016 6017 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6018 if (perms != null) { 6019 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6020 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6021 return null; 6022 } 6023 } 6024 } 6025 6026 String msg; 6027 if (!cpi.exported) { 6028 msg = "Permission Denial: opening provider " + cpi.name 6029 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6030 + ", uid=" + callingUid + ") that is not exported from uid " 6031 + cpi.applicationInfo.uid; 6032 } else { 6033 msg = "Permission Denial: opening provider " + cpi.name 6034 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6035 + ", uid=" + callingUid + ") requires " 6036 + cpi.readPermission + " or " + cpi.writePermission; 6037 } 6038 Slog.w(TAG, msg); 6039 return msg; 6040 } 6041 6042 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6043 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6044 if (r != null) { 6045 for (int i=0; i<r.conProviders.size(); i++) { 6046 ContentProviderConnection conn = r.conProviders.get(i); 6047 if (conn.provider == cpr) { 6048 if (DEBUG_PROVIDER) Slog.v(TAG, 6049 "Adding provider requested by " 6050 + r.processName + " from process " 6051 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6052 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6053 if (stable) { 6054 conn.stableCount++; 6055 conn.numStableIncs++; 6056 } else { 6057 conn.unstableCount++; 6058 conn.numUnstableIncs++; 6059 } 6060 return conn; 6061 } 6062 } 6063 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6064 if (stable) { 6065 conn.stableCount = 1; 6066 conn.numStableIncs = 1; 6067 } else { 6068 conn.unstableCount = 1; 6069 conn.numUnstableIncs = 1; 6070 } 6071 cpr.connections.add(conn); 6072 r.conProviders.add(conn); 6073 return conn; 6074 } 6075 cpr.addExternalProcessHandleLocked(externalProcessToken); 6076 return null; 6077 } 6078 6079 boolean decProviderCountLocked(ContentProviderConnection conn, 6080 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6081 if (conn != null) { 6082 cpr = conn.provider; 6083 if (DEBUG_PROVIDER) Slog.v(TAG, 6084 "Removing provider requested by " 6085 + conn.client.processName + " from process " 6086 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6087 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6088 if (stable) { 6089 conn.stableCount--; 6090 } else { 6091 conn.unstableCount--; 6092 } 6093 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6094 cpr.connections.remove(conn); 6095 conn.client.conProviders.remove(conn); 6096 return true; 6097 } 6098 return false; 6099 } 6100 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6101 return false; 6102 } 6103 6104 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6105 String name, IBinder token, boolean stable) { 6106 ContentProviderRecord cpr; 6107 ContentProviderConnection conn = null; 6108 ProviderInfo cpi = null; 6109 6110 synchronized(this) { 6111 ProcessRecord r = null; 6112 if (caller != null) { 6113 r = getRecordForAppLocked(caller); 6114 if (r == null) { 6115 throw new SecurityException( 6116 "Unable to find app for caller " + caller 6117 + " (pid=" + Binder.getCallingPid() 6118 + ") when getting content provider " + name); 6119 } 6120 } 6121 6122 // First check if this content provider has been published... 6123 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6124 cpr = mProviderMap.getProviderByName(name, userId); 6125 boolean providerRunning = cpr != null; 6126 if (providerRunning) { 6127 cpi = cpr.info; 6128 String msg; 6129 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6130 throw new SecurityException(msg); 6131 } 6132 6133 if (r != null && cpr.canRunHere(r)) { 6134 // This provider has been published or is in the process 6135 // of being published... but it is also allowed to run 6136 // in the caller's process, so don't make a connection 6137 // and just let the caller instantiate its own instance. 6138 ContentProviderHolder holder = cpr.newHolder(null); 6139 // don't give caller the provider object, it needs 6140 // to make its own. 6141 holder.provider = null; 6142 return holder; 6143 } 6144 6145 final long origId = Binder.clearCallingIdentity(); 6146 6147 // In this case the provider instance already exists, so we can 6148 // return it right away. 6149 conn = incProviderCountLocked(r, cpr, token, stable); 6150 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6151 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6152 // If this is a perceptible app accessing the provider, 6153 // make sure to count it as being accessed and thus 6154 // back up on the LRU list. This is good because 6155 // content providers are often expensive to start. 6156 updateLruProcessLocked(cpr.proc, false, true); 6157 } 6158 } 6159 6160 if (cpr.proc != null) { 6161 if (false) { 6162 if (cpr.name.flattenToShortString().equals( 6163 "com.android.providers.calendar/.CalendarProvider2")) { 6164 Slog.v(TAG, "****************** KILLING " 6165 + cpr.name.flattenToShortString()); 6166 Process.killProcess(cpr.proc.pid); 6167 } 6168 } 6169 boolean success = updateOomAdjLocked(cpr.proc); 6170 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6171 // NOTE: there is still a race here where a signal could be 6172 // pending on the process even though we managed to update its 6173 // adj level. Not sure what to do about this, but at least 6174 // the race is now smaller. 6175 if (!success) { 6176 // Uh oh... it looks like the provider's process 6177 // has been killed on us. We need to wait for a new 6178 // process to be started, and make sure its death 6179 // doesn't kill our process. 6180 Slog.i(TAG, 6181 "Existing provider " + cpr.name.flattenToShortString() 6182 + " is crashing; detaching " + r); 6183 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6184 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6185 if (!lastRef) { 6186 // This wasn't the last ref our process had on 6187 // the provider... we have now been killed, bail. 6188 return null; 6189 } 6190 providerRunning = false; 6191 conn = null; 6192 } 6193 } 6194 6195 Binder.restoreCallingIdentity(origId); 6196 } 6197 6198 boolean singleton; 6199 if (!providerRunning) { 6200 try { 6201 cpi = AppGlobals.getPackageManager(). 6202 resolveContentProvider(name, 6203 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6204 } catch (RemoteException ex) { 6205 } 6206 if (cpi == null) { 6207 return null; 6208 } 6209 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6210 cpi.name, cpi.flags); 6211 if (singleton) { 6212 userId = 0; 6213 } 6214 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6215 6216 String msg; 6217 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6218 throw new SecurityException(msg); 6219 } 6220 6221 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6222 && !cpi.processName.equals("system")) { 6223 // If this content provider does not run in the system 6224 // process, and the system is not yet ready to run other 6225 // processes, then fail fast instead of hanging. 6226 throw new IllegalArgumentException( 6227 "Attempt to launch content provider before system ready"); 6228 } 6229 6230 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6231 cpr = mProviderMap.getProviderByClass(comp, userId); 6232 final boolean firstClass = cpr == null; 6233 if (firstClass) { 6234 try { 6235 ApplicationInfo ai = 6236 AppGlobals.getPackageManager(). 6237 getApplicationInfo( 6238 cpi.applicationInfo.packageName, 6239 STOCK_PM_FLAGS, userId); 6240 if (ai == null) { 6241 Slog.w(TAG, "No package info for content provider " 6242 + cpi.name); 6243 return null; 6244 } 6245 ai = getAppInfoForUser(ai, userId); 6246 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6247 } catch (RemoteException ex) { 6248 // pm is in same process, this will never happen. 6249 } 6250 } 6251 6252 if (r != null && cpr.canRunHere(r)) { 6253 // If this is a multiprocess provider, then just return its 6254 // info and allow the caller to instantiate it. Only do 6255 // this if the provider is the same user as the caller's 6256 // process, or can run as root (so can be in any process). 6257 return cpr.newHolder(null); 6258 } 6259 6260 if (DEBUG_PROVIDER) { 6261 RuntimeException e = new RuntimeException("here"); 6262 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6263 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6264 } 6265 6266 // This is single process, and our app is now connecting to it. 6267 // See if we are already in the process of launching this 6268 // provider. 6269 final int N = mLaunchingProviders.size(); 6270 int i; 6271 for (i=0; i<N; i++) { 6272 if (mLaunchingProviders.get(i) == cpr) { 6273 break; 6274 } 6275 } 6276 6277 // If the provider is not already being launched, then get it 6278 // started. 6279 if (i >= N) { 6280 final long origId = Binder.clearCallingIdentity(); 6281 6282 try { 6283 // Content provider is now in use, its package can't be stopped. 6284 try { 6285 AppGlobals.getPackageManager().setPackageStoppedState( 6286 cpr.appInfo.packageName, false, userId); 6287 } catch (RemoteException e) { 6288 } catch (IllegalArgumentException e) { 6289 Slog.w(TAG, "Failed trying to unstop package " 6290 + cpr.appInfo.packageName + ": " + e); 6291 } 6292 6293 ProcessRecord proc = startProcessLocked(cpi.processName, 6294 cpr.appInfo, false, 0, "content provider", 6295 new ComponentName(cpi.applicationInfo.packageName, 6296 cpi.name), false, false); 6297 if (proc == null) { 6298 Slog.w(TAG, "Unable to launch app " 6299 + cpi.applicationInfo.packageName + "/" 6300 + cpi.applicationInfo.uid + " for provider " 6301 + name + ": process is bad"); 6302 return null; 6303 } 6304 cpr.launchingApp = proc; 6305 mLaunchingProviders.add(cpr); 6306 } finally { 6307 Binder.restoreCallingIdentity(origId); 6308 } 6309 } 6310 6311 // Make sure the provider is published (the same provider class 6312 // may be published under multiple names). 6313 if (firstClass) { 6314 mProviderMap.putProviderByClass(comp, cpr); 6315 } 6316 6317 mProviderMap.putProviderByName(name, cpr); 6318 conn = incProviderCountLocked(r, cpr, token, stable); 6319 if (conn != null) { 6320 conn.waiting = true; 6321 } 6322 } 6323 } 6324 6325 // Wait for the provider to be published... 6326 synchronized (cpr) { 6327 while (cpr.provider == null) { 6328 if (cpr.launchingApp == null) { 6329 Slog.w(TAG, "Unable to launch app " 6330 + cpi.applicationInfo.packageName + "/" 6331 + cpi.applicationInfo.uid + " for provider " 6332 + name + ": launching app became null"); 6333 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6334 cpi.applicationInfo.packageName, 6335 cpi.applicationInfo.uid, name); 6336 return null; 6337 } 6338 try { 6339 if (DEBUG_MU) { 6340 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6341 + cpr.launchingApp); 6342 } 6343 if (conn != null) { 6344 conn.waiting = true; 6345 } 6346 cpr.wait(); 6347 } catch (InterruptedException ex) { 6348 } finally { 6349 if (conn != null) { 6350 conn.waiting = false; 6351 } 6352 } 6353 } 6354 } 6355 return cpr != null ? cpr.newHolder(conn) : null; 6356 } 6357 6358 public final ContentProviderHolder getContentProvider( 6359 IApplicationThread caller, String name, boolean stable) { 6360 enforceNotIsolatedCaller("getContentProvider"); 6361 if (caller == null) { 6362 String msg = "null IApplicationThread when getting content provider " 6363 + name; 6364 Slog.w(TAG, msg); 6365 throw new SecurityException(msg); 6366 } 6367 6368 return getContentProviderImpl(caller, name, null, stable); 6369 } 6370 6371 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6372 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6373 "Do not have permission in call getContentProviderExternal()"); 6374 return getContentProviderExternalUnchecked(name, token); 6375 } 6376 6377 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6378 return getContentProviderImpl(null, name, token, true); 6379 } 6380 6381 /** 6382 * Drop a content provider from a ProcessRecord's bookkeeping 6383 * @param cpr 6384 */ 6385 public void removeContentProvider(IBinder connection, boolean stable) { 6386 enforceNotIsolatedCaller("removeContentProvider"); 6387 synchronized (this) { 6388 ContentProviderConnection conn; 6389 try { 6390 conn = (ContentProviderConnection)connection; 6391 } catch (ClassCastException e) { 6392 String msg ="removeContentProvider: " + connection 6393 + " not a ContentProviderConnection"; 6394 Slog.w(TAG, msg); 6395 throw new IllegalArgumentException(msg); 6396 } 6397 if (conn == null) { 6398 throw new NullPointerException("connection is null"); 6399 } 6400 if (decProviderCountLocked(conn, null, null, stable)) { 6401 updateOomAdjLocked(); 6402 } 6403 } 6404 } 6405 6406 public void removeContentProviderExternal(String name, IBinder token) { 6407 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6408 "Do not have permission in call removeContentProviderExternal()"); 6409 removeContentProviderExternalUnchecked(name, token); 6410 } 6411 6412 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6413 synchronized (this) { 6414 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6415 Binder.getOrigCallingUser()); 6416 if(cpr == null) { 6417 //remove from mProvidersByClass 6418 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6419 return; 6420 } 6421 6422 //update content provider record entry info 6423 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6424 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6425 Binder.getOrigCallingUser()); 6426 if (localCpr.hasExternalProcessHandles()) { 6427 if (localCpr.removeExternalProcessHandleLocked(token)) { 6428 updateOomAdjLocked(); 6429 } else { 6430 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6431 + " with no external reference for token: " 6432 + token + "."); 6433 } 6434 } else { 6435 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6436 + " with no external references."); 6437 } 6438 } 6439 } 6440 6441 public final void publishContentProviders(IApplicationThread caller, 6442 List<ContentProviderHolder> providers) { 6443 if (providers == null) { 6444 return; 6445 } 6446 6447 enforceNotIsolatedCaller("publishContentProviders"); 6448 synchronized (this) { 6449 final ProcessRecord r = getRecordForAppLocked(caller); 6450 if (DEBUG_MU) 6451 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6452 if (r == null) { 6453 throw new SecurityException( 6454 "Unable to find app for caller " + caller 6455 + " (pid=" + Binder.getCallingPid() 6456 + ") when publishing content providers"); 6457 } 6458 6459 final long origId = Binder.clearCallingIdentity(); 6460 6461 final int N = providers.size(); 6462 for (int i=0; i<N; i++) { 6463 ContentProviderHolder src = providers.get(i); 6464 if (src == null || src.info == null || src.provider == null) { 6465 continue; 6466 } 6467 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6468 if (DEBUG_MU) 6469 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6470 if (dst != null) { 6471 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6472 mProviderMap.putProviderByClass(comp, dst); 6473 String names[] = dst.info.authority.split(";"); 6474 for (int j = 0; j < names.length; j++) { 6475 mProviderMap.putProviderByName(names[j], dst); 6476 } 6477 6478 int NL = mLaunchingProviders.size(); 6479 int j; 6480 for (j=0; j<NL; j++) { 6481 if (mLaunchingProviders.get(j) == dst) { 6482 mLaunchingProviders.remove(j); 6483 j--; 6484 NL--; 6485 } 6486 } 6487 synchronized (dst) { 6488 dst.provider = src.provider; 6489 dst.proc = r; 6490 dst.notifyAll(); 6491 } 6492 updateOomAdjLocked(r); 6493 } 6494 } 6495 6496 Binder.restoreCallingIdentity(origId); 6497 } 6498 } 6499 6500 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6501 ContentProviderConnection conn; 6502 try { 6503 conn = (ContentProviderConnection)connection; 6504 } catch (ClassCastException e) { 6505 String msg ="refContentProvider: " + connection 6506 + " not a ContentProviderConnection"; 6507 Slog.w(TAG, msg); 6508 throw new IllegalArgumentException(msg); 6509 } 6510 if (conn == null) { 6511 throw new NullPointerException("connection is null"); 6512 } 6513 6514 synchronized (this) { 6515 if (stable > 0) { 6516 conn.numStableIncs += stable; 6517 } 6518 stable = conn.stableCount + stable; 6519 if (stable < 0) { 6520 throw new IllegalStateException("stableCount < 0: " + stable); 6521 } 6522 6523 if (unstable > 0) { 6524 conn.numUnstableIncs += unstable; 6525 } 6526 unstable = conn.unstableCount + unstable; 6527 if (unstable < 0) { 6528 throw new IllegalStateException("unstableCount < 0: " + unstable); 6529 } 6530 6531 if ((stable+unstable) <= 0) { 6532 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6533 + stable + " unstable=" + unstable); 6534 } 6535 conn.stableCount = stable; 6536 conn.unstableCount = unstable; 6537 return !conn.dead; 6538 } 6539 } 6540 6541 public void unstableProviderDied(IBinder connection) { 6542 ContentProviderConnection conn; 6543 try { 6544 conn = (ContentProviderConnection)connection; 6545 } catch (ClassCastException e) { 6546 String msg ="refContentProvider: " + connection 6547 + " not a ContentProviderConnection"; 6548 Slog.w(TAG, msg); 6549 throw new IllegalArgumentException(msg); 6550 } 6551 if (conn == null) { 6552 throw new NullPointerException("connection is null"); 6553 } 6554 6555 // Safely retrieve the content provider associated with the connection. 6556 IContentProvider provider; 6557 synchronized (this) { 6558 provider = conn.provider.provider; 6559 } 6560 6561 if (provider == null) { 6562 // Um, yeah, we're way ahead of you. 6563 return; 6564 } 6565 6566 // Make sure the caller is being honest with us. 6567 if (provider.asBinder().pingBinder()) { 6568 // Er, no, still looks good to us. 6569 synchronized (this) { 6570 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6571 + " says " + conn + " died, but we don't agree"); 6572 return; 6573 } 6574 } 6575 6576 // Well look at that! It's dead! 6577 synchronized (this) { 6578 if (conn.provider.provider != provider) { 6579 // But something changed... good enough. 6580 return; 6581 } 6582 6583 ProcessRecord proc = conn.provider.proc; 6584 if (proc == null || proc.thread == null) { 6585 // Seems like the process is already cleaned up. 6586 return; 6587 } 6588 6589 // As far as we're concerned, this is just like receiving a 6590 // death notification... just a bit prematurely. 6591 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6592 + ") early provider death"); 6593 final long ident = Binder.clearCallingIdentity(); 6594 try { 6595 appDiedLocked(proc, proc.pid, proc.thread); 6596 } finally { 6597 Binder.restoreCallingIdentity(ident); 6598 } 6599 } 6600 } 6601 6602 public static final void installSystemProviders() { 6603 List<ProviderInfo> providers; 6604 synchronized (mSelf) { 6605 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6606 providers = mSelf.generateApplicationProvidersLocked(app); 6607 if (providers != null) { 6608 for (int i=providers.size()-1; i>=0; i--) { 6609 ProviderInfo pi = (ProviderInfo)providers.get(i); 6610 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6611 Slog.w(TAG, "Not installing system proc provider " + pi.name 6612 + ": not system .apk"); 6613 providers.remove(i); 6614 } 6615 } 6616 } 6617 } 6618 if (providers != null) { 6619 mSystemThread.installSystemProviders(providers); 6620 } 6621 6622 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6623 6624 mSelf.mUsageStatsService.monitorPackages(); 6625 } 6626 6627 /** 6628 * Allows app to retrieve the MIME type of a URI without having permission 6629 * to access its content provider. 6630 * 6631 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6632 * 6633 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6634 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6635 */ 6636 public String getProviderMimeType(Uri uri) { 6637 enforceNotIsolatedCaller("getProviderMimeType"); 6638 final String name = uri.getAuthority(); 6639 final long ident = Binder.clearCallingIdentity(); 6640 ContentProviderHolder holder = null; 6641 6642 try { 6643 holder = getContentProviderExternalUnchecked(name, null); 6644 if (holder != null) { 6645 return holder.provider.getType(uri); 6646 } 6647 } catch (RemoteException e) { 6648 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6649 return null; 6650 } finally { 6651 if (holder != null) { 6652 removeContentProviderExternalUnchecked(name, null); 6653 } 6654 Binder.restoreCallingIdentity(ident); 6655 } 6656 6657 return null; 6658 } 6659 6660 // ========================================================= 6661 // GLOBAL MANAGEMENT 6662 // ========================================================= 6663 6664 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6665 ApplicationInfo info, String customProcess, boolean isolated) { 6666 String proc = customProcess != null ? customProcess : info.processName; 6667 BatteryStatsImpl.Uid.Proc ps = null; 6668 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6669 int uid = info.uid; 6670 if (isolated) { 6671 int userId = UserId.getUserId(uid); 6672 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6673 uid = 0; 6674 while (true) { 6675 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6676 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6677 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6678 } 6679 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6680 mNextIsolatedProcessUid++; 6681 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6682 // No process for this uid, use it. 6683 break; 6684 } 6685 stepsLeft--; 6686 if (stepsLeft <= 0) { 6687 return null; 6688 } 6689 } 6690 } 6691 synchronized (stats) { 6692 ps = stats.getProcessStatsLocked(info.uid, proc); 6693 } 6694 return new ProcessRecord(ps, thread, info, proc, uid); 6695 } 6696 6697 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6698 ProcessRecord app; 6699 if (!isolated) { 6700 app = getProcessRecordLocked(info.processName, info.uid); 6701 } else { 6702 app = null; 6703 } 6704 6705 if (app == null) { 6706 app = newProcessRecordLocked(null, info, null, isolated); 6707 mProcessNames.put(info.processName, app.uid, app); 6708 if (isolated) { 6709 mIsolatedProcesses.put(app.uid, app); 6710 } 6711 updateLruProcessLocked(app, true, true); 6712 } 6713 6714 // This package really, really can not be stopped. 6715 try { 6716 AppGlobals.getPackageManager().setPackageStoppedState( 6717 info.packageName, false, UserId.getUserId(app.uid)); 6718 } catch (RemoteException e) { 6719 } catch (IllegalArgumentException e) { 6720 Slog.w(TAG, "Failed trying to unstop package " 6721 + info.packageName + ": " + e); 6722 } 6723 6724 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6725 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6726 app.persistent = true; 6727 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6728 } 6729 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6730 mPersistentStartingProcesses.add(app); 6731 startProcessLocked(app, "added application", app.processName); 6732 } 6733 6734 return app; 6735 } 6736 6737 public void unhandledBack() { 6738 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6739 "unhandledBack()"); 6740 6741 synchronized(this) { 6742 int count = mMainStack.mHistory.size(); 6743 if (DEBUG_SWITCH) Slog.d( 6744 TAG, "Performing unhandledBack(): stack size = " + count); 6745 if (count > 1) { 6746 final long origId = Binder.clearCallingIdentity(); 6747 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6748 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6749 Binder.restoreCallingIdentity(origId); 6750 } 6751 } 6752 } 6753 6754 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6755 enforceNotIsolatedCaller("openContentUri"); 6756 String name = uri.getAuthority(); 6757 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6758 ParcelFileDescriptor pfd = null; 6759 if (cph != null) { 6760 // We record the binder invoker's uid in thread-local storage before 6761 // going to the content provider to open the file. Later, in the code 6762 // that handles all permissions checks, we look for this uid and use 6763 // that rather than the Activity Manager's own uid. The effect is that 6764 // we do the check against the caller's permissions even though it looks 6765 // to the content provider like the Activity Manager itself is making 6766 // the request. 6767 sCallerIdentity.set(new Identity( 6768 Binder.getCallingPid(), Binder.getCallingUid())); 6769 try { 6770 pfd = cph.provider.openFile(uri, "r"); 6771 } catch (FileNotFoundException e) { 6772 // do nothing; pfd will be returned null 6773 } finally { 6774 // Ensure that whatever happens, we clean up the identity state 6775 sCallerIdentity.remove(); 6776 } 6777 6778 // We've got the fd now, so we're done with the provider. 6779 removeContentProviderExternalUnchecked(name, null); 6780 } else { 6781 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6782 } 6783 return pfd; 6784 } 6785 6786 // Actually is sleeping or shutting down or whatever else in the future 6787 // is an inactive state. 6788 public boolean isSleeping() { 6789 return mSleeping || mShuttingDown; 6790 } 6791 6792 public void goingToSleep() { 6793 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6794 != PackageManager.PERMISSION_GRANTED) { 6795 throw new SecurityException("Requires permission " 6796 + android.Manifest.permission.DEVICE_POWER); 6797 } 6798 6799 synchronized(this) { 6800 mWentToSleep = true; 6801 updateEventDispatchingLocked(); 6802 6803 if (!mSleeping) { 6804 mSleeping = true; 6805 mMainStack.stopIfSleepingLocked(); 6806 6807 // Initialize the wake times of all processes. 6808 checkExcessivePowerUsageLocked(false); 6809 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6810 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6811 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6812 } 6813 } 6814 } 6815 6816 public boolean shutdown(int timeout) { 6817 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6818 != PackageManager.PERMISSION_GRANTED) { 6819 throw new SecurityException("Requires permission " 6820 + android.Manifest.permission.SHUTDOWN); 6821 } 6822 6823 boolean timedout = false; 6824 6825 synchronized(this) { 6826 mShuttingDown = true; 6827 updateEventDispatchingLocked(); 6828 6829 if (mMainStack.mResumedActivity != null) { 6830 mMainStack.stopIfSleepingLocked(); 6831 final long endTime = System.currentTimeMillis() + timeout; 6832 while (mMainStack.mResumedActivity != null 6833 || mMainStack.mPausingActivity != null) { 6834 long delay = endTime - System.currentTimeMillis(); 6835 if (delay <= 0) { 6836 Slog.w(TAG, "Activity manager shutdown timed out"); 6837 timedout = true; 6838 break; 6839 } 6840 try { 6841 this.wait(); 6842 } catch (InterruptedException e) { 6843 } 6844 } 6845 } 6846 } 6847 6848 mUsageStatsService.shutdown(); 6849 mBatteryStatsService.shutdown(); 6850 6851 return timedout; 6852 } 6853 6854 public final void activitySlept(IBinder token) { 6855 if (localLOGV) Slog.v( 6856 TAG, "Activity slept: token=" + token); 6857 6858 ActivityRecord r = null; 6859 6860 final long origId = Binder.clearCallingIdentity(); 6861 6862 synchronized (this) { 6863 r = mMainStack.isInStackLocked(token); 6864 if (r != null) { 6865 mMainStack.activitySleptLocked(r); 6866 } 6867 } 6868 6869 Binder.restoreCallingIdentity(origId); 6870 } 6871 6872 private void comeOutOfSleepIfNeededLocked() { 6873 if (!mWentToSleep && !mLockScreenShown) { 6874 if (mSleeping) { 6875 mSleeping = false; 6876 mMainStack.awakeFromSleepingLocked(); 6877 mMainStack.resumeTopActivityLocked(null); 6878 } 6879 } 6880 } 6881 6882 public void wakingUp() { 6883 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6884 != PackageManager.PERMISSION_GRANTED) { 6885 throw new SecurityException("Requires permission " 6886 + android.Manifest.permission.DEVICE_POWER); 6887 } 6888 6889 synchronized(this) { 6890 mWentToSleep = false; 6891 updateEventDispatchingLocked(); 6892 comeOutOfSleepIfNeededLocked(); 6893 } 6894 } 6895 6896 private void updateEventDispatchingLocked() { 6897 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6898 } 6899 6900 public void setLockScreenShown(boolean shown) { 6901 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6902 != PackageManager.PERMISSION_GRANTED) { 6903 throw new SecurityException("Requires permission " 6904 + android.Manifest.permission.DEVICE_POWER); 6905 } 6906 6907 synchronized(this) { 6908 mLockScreenShown = shown; 6909 comeOutOfSleepIfNeededLocked(); 6910 } 6911 } 6912 6913 public void stopAppSwitches() { 6914 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6915 != PackageManager.PERMISSION_GRANTED) { 6916 throw new SecurityException("Requires permission " 6917 + android.Manifest.permission.STOP_APP_SWITCHES); 6918 } 6919 6920 synchronized(this) { 6921 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6922 + APP_SWITCH_DELAY_TIME; 6923 mDidAppSwitch = false; 6924 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6925 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6926 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6927 } 6928 } 6929 6930 public void resumeAppSwitches() { 6931 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6932 != PackageManager.PERMISSION_GRANTED) { 6933 throw new SecurityException("Requires permission " 6934 + android.Manifest.permission.STOP_APP_SWITCHES); 6935 } 6936 6937 synchronized(this) { 6938 // Note that we don't execute any pending app switches... we will 6939 // let those wait until either the timeout, or the next start 6940 // activity request. 6941 mAppSwitchesAllowedTime = 0; 6942 } 6943 } 6944 6945 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6946 String name) { 6947 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6948 return true; 6949 } 6950 6951 final int perm = checkComponentPermission( 6952 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6953 callingUid, -1, true); 6954 if (perm == PackageManager.PERMISSION_GRANTED) { 6955 return true; 6956 } 6957 6958 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6959 return false; 6960 } 6961 6962 public void setDebugApp(String packageName, boolean waitForDebugger, 6963 boolean persistent) { 6964 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 6965 "setDebugApp()"); 6966 6967 // Note that this is not really thread safe if there are multiple 6968 // callers into it at the same time, but that's not a situation we 6969 // care about. 6970 if (persistent) { 6971 final ContentResolver resolver = mContext.getContentResolver(); 6972 Settings.System.putString( 6973 resolver, Settings.System.DEBUG_APP, 6974 packageName); 6975 Settings.System.putInt( 6976 resolver, Settings.System.WAIT_FOR_DEBUGGER, 6977 waitForDebugger ? 1 : 0); 6978 } 6979 6980 synchronized (this) { 6981 if (!persistent) { 6982 mOrigDebugApp = mDebugApp; 6983 mOrigWaitForDebugger = mWaitForDebugger; 6984 } 6985 mDebugApp = packageName; 6986 mWaitForDebugger = waitForDebugger; 6987 mDebugTransient = !persistent; 6988 if (packageName != null) { 6989 final long origId = Binder.clearCallingIdentity(); 6990 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 6991 Binder.restoreCallingIdentity(origId); 6992 } 6993 } 6994 } 6995 6996 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 6997 synchronized (this) { 6998 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6999 if (!isDebuggable) { 7000 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7001 throw new SecurityException("Process not debuggable: " + app.packageName); 7002 } 7003 } 7004 7005 mOpenGlTraceApp = processName; 7006 } 7007 } 7008 7009 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7010 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7011 synchronized (this) { 7012 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7013 if (!isDebuggable) { 7014 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7015 throw new SecurityException("Process not debuggable: " + app.packageName); 7016 } 7017 } 7018 mProfileApp = processName; 7019 mProfileFile = profileFile; 7020 if (mProfileFd != null) { 7021 try { 7022 mProfileFd.close(); 7023 } catch (IOException e) { 7024 } 7025 mProfileFd = null; 7026 } 7027 mProfileFd = profileFd; 7028 mProfileType = 0; 7029 mAutoStopProfiler = autoStopProfiler; 7030 } 7031 } 7032 7033 public void setAlwaysFinish(boolean enabled) { 7034 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7035 "setAlwaysFinish()"); 7036 7037 Settings.System.putInt( 7038 mContext.getContentResolver(), 7039 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7040 7041 synchronized (this) { 7042 mAlwaysFinishActivities = enabled; 7043 } 7044 } 7045 7046 public void setActivityController(IActivityController controller) { 7047 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7048 "setActivityController()"); 7049 synchronized (this) { 7050 mController = controller; 7051 } 7052 } 7053 7054 public boolean isUserAMonkey() { 7055 // For now the fact that there is a controller implies 7056 // we have a monkey. 7057 synchronized (this) { 7058 return mController != null; 7059 } 7060 } 7061 7062 public void registerProcessObserver(IProcessObserver observer) { 7063 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7064 "registerProcessObserver()"); 7065 synchronized (this) { 7066 mProcessObservers.register(observer); 7067 } 7068 } 7069 7070 public void unregisterProcessObserver(IProcessObserver observer) { 7071 synchronized (this) { 7072 mProcessObservers.unregister(observer); 7073 } 7074 } 7075 7076 public void setImmersive(IBinder token, boolean immersive) { 7077 synchronized(this) { 7078 ActivityRecord r = mMainStack.isInStackLocked(token); 7079 if (r == null) { 7080 throw new IllegalArgumentException(); 7081 } 7082 r.immersive = immersive; 7083 } 7084 } 7085 7086 public boolean isImmersive(IBinder token) { 7087 synchronized (this) { 7088 ActivityRecord r = mMainStack.isInStackLocked(token); 7089 if (r == null) { 7090 throw new IllegalArgumentException(); 7091 } 7092 return r.immersive; 7093 } 7094 } 7095 7096 public boolean isTopActivityImmersive() { 7097 enforceNotIsolatedCaller("startActivity"); 7098 synchronized (this) { 7099 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7100 return (r != null) ? r.immersive : false; 7101 } 7102 } 7103 7104 public final void enterSafeMode() { 7105 synchronized(this) { 7106 // It only makes sense to do this before the system is ready 7107 // and started launching other packages. 7108 if (!mSystemReady) { 7109 try { 7110 AppGlobals.getPackageManager().enterSafeMode(); 7111 } catch (RemoteException e) { 7112 } 7113 } 7114 } 7115 } 7116 7117 public final void showSafeModeOverlay() { 7118 View v = LayoutInflater.from(mContext).inflate( 7119 com.android.internal.R.layout.safe_mode, null); 7120 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7121 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7122 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7123 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7124 lp.gravity = Gravity.BOTTOM | Gravity.START; 7125 lp.format = v.getBackground().getOpacity(); 7126 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7127 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7128 ((WindowManager)mContext.getSystemService( 7129 Context.WINDOW_SERVICE)).addView(v, lp); 7130 } 7131 7132 public void noteWakeupAlarm(IIntentSender sender) { 7133 if (!(sender instanceof PendingIntentRecord)) { 7134 return; 7135 } 7136 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7137 synchronized (stats) { 7138 if (mBatteryStatsService.isOnBattery()) { 7139 mBatteryStatsService.enforceCallingPermission(); 7140 PendingIntentRecord rec = (PendingIntentRecord)sender; 7141 int MY_UID = Binder.getCallingUid(); 7142 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7143 BatteryStatsImpl.Uid.Pkg pkg = 7144 stats.getPackageStatsLocked(uid, rec.key.packageName); 7145 pkg.incWakeupsLocked(); 7146 } 7147 } 7148 } 7149 7150 public boolean killPids(int[] pids, String pReason, boolean secure) { 7151 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7152 throw new SecurityException("killPids only available to the system"); 7153 } 7154 String reason = (pReason == null) ? "Unknown" : pReason; 7155 // XXX Note: don't acquire main activity lock here, because the window 7156 // manager calls in with its locks held. 7157 7158 boolean killed = false; 7159 synchronized (mPidsSelfLocked) { 7160 int[] types = new int[pids.length]; 7161 int worstType = 0; 7162 for (int i=0; i<pids.length; i++) { 7163 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7164 if (proc != null) { 7165 int type = proc.setAdj; 7166 types[i] = type; 7167 if (type > worstType) { 7168 worstType = type; 7169 } 7170 } 7171 } 7172 7173 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7174 // then constrain it so we will kill all hidden procs. 7175 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7176 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7177 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7178 } 7179 7180 // If this is not a secure call, don't let it kill processes that 7181 // are important. 7182 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7183 worstType = ProcessList.SERVICE_ADJ; 7184 } 7185 7186 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7187 for (int i=0; i<pids.length; i++) { 7188 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7189 if (proc == null) { 7190 continue; 7191 } 7192 int adj = proc.setAdj; 7193 if (adj >= worstType && !proc.killedBackground) { 7194 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7195 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7196 proc.processName, adj, reason); 7197 killed = true; 7198 proc.killedBackground = true; 7199 Process.killProcessQuiet(pids[i]); 7200 } 7201 } 7202 } 7203 return killed; 7204 } 7205 7206 @Override 7207 public boolean killProcessesBelowForeground(String reason) { 7208 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7209 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7210 } 7211 7212 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7213 } 7214 7215 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7216 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7217 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7218 } 7219 7220 boolean killed = false; 7221 synchronized (mPidsSelfLocked) { 7222 final int size = mPidsSelfLocked.size(); 7223 for (int i = 0; i < size; i++) { 7224 final int pid = mPidsSelfLocked.keyAt(i); 7225 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7226 if (proc == null) continue; 7227 7228 final int adj = proc.setAdj; 7229 if (adj > belowAdj && !proc.killedBackground) { 7230 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7231 EventLog.writeEvent( 7232 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7233 killed = true; 7234 proc.killedBackground = true; 7235 Process.killProcessQuiet(pid); 7236 } 7237 } 7238 } 7239 return killed; 7240 } 7241 7242 public final void startRunning(String pkg, String cls, String action, 7243 String data) { 7244 synchronized(this) { 7245 if (mStartRunning) { 7246 return; 7247 } 7248 mStartRunning = true; 7249 mTopComponent = pkg != null && cls != null 7250 ? new ComponentName(pkg, cls) : null; 7251 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7252 mTopData = data; 7253 if (!mSystemReady) { 7254 return; 7255 } 7256 } 7257 7258 systemReady(null); 7259 } 7260 7261 private void retrieveSettings() { 7262 final ContentResolver resolver = mContext.getContentResolver(); 7263 String debugApp = Settings.System.getString( 7264 resolver, Settings.System.DEBUG_APP); 7265 boolean waitForDebugger = Settings.System.getInt( 7266 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7267 boolean alwaysFinishActivities = Settings.System.getInt( 7268 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7269 7270 Configuration configuration = new Configuration(); 7271 Settings.System.getConfiguration(resolver, configuration); 7272 7273 synchronized (this) { 7274 mDebugApp = mOrigDebugApp = debugApp; 7275 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7276 mAlwaysFinishActivities = alwaysFinishActivities; 7277 // This happens before any activities are started, so we can 7278 // change mConfiguration in-place. 7279 updateConfigurationLocked(configuration, null, false, true); 7280 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7281 } 7282 } 7283 7284 public boolean testIsSystemReady() { 7285 // no need to synchronize(this) just to read & return the value 7286 return mSystemReady; 7287 } 7288 7289 private static File getCalledPreBootReceiversFile() { 7290 File dataDir = Environment.getDataDirectory(); 7291 File systemDir = new File(dataDir, "system"); 7292 File fname = new File(systemDir, "called_pre_boots.dat"); 7293 return fname; 7294 } 7295 7296 static final int LAST_DONE_VERSION = 10000; 7297 7298 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7299 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7300 File file = getCalledPreBootReceiversFile(); 7301 FileInputStream fis = null; 7302 try { 7303 fis = new FileInputStream(file); 7304 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7305 int fvers = dis.readInt(); 7306 if (fvers == LAST_DONE_VERSION) { 7307 String vers = dis.readUTF(); 7308 String codename = dis.readUTF(); 7309 String build = dis.readUTF(); 7310 if (android.os.Build.VERSION.RELEASE.equals(vers) 7311 && android.os.Build.VERSION.CODENAME.equals(codename) 7312 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7313 int num = dis.readInt(); 7314 while (num > 0) { 7315 num--; 7316 String pkg = dis.readUTF(); 7317 String cls = dis.readUTF(); 7318 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7319 } 7320 } 7321 } 7322 } catch (FileNotFoundException e) { 7323 } catch (IOException e) { 7324 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7325 } finally { 7326 if (fis != null) { 7327 try { 7328 fis.close(); 7329 } catch (IOException e) { 7330 } 7331 } 7332 } 7333 return lastDoneReceivers; 7334 } 7335 7336 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7337 File file = getCalledPreBootReceiversFile(); 7338 FileOutputStream fos = null; 7339 DataOutputStream dos = null; 7340 try { 7341 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7342 fos = new FileOutputStream(file); 7343 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7344 dos.writeInt(LAST_DONE_VERSION); 7345 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7346 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7347 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7348 dos.writeInt(list.size()); 7349 for (int i=0; i<list.size(); i++) { 7350 dos.writeUTF(list.get(i).getPackageName()); 7351 dos.writeUTF(list.get(i).getClassName()); 7352 } 7353 } catch (IOException e) { 7354 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7355 file.delete(); 7356 } finally { 7357 FileUtils.sync(fos); 7358 if (dos != null) { 7359 try { 7360 dos.close(); 7361 } catch (IOException e) { 7362 // TODO Auto-generated catch block 7363 e.printStackTrace(); 7364 } 7365 } 7366 } 7367 } 7368 7369 public void systemReady(final Runnable goingCallback) { 7370 synchronized(this) { 7371 if (mSystemReady) { 7372 if (goingCallback != null) goingCallback.run(); 7373 return; 7374 } 7375 7376 // Check to see if there are any update receivers to run. 7377 if (!mDidUpdate) { 7378 if (mWaitingUpdate) { 7379 return; 7380 } 7381 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7382 List<ResolveInfo> ris = null; 7383 try { 7384 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7385 intent, null, 0, 0); 7386 } catch (RemoteException e) { 7387 } 7388 if (ris != null) { 7389 for (int i=ris.size()-1; i>=0; i--) { 7390 if ((ris.get(i).activityInfo.applicationInfo.flags 7391 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7392 ris.remove(i); 7393 } 7394 } 7395 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7396 7397 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7398 7399 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7400 for (int i=0; i<ris.size(); i++) { 7401 ActivityInfo ai = ris.get(i).activityInfo; 7402 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7403 if (lastDoneReceivers.contains(comp)) { 7404 ris.remove(i); 7405 i--; 7406 } 7407 } 7408 7409 for (int i=0; i<ris.size(); i++) { 7410 ActivityInfo ai = ris.get(i).activityInfo; 7411 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7412 doneReceivers.add(comp); 7413 intent.setComponent(comp); 7414 IIntentReceiver finisher = null; 7415 if (i == ris.size()-1) { 7416 finisher = new IIntentReceiver.Stub() { 7417 public void performReceive(Intent intent, int resultCode, 7418 String data, Bundle extras, boolean ordered, 7419 boolean sticky) { 7420 // The raw IIntentReceiver interface is called 7421 // with the AM lock held, so redispatch to 7422 // execute our code without the lock. 7423 mHandler.post(new Runnable() { 7424 public void run() { 7425 synchronized (ActivityManagerService.this) { 7426 mDidUpdate = true; 7427 } 7428 writeLastDonePreBootReceivers(doneReceivers); 7429 showBootMessage(mContext.getText( 7430 R.string.android_upgrading_complete), 7431 false); 7432 systemReady(goingCallback); 7433 } 7434 }); 7435 } 7436 }; 7437 } 7438 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7439 /* TODO: Send this to all users */ 7440 broadcastIntentLocked(null, null, intent, null, finisher, 7441 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7442 0 /* UserId zero */); 7443 if (finisher != null) { 7444 mWaitingUpdate = true; 7445 } 7446 } 7447 } 7448 if (mWaitingUpdate) { 7449 return; 7450 } 7451 mDidUpdate = true; 7452 } 7453 7454 mSystemReady = true; 7455 if (!mStartRunning) { 7456 return; 7457 } 7458 } 7459 7460 ArrayList<ProcessRecord> procsToKill = null; 7461 synchronized(mPidsSelfLocked) { 7462 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7463 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7464 if (!isAllowedWhileBooting(proc.info)){ 7465 if (procsToKill == null) { 7466 procsToKill = new ArrayList<ProcessRecord>(); 7467 } 7468 procsToKill.add(proc); 7469 } 7470 } 7471 } 7472 7473 synchronized(this) { 7474 if (procsToKill != null) { 7475 for (int i=procsToKill.size()-1; i>=0; i--) { 7476 ProcessRecord proc = procsToKill.get(i); 7477 Slog.i(TAG, "Removing system update proc: " + proc); 7478 removeProcessLocked(proc, true, false, "system update done"); 7479 } 7480 } 7481 7482 // Now that we have cleaned up any update processes, we 7483 // are ready to start launching real processes and know that 7484 // we won't trample on them any more. 7485 mProcessesReady = true; 7486 } 7487 7488 Slog.i(TAG, "System now ready"); 7489 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7490 SystemClock.uptimeMillis()); 7491 7492 synchronized(this) { 7493 // Make sure we have no pre-ready processes sitting around. 7494 7495 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7496 ResolveInfo ri = mContext.getPackageManager() 7497 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7498 STOCK_PM_FLAGS); 7499 CharSequence errorMsg = null; 7500 if (ri != null) { 7501 ActivityInfo ai = ri.activityInfo; 7502 ApplicationInfo app = ai.applicationInfo; 7503 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7504 mTopAction = Intent.ACTION_FACTORY_TEST; 7505 mTopData = null; 7506 mTopComponent = new ComponentName(app.packageName, 7507 ai.name); 7508 } else { 7509 errorMsg = mContext.getResources().getText( 7510 com.android.internal.R.string.factorytest_not_system); 7511 } 7512 } else { 7513 errorMsg = mContext.getResources().getText( 7514 com.android.internal.R.string.factorytest_no_action); 7515 } 7516 if (errorMsg != null) { 7517 mTopAction = null; 7518 mTopData = null; 7519 mTopComponent = null; 7520 Message msg = Message.obtain(); 7521 msg.what = SHOW_FACTORY_ERROR_MSG; 7522 msg.getData().putCharSequence("msg", errorMsg); 7523 mHandler.sendMessage(msg); 7524 } 7525 } 7526 } 7527 7528 retrieveSettings(); 7529 7530 if (goingCallback != null) goingCallback.run(); 7531 7532 synchronized (this) { 7533 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7534 try { 7535 List apps = AppGlobals.getPackageManager(). 7536 getPersistentApplications(STOCK_PM_FLAGS); 7537 if (apps != null) { 7538 int N = apps.size(); 7539 int i; 7540 for (i=0; i<N; i++) { 7541 ApplicationInfo info 7542 = (ApplicationInfo)apps.get(i); 7543 if (info != null && 7544 !info.packageName.equals("android")) { 7545 addAppLocked(info, false); 7546 } 7547 } 7548 } 7549 } catch (RemoteException ex) { 7550 // pm is in same process, this will never happen. 7551 } 7552 } 7553 7554 // Start up initial activity. 7555 mBooting = true; 7556 7557 try { 7558 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7559 Message msg = Message.obtain(); 7560 msg.what = SHOW_UID_ERROR_MSG; 7561 mHandler.sendMessage(msg); 7562 } 7563 } catch (RemoteException e) { 7564 } 7565 7566 mMainStack.resumeTopActivityLocked(null); 7567 } 7568 } 7569 7570 private boolean makeAppCrashingLocked(ProcessRecord app, 7571 String shortMsg, String longMsg, String stackTrace) { 7572 app.crashing = true; 7573 app.crashingReport = generateProcessError(app, 7574 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7575 startAppProblemLocked(app); 7576 app.stopFreezingAllLocked(); 7577 return handleAppCrashLocked(app); 7578 } 7579 7580 private void makeAppNotRespondingLocked(ProcessRecord app, 7581 String activity, String shortMsg, String longMsg) { 7582 app.notResponding = true; 7583 app.notRespondingReport = generateProcessError(app, 7584 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7585 activity, shortMsg, longMsg, null); 7586 startAppProblemLocked(app); 7587 app.stopFreezingAllLocked(); 7588 } 7589 7590 /** 7591 * Generate a process error record, suitable for attachment to a ProcessRecord. 7592 * 7593 * @param app The ProcessRecord in which the error occurred. 7594 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7595 * ActivityManager.AppErrorStateInfo 7596 * @param activity The activity associated with the crash, if known. 7597 * @param shortMsg Short message describing the crash. 7598 * @param longMsg Long message describing the crash. 7599 * @param stackTrace Full crash stack trace, may be null. 7600 * 7601 * @return Returns a fully-formed AppErrorStateInfo record. 7602 */ 7603 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7604 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7605 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7606 7607 report.condition = condition; 7608 report.processName = app.processName; 7609 report.pid = app.pid; 7610 report.uid = app.info.uid; 7611 report.tag = activity; 7612 report.shortMsg = shortMsg; 7613 report.longMsg = longMsg; 7614 report.stackTrace = stackTrace; 7615 7616 return report; 7617 } 7618 7619 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7620 synchronized (this) { 7621 app.crashing = false; 7622 app.crashingReport = null; 7623 app.notResponding = false; 7624 app.notRespondingReport = null; 7625 if (app.anrDialog == fromDialog) { 7626 app.anrDialog = null; 7627 } 7628 if (app.waitDialog == fromDialog) { 7629 app.waitDialog = null; 7630 } 7631 if (app.pid > 0 && app.pid != MY_PID) { 7632 handleAppCrashLocked(app); 7633 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7634 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7635 app.processName, app.setAdj, "user's request after error"); 7636 Process.killProcessQuiet(app.pid); 7637 } 7638 } 7639 } 7640 7641 private boolean handleAppCrashLocked(ProcessRecord app) { 7642 if (mHeadless) { 7643 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7644 return false; 7645 } 7646 long now = SystemClock.uptimeMillis(); 7647 7648 Long crashTime; 7649 if (!app.isolated) { 7650 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7651 } else { 7652 crashTime = null; 7653 } 7654 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7655 // This process loses! 7656 Slog.w(TAG, "Process " + app.info.processName 7657 + " has crashed too many times: killing!"); 7658 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7659 app.info.processName, app.uid); 7660 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7661 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7662 if (r.app == app) { 7663 Slog.w(TAG, " Force finishing activity " 7664 + r.intent.getComponent().flattenToShortString()); 7665 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7666 } 7667 } 7668 if (!app.persistent) { 7669 // We don't want to start this process again until the user 7670 // explicitly does so... but for persistent process, we really 7671 // need to keep it running. If a persistent process is actually 7672 // repeatedly crashing, then badness for everyone. 7673 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7674 app.info.processName); 7675 if (!app.isolated) { 7676 // XXX We don't have a way to mark isolated processes 7677 // as bad, since they don't have a peristent identity. 7678 mBadProcesses.put(app.info.processName, app.uid, now); 7679 mProcessCrashTimes.remove(app.info.processName, app.uid); 7680 } 7681 app.bad = true; 7682 app.removed = true; 7683 // Don't let services in this process be restarted and potentially 7684 // annoy the user repeatedly. Unless it is persistent, since those 7685 // processes run critical code. 7686 removeProcessLocked(app, false, false, "crash"); 7687 mMainStack.resumeTopActivityLocked(null); 7688 return false; 7689 } 7690 mMainStack.resumeTopActivityLocked(null); 7691 } else { 7692 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7693 if (r != null && r.app == app) { 7694 // If the top running activity is from this crashing 7695 // process, then terminate it to avoid getting in a loop. 7696 Slog.w(TAG, " Force finishing activity " 7697 + r.intent.getComponent().flattenToShortString()); 7698 int index = mMainStack.indexOfActivityLocked(r); 7699 r.stack.finishActivityLocked(r, index, 7700 Activity.RESULT_CANCELED, null, "crashed"); 7701 // Also terminate any activities below it that aren't yet 7702 // stopped, to avoid a situation where one will get 7703 // re-start our crashing activity once it gets resumed again. 7704 index--; 7705 if (index >= 0) { 7706 r = (ActivityRecord)mMainStack.mHistory.get(index); 7707 if (r.state == ActivityState.RESUMED 7708 || r.state == ActivityState.PAUSING 7709 || r.state == ActivityState.PAUSED) { 7710 if (!r.isHomeActivity || mHomeProcess != r.app) { 7711 Slog.w(TAG, " Force finishing activity " 7712 + r.intent.getComponent().flattenToShortString()); 7713 r.stack.finishActivityLocked(r, index, 7714 Activity.RESULT_CANCELED, null, "crashed"); 7715 } 7716 } 7717 } 7718 } 7719 } 7720 7721 // Bump up the crash count of any services currently running in the proc. 7722 if (app.services.size() != 0) { 7723 // Any services running in the application need to be placed 7724 // back in the pending list. 7725 Iterator<ServiceRecord> it = app.services.iterator(); 7726 while (it.hasNext()) { 7727 ServiceRecord sr = it.next(); 7728 sr.crashCount++; 7729 } 7730 } 7731 7732 // If the crashing process is what we consider to be the "home process" and it has been 7733 // replaced by a third-party app, clear the package preferred activities from packages 7734 // with a home activity running in the process to prevent a repeatedly crashing app 7735 // from blocking the user to manually clear the list. 7736 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7737 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7738 Iterator it = mHomeProcess.activities.iterator(); 7739 while (it.hasNext()) { 7740 ActivityRecord r = (ActivityRecord)it.next(); 7741 if (r.isHomeActivity) { 7742 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7743 try { 7744 ActivityThread.getPackageManager() 7745 .clearPackagePreferredActivities(r.packageName); 7746 } catch (RemoteException c) { 7747 // pm is in same process, this will never happen. 7748 } 7749 } 7750 } 7751 } 7752 7753 if (!app.isolated) { 7754 // XXX Can't keep track of crash times for isolated processes, 7755 // because they don't have a perisistent identity. 7756 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7757 } 7758 7759 return true; 7760 } 7761 7762 void startAppProblemLocked(ProcessRecord app) { 7763 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7764 mContext, app.info.packageName, app.info.flags); 7765 skipCurrentReceiverLocked(app); 7766 } 7767 7768 void skipCurrentReceiverLocked(ProcessRecord app) { 7769 for (BroadcastQueue queue : mBroadcastQueues) { 7770 queue.skipCurrentReceiverLocked(app); 7771 } 7772 } 7773 7774 /** 7775 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7776 * The application process will exit immediately after this call returns. 7777 * @param app object of the crashing app, null for the system server 7778 * @param crashInfo describing the exception 7779 */ 7780 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7781 ProcessRecord r = findAppProcess(app, "Crash"); 7782 final String processName = app == null ? "system_server" 7783 : (r == null ? "unknown" : r.processName); 7784 7785 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7786 processName, 7787 r == null ? -1 : r.info.flags, 7788 crashInfo.exceptionClassName, 7789 crashInfo.exceptionMessage, 7790 crashInfo.throwFileName, 7791 crashInfo.throwLineNumber); 7792 7793 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7794 7795 crashApplication(r, crashInfo); 7796 } 7797 7798 public void handleApplicationStrictModeViolation( 7799 IBinder app, 7800 int violationMask, 7801 StrictMode.ViolationInfo info) { 7802 ProcessRecord r = findAppProcess(app, "StrictMode"); 7803 if (r == null) { 7804 return; 7805 } 7806 7807 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7808 Integer stackFingerprint = info.hashCode(); 7809 boolean logIt = true; 7810 synchronized (mAlreadyLoggedViolatedStacks) { 7811 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7812 logIt = false; 7813 // TODO: sub-sample into EventLog for these, with 7814 // the info.durationMillis? Then we'd get 7815 // the relative pain numbers, without logging all 7816 // the stack traces repeatedly. We'd want to do 7817 // likewise in the client code, which also does 7818 // dup suppression, before the Binder call. 7819 } else { 7820 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7821 mAlreadyLoggedViolatedStacks.clear(); 7822 } 7823 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7824 } 7825 } 7826 if (logIt) { 7827 logStrictModeViolationToDropBox(r, info); 7828 } 7829 } 7830 7831 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7832 AppErrorResult result = new AppErrorResult(); 7833 synchronized (this) { 7834 final long origId = Binder.clearCallingIdentity(); 7835 7836 Message msg = Message.obtain(); 7837 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7838 HashMap<String, Object> data = new HashMap<String, Object>(); 7839 data.put("result", result); 7840 data.put("app", r); 7841 data.put("violationMask", violationMask); 7842 data.put("info", info); 7843 msg.obj = data; 7844 mHandler.sendMessage(msg); 7845 7846 Binder.restoreCallingIdentity(origId); 7847 } 7848 int res = result.get(); 7849 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7850 } 7851 } 7852 7853 // Depending on the policy in effect, there could be a bunch of 7854 // these in quick succession so we try to batch these together to 7855 // minimize disk writes, number of dropbox entries, and maximize 7856 // compression, by having more fewer, larger records. 7857 private void logStrictModeViolationToDropBox( 7858 ProcessRecord process, 7859 StrictMode.ViolationInfo info) { 7860 if (info == null) { 7861 return; 7862 } 7863 final boolean isSystemApp = process == null || 7864 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7865 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7866 final String processName = process == null ? "unknown" : process.processName; 7867 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7868 final DropBoxManager dbox = (DropBoxManager) 7869 mContext.getSystemService(Context.DROPBOX_SERVICE); 7870 7871 // Exit early if the dropbox isn't configured to accept this report type. 7872 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7873 7874 boolean bufferWasEmpty; 7875 boolean needsFlush; 7876 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7877 synchronized (sb) { 7878 bufferWasEmpty = sb.length() == 0; 7879 appendDropBoxProcessHeaders(process, processName, sb); 7880 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7881 sb.append("System-App: ").append(isSystemApp).append("\n"); 7882 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7883 if (info.violationNumThisLoop != 0) { 7884 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7885 } 7886 if (info.numAnimationsRunning != 0) { 7887 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7888 } 7889 if (info.broadcastIntentAction != null) { 7890 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7891 } 7892 if (info.durationMillis != -1) { 7893 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7894 } 7895 if (info.numInstances != -1) { 7896 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7897 } 7898 if (info.tags != null) { 7899 for (String tag : info.tags) { 7900 sb.append("Span-Tag: ").append(tag).append("\n"); 7901 } 7902 } 7903 sb.append("\n"); 7904 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7905 sb.append(info.crashInfo.stackTrace); 7906 } 7907 sb.append("\n"); 7908 7909 // Only buffer up to ~64k. Various logging bits truncate 7910 // things at 128k. 7911 needsFlush = (sb.length() > 64 * 1024); 7912 } 7913 7914 // Flush immediately if the buffer's grown too large, or this 7915 // is a non-system app. Non-system apps are isolated with a 7916 // different tag & policy and not batched. 7917 // 7918 // Batching is useful during internal testing with 7919 // StrictMode settings turned up high. Without batching, 7920 // thousands of separate files could be created on boot. 7921 if (!isSystemApp || needsFlush) { 7922 new Thread("Error dump: " + dropboxTag) { 7923 @Override 7924 public void run() { 7925 String report; 7926 synchronized (sb) { 7927 report = sb.toString(); 7928 sb.delete(0, sb.length()); 7929 sb.trimToSize(); 7930 } 7931 if (report.length() != 0) { 7932 dbox.addText(dropboxTag, report); 7933 } 7934 } 7935 }.start(); 7936 return; 7937 } 7938 7939 // System app batching: 7940 if (!bufferWasEmpty) { 7941 // An existing dropbox-writing thread is outstanding, so 7942 // we don't need to start it up. The existing thread will 7943 // catch the buffer appends we just did. 7944 return; 7945 } 7946 7947 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7948 // (After this point, we shouldn't access AMS internal data structures.) 7949 new Thread("Error dump: " + dropboxTag) { 7950 @Override 7951 public void run() { 7952 // 5 second sleep to let stacks arrive and be batched together 7953 try { 7954 Thread.sleep(5000); // 5 seconds 7955 } catch (InterruptedException e) {} 7956 7957 String errorReport; 7958 synchronized (mStrictModeBuffer) { 7959 errorReport = mStrictModeBuffer.toString(); 7960 if (errorReport.length() == 0) { 7961 return; 7962 } 7963 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 7964 mStrictModeBuffer.trimToSize(); 7965 } 7966 dbox.addText(dropboxTag, errorReport); 7967 } 7968 }.start(); 7969 } 7970 7971 /** 7972 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 7973 * @param app object of the crashing app, null for the system server 7974 * @param tag reported by the caller 7975 * @param crashInfo describing the context of the error 7976 * @return true if the process should exit immediately (WTF is fatal) 7977 */ 7978 public boolean handleApplicationWtf(IBinder app, String tag, 7979 ApplicationErrorReport.CrashInfo crashInfo) { 7980 ProcessRecord r = findAppProcess(app, "WTF"); 7981 final String processName = app == null ? "system_server" 7982 : (r == null ? "unknown" : r.processName); 7983 7984 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 7985 processName, 7986 r == null ? -1 : r.info.flags, 7987 tag, crashInfo.exceptionMessage); 7988 7989 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 7990 7991 if (r != null && r.pid != Process.myPid() && 7992 Settings.Secure.getInt(mContext.getContentResolver(), 7993 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 7994 crashApplication(r, crashInfo); 7995 return true; 7996 } else { 7997 return false; 7998 } 7999 } 8000 8001 /** 8002 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8003 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8004 */ 8005 private ProcessRecord findAppProcess(IBinder app, String reason) { 8006 if (app == null) { 8007 return null; 8008 } 8009 8010 synchronized (this) { 8011 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8012 final int NA = apps.size(); 8013 for (int ia=0; ia<NA; ia++) { 8014 ProcessRecord p = apps.valueAt(ia); 8015 if (p.thread != null && p.thread.asBinder() == app) { 8016 return p; 8017 } 8018 } 8019 } 8020 8021 Slog.w(TAG, "Can't find mystery application for " + reason 8022 + " from pid=" + Binder.getCallingPid() 8023 + " uid=" + Binder.getCallingUid() + ": " + app); 8024 return null; 8025 } 8026 } 8027 8028 /** 8029 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8030 * to append various headers to the dropbox log text. 8031 */ 8032 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8033 StringBuilder sb) { 8034 // Watchdog thread ends up invoking this function (with 8035 // a null ProcessRecord) to add the stack file to dropbox. 8036 // Do not acquire a lock on this (am) in such cases, as it 8037 // could cause a potential deadlock, if and when watchdog 8038 // is invoked due to unavailability of lock on am and it 8039 // would prevent watchdog from killing system_server. 8040 if (process == null) { 8041 sb.append("Process: ").append(processName).append("\n"); 8042 return; 8043 } 8044 // Note: ProcessRecord 'process' is guarded by the service 8045 // instance. (notably process.pkgList, which could otherwise change 8046 // concurrently during execution of this method) 8047 synchronized (this) { 8048 sb.append("Process: ").append(processName).append("\n"); 8049 int flags = process.info.flags; 8050 IPackageManager pm = AppGlobals.getPackageManager(); 8051 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8052 for (String pkg : process.pkgList) { 8053 sb.append("Package: ").append(pkg); 8054 try { 8055 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8056 if (pi != null) { 8057 sb.append(" v").append(pi.versionCode); 8058 if (pi.versionName != null) { 8059 sb.append(" (").append(pi.versionName).append(")"); 8060 } 8061 } 8062 } catch (RemoteException e) { 8063 Slog.e(TAG, "Error getting package info: " + pkg, e); 8064 } 8065 sb.append("\n"); 8066 } 8067 } 8068 } 8069 8070 private static String processClass(ProcessRecord process) { 8071 if (process == null || process.pid == MY_PID) { 8072 return "system_server"; 8073 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8074 return "system_app"; 8075 } else { 8076 return "data_app"; 8077 } 8078 } 8079 8080 /** 8081 * Write a description of an error (crash, WTF, ANR) to the drop box. 8082 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8083 * @param process which caused the error, null means the system server 8084 * @param activity which triggered the error, null if unknown 8085 * @param parent activity related to the error, null if unknown 8086 * @param subject line related to the error, null if absent 8087 * @param report in long form describing the error, null if absent 8088 * @param logFile to include in the report, null if none 8089 * @param crashInfo giving an application stack trace, null if absent 8090 */ 8091 public void addErrorToDropBox(String eventType, 8092 ProcessRecord process, String processName, ActivityRecord activity, 8093 ActivityRecord parent, String subject, 8094 final String report, final File logFile, 8095 final ApplicationErrorReport.CrashInfo crashInfo) { 8096 // NOTE -- this must never acquire the ActivityManagerService lock, 8097 // otherwise the watchdog may be prevented from resetting the system. 8098 8099 final String dropboxTag = processClass(process) + "_" + eventType; 8100 final DropBoxManager dbox = (DropBoxManager) 8101 mContext.getSystemService(Context.DROPBOX_SERVICE); 8102 8103 // Exit early if the dropbox isn't configured to accept this report type. 8104 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8105 8106 final StringBuilder sb = new StringBuilder(1024); 8107 appendDropBoxProcessHeaders(process, processName, sb); 8108 if (activity != null) { 8109 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8110 } 8111 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8112 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8113 } 8114 if (parent != null && parent != activity) { 8115 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8116 } 8117 if (subject != null) { 8118 sb.append("Subject: ").append(subject).append("\n"); 8119 } 8120 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8121 if (Debug.isDebuggerConnected()) { 8122 sb.append("Debugger: Connected\n"); 8123 } 8124 sb.append("\n"); 8125 8126 // Do the rest in a worker thread to avoid blocking the caller on I/O 8127 // (After this point, we shouldn't access AMS internal data structures.) 8128 Thread worker = new Thread("Error dump: " + dropboxTag) { 8129 @Override 8130 public void run() { 8131 if (report != null) { 8132 sb.append(report); 8133 } 8134 if (logFile != null) { 8135 try { 8136 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8137 } catch (IOException e) { 8138 Slog.e(TAG, "Error reading " + logFile, e); 8139 } 8140 } 8141 if (crashInfo != null && crashInfo.stackTrace != null) { 8142 sb.append(crashInfo.stackTrace); 8143 } 8144 8145 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8146 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8147 if (lines > 0) { 8148 sb.append("\n"); 8149 8150 // Merge several logcat streams, and take the last N lines 8151 InputStreamReader input = null; 8152 try { 8153 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8154 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8155 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8156 8157 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8158 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8159 input = new InputStreamReader(logcat.getInputStream()); 8160 8161 int num; 8162 char[] buf = new char[8192]; 8163 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8164 } catch (IOException e) { 8165 Slog.e(TAG, "Error running logcat", e); 8166 } finally { 8167 if (input != null) try { input.close(); } catch (IOException e) {} 8168 } 8169 } 8170 8171 dbox.addText(dropboxTag, sb.toString()); 8172 } 8173 }; 8174 8175 if (process == null) { 8176 // If process is null, we are being called from some internal code 8177 // and may be about to die -- run this synchronously. 8178 worker.run(); 8179 } else { 8180 worker.start(); 8181 } 8182 } 8183 8184 /** 8185 * Bring up the "unexpected error" dialog box for a crashing app. 8186 * Deal with edge cases (intercepts from instrumented applications, 8187 * ActivityController, error intent receivers, that sort of thing). 8188 * @param r the application crashing 8189 * @param crashInfo describing the failure 8190 */ 8191 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8192 long timeMillis = System.currentTimeMillis(); 8193 String shortMsg = crashInfo.exceptionClassName; 8194 String longMsg = crashInfo.exceptionMessage; 8195 String stackTrace = crashInfo.stackTrace; 8196 if (shortMsg != null && longMsg != null) { 8197 longMsg = shortMsg + ": " + longMsg; 8198 } else if (shortMsg != null) { 8199 longMsg = shortMsg; 8200 } 8201 8202 AppErrorResult result = new AppErrorResult(); 8203 synchronized (this) { 8204 if (mController != null) { 8205 try { 8206 String name = r != null ? r.processName : null; 8207 int pid = r != null ? r.pid : Binder.getCallingPid(); 8208 if (!mController.appCrashed(name, pid, 8209 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8210 Slog.w(TAG, "Force-killing crashed app " + name 8211 + " at watcher's request"); 8212 Process.killProcess(pid); 8213 return; 8214 } 8215 } catch (RemoteException e) { 8216 mController = null; 8217 } 8218 } 8219 8220 final long origId = Binder.clearCallingIdentity(); 8221 8222 // If this process is running instrumentation, finish it. 8223 if (r != null && r.instrumentationClass != null) { 8224 Slog.w(TAG, "Error in app " + r.processName 8225 + " running instrumentation " + r.instrumentationClass + ":"); 8226 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8227 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8228 Bundle info = new Bundle(); 8229 info.putString("shortMsg", shortMsg); 8230 info.putString("longMsg", longMsg); 8231 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8232 Binder.restoreCallingIdentity(origId); 8233 return; 8234 } 8235 8236 // If we can't identify the process or it's already exceeded its crash quota, 8237 // quit right away without showing a crash dialog. 8238 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8239 Binder.restoreCallingIdentity(origId); 8240 return; 8241 } 8242 8243 Message msg = Message.obtain(); 8244 msg.what = SHOW_ERROR_MSG; 8245 HashMap data = new HashMap(); 8246 data.put("result", result); 8247 data.put("app", r); 8248 msg.obj = data; 8249 mHandler.sendMessage(msg); 8250 8251 Binder.restoreCallingIdentity(origId); 8252 } 8253 8254 int res = result.get(); 8255 8256 Intent appErrorIntent = null; 8257 synchronized (this) { 8258 if (r != null && !r.isolated) { 8259 // XXX Can't keep track of crash time for isolated processes, 8260 // since they don't have a persistent identity. 8261 mProcessCrashTimes.put(r.info.processName, r.uid, 8262 SystemClock.uptimeMillis()); 8263 } 8264 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8265 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8266 } 8267 } 8268 8269 if (appErrorIntent != null) { 8270 try { 8271 mContext.startActivity(appErrorIntent); 8272 } catch (ActivityNotFoundException e) { 8273 Slog.w(TAG, "bug report receiver dissappeared", e); 8274 } 8275 } 8276 } 8277 8278 Intent createAppErrorIntentLocked(ProcessRecord r, 8279 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8280 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8281 if (report == null) { 8282 return null; 8283 } 8284 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8285 result.setComponent(r.errorReportReceiver); 8286 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8287 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8288 return result; 8289 } 8290 8291 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8292 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8293 if (r.errorReportReceiver == null) { 8294 return null; 8295 } 8296 8297 if (!r.crashing && !r.notResponding) { 8298 return null; 8299 } 8300 8301 ApplicationErrorReport report = new ApplicationErrorReport(); 8302 report.packageName = r.info.packageName; 8303 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8304 report.processName = r.processName; 8305 report.time = timeMillis; 8306 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8307 8308 if (r.crashing) { 8309 report.type = ApplicationErrorReport.TYPE_CRASH; 8310 report.crashInfo = crashInfo; 8311 } else if (r.notResponding) { 8312 report.type = ApplicationErrorReport.TYPE_ANR; 8313 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8314 8315 report.anrInfo.activity = r.notRespondingReport.tag; 8316 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8317 report.anrInfo.info = r.notRespondingReport.longMsg; 8318 } 8319 8320 return report; 8321 } 8322 8323 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8324 enforceNotIsolatedCaller("getProcessesInErrorState"); 8325 // assume our apps are happy - lazy create the list 8326 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8327 8328 synchronized (this) { 8329 8330 // iterate across all processes 8331 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8332 ProcessRecord app = mLruProcesses.get(i); 8333 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8334 // This one's in trouble, so we'll generate a report for it 8335 // crashes are higher priority (in case there's a crash *and* an anr) 8336 ActivityManager.ProcessErrorStateInfo report = null; 8337 if (app.crashing) { 8338 report = app.crashingReport; 8339 } else if (app.notResponding) { 8340 report = app.notRespondingReport; 8341 } 8342 8343 if (report != null) { 8344 if (errList == null) { 8345 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8346 } 8347 errList.add(report); 8348 } else { 8349 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8350 " crashing = " + app.crashing + 8351 " notResponding = " + app.notResponding); 8352 } 8353 } 8354 } 8355 } 8356 8357 return errList; 8358 } 8359 8360 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8361 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8362 if (currApp != null) { 8363 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8364 } 8365 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8366 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8367 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8368 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8369 if (currApp != null) { 8370 currApp.lru = 0; 8371 } 8372 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8373 } else if (adj >= ProcessList.SERVICE_ADJ) { 8374 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8375 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8376 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8377 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8378 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8379 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8380 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8381 } else { 8382 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8383 } 8384 } 8385 8386 private void fillInProcMemInfo(ProcessRecord app, 8387 ActivityManager.RunningAppProcessInfo outInfo) { 8388 outInfo.pid = app.pid; 8389 outInfo.uid = app.info.uid; 8390 if (mHeavyWeightProcess == app) { 8391 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8392 } 8393 if (app.persistent) { 8394 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8395 } 8396 outInfo.lastTrimLevel = app.trimMemoryLevel; 8397 int adj = app.curAdj; 8398 outInfo.importance = oomAdjToImportance(adj, outInfo); 8399 outInfo.importanceReasonCode = app.adjTypeCode; 8400 } 8401 8402 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8403 enforceNotIsolatedCaller("getRunningAppProcesses"); 8404 // Lazy instantiation of list 8405 List<ActivityManager.RunningAppProcessInfo> runList = null; 8406 synchronized (this) { 8407 // Iterate across all processes 8408 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8409 ProcessRecord app = mLruProcesses.get(i); 8410 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8411 // Generate process state info for running application 8412 ActivityManager.RunningAppProcessInfo currApp = 8413 new ActivityManager.RunningAppProcessInfo(app.processName, 8414 app.pid, app.getPackageList()); 8415 fillInProcMemInfo(app, currApp); 8416 if (app.adjSource instanceof ProcessRecord) { 8417 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8418 currApp.importanceReasonImportance = oomAdjToImportance( 8419 app.adjSourceOom, null); 8420 } else if (app.adjSource instanceof ActivityRecord) { 8421 ActivityRecord r = (ActivityRecord)app.adjSource; 8422 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8423 } 8424 if (app.adjTarget instanceof ComponentName) { 8425 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8426 } 8427 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8428 // + " lru=" + currApp.lru); 8429 if (runList == null) { 8430 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8431 } 8432 runList.add(currApp); 8433 } 8434 } 8435 } 8436 return runList; 8437 } 8438 8439 public List<ApplicationInfo> getRunningExternalApplications() { 8440 enforceNotIsolatedCaller("getRunningExternalApplications"); 8441 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8442 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8443 if (runningApps != null && runningApps.size() > 0) { 8444 Set<String> extList = new HashSet<String>(); 8445 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8446 if (app.pkgList != null) { 8447 for (String pkg : app.pkgList) { 8448 extList.add(pkg); 8449 } 8450 } 8451 } 8452 IPackageManager pm = AppGlobals.getPackageManager(); 8453 for (String pkg : extList) { 8454 try { 8455 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8456 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8457 retList.add(info); 8458 } 8459 } catch (RemoteException e) { 8460 } 8461 } 8462 } 8463 return retList; 8464 } 8465 8466 @Override 8467 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8468 enforceNotIsolatedCaller("getMyMemoryState"); 8469 synchronized (this) { 8470 ProcessRecord proc; 8471 synchronized (mPidsSelfLocked) { 8472 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8473 } 8474 fillInProcMemInfo(proc, outInfo); 8475 } 8476 } 8477 8478 @Override 8479 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8480 if (checkCallingPermission(android.Manifest.permission.DUMP) 8481 != PackageManager.PERMISSION_GRANTED) { 8482 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8483 + Binder.getCallingPid() 8484 + ", uid=" + Binder.getCallingUid() 8485 + " without permission " 8486 + android.Manifest.permission.DUMP); 8487 return; 8488 } 8489 8490 boolean dumpAll = false; 8491 boolean dumpClient = false; 8492 String dumpPackage = null; 8493 8494 int opti = 0; 8495 while (opti < args.length) { 8496 String opt = args[opti]; 8497 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8498 break; 8499 } 8500 opti++; 8501 if ("-a".equals(opt)) { 8502 dumpAll = true; 8503 } else if ("-c".equals(opt)) { 8504 dumpClient = true; 8505 } else if ("-h".equals(opt)) { 8506 pw.println("Activity manager dump options:"); 8507 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8508 pw.println(" cmd may be one of:"); 8509 pw.println(" a[ctivities]: activity stack state"); 8510 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8511 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8512 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8513 pw.println(" o[om]: out of memory management"); 8514 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8515 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8516 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8517 pw.println(" service [COMP_SPEC]: service client-side state"); 8518 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8519 pw.println(" all: dump all activities"); 8520 pw.println(" top: dump the top activity"); 8521 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8522 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8523 pw.println(" a partial substring in a component name, a"); 8524 pw.println(" hex object identifier."); 8525 pw.println(" -a: include all available server state."); 8526 pw.println(" -c: include client state."); 8527 return; 8528 } else { 8529 pw.println("Unknown argument: " + opt + "; use -h for help"); 8530 } 8531 } 8532 8533 long origId = Binder.clearCallingIdentity(); 8534 boolean more = false; 8535 // Is the caller requesting to dump a particular piece of data? 8536 if (opti < args.length) { 8537 String cmd = args[opti]; 8538 opti++; 8539 if ("activities".equals(cmd) || "a".equals(cmd)) { 8540 synchronized (this) { 8541 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8542 } 8543 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8544 String[] newArgs; 8545 String name; 8546 if (opti >= args.length) { 8547 name = null; 8548 newArgs = EMPTY_STRING_ARRAY; 8549 } else { 8550 name = args[opti]; 8551 opti++; 8552 newArgs = new String[args.length - opti]; 8553 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8554 args.length - opti); 8555 } 8556 synchronized (this) { 8557 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8558 } 8559 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8560 String[] newArgs; 8561 String name; 8562 if (opti >= args.length) { 8563 name = null; 8564 newArgs = EMPTY_STRING_ARRAY; 8565 } else { 8566 name = args[opti]; 8567 opti++; 8568 newArgs = new String[args.length - opti]; 8569 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8570 args.length - opti); 8571 } 8572 synchronized (this) { 8573 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8574 } 8575 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8576 String[] newArgs; 8577 String name; 8578 if (opti >= args.length) { 8579 name = null; 8580 newArgs = EMPTY_STRING_ARRAY; 8581 } else { 8582 name = args[opti]; 8583 opti++; 8584 newArgs = new String[args.length - opti]; 8585 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8586 args.length - opti); 8587 } 8588 synchronized (this) { 8589 dumpProcessesLocked(fd, pw, args, opti, true, name); 8590 } 8591 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8592 synchronized (this) { 8593 dumpOomLocked(fd, pw, args, opti, true); 8594 } 8595 } else if ("provider".equals(cmd)) { 8596 String[] newArgs; 8597 String name; 8598 if (opti >= args.length) { 8599 name = null; 8600 newArgs = EMPTY_STRING_ARRAY; 8601 } else { 8602 name = args[opti]; 8603 opti++; 8604 newArgs = new String[args.length - opti]; 8605 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8606 } 8607 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8608 pw.println("No providers match: " + name); 8609 pw.println("Use -h for help."); 8610 } 8611 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8612 synchronized (this) { 8613 dumpProvidersLocked(fd, pw, args, opti, true, null); 8614 } 8615 } else if ("service".equals(cmd)) { 8616 String[] newArgs; 8617 String name; 8618 if (opti >= args.length) { 8619 name = null; 8620 newArgs = EMPTY_STRING_ARRAY; 8621 } else { 8622 name = args[opti]; 8623 opti++; 8624 newArgs = new String[args.length - opti]; 8625 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8626 args.length - opti); 8627 } 8628 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8629 pw.println("No services match: " + name); 8630 pw.println("Use -h for help."); 8631 } 8632 } else if ("package".equals(cmd)) { 8633 String[] newArgs; 8634 if (opti >= args.length) { 8635 pw.println("package: no package name specified"); 8636 pw.println("Use -h for help."); 8637 } else { 8638 dumpPackage = args[opti]; 8639 opti++; 8640 newArgs = new String[args.length - opti]; 8641 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8642 args.length - opti); 8643 args = newArgs; 8644 opti = 0; 8645 more = true; 8646 } 8647 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8648 synchronized (this) { 8649 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8650 } 8651 } else { 8652 // Dumping a single activity? 8653 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8654 pw.println("Bad activity command, or no activities match: " + cmd); 8655 pw.println("Use -h for help."); 8656 } 8657 } 8658 if (!more) { 8659 Binder.restoreCallingIdentity(origId); 8660 return; 8661 } 8662 } 8663 8664 // No piece of data specified, dump everything. 8665 synchronized (this) { 8666 boolean needSep; 8667 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8668 if (needSep) { 8669 pw.println(" "); 8670 } 8671 if (dumpAll) { 8672 pw.println("-------------------------------------------------------------------------------"); 8673 } 8674 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8675 if (needSep) { 8676 pw.println(" "); 8677 } 8678 if (dumpAll) { 8679 pw.println("-------------------------------------------------------------------------------"); 8680 } 8681 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8682 if (needSep) { 8683 pw.println(" "); 8684 } 8685 if (dumpAll) { 8686 pw.println("-------------------------------------------------------------------------------"); 8687 } 8688 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8689 if (needSep) { 8690 pw.println(" "); 8691 } 8692 if (dumpAll) { 8693 pw.println("-------------------------------------------------------------------------------"); 8694 } 8695 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8696 if (needSep) { 8697 pw.println(" "); 8698 } 8699 if (dumpAll) { 8700 pw.println("-------------------------------------------------------------------------------"); 8701 } 8702 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8703 } 8704 Binder.restoreCallingIdentity(origId); 8705 } 8706 8707 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8708 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8709 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8710 pw.println(" Main stack:"); 8711 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8712 dumpPackage); 8713 pw.println(" "); 8714 pw.println(" Running activities (most recent first):"); 8715 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8716 dumpPackage); 8717 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8718 pw.println(" "); 8719 pw.println(" Activities waiting for another to become visible:"); 8720 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8721 !dumpAll, false, dumpPackage); 8722 } 8723 if (mMainStack.mStoppingActivities.size() > 0) { 8724 pw.println(" "); 8725 pw.println(" Activities waiting to stop:"); 8726 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8727 !dumpAll, false, dumpPackage); 8728 } 8729 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8730 pw.println(" "); 8731 pw.println(" Activities waiting to sleep:"); 8732 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8733 !dumpAll, false, dumpPackage); 8734 } 8735 if (mMainStack.mFinishingActivities.size() > 0) { 8736 pw.println(" "); 8737 pw.println(" Activities waiting to finish:"); 8738 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8739 !dumpAll, false, dumpPackage); 8740 } 8741 8742 pw.println(" "); 8743 if (mMainStack.mPausingActivity != null) { 8744 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8745 } 8746 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8747 pw.println(" mFocusedActivity: " + mFocusedActivity); 8748 if (dumpAll) { 8749 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8750 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8751 pw.println(" mDismissKeyguardOnNextActivity: " 8752 + mMainStack.mDismissKeyguardOnNextActivity); 8753 } 8754 8755 if (mRecentTasks.size() > 0) { 8756 pw.println(); 8757 pw.println(" Recent tasks:"); 8758 8759 final int N = mRecentTasks.size(); 8760 for (int i=0; i<N; i++) { 8761 TaskRecord tr = mRecentTasks.get(i); 8762 if (dumpPackage != null) { 8763 if (tr.realActivity == null || 8764 !dumpPackage.equals(tr.realActivity)) { 8765 continue; 8766 } 8767 } 8768 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8769 pw.println(tr); 8770 if (dumpAll) { 8771 mRecentTasks.get(i).dump(pw, " "); 8772 } 8773 } 8774 } 8775 8776 if (dumpAll) { 8777 pw.println(" "); 8778 pw.println(" mCurTask: " + mCurTask); 8779 } 8780 8781 return true; 8782 } 8783 8784 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8785 int opti, boolean dumpAll, String dumpPackage) { 8786 boolean needSep = false; 8787 int numPers = 0; 8788 8789 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8790 8791 if (dumpAll) { 8792 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8793 final int NA = procs.size(); 8794 for (int ia=0; ia<NA; ia++) { 8795 ProcessRecord r = procs.valueAt(ia); 8796 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8797 continue; 8798 } 8799 if (!needSep) { 8800 pw.println(" All known processes:"); 8801 needSep = true; 8802 } 8803 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8804 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8805 pw.print(" "); pw.println(r); 8806 r.dump(pw, " "); 8807 if (r.persistent) { 8808 numPers++; 8809 } 8810 } 8811 } 8812 } 8813 8814 if (mIsolatedProcesses.size() > 0) { 8815 if (needSep) pw.println(" "); 8816 needSep = true; 8817 pw.println(" Isolated process list (sorted by uid):"); 8818 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8819 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8820 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8821 continue; 8822 } 8823 pw.println(String.format("%sIsolated #%2d: %s", 8824 " ", i, r.toString())); 8825 } 8826 } 8827 8828 if (mLruProcesses.size() > 0) { 8829 if (needSep) pw.println(" "); 8830 needSep = true; 8831 pw.println(" Process LRU list (sorted by oom_adj):"); 8832 dumpProcessOomList(pw, this, mLruProcesses, " ", 8833 "Proc", "PERS", false, dumpPackage); 8834 needSep = true; 8835 } 8836 8837 if (dumpAll) { 8838 synchronized (mPidsSelfLocked) { 8839 boolean printed = false; 8840 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8841 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8842 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8843 continue; 8844 } 8845 if (!printed) { 8846 if (needSep) pw.println(" "); 8847 needSep = true; 8848 pw.println(" PID mappings:"); 8849 printed = true; 8850 } 8851 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8852 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8853 } 8854 } 8855 } 8856 8857 if (mForegroundProcesses.size() > 0) { 8858 synchronized (mPidsSelfLocked) { 8859 boolean printed = false; 8860 for (int i=0; i<mForegroundProcesses.size(); i++) { 8861 ProcessRecord r = mPidsSelfLocked.get( 8862 mForegroundProcesses.valueAt(i).pid); 8863 if (dumpPackage != null && (r == null 8864 || !dumpPackage.equals(r.info.packageName))) { 8865 continue; 8866 } 8867 if (!printed) { 8868 if (needSep) pw.println(" "); 8869 needSep = true; 8870 pw.println(" Foreground Processes:"); 8871 printed = true; 8872 } 8873 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8874 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8875 } 8876 } 8877 } 8878 8879 if (mPersistentStartingProcesses.size() > 0) { 8880 if (needSep) pw.println(" "); 8881 needSep = true; 8882 pw.println(" Persisent processes that are starting:"); 8883 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8884 "Starting Norm", "Restarting PERS", dumpPackage); 8885 } 8886 8887 if (mRemovedProcesses.size() > 0) { 8888 if (needSep) pw.println(" "); 8889 needSep = true; 8890 pw.println(" Processes that are being removed:"); 8891 dumpProcessList(pw, this, mRemovedProcesses, " ", 8892 "Removed Norm", "Removed PERS", dumpPackage); 8893 } 8894 8895 if (mProcessesOnHold.size() > 0) { 8896 if (needSep) pw.println(" "); 8897 needSep = true; 8898 pw.println(" Processes that are on old until the system is ready:"); 8899 dumpProcessList(pw, this, mProcessesOnHold, " ", 8900 "OnHold Norm", "OnHold PERS", dumpPackage); 8901 } 8902 8903 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8904 8905 if (mProcessCrashTimes.getMap().size() > 0) { 8906 boolean printed = false; 8907 long now = SystemClock.uptimeMillis(); 8908 for (Map.Entry<String, SparseArray<Long>> procs 8909 : mProcessCrashTimes.getMap().entrySet()) { 8910 String pname = procs.getKey(); 8911 SparseArray<Long> uids = procs.getValue(); 8912 final int N = uids.size(); 8913 for (int i=0; i<N; i++) { 8914 int puid = uids.keyAt(i); 8915 ProcessRecord r = mProcessNames.get(pname, puid); 8916 if (dumpPackage != null && (r == null 8917 || !dumpPackage.equals(r.info.packageName))) { 8918 continue; 8919 } 8920 if (!printed) { 8921 if (needSep) pw.println(" "); 8922 needSep = true; 8923 pw.println(" Time since processes crashed:"); 8924 printed = true; 8925 } 8926 pw.print(" Process "); pw.print(pname); 8927 pw.print(" uid "); pw.print(puid); 8928 pw.print(": last crashed "); 8929 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8930 pw.println(" ago"); 8931 } 8932 } 8933 } 8934 8935 if (mBadProcesses.getMap().size() > 0) { 8936 boolean printed = false; 8937 for (Map.Entry<String, SparseArray<Long>> procs 8938 : mBadProcesses.getMap().entrySet()) { 8939 String pname = procs.getKey(); 8940 SparseArray<Long> uids = procs.getValue(); 8941 final int N = uids.size(); 8942 for (int i=0; i<N; i++) { 8943 int puid = uids.keyAt(i); 8944 ProcessRecord r = mProcessNames.get(pname, puid); 8945 if (dumpPackage != null && (r == null 8946 || !dumpPackage.equals(r.info.packageName))) { 8947 continue; 8948 } 8949 if (!printed) { 8950 if (needSep) pw.println(" "); 8951 needSep = true; 8952 pw.println(" Bad processes:"); 8953 } 8954 pw.print(" Bad process "); pw.print(pname); 8955 pw.print(" uid "); pw.print(puid); 8956 pw.print(": crashed at time "); 8957 pw.println(uids.valueAt(i)); 8958 } 8959 } 8960 } 8961 8962 pw.println(); 8963 pw.println(" mHomeProcess: " + mHomeProcess); 8964 pw.println(" mPreviousProcess: " + mPreviousProcess); 8965 if (dumpAll) { 8966 StringBuilder sb = new StringBuilder(128); 8967 sb.append(" mPreviousProcessVisibleTime: "); 8968 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 8969 pw.println(sb); 8970 } 8971 if (mHeavyWeightProcess != null) { 8972 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 8973 } 8974 pw.println(" mConfiguration: " + mConfiguration); 8975 if (dumpAll) { 8976 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 8977 if (mCompatModePackages.getPackages().size() > 0) { 8978 boolean printed = false; 8979 for (Map.Entry<String, Integer> entry 8980 : mCompatModePackages.getPackages().entrySet()) { 8981 String pkg = entry.getKey(); 8982 int mode = entry.getValue(); 8983 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 8984 continue; 8985 } 8986 if (!printed) { 8987 pw.println(" mScreenCompatPackages:"); 8988 printed = true; 8989 } 8990 pw.print(" "); pw.print(pkg); pw.print(": "); 8991 pw.print(mode); pw.println(); 8992 } 8993 } 8994 } 8995 if (mSleeping || mWentToSleep || mLockScreenShown) { 8996 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 8997 + " mLockScreenShown " + mLockScreenShown); 8998 } 8999 if (mShuttingDown) { 9000 pw.println(" mShuttingDown=" + mShuttingDown); 9001 } 9002 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9003 || mOrigWaitForDebugger) { 9004 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9005 + " mDebugTransient=" + mDebugTransient 9006 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9007 } 9008 if (mOpenGlTraceApp != null) { 9009 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9010 } 9011 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9012 || mProfileFd != null) { 9013 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9014 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9015 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9016 + mAutoStopProfiler); 9017 } 9018 if (mAlwaysFinishActivities || mController != null) { 9019 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9020 + " mController=" + mController); 9021 } 9022 if (dumpAll) { 9023 pw.println(" Total persistent processes: " + numPers); 9024 pw.println(" mStartRunning=" + mStartRunning 9025 + " mProcessesReady=" + mProcessesReady 9026 + " mSystemReady=" + mSystemReady); 9027 pw.println(" mBooting=" + mBooting 9028 + " mBooted=" + mBooted 9029 + " mFactoryTest=" + mFactoryTest); 9030 pw.print(" mLastPowerCheckRealtime="); 9031 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9032 pw.println(""); 9033 pw.print(" mLastPowerCheckUptime="); 9034 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9035 pw.println(""); 9036 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9037 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9038 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9039 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9040 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9041 } 9042 9043 return true; 9044 } 9045 9046 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9047 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9048 if (mProcessesToGc.size() > 0) { 9049 boolean printed = false; 9050 long now = SystemClock.uptimeMillis(); 9051 for (int i=0; i<mProcessesToGc.size(); i++) { 9052 ProcessRecord proc = mProcessesToGc.get(i); 9053 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9054 continue; 9055 } 9056 if (!printed) { 9057 if (needSep) pw.println(" "); 9058 needSep = true; 9059 pw.println(" Processes that are waiting to GC:"); 9060 printed = true; 9061 } 9062 pw.print(" Process "); pw.println(proc); 9063 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9064 pw.print(", last gced="); 9065 pw.print(now-proc.lastRequestedGc); 9066 pw.print(" ms ago, last lowMem="); 9067 pw.print(now-proc.lastLowMemory); 9068 pw.println(" ms ago"); 9069 9070 } 9071 } 9072 return needSep; 9073 } 9074 9075 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9076 int opti, boolean dumpAll) { 9077 boolean needSep = false; 9078 9079 if (mLruProcesses.size() > 0) { 9080 if (needSep) pw.println(" "); 9081 needSep = true; 9082 pw.println(" OOM levels:"); 9083 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9084 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9085 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9086 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9087 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9088 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9089 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9090 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9091 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9092 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9093 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9094 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9095 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9096 9097 if (needSep) pw.println(" "); 9098 needSep = true; 9099 pw.println(" Process OOM control:"); 9100 dumpProcessOomList(pw, this, mLruProcesses, " ", 9101 "Proc", "PERS", true, null); 9102 needSep = true; 9103 } 9104 9105 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9106 9107 pw.println(); 9108 pw.println(" mHomeProcess: " + mHomeProcess); 9109 pw.println(" mPreviousProcess: " + mPreviousProcess); 9110 if (mHeavyWeightProcess != null) { 9111 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9112 } 9113 9114 return true; 9115 } 9116 9117 /** 9118 * There are three ways to call this: 9119 * - no provider specified: dump all the providers 9120 * - a flattened component name that matched an existing provider was specified as the 9121 * first arg: dump that one provider 9122 * - the first arg isn't the flattened component name of an existing provider: 9123 * dump all providers whose component contains the first arg as a substring 9124 */ 9125 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9126 int opti, boolean dumpAll) { 9127 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9128 } 9129 9130 static class ItemMatcher { 9131 ArrayList<ComponentName> components; 9132 ArrayList<String> strings; 9133 ArrayList<Integer> objects; 9134 boolean all; 9135 9136 ItemMatcher() { 9137 all = true; 9138 } 9139 9140 void build(String name) { 9141 ComponentName componentName = ComponentName.unflattenFromString(name); 9142 if (componentName != null) { 9143 if (components == null) { 9144 components = new ArrayList<ComponentName>(); 9145 } 9146 components.add(componentName); 9147 all = false; 9148 } else { 9149 int objectId = 0; 9150 // Not a '/' separated full component name; maybe an object ID? 9151 try { 9152 objectId = Integer.parseInt(name, 16); 9153 if (objects == null) { 9154 objects = new ArrayList<Integer>(); 9155 } 9156 objects.add(objectId); 9157 all = false; 9158 } catch (RuntimeException e) { 9159 // Not an integer; just do string match. 9160 if (strings == null) { 9161 strings = new ArrayList<String>(); 9162 } 9163 strings.add(name); 9164 all = false; 9165 } 9166 } 9167 } 9168 9169 int build(String[] args, int opti) { 9170 for (; opti<args.length; opti++) { 9171 String name = args[opti]; 9172 if ("--".equals(name)) { 9173 return opti+1; 9174 } 9175 build(name); 9176 } 9177 return opti; 9178 } 9179 9180 boolean match(Object object, ComponentName comp) { 9181 if (all) { 9182 return true; 9183 } 9184 if (components != null) { 9185 for (int i=0; i<components.size(); i++) { 9186 if (components.get(i).equals(comp)) { 9187 return true; 9188 } 9189 } 9190 } 9191 if (objects != null) { 9192 for (int i=0; i<objects.size(); i++) { 9193 if (System.identityHashCode(object) == objects.get(i)) { 9194 return true; 9195 } 9196 } 9197 } 9198 if (strings != null) { 9199 String flat = comp.flattenToString(); 9200 for (int i=0; i<strings.size(); i++) { 9201 if (flat.contains(strings.get(i))) { 9202 return true; 9203 } 9204 } 9205 } 9206 return false; 9207 } 9208 } 9209 9210 /** 9211 * There are three things that cmd can be: 9212 * - a flattened component name that matches an existing activity 9213 * - the cmd arg isn't the flattened component name of an existing activity: 9214 * dump all activity whose component contains the cmd as a substring 9215 * - A hex number of the ActivityRecord object instance. 9216 */ 9217 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9218 int opti, boolean dumpAll) { 9219 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9220 9221 if ("all".equals(name)) { 9222 synchronized (this) { 9223 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9224 activities.add(r1); 9225 } 9226 } 9227 } else if ("top".equals(name)) { 9228 synchronized (this) { 9229 final int N = mMainStack.mHistory.size(); 9230 if (N > 0) { 9231 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9232 } 9233 } 9234 } else { 9235 ItemMatcher matcher = new ItemMatcher(); 9236 matcher.build(name); 9237 9238 synchronized (this) { 9239 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9240 if (matcher.match(r1, r1.intent.getComponent())) { 9241 activities.add(r1); 9242 } 9243 } 9244 } 9245 } 9246 9247 if (activities.size() <= 0) { 9248 return false; 9249 } 9250 9251 String[] newArgs = new String[args.length - opti]; 9252 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9253 9254 TaskRecord lastTask = null; 9255 boolean needSep = false; 9256 for (int i=activities.size()-1; i>=0; i--) { 9257 ActivityRecord r = (ActivityRecord)activities.get(i); 9258 if (needSep) { 9259 pw.println(); 9260 } 9261 needSep = true; 9262 synchronized (this) { 9263 if (lastTask != r.task) { 9264 lastTask = r.task; 9265 pw.print("TASK "); pw.print(lastTask.affinity); 9266 pw.print(" id="); pw.println(lastTask.taskId); 9267 if (dumpAll) { 9268 lastTask.dump(pw, " "); 9269 } 9270 } 9271 } 9272 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9273 } 9274 return true; 9275 } 9276 9277 /** 9278 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9279 * there is a thread associated with the activity. 9280 */ 9281 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9282 final ActivityRecord r, String[] args, boolean dumpAll) { 9283 String innerPrefix = prefix + " "; 9284 synchronized (this) { 9285 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9286 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9287 pw.print(" pid="); 9288 if (r.app != null) pw.println(r.app.pid); 9289 else pw.println("(not running)"); 9290 if (dumpAll) { 9291 r.dump(pw, innerPrefix); 9292 } 9293 } 9294 if (r.app != null && r.app.thread != null) { 9295 // flush anything that is already in the PrintWriter since the thread is going 9296 // to write to the file descriptor directly 9297 pw.flush(); 9298 try { 9299 TransferPipe tp = new TransferPipe(); 9300 try { 9301 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9302 r.appToken, innerPrefix, args); 9303 tp.go(fd); 9304 } finally { 9305 tp.kill(); 9306 } 9307 } catch (IOException e) { 9308 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9309 } catch (RemoteException e) { 9310 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9311 } 9312 } 9313 } 9314 9315 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9316 int opti, boolean dumpAll, String dumpPackage) { 9317 boolean needSep = false; 9318 9319 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9320 if (dumpAll) { 9321 if (mRegisteredReceivers.size() > 0) { 9322 boolean printed = false; 9323 Iterator it = mRegisteredReceivers.values().iterator(); 9324 while (it.hasNext()) { 9325 ReceiverList r = (ReceiverList)it.next(); 9326 if (dumpPackage != null && (r.app == null || 9327 !dumpPackage.equals(r.app.info.packageName))) { 9328 continue; 9329 } 9330 if (!printed) { 9331 pw.println(" Registered Receivers:"); 9332 needSep = true; 9333 printed = true; 9334 } 9335 pw.print(" * "); pw.println(r); 9336 r.dump(pw, " "); 9337 } 9338 } 9339 9340 if (mReceiverResolver.dump(pw, needSep ? 9341 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9342 " ", dumpPackage, false)) { 9343 needSep = true; 9344 } 9345 } 9346 9347 for (BroadcastQueue q : mBroadcastQueues) { 9348 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9349 } 9350 9351 needSep = true; 9352 9353 if (mStickyBroadcasts != null && dumpPackage == null) { 9354 if (needSep) { 9355 pw.println(); 9356 } 9357 needSep = true; 9358 pw.println(" Sticky broadcasts:"); 9359 StringBuilder sb = new StringBuilder(128); 9360 for (Map.Entry<String, ArrayList<Intent>> ent 9361 : mStickyBroadcasts.entrySet()) { 9362 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9363 if (dumpAll) { 9364 pw.println(":"); 9365 ArrayList<Intent> intents = ent.getValue(); 9366 final int N = intents.size(); 9367 for (int i=0; i<N; i++) { 9368 sb.setLength(0); 9369 sb.append(" Intent: "); 9370 intents.get(i).toShortString(sb, false, true, false, false); 9371 pw.println(sb.toString()); 9372 Bundle bundle = intents.get(i).getExtras(); 9373 if (bundle != null) { 9374 pw.print(" "); 9375 pw.println(bundle.toString()); 9376 } 9377 } 9378 } else { 9379 pw.println(""); 9380 } 9381 } 9382 needSep = true; 9383 } 9384 9385 if (dumpAll) { 9386 pw.println(); 9387 for (BroadcastQueue queue : mBroadcastQueues) { 9388 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9389 + queue.mBroadcastsScheduled); 9390 } 9391 pw.println(" mHandler:"); 9392 mHandler.dump(new PrintWriterPrinter(pw), " "); 9393 needSep = true; 9394 } 9395 9396 return needSep; 9397 } 9398 9399 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9400 int opti, boolean dumpAll, String dumpPackage) { 9401 boolean needSep = true; 9402 9403 ItemMatcher matcher = new ItemMatcher(); 9404 matcher.build(args, opti); 9405 9406 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9407 9408 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9409 9410 if (mLaunchingProviders.size() > 0) { 9411 boolean printed = false; 9412 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9413 ContentProviderRecord r = mLaunchingProviders.get(i); 9414 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9415 continue; 9416 } 9417 if (!printed) { 9418 if (needSep) pw.println(" "); 9419 needSep = true; 9420 pw.println(" Launching content providers:"); 9421 printed = true; 9422 } 9423 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9424 pw.println(r); 9425 } 9426 } 9427 9428 if (mGrantedUriPermissions.size() > 0) { 9429 if (needSep) pw.println(); 9430 needSep = true; 9431 pw.println("Granted Uri Permissions:"); 9432 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9433 int uid = mGrantedUriPermissions.keyAt(i); 9434 HashMap<Uri, UriPermission> perms 9435 = mGrantedUriPermissions.valueAt(i); 9436 pw.print(" * UID "); pw.print(uid); 9437 pw.println(" holds:"); 9438 for (UriPermission perm : perms.values()) { 9439 pw.print(" "); pw.println(perm); 9440 if (dumpAll) { 9441 perm.dump(pw, " "); 9442 } 9443 } 9444 } 9445 needSep = true; 9446 } 9447 9448 return needSep; 9449 } 9450 9451 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9452 int opti, boolean dumpAll, String dumpPackage) { 9453 boolean needSep = false; 9454 9455 if (mIntentSenderRecords.size() > 0) { 9456 boolean printed = false; 9457 Iterator<WeakReference<PendingIntentRecord>> it 9458 = mIntentSenderRecords.values().iterator(); 9459 while (it.hasNext()) { 9460 WeakReference<PendingIntentRecord> ref = it.next(); 9461 PendingIntentRecord rec = ref != null ? ref.get(): null; 9462 if (dumpPackage != null && (rec == null 9463 || !dumpPackage.equals(rec.key.packageName))) { 9464 continue; 9465 } 9466 if (!printed) { 9467 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9468 printed = true; 9469 } 9470 needSep = true; 9471 if (rec != null) { 9472 pw.print(" * "); pw.println(rec); 9473 if (dumpAll) { 9474 rec.dump(pw, " "); 9475 } 9476 } else { 9477 pw.print(" * "); pw.println(ref); 9478 } 9479 } 9480 } 9481 9482 return needSep; 9483 } 9484 9485 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9486 String prefix, String label, boolean complete, boolean brief, boolean client, 9487 String dumpPackage) { 9488 TaskRecord lastTask = null; 9489 boolean needNL = false; 9490 final String innerPrefix = prefix + " "; 9491 final String[] args = new String[0]; 9492 for (int i=list.size()-1; i>=0; i--) { 9493 final ActivityRecord r = (ActivityRecord)list.get(i); 9494 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9495 continue; 9496 } 9497 final boolean full = !brief && (complete || !r.isInHistory()); 9498 if (needNL) { 9499 pw.println(" "); 9500 needNL = false; 9501 } 9502 if (lastTask != r.task) { 9503 lastTask = r.task; 9504 pw.print(prefix); 9505 pw.print(full ? "* " : " "); 9506 pw.println(lastTask); 9507 if (full) { 9508 lastTask.dump(pw, prefix + " "); 9509 } else if (complete) { 9510 // Complete + brief == give a summary. Isn't that obvious?!? 9511 if (lastTask.intent != null) { 9512 pw.print(prefix); pw.print(" "); 9513 pw.println(lastTask.intent.toInsecureStringWithClip()); 9514 } 9515 } 9516 } 9517 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9518 pw.print(" #"); pw.print(i); pw.print(": "); 9519 pw.println(r); 9520 if (full) { 9521 r.dump(pw, innerPrefix); 9522 } else if (complete) { 9523 // Complete + brief == give a summary. Isn't that obvious?!? 9524 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9525 if (r.app != null) { 9526 pw.print(innerPrefix); pw.println(r.app); 9527 } 9528 } 9529 if (client && r.app != null && r.app.thread != null) { 9530 // flush anything that is already in the PrintWriter since the thread is going 9531 // to write to the file descriptor directly 9532 pw.flush(); 9533 try { 9534 TransferPipe tp = new TransferPipe(); 9535 try { 9536 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9537 r.appToken, innerPrefix, args); 9538 // Short timeout, since blocking here can 9539 // deadlock with the application. 9540 tp.go(fd, 2000); 9541 } finally { 9542 tp.kill(); 9543 } 9544 } catch (IOException e) { 9545 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9546 } catch (RemoteException e) { 9547 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9548 } 9549 needNL = true; 9550 } 9551 } 9552 } 9553 9554 private static String buildOomTag(String prefix, String space, int val, int base) { 9555 if (val == base) { 9556 if (space == null) return prefix; 9557 return prefix + " "; 9558 } 9559 return prefix + "+" + Integer.toString(val-base); 9560 } 9561 9562 private static final int dumpProcessList(PrintWriter pw, 9563 ActivityManagerService service, List list, 9564 String prefix, String normalLabel, String persistentLabel, 9565 String dumpPackage) { 9566 int numPers = 0; 9567 final int N = list.size()-1; 9568 for (int i=N; i>=0; i--) { 9569 ProcessRecord r = (ProcessRecord)list.get(i); 9570 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9571 continue; 9572 } 9573 pw.println(String.format("%s%s #%2d: %s", 9574 prefix, (r.persistent ? persistentLabel : normalLabel), 9575 i, r.toString())); 9576 if (r.persistent) { 9577 numPers++; 9578 } 9579 } 9580 return numPers; 9581 } 9582 9583 private static final boolean dumpProcessOomList(PrintWriter pw, 9584 ActivityManagerService service, List<ProcessRecord> origList, 9585 String prefix, String normalLabel, String persistentLabel, 9586 boolean inclDetails, String dumpPackage) { 9587 9588 ArrayList<Pair<ProcessRecord, Integer>> list 9589 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9590 for (int i=0; i<origList.size(); i++) { 9591 ProcessRecord r = origList.get(i); 9592 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9593 continue; 9594 } 9595 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9596 } 9597 9598 if (list.size() <= 0) { 9599 return false; 9600 } 9601 9602 Comparator<Pair<ProcessRecord, Integer>> comparator 9603 = new Comparator<Pair<ProcessRecord, Integer>>() { 9604 @Override 9605 public int compare(Pair<ProcessRecord, Integer> object1, 9606 Pair<ProcessRecord, Integer> object2) { 9607 if (object1.first.setAdj != object2.first.setAdj) { 9608 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9609 } 9610 if (object1.second.intValue() != object2.second.intValue()) { 9611 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9612 } 9613 return 0; 9614 } 9615 }; 9616 9617 Collections.sort(list, comparator); 9618 9619 final long curRealtime = SystemClock.elapsedRealtime(); 9620 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9621 final long curUptime = SystemClock.uptimeMillis(); 9622 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9623 9624 for (int i=list.size()-1; i>=0; i--) { 9625 ProcessRecord r = list.get(i).first; 9626 String oomAdj; 9627 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9628 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9629 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9630 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9631 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9632 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9633 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9634 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9635 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9636 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9637 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9638 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9639 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9640 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9641 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9642 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9643 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9644 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9645 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9646 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9647 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9648 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9649 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9650 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9651 } else { 9652 oomAdj = Integer.toString(r.setAdj); 9653 } 9654 String schedGroup; 9655 switch (r.setSchedGroup) { 9656 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9657 schedGroup = "B"; 9658 break; 9659 case Process.THREAD_GROUP_DEFAULT: 9660 schedGroup = "F"; 9661 break; 9662 default: 9663 schedGroup = Integer.toString(r.setSchedGroup); 9664 break; 9665 } 9666 String foreground; 9667 if (r.foregroundActivities) { 9668 foreground = "A"; 9669 } else if (r.foregroundServices) { 9670 foreground = "S"; 9671 } else { 9672 foreground = " "; 9673 } 9674 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9675 prefix, (r.persistent ? persistentLabel : normalLabel), 9676 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9677 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9678 if (r.adjSource != null || r.adjTarget != null) { 9679 pw.print(prefix); 9680 pw.print(" "); 9681 if (r.adjTarget instanceof ComponentName) { 9682 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9683 } else if (r.adjTarget != null) { 9684 pw.print(r.adjTarget.toString()); 9685 } else { 9686 pw.print("{null}"); 9687 } 9688 pw.print("<="); 9689 if (r.adjSource instanceof ProcessRecord) { 9690 pw.print("Proc{"); 9691 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9692 pw.println("}"); 9693 } else if (r.adjSource != null) { 9694 pw.println(r.adjSource.toString()); 9695 } else { 9696 pw.println("{null}"); 9697 } 9698 } 9699 if (inclDetails) { 9700 pw.print(prefix); 9701 pw.print(" "); 9702 pw.print("oom: max="); pw.print(r.maxAdj); 9703 pw.print(" hidden="); pw.print(r.hiddenAdj); 9704 pw.print(" curRaw="); pw.print(r.curRawAdj); 9705 pw.print(" setRaw="); pw.print(r.setRawAdj); 9706 pw.print(" cur="); pw.print(r.curAdj); 9707 pw.print(" set="); pw.println(r.setAdj); 9708 pw.print(prefix); 9709 pw.print(" "); 9710 pw.print("keeping="); pw.print(r.keeping); 9711 pw.print(" hidden="); pw.print(r.hidden); 9712 pw.print(" empty="); pw.print(r.empty); 9713 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9714 9715 if (!r.keeping) { 9716 if (r.lastWakeTime != 0) { 9717 long wtime; 9718 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9719 synchronized (stats) { 9720 wtime = stats.getProcessWakeTime(r.info.uid, 9721 r.pid, curRealtime); 9722 } 9723 long timeUsed = wtime - r.lastWakeTime; 9724 pw.print(prefix); 9725 pw.print(" "); 9726 pw.print("keep awake over "); 9727 TimeUtils.formatDuration(realtimeSince, pw); 9728 pw.print(" used "); 9729 TimeUtils.formatDuration(timeUsed, pw); 9730 pw.print(" ("); 9731 pw.print((timeUsed*100)/realtimeSince); 9732 pw.println("%)"); 9733 } 9734 if (r.lastCpuTime != 0) { 9735 long timeUsed = r.curCpuTime - r.lastCpuTime; 9736 pw.print(prefix); 9737 pw.print(" "); 9738 pw.print("run cpu over "); 9739 TimeUtils.formatDuration(uptimeSince, pw); 9740 pw.print(" used "); 9741 TimeUtils.formatDuration(timeUsed, pw); 9742 pw.print(" ("); 9743 pw.print((timeUsed*100)/uptimeSince); 9744 pw.println("%)"); 9745 } 9746 } 9747 } 9748 } 9749 return true; 9750 } 9751 9752 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9753 ArrayList<ProcessRecord> procs; 9754 synchronized (this) { 9755 if (args != null && args.length > start 9756 && args[start].charAt(0) != '-') { 9757 procs = new ArrayList<ProcessRecord>(); 9758 int pid = -1; 9759 try { 9760 pid = Integer.parseInt(args[start]); 9761 } catch (NumberFormatException e) { 9762 9763 } 9764 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9765 ProcessRecord proc = mLruProcesses.get(i); 9766 if (proc.pid == pid) { 9767 procs.add(proc); 9768 } else if (proc.processName.equals(args[start])) { 9769 procs.add(proc); 9770 } 9771 } 9772 if (procs.size() <= 0) { 9773 pw.println("No process found for: " + args[start]); 9774 return null; 9775 } 9776 } else { 9777 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9778 } 9779 } 9780 return procs; 9781 } 9782 9783 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9784 PrintWriter pw, String[] args) { 9785 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9786 if (procs == null) { 9787 return; 9788 } 9789 9790 long uptime = SystemClock.uptimeMillis(); 9791 long realtime = SystemClock.elapsedRealtime(); 9792 pw.println("Applications Graphics Acceleration Info:"); 9793 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9794 9795 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9796 ProcessRecord r = procs.get(i); 9797 if (r.thread != null) { 9798 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9799 pw.flush(); 9800 try { 9801 TransferPipe tp = new TransferPipe(); 9802 try { 9803 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9804 tp.go(fd); 9805 } finally { 9806 tp.kill(); 9807 } 9808 } catch (IOException e) { 9809 pw.println("Failure while dumping the app: " + r); 9810 pw.flush(); 9811 } catch (RemoteException e) { 9812 pw.println("Got a RemoteException while dumping the app " + r); 9813 pw.flush(); 9814 } 9815 } 9816 } 9817 } 9818 9819 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9820 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9821 if (procs == null) { 9822 return; 9823 } 9824 9825 pw.println("Applications Database Info:"); 9826 9827 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9828 ProcessRecord r = procs.get(i); 9829 if (r.thread != null) { 9830 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9831 pw.flush(); 9832 try { 9833 TransferPipe tp = new TransferPipe(); 9834 try { 9835 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9836 tp.go(fd); 9837 } finally { 9838 tp.kill(); 9839 } 9840 } catch (IOException e) { 9841 pw.println("Failure while dumping the app: " + r); 9842 pw.flush(); 9843 } catch (RemoteException e) { 9844 pw.println("Got a RemoteException while dumping the app " + r); 9845 pw.flush(); 9846 } 9847 } 9848 } 9849 } 9850 9851 final static class MemItem { 9852 final String label; 9853 final String shortLabel; 9854 final long pss; 9855 final int id; 9856 ArrayList<MemItem> subitems; 9857 9858 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9859 label = _label; 9860 shortLabel = _shortLabel; 9861 pss = _pss; 9862 id = _id; 9863 } 9864 } 9865 9866 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9867 boolean sort) { 9868 if (sort) { 9869 Collections.sort(items, new Comparator<MemItem>() { 9870 @Override 9871 public int compare(MemItem lhs, MemItem rhs) { 9872 if (lhs.pss < rhs.pss) { 9873 return 1; 9874 } else if (lhs.pss > rhs.pss) { 9875 return -1; 9876 } 9877 return 0; 9878 } 9879 }); 9880 } 9881 9882 for (int i=0; i<items.size(); i++) { 9883 MemItem mi = items.get(i); 9884 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9885 if (mi.subitems != null) { 9886 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9887 } 9888 } 9889 } 9890 9891 // These are in KB. 9892 static final long[] DUMP_MEM_BUCKETS = new long[] { 9893 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9894 120*1024, 160*1024, 200*1024, 9895 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9896 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9897 }; 9898 9899 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9900 boolean stackLike) { 9901 int start = label.lastIndexOf('.'); 9902 if (start >= 0) start++; 9903 else start = 0; 9904 int end = label.length(); 9905 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9906 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9907 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9908 out.append(bucket); 9909 out.append(stackLike ? "MB." : "MB "); 9910 out.append(label, start, end); 9911 return; 9912 } 9913 } 9914 out.append(memKB/1024); 9915 out.append(stackLike ? "MB." : "MB "); 9916 out.append(label, start, end); 9917 } 9918 9919 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9920 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9921 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9922 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9923 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9924 }; 9925 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9926 "System", "Persistent", "Foreground", 9927 "Visible", "Perceptible", "Heavy Weight", 9928 "Backup", "A Services", "Home", "Previous", 9929 "B Services", "Background" 9930 }; 9931 9932 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9933 PrintWriter pw, String prefix, String[] args, boolean brief, 9934 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9935 boolean dumpAll = false; 9936 boolean oomOnly = false; 9937 9938 int opti = 0; 9939 while (opti < args.length) { 9940 String opt = args[opti]; 9941 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9942 break; 9943 } 9944 opti++; 9945 if ("-a".equals(opt)) { 9946 dumpAll = true; 9947 } else if ("--oom".equals(opt)) { 9948 oomOnly = true; 9949 } else if ("-h".equals(opt)) { 9950 pw.println("meminfo dump options: [-a] [--oom] [process]"); 9951 pw.println(" -a: include all available information for each process."); 9952 pw.println(" --oom: only show processes organized by oom adj."); 9953 pw.println("If [process] is specified it can be the name or "); 9954 pw.println("pid of a specific process to dump."); 9955 return; 9956 } else { 9957 pw.println("Unknown argument: " + opt + "; use -h for help"); 9958 } 9959 } 9960 9961 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 9962 if (procs == null) { 9963 return; 9964 } 9965 9966 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9967 long uptime = SystemClock.uptimeMillis(); 9968 long realtime = SystemClock.elapsedRealtime(); 9969 9970 if (procs.size() == 1 || isCheckinRequest) { 9971 dumpAll = true; 9972 } 9973 9974 if (isCheckinRequest) { 9975 // short checkin version 9976 pw.println(uptime + "," + realtime); 9977 pw.flush(); 9978 } else { 9979 pw.println("Applications Memory Usage (kB):"); 9980 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9981 } 9982 9983 String[] innerArgs = new String[args.length-opti]; 9984 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 9985 9986 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 9987 long nativePss=0, dalvikPss=0, otherPss=0; 9988 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 9989 9990 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 9991 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 9992 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 9993 9994 long totalPss = 0; 9995 9996 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9997 ProcessRecord r = procs.get(i); 9998 if (r.thread != null) { 9999 if (!isCheckinRequest && dumpAll) { 10000 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10001 pw.flush(); 10002 } 10003 Debug.MemoryInfo mi = null; 10004 if (dumpAll) { 10005 try { 10006 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10007 } catch (RemoteException e) { 10008 if (!isCheckinRequest) { 10009 pw.println("Got RemoteException!"); 10010 pw.flush(); 10011 } 10012 } 10013 } else { 10014 mi = new Debug.MemoryInfo(); 10015 Debug.getMemoryInfo(r.pid, mi); 10016 } 10017 10018 if (!isCheckinRequest && mi != null) { 10019 long myTotalPss = mi.getTotalPss(); 10020 totalPss += myTotalPss; 10021 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10022 r.processName, myTotalPss, 0); 10023 procMems.add(pssItem); 10024 10025 nativePss += mi.nativePss; 10026 dalvikPss += mi.dalvikPss; 10027 otherPss += mi.otherPss; 10028 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10029 long mem = mi.getOtherPss(j); 10030 miscPss[j] += mem; 10031 otherPss -= mem; 10032 } 10033 10034 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10035 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10036 || oomIndex == (oomPss.length-1)) { 10037 oomPss[oomIndex] += myTotalPss; 10038 if (oomProcs[oomIndex] == null) { 10039 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10040 } 10041 oomProcs[oomIndex].add(pssItem); 10042 break; 10043 } 10044 } 10045 } 10046 } 10047 } 10048 10049 if (!isCheckinRequest && procs.size() > 1) { 10050 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10051 10052 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10053 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10054 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10055 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10056 String label = Debug.MemoryInfo.getOtherLabel(j); 10057 catMems.add(new MemItem(label, label, miscPss[j], j)); 10058 } 10059 10060 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10061 for (int j=0; j<oomPss.length; j++) { 10062 if (oomPss[j] != 0) { 10063 String label = DUMP_MEM_OOM_LABEL[j]; 10064 MemItem item = new MemItem(label, label, oomPss[j], 10065 DUMP_MEM_OOM_ADJ[j]); 10066 item.subitems = oomProcs[j]; 10067 oomMems.add(item); 10068 } 10069 } 10070 10071 if (outTag != null || outStack != null) { 10072 if (outTag != null) { 10073 appendMemBucket(outTag, totalPss, "total", false); 10074 } 10075 if (outStack != null) { 10076 appendMemBucket(outStack, totalPss, "total", true); 10077 } 10078 boolean firstLine = true; 10079 for (int i=0; i<oomMems.size(); i++) { 10080 MemItem miCat = oomMems.get(i); 10081 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10082 continue; 10083 } 10084 if (miCat.id < ProcessList.SERVICE_ADJ 10085 || miCat.id == ProcessList.HOME_APP_ADJ 10086 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10087 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10088 outTag.append(" / "); 10089 } 10090 if (outStack != null) { 10091 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10092 if (firstLine) { 10093 outStack.append(":"); 10094 firstLine = false; 10095 } 10096 outStack.append("\n\t at "); 10097 } else { 10098 outStack.append("$"); 10099 } 10100 } 10101 for (int j=0; j<miCat.subitems.size(); j++) { 10102 MemItem mi = miCat.subitems.get(j); 10103 if (j > 0) { 10104 if (outTag != null) { 10105 outTag.append(" "); 10106 } 10107 if (outStack != null) { 10108 outStack.append("$"); 10109 } 10110 } 10111 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10112 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10113 } 10114 if (outStack != null) { 10115 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10116 } 10117 } 10118 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10119 outStack.append("("); 10120 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10121 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10122 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10123 outStack.append(":"); 10124 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10125 } 10126 } 10127 outStack.append(")"); 10128 } 10129 } 10130 } 10131 } 10132 10133 if (!brief && !oomOnly) { 10134 pw.println(); 10135 pw.println("Total PSS by process:"); 10136 dumpMemItems(pw, " ", procMems, true); 10137 pw.println(); 10138 } 10139 pw.println("Total PSS by OOM adjustment:"); 10140 dumpMemItems(pw, " ", oomMems, false); 10141 if (!oomOnly) { 10142 PrintWriter out = categoryPw != null ? categoryPw : pw; 10143 out.println(); 10144 out.println("Total PSS by category:"); 10145 dumpMemItems(out, " ", catMems, true); 10146 } 10147 pw.println(); 10148 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10149 final int[] SINGLE_LONG_FORMAT = new int[] { 10150 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10151 }; 10152 long[] longOut = new long[1]; 10153 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10154 SINGLE_LONG_FORMAT, null, longOut, null); 10155 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10156 longOut[0] = 0; 10157 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10158 SINGLE_LONG_FORMAT, null, longOut, null); 10159 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10160 longOut[0] = 0; 10161 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10162 SINGLE_LONG_FORMAT, null, longOut, null); 10163 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10164 longOut[0] = 0; 10165 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10166 SINGLE_LONG_FORMAT, null, longOut, null); 10167 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10168 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10169 pw.print(shared); pw.println(" kB"); 10170 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10171 pw.print(voltile); pw.println(" kB volatile"); 10172 } 10173 } 10174 10175 /** 10176 * Searches array of arguments for the specified string 10177 * @param args array of argument strings 10178 * @param value value to search for 10179 * @return true if the value is contained in the array 10180 */ 10181 private static boolean scanArgs(String[] args, String value) { 10182 if (args != null) { 10183 for (String arg : args) { 10184 if (value.equals(arg)) { 10185 return true; 10186 } 10187 } 10188 } 10189 return false; 10190 } 10191 10192 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10193 ContentProviderRecord cpr, boolean always) { 10194 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10195 10196 if (!inLaunching || always) { 10197 synchronized (cpr) { 10198 cpr.launchingApp = null; 10199 cpr.notifyAll(); 10200 } 10201 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10202 String names[] = cpr.info.authority.split(";"); 10203 for (int j = 0; j < names.length; j++) { 10204 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10205 } 10206 } 10207 10208 for (int i=0; i<cpr.connections.size(); i++) { 10209 ContentProviderConnection conn = cpr.connections.get(i); 10210 if (conn.waiting) { 10211 // If this connection is waiting for the provider, then we don't 10212 // need to mess with its process unless we are always removing 10213 // or for some reason the provider is not currently launching. 10214 if (inLaunching && !always) { 10215 continue; 10216 } 10217 } 10218 ProcessRecord capp = conn.client; 10219 conn.dead = true; 10220 if (conn.stableCount > 0) { 10221 if (!capp.persistent && capp.thread != null 10222 && capp.pid != 0 10223 && capp.pid != MY_PID) { 10224 Slog.i(TAG, "Kill " + capp.processName 10225 + " (pid " + capp.pid + "): provider " + cpr.info.name 10226 + " in dying process " + (proc != null ? proc.processName : "??")); 10227 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10228 capp.processName, capp.setAdj, "dying provider " 10229 + cpr.name.toShortString()); 10230 Process.killProcessQuiet(capp.pid); 10231 } 10232 } else if (capp.thread != null && conn.provider.provider != null) { 10233 try { 10234 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10235 } catch (RemoteException e) { 10236 } 10237 // In the protocol here, we don't expect the client to correctly 10238 // clean up this connection, we'll just remove it. 10239 cpr.connections.remove(i); 10240 conn.client.conProviders.remove(conn); 10241 } 10242 } 10243 10244 if (inLaunching && always) { 10245 mLaunchingProviders.remove(cpr); 10246 } 10247 return inLaunching; 10248 } 10249 10250 /** 10251 * Main code for cleaning up a process when it has gone away. This is 10252 * called both as a result of the process dying, or directly when stopping 10253 * a process when running in single process mode. 10254 */ 10255 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10256 boolean restarting, boolean allowRestart, int index) { 10257 if (index >= 0) { 10258 mLruProcesses.remove(index); 10259 } 10260 10261 mProcessesToGc.remove(app); 10262 10263 // Dismiss any open dialogs. 10264 if (app.crashDialog != null) { 10265 app.crashDialog.dismiss(); 10266 app.crashDialog = null; 10267 } 10268 if (app.anrDialog != null) { 10269 app.anrDialog.dismiss(); 10270 app.anrDialog = null; 10271 } 10272 if (app.waitDialog != null) { 10273 app.waitDialog.dismiss(); 10274 app.waitDialog = null; 10275 } 10276 10277 app.crashing = false; 10278 app.notResponding = false; 10279 10280 app.resetPackageList(); 10281 app.unlinkDeathRecipient(); 10282 app.thread = null; 10283 app.forcingToForeground = null; 10284 app.foregroundServices = false; 10285 app.foregroundActivities = false; 10286 app.hasShownUi = false; 10287 app.hasAboveClient = false; 10288 10289 mServices.killServicesLocked(app, allowRestart); 10290 10291 boolean restart = false; 10292 10293 // Remove published content providers. 10294 if (!app.pubProviders.isEmpty()) { 10295 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10296 while (it.hasNext()) { 10297 ContentProviderRecord cpr = it.next(); 10298 10299 final boolean always = app.bad || !allowRestart; 10300 if (removeDyingProviderLocked(app, cpr, always) || always) { 10301 // We left the provider in the launching list, need to 10302 // restart it. 10303 restart = true; 10304 } 10305 10306 cpr.provider = null; 10307 cpr.proc = null; 10308 } 10309 app.pubProviders.clear(); 10310 } 10311 10312 // Take care of any launching providers waiting for this process. 10313 if (checkAppInLaunchingProvidersLocked(app, false)) { 10314 restart = true; 10315 } 10316 10317 // Unregister from connected content providers. 10318 if (!app.conProviders.isEmpty()) { 10319 for (int i=0; i<app.conProviders.size(); i++) { 10320 ContentProviderConnection conn = app.conProviders.get(i); 10321 conn.provider.connections.remove(conn); 10322 } 10323 app.conProviders.clear(); 10324 } 10325 10326 // At this point there may be remaining entries in mLaunchingProviders 10327 // where we were the only one waiting, so they are no longer of use. 10328 // Look for these and clean up if found. 10329 // XXX Commented out for now. Trying to figure out a way to reproduce 10330 // the actual situation to identify what is actually going on. 10331 if (false) { 10332 for (int i=0; i<mLaunchingProviders.size(); i++) { 10333 ContentProviderRecord cpr = (ContentProviderRecord) 10334 mLaunchingProviders.get(i); 10335 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10336 synchronized (cpr) { 10337 cpr.launchingApp = null; 10338 cpr.notifyAll(); 10339 } 10340 } 10341 } 10342 } 10343 10344 skipCurrentReceiverLocked(app); 10345 10346 // Unregister any receivers. 10347 if (app.receivers.size() > 0) { 10348 Iterator<ReceiverList> it = app.receivers.iterator(); 10349 while (it.hasNext()) { 10350 removeReceiverLocked(it.next()); 10351 } 10352 app.receivers.clear(); 10353 } 10354 10355 // If the app is undergoing backup, tell the backup manager about it 10356 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10357 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10358 try { 10359 IBackupManager bm = IBackupManager.Stub.asInterface( 10360 ServiceManager.getService(Context.BACKUP_SERVICE)); 10361 bm.agentDisconnected(app.info.packageName); 10362 } catch (RemoteException e) { 10363 // can't happen; backup manager is local 10364 } 10365 } 10366 10367 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10368 ProcessChangeItem item = mPendingProcessChanges.get(i); 10369 if (item.pid == app.pid) { 10370 mPendingProcessChanges.remove(i); 10371 mAvailProcessChanges.add(item); 10372 } 10373 } 10374 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10375 10376 // If the caller is restarting this app, then leave it in its 10377 // current lists and let the caller take care of it. 10378 if (restarting) { 10379 return; 10380 } 10381 10382 if (!app.persistent || app.isolated) { 10383 if (DEBUG_PROCESSES) Slog.v(TAG, 10384 "Removing non-persistent process during cleanup: " + app); 10385 mProcessNames.remove(app.processName, app.uid); 10386 mIsolatedProcesses.remove(app.uid); 10387 if (mHeavyWeightProcess == app) { 10388 mHeavyWeightProcess = null; 10389 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10390 } 10391 } else if (!app.removed) { 10392 // This app is persistent, so we need to keep its record around. 10393 // If it is not already on the pending app list, add it there 10394 // and start a new process for it. 10395 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10396 mPersistentStartingProcesses.add(app); 10397 restart = true; 10398 } 10399 } 10400 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10401 "Clean-up removing on hold: " + app); 10402 mProcessesOnHold.remove(app); 10403 10404 if (app == mHomeProcess) { 10405 mHomeProcess = null; 10406 } 10407 if (app == mPreviousProcess) { 10408 mPreviousProcess = null; 10409 } 10410 10411 if (restart && !app.isolated) { 10412 // We have components that still need to be running in the 10413 // process, so re-launch it. 10414 mProcessNames.put(app.processName, app.uid, app); 10415 startProcessLocked(app, "restart", app.processName); 10416 } else if (app.pid > 0 && app.pid != MY_PID) { 10417 // Goodbye! 10418 synchronized (mPidsSelfLocked) { 10419 mPidsSelfLocked.remove(app.pid); 10420 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10421 } 10422 app.setPid(0); 10423 } 10424 } 10425 10426 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10427 // Look through the content providers we are waiting to have launched, 10428 // and if any run in this process then either schedule a restart of 10429 // the process or kill the client waiting for it if this process has 10430 // gone bad. 10431 int NL = mLaunchingProviders.size(); 10432 boolean restart = false; 10433 for (int i=0; i<NL; i++) { 10434 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10435 if (cpr.launchingApp == app) { 10436 if (!alwaysBad && !app.bad) { 10437 restart = true; 10438 } else { 10439 removeDyingProviderLocked(app, cpr, true); 10440 NL = mLaunchingProviders.size(); 10441 } 10442 } 10443 } 10444 return restart; 10445 } 10446 10447 // ========================================================= 10448 // SERVICES 10449 // ========================================================= 10450 10451 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10452 int flags) { 10453 enforceNotIsolatedCaller("getServices"); 10454 synchronized (this) { 10455 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10456 } 10457 } 10458 10459 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10460 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10461 synchronized (this) { 10462 return mServices.getRunningServiceControlPanelLocked(name); 10463 } 10464 } 10465 10466 public ComponentName startService(IApplicationThread caller, Intent service, 10467 String resolvedType) { 10468 enforceNotIsolatedCaller("startService"); 10469 // Refuse possible leaked file descriptors 10470 if (service != null && service.hasFileDescriptors() == true) { 10471 throw new IllegalArgumentException("File descriptors passed in Intent"); 10472 } 10473 10474 if (DEBUG_SERVICE) 10475 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10476 synchronized(this) { 10477 final int callingPid = Binder.getCallingPid(); 10478 final int callingUid = Binder.getCallingUid(); 10479 final long origId = Binder.clearCallingIdentity(); 10480 ComponentName res = mServices.startServiceLocked(caller, service, 10481 resolvedType, callingPid, callingUid); 10482 Binder.restoreCallingIdentity(origId); 10483 return res; 10484 } 10485 } 10486 10487 ComponentName startServiceInPackage(int uid, 10488 Intent service, String resolvedType) { 10489 synchronized(this) { 10490 if (DEBUG_SERVICE) 10491 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10492 final long origId = Binder.clearCallingIdentity(); 10493 ComponentName res = mServices.startServiceLocked(null, service, 10494 resolvedType, -1, uid); 10495 Binder.restoreCallingIdentity(origId); 10496 return res; 10497 } 10498 } 10499 10500 public int stopService(IApplicationThread caller, Intent service, 10501 String resolvedType) { 10502 enforceNotIsolatedCaller("stopService"); 10503 // Refuse possible leaked file descriptors 10504 if (service != null && service.hasFileDescriptors() == true) { 10505 throw new IllegalArgumentException("File descriptors passed in Intent"); 10506 } 10507 10508 synchronized(this) { 10509 return mServices.stopServiceLocked(caller, service, resolvedType); 10510 } 10511 } 10512 10513 public IBinder peekService(Intent service, String resolvedType) { 10514 enforceNotIsolatedCaller("peekService"); 10515 // Refuse possible leaked file descriptors 10516 if (service != null && service.hasFileDescriptors() == true) { 10517 throw new IllegalArgumentException("File descriptors passed in Intent"); 10518 } 10519 synchronized(this) { 10520 return mServices.peekServiceLocked(service, resolvedType); 10521 } 10522 } 10523 10524 public boolean stopServiceToken(ComponentName className, IBinder token, 10525 int startId) { 10526 synchronized(this) { 10527 return mServices.stopServiceTokenLocked(className, token, startId); 10528 } 10529 } 10530 10531 public void setServiceForeground(ComponentName className, IBinder token, 10532 int id, Notification notification, boolean removeNotification) { 10533 synchronized(this) { 10534 mServices.setServiceForegroundLocked(className, token, id, notification, 10535 removeNotification); 10536 } 10537 } 10538 10539 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10540 String className, int flags) { 10541 boolean result = false; 10542 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10543 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10544 if (ActivityManager.checkUidPermission( 10545 android.Manifest.permission.INTERACT_ACROSS_USERS, 10546 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10547 ComponentName comp = new ComponentName(aInfo.packageName, className); 10548 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10549 + " requests FLAG_SINGLE_USER, but app does not hold " 10550 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10551 Slog.w(TAG, msg); 10552 throw new SecurityException(msg); 10553 } 10554 result = true; 10555 } 10556 } else if (componentProcessName == aInfo.packageName) { 10557 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10558 } else if ("system".equals(componentProcessName)) { 10559 result = true; 10560 } 10561 if (DEBUG_MU) { 10562 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10563 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10564 } 10565 return result; 10566 } 10567 10568 public int bindService(IApplicationThread caller, IBinder token, 10569 Intent service, String resolvedType, 10570 IServiceConnection connection, int flags, int userId) { 10571 enforceNotIsolatedCaller("bindService"); 10572 // Refuse possible leaked file descriptors 10573 if (service != null && service.hasFileDescriptors() == true) { 10574 throw new IllegalArgumentException("File descriptors passed in Intent"); 10575 } 10576 10577 checkValidCaller(Binder.getCallingUid(), userId); 10578 10579 synchronized(this) { 10580 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10581 connection, flags, userId); 10582 } 10583 } 10584 10585 public boolean unbindService(IServiceConnection connection) { 10586 synchronized (this) { 10587 return mServices.unbindServiceLocked(connection); 10588 } 10589 } 10590 10591 public void publishService(IBinder token, Intent intent, IBinder service) { 10592 // Refuse possible leaked file descriptors 10593 if (intent != null && intent.hasFileDescriptors() == true) { 10594 throw new IllegalArgumentException("File descriptors passed in Intent"); 10595 } 10596 10597 synchronized(this) { 10598 if (!(token instanceof ServiceRecord)) { 10599 throw new IllegalArgumentException("Invalid service token"); 10600 } 10601 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10602 } 10603 } 10604 10605 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10606 // Refuse possible leaked file descriptors 10607 if (intent != null && intent.hasFileDescriptors() == true) { 10608 throw new IllegalArgumentException("File descriptors passed in Intent"); 10609 } 10610 10611 synchronized(this) { 10612 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10613 } 10614 } 10615 10616 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10617 synchronized(this) { 10618 if (!(token instanceof ServiceRecord)) { 10619 throw new IllegalArgumentException("Invalid service token"); 10620 } 10621 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10622 } 10623 } 10624 10625 // ========================================================= 10626 // BACKUP AND RESTORE 10627 // ========================================================= 10628 10629 // Cause the target app to be launched if necessary and its backup agent 10630 // instantiated. The backup agent will invoke backupAgentCreated() on the 10631 // activity manager to announce its creation. 10632 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10633 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10634 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10635 10636 synchronized(this) { 10637 // !!! TODO: currently no check here that we're already bound 10638 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10639 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10640 synchronized (stats) { 10641 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10642 } 10643 10644 // Backup agent is now in use, its package can't be stopped. 10645 try { 10646 AppGlobals.getPackageManager().setPackageStoppedState( 10647 app.packageName, false, UserId.getUserId(app.uid)); 10648 } catch (RemoteException e) { 10649 } catch (IllegalArgumentException e) { 10650 Slog.w(TAG, "Failed trying to unstop package " 10651 + app.packageName + ": " + e); 10652 } 10653 10654 BackupRecord r = new BackupRecord(ss, app, backupMode); 10655 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10656 ? new ComponentName(app.packageName, app.backupAgentName) 10657 : new ComponentName("android", "FullBackupAgent"); 10658 // startProcessLocked() returns existing proc's record if it's already running 10659 ProcessRecord proc = startProcessLocked(app.processName, app, 10660 false, 0, "backup", hostingName, false, false); 10661 if (proc == null) { 10662 Slog.e(TAG, "Unable to start backup agent process " + r); 10663 return false; 10664 } 10665 10666 r.app = proc; 10667 mBackupTarget = r; 10668 mBackupAppName = app.packageName; 10669 10670 // Try not to kill the process during backup 10671 updateOomAdjLocked(proc); 10672 10673 // If the process is already attached, schedule the creation of the backup agent now. 10674 // If it is not yet live, this will be done when it attaches to the framework. 10675 if (proc.thread != null) { 10676 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10677 try { 10678 proc.thread.scheduleCreateBackupAgent(app, 10679 compatibilityInfoForPackageLocked(app), backupMode); 10680 } catch (RemoteException e) { 10681 // Will time out on the backup manager side 10682 } 10683 } else { 10684 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10685 } 10686 // Invariants: at this point, the target app process exists and the application 10687 // is either already running or in the process of coming up. mBackupTarget and 10688 // mBackupAppName describe the app, so that when it binds back to the AM we 10689 // know that it's scheduled for a backup-agent operation. 10690 } 10691 10692 return true; 10693 } 10694 10695 // A backup agent has just come up 10696 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10697 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10698 + " = " + agent); 10699 10700 synchronized(this) { 10701 if (!agentPackageName.equals(mBackupAppName)) { 10702 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10703 return; 10704 } 10705 } 10706 10707 long oldIdent = Binder.clearCallingIdentity(); 10708 try { 10709 IBackupManager bm = IBackupManager.Stub.asInterface( 10710 ServiceManager.getService(Context.BACKUP_SERVICE)); 10711 bm.agentConnected(agentPackageName, agent); 10712 } catch (RemoteException e) { 10713 // can't happen; the backup manager service is local 10714 } catch (Exception e) { 10715 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10716 e.printStackTrace(); 10717 } finally { 10718 Binder.restoreCallingIdentity(oldIdent); 10719 } 10720 } 10721 10722 // done with this agent 10723 public void unbindBackupAgent(ApplicationInfo appInfo) { 10724 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10725 if (appInfo == null) { 10726 Slog.w(TAG, "unbind backup agent for null app"); 10727 return; 10728 } 10729 10730 synchronized(this) { 10731 if (mBackupAppName == null) { 10732 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10733 return; 10734 } 10735 10736 if (!mBackupAppName.equals(appInfo.packageName)) { 10737 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10738 return; 10739 } 10740 10741 ProcessRecord proc = mBackupTarget.app; 10742 mBackupTarget = null; 10743 mBackupAppName = null; 10744 10745 // Not backing this app up any more; reset its OOM adjustment 10746 updateOomAdjLocked(proc); 10747 10748 // If the app crashed during backup, 'thread' will be null here 10749 if (proc.thread != null) { 10750 try { 10751 proc.thread.scheduleDestroyBackupAgent(appInfo, 10752 compatibilityInfoForPackageLocked(appInfo)); 10753 } catch (Exception e) { 10754 Slog.e(TAG, "Exception when unbinding backup agent:"); 10755 e.printStackTrace(); 10756 } 10757 } 10758 } 10759 } 10760 // ========================================================= 10761 // BROADCASTS 10762 // ========================================================= 10763 10764 private final List getStickiesLocked(String action, IntentFilter filter, 10765 List cur) { 10766 final ContentResolver resolver = mContext.getContentResolver(); 10767 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10768 if (list == null) { 10769 return cur; 10770 } 10771 int N = list.size(); 10772 for (int i=0; i<N; i++) { 10773 Intent intent = list.get(i); 10774 if (filter.match(resolver, intent, true, TAG) >= 0) { 10775 if (cur == null) { 10776 cur = new ArrayList<Intent>(); 10777 } 10778 cur.add(intent); 10779 } 10780 } 10781 return cur; 10782 } 10783 10784 boolean isPendingBroadcastProcessLocked(int pid) { 10785 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10786 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10787 } 10788 10789 void skipPendingBroadcastLocked(int pid) { 10790 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10791 for (BroadcastQueue queue : mBroadcastQueues) { 10792 queue.skipPendingBroadcastLocked(pid); 10793 } 10794 } 10795 10796 // The app just attached; send any pending broadcasts that it should receive 10797 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10798 boolean didSomething = false; 10799 for (BroadcastQueue queue : mBroadcastQueues) { 10800 didSomething |= queue.sendPendingBroadcastsLocked(app); 10801 } 10802 return didSomething; 10803 } 10804 10805 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10806 IIntentReceiver receiver, IntentFilter filter, String permission) { 10807 enforceNotIsolatedCaller("registerReceiver"); 10808 int callingUid; 10809 synchronized(this) { 10810 ProcessRecord callerApp = null; 10811 if (caller != null) { 10812 callerApp = getRecordForAppLocked(caller); 10813 if (callerApp == null) { 10814 throw new SecurityException( 10815 "Unable to find app for caller " + caller 10816 + " (pid=" + Binder.getCallingPid() 10817 + ") when registering receiver " + receiver); 10818 } 10819 if (callerApp.info.uid != Process.SYSTEM_UID && 10820 !callerApp.pkgList.contains(callerPackage)) { 10821 throw new SecurityException("Given caller package " + callerPackage 10822 + " is not running in process " + callerApp); 10823 } 10824 callingUid = callerApp.info.uid; 10825 } else { 10826 callerPackage = null; 10827 callingUid = Binder.getCallingUid(); 10828 } 10829 10830 List allSticky = null; 10831 10832 // Look for any matching sticky broadcasts... 10833 Iterator actions = filter.actionsIterator(); 10834 if (actions != null) { 10835 while (actions.hasNext()) { 10836 String action = (String)actions.next(); 10837 allSticky = getStickiesLocked(action, filter, allSticky); 10838 } 10839 } else { 10840 allSticky = getStickiesLocked(null, filter, allSticky); 10841 } 10842 10843 // The first sticky in the list is returned directly back to 10844 // the client. 10845 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10846 10847 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10848 + ": " + sticky); 10849 10850 if (receiver == null) { 10851 return sticky; 10852 } 10853 10854 ReceiverList rl 10855 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10856 if (rl == null) { 10857 rl = new ReceiverList(this, callerApp, 10858 Binder.getCallingPid(), 10859 Binder.getCallingUid(), receiver); 10860 if (rl.app != null) { 10861 rl.app.receivers.add(rl); 10862 } else { 10863 try { 10864 receiver.asBinder().linkToDeath(rl, 0); 10865 } catch (RemoteException e) { 10866 return sticky; 10867 } 10868 rl.linkedToDeath = true; 10869 } 10870 mRegisteredReceivers.put(receiver.asBinder(), rl); 10871 } 10872 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10873 permission, callingUid); 10874 rl.add(bf); 10875 if (!bf.debugCheck()) { 10876 Slog.w(TAG, "==> For Dynamic broadast"); 10877 } 10878 mReceiverResolver.addFilter(bf); 10879 10880 // Enqueue broadcasts for all existing stickies that match 10881 // this filter. 10882 if (allSticky != null) { 10883 ArrayList receivers = new ArrayList(); 10884 receivers.add(bf); 10885 10886 int N = allSticky.size(); 10887 for (int i=0; i<N; i++) { 10888 Intent intent = (Intent)allSticky.get(i); 10889 BroadcastQueue queue = broadcastQueueForIntent(intent); 10890 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10891 null, -1, -1, null, receivers, null, 0, null, null, 10892 false, true, true, false); 10893 queue.enqueueParallelBroadcastLocked(r); 10894 queue.scheduleBroadcastsLocked(); 10895 } 10896 } 10897 10898 return sticky; 10899 } 10900 } 10901 10902 public void unregisterReceiver(IIntentReceiver receiver) { 10903 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10904 10905 final long origId = Binder.clearCallingIdentity(); 10906 try { 10907 boolean doTrim = false; 10908 10909 synchronized(this) { 10910 ReceiverList rl 10911 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10912 if (rl != null) { 10913 if (rl.curBroadcast != null) { 10914 BroadcastRecord r = rl.curBroadcast; 10915 final boolean doNext = finishReceiverLocked( 10916 receiver.asBinder(), r.resultCode, r.resultData, 10917 r.resultExtras, r.resultAbort, true); 10918 if (doNext) { 10919 doTrim = true; 10920 r.queue.processNextBroadcast(false); 10921 } 10922 } 10923 10924 if (rl.app != null) { 10925 rl.app.receivers.remove(rl); 10926 } 10927 removeReceiverLocked(rl); 10928 if (rl.linkedToDeath) { 10929 rl.linkedToDeath = false; 10930 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10931 } 10932 } 10933 } 10934 10935 // If we actually concluded any broadcasts, we might now be able 10936 // to trim the recipients' apps from our working set 10937 if (doTrim) { 10938 trimApplications(); 10939 return; 10940 } 10941 10942 } finally { 10943 Binder.restoreCallingIdentity(origId); 10944 } 10945 } 10946 10947 void removeReceiverLocked(ReceiverList rl) { 10948 mRegisteredReceivers.remove(rl.receiver.asBinder()); 10949 int N = rl.size(); 10950 for (int i=0; i<N; i++) { 10951 mReceiverResolver.removeFilter(rl.get(i)); 10952 } 10953 } 10954 10955 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 10956 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10957 ProcessRecord r = mLruProcesses.get(i); 10958 if (r.thread != null) { 10959 try { 10960 r.thread.dispatchPackageBroadcast(cmd, packages); 10961 } catch (RemoteException ex) { 10962 } 10963 } 10964 } 10965 } 10966 10967 private final int broadcastIntentLocked(ProcessRecord callerApp, 10968 String callerPackage, Intent intent, String resolvedType, 10969 IIntentReceiver resultTo, int resultCode, String resultData, 10970 Bundle map, String requiredPermission, 10971 boolean ordered, boolean sticky, int callingPid, int callingUid, 10972 int userId) { 10973 intent = new Intent(intent); 10974 10975 // By default broadcasts do not go to stopped apps. 10976 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 10977 10978 if (DEBUG_BROADCAST_LIGHT) Slog.v( 10979 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 10980 + " ordered=" + ordered + " userid=" + userId); 10981 if ((resultTo != null) && !ordered) { 10982 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 10983 } 10984 10985 boolean onlySendToCaller = false; 10986 10987 // If the caller is trying to send this broadcast to a different 10988 // user, verify that is allowed. 10989 if (UserId.getUserId(callingUid) != userId) { 10990 if (checkComponentPermission( 10991 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10992 callingPid, callingUid, -1, true) 10993 != PackageManager.PERMISSION_GRANTED) { 10994 if (checkComponentPermission( 10995 android.Manifest.permission.INTERACT_ACROSS_USERS, 10996 callingPid, callingUid, -1, true) 10997 == PackageManager.PERMISSION_GRANTED) { 10998 onlySendToCaller = true; 10999 } else { 11000 String msg = "Permission Denial: " + intent.getAction() 11001 + " broadcast from " + callerPackage 11002 + " asks to send as user " + userId 11003 + " but is calling from user " + UserId.getUserId(callingUid) 11004 + "; this requires " 11005 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11006 Slog.w(TAG, msg); 11007 throw new SecurityException(msg); 11008 } 11009 } 11010 } 11011 11012 // Handle special intents: if this broadcast is from the package 11013 // manager about a package being removed, we need to remove all of 11014 // its activities from the history stack. 11015 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11016 intent.getAction()); 11017 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11018 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11019 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11020 || uidRemoved) { 11021 if (checkComponentPermission( 11022 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11023 callingPid, callingUid, -1, true) 11024 == PackageManager.PERMISSION_GRANTED) { 11025 if (uidRemoved) { 11026 final Bundle intentExtras = intent.getExtras(); 11027 final int uid = intentExtras != null 11028 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11029 if (uid >= 0) { 11030 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11031 synchronized (bs) { 11032 bs.removeUidStatsLocked(uid); 11033 } 11034 } 11035 } else { 11036 // If resources are unvailble just force stop all 11037 // those packages and flush the attribute cache as well. 11038 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11039 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11040 if (list != null && (list.length > 0)) { 11041 for (String pkg : list) { 11042 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11043 } 11044 sendPackageBroadcastLocked( 11045 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11046 } 11047 } else { 11048 Uri data = intent.getData(); 11049 String ssp; 11050 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11051 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11052 forceStopPackageLocked(ssp, 11053 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11054 false, userId); 11055 } 11056 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11057 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11058 new String[] {ssp}); 11059 } 11060 } 11061 } 11062 } 11063 } else { 11064 String msg = "Permission Denial: " + intent.getAction() 11065 + " broadcast from " + callerPackage + " (pid=" + callingPid 11066 + ", uid=" + callingUid + ")" 11067 + " requires " 11068 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11069 Slog.w(TAG, msg); 11070 throw new SecurityException(msg); 11071 } 11072 11073 // Special case for adding a package: by default turn on compatibility 11074 // mode. 11075 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11076 Uri data = intent.getData(); 11077 String ssp; 11078 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11079 mCompatModePackages.handlePackageAddedLocked(ssp, 11080 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11081 } 11082 } 11083 11084 /* 11085 * If this is the time zone changed action, queue up a message that will reset the timezone 11086 * of all currently running processes. This message will get queued up before the broadcast 11087 * happens. 11088 */ 11089 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11090 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11091 } 11092 11093 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11094 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11095 } 11096 11097 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11098 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11099 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11100 } 11101 11102 /* 11103 * Prevent non-system code (defined here to be non-persistent 11104 * processes) from sending protected broadcasts. 11105 */ 11106 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11107 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11108 callingUid == 0) { 11109 // Always okay. 11110 } else if (callerApp == null || !callerApp.persistent) { 11111 try { 11112 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11113 intent.getAction())) { 11114 String msg = "Permission Denial: not allowed to send broadcast " 11115 + intent.getAction() + " from pid=" 11116 + callingPid + ", uid=" + callingUid; 11117 Slog.w(TAG, msg); 11118 throw new SecurityException(msg); 11119 } 11120 } catch (RemoteException e) { 11121 Slog.w(TAG, "Remote exception", e); 11122 return ActivityManager.BROADCAST_SUCCESS; 11123 } 11124 } 11125 11126 // Add to the sticky list if requested. 11127 if (sticky) { 11128 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11129 callingPid, callingUid) 11130 != PackageManager.PERMISSION_GRANTED) { 11131 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11132 + callingPid + ", uid=" + callingUid 11133 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11134 Slog.w(TAG, msg); 11135 throw new SecurityException(msg); 11136 } 11137 if (requiredPermission != null) { 11138 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11139 + " and enforce permission " + requiredPermission); 11140 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11141 } 11142 if (intent.getComponent() != null) { 11143 throw new SecurityException( 11144 "Sticky broadcasts can't target a specific component"); 11145 } 11146 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11147 if (list == null) { 11148 list = new ArrayList<Intent>(); 11149 mStickyBroadcasts.put(intent.getAction(), list); 11150 } 11151 int N = list.size(); 11152 int i; 11153 for (i=0; i<N; i++) { 11154 if (intent.filterEquals(list.get(i))) { 11155 // This sticky already exists, replace it. 11156 list.set(i, new Intent(intent)); 11157 break; 11158 } 11159 } 11160 if (i >= N) { 11161 list.add(new Intent(intent)); 11162 } 11163 } 11164 11165 // Figure out who all will receive this broadcast. 11166 List receivers = null; 11167 List<BroadcastFilter> registeredReceivers = null; 11168 try { 11169 // Need to resolve the intent to interested receivers... 11170 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11171 == 0) { 11172 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11173 intent, resolvedType, STOCK_PM_FLAGS, userId); 11174 } 11175 if (intent.getComponent() == null) { 11176 registeredReceivers = mReceiverResolver.queryIntent(intent, 11177 resolvedType, false, userId); 11178 } 11179 } catch (RemoteException ex) { 11180 // pm is in same process, this will never happen. 11181 } 11182 11183 final boolean replacePending = 11184 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11185 11186 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11187 + " replacePending=" + replacePending); 11188 11189 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11190 if (!ordered && NR > 0) { 11191 // If we are not serializing this broadcast, then send the 11192 // registered receivers separately so they don't wait for the 11193 // components to be launched. 11194 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11195 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11196 callerPackage, callingPid, callingUid, requiredPermission, 11197 registeredReceivers, resultTo, resultCode, resultData, map, 11198 ordered, sticky, false, onlySendToCaller); 11199 if (DEBUG_BROADCAST) Slog.v( 11200 TAG, "Enqueueing parallel broadcast " + r); 11201 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11202 if (!replaced) { 11203 queue.enqueueParallelBroadcastLocked(r); 11204 queue.scheduleBroadcastsLocked(); 11205 } 11206 registeredReceivers = null; 11207 NR = 0; 11208 } 11209 11210 // Merge into one list. 11211 int ir = 0; 11212 if (receivers != null) { 11213 // A special case for PACKAGE_ADDED: do not allow the package 11214 // being added to see this broadcast. This prevents them from 11215 // using this as a back door to get run as soon as they are 11216 // installed. Maybe in the future we want to have a special install 11217 // broadcast or such for apps, but we'd like to deliberately make 11218 // this decision. 11219 String skipPackages[] = null; 11220 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11221 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11222 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11223 Uri data = intent.getData(); 11224 if (data != null) { 11225 String pkgName = data.getSchemeSpecificPart(); 11226 if (pkgName != null) { 11227 skipPackages = new String[] { pkgName }; 11228 } 11229 } 11230 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11231 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11232 } 11233 if (skipPackages != null && (skipPackages.length > 0)) { 11234 for (String skipPackage : skipPackages) { 11235 if (skipPackage != null) { 11236 int NT = receivers.size(); 11237 for (int it=0; it<NT; it++) { 11238 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11239 if (curt.activityInfo.packageName.equals(skipPackage)) { 11240 receivers.remove(it); 11241 it--; 11242 NT--; 11243 } 11244 } 11245 } 11246 } 11247 } 11248 11249 int NT = receivers != null ? receivers.size() : 0; 11250 int it = 0; 11251 ResolveInfo curt = null; 11252 BroadcastFilter curr = null; 11253 while (it < NT && ir < NR) { 11254 if (curt == null) { 11255 curt = (ResolveInfo)receivers.get(it); 11256 } 11257 if (curr == null) { 11258 curr = registeredReceivers.get(ir); 11259 } 11260 if (curr.getPriority() >= curt.priority) { 11261 // Insert this broadcast record into the final list. 11262 receivers.add(it, curr); 11263 ir++; 11264 curr = null; 11265 it++; 11266 NT++; 11267 } else { 11268 // Skip to the next ResolveInfo in the final list. 11269 it++; 11270 curt = null; 11271 } 11272 } 11273 } 11274 while (ir < NR) { 11275 if (receivers == null) { 11276 receivers = new ArrayList(); 11277 } 11278 receivers.add(registeredReceivers.get(ir)); 11279 ir++; 11280 } 11281 11282 if ((receivers != null && receivers.size() > 0) 11283 || resultTo != null) { 11284 BroadcastQueue queue = broadcastQueueForIntent(intent); 11285 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11286 callerPackage, callingPid, callingUid, requiredPermission, 11287 receivers, resultTo, resultCode, resultData, map, ordered, 11288 sticky, false, onlySendToCaller); 11289 if (DEBUG_BROADCAST) Slog.v( 11290 TAG, "Enqueueing ordered broadcast " + r 11291 + ": prev had " + queue.mOrderedBroadcasts.size()); 11292 if (DEBUG_BROADCAST) { 11293 int seq = r.intent.getIntExtra("seq", -1); 11294 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11295 } 11296 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11297 if (!replaced) { 11298 queue.enqueueOrderedBroadcastLocked(r); 11299 queue.scheduleBroadcastsLocked(); 11300 } 11301 } 11302 11303 return ActivityManager.BROADCAST_SUCCESS; 11304 } 11305 11306 final Intent verifyBroadcastLocked(Intent intent) { 11307 // Refuse possible leaked file descriptors 11308 if (intent != null && intent.hasFileDescriptors() == true) { 11309 throw new IllegalArgumentException("File descriptors passed in Intent"); 11310 } 11311 11312 int flags = intent.getFlags(); 11313 11314 if (!mProcessesReady) { 11315 // if the caller really truly claims to know what they're doing, go 11316 // ahead and allow the broadcast without launching any receivers 11317 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11318 intent = new Intent(intent); 11319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11320 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11321 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11322 + " before boot completion"); 11323 throw new IllegalStateException("Cannot broadcast before boot completed"); 11324 } 11325 } 11326 11327 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11328 throw new IllegalArgumentException( 11329 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11330 } 11331 11332 return intent; 11333 } 11334 11335 public final int broadcastIntent(IApplicationThread caller, 11336 Intent intent, String resolvedType, IIntentReceiver resultTo, 11337 int resultCode, String resultData, Bundle map, 11338 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11339 enforceNotIsolatedCaller("broadcastIntent"); 11340 synchronized(this) { 11341 intent = verifyBroadcastLocked(intent); 11342 11343 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11344 final int callingPid = Binder.getCallingPid(); 11345 final int callingUid = Binder.getCallingUid(); 11346 final long origId = Binder.clearCallingIdentity(); 11347 int res = broadcastIntentLocked(callerApp, 11348 callerApp != null ? callerApp.info.packageName : null, 11349 intent, resolvedType, resultTo, 11350 resultCode, resultData, map, requiredPermission, serialized, sticky, 11351 callingPid, callingUid, userId); 11352 Binder.restoreCallingIdentity(origId); 11353 return res; 11354 } 11355 } 11356 11357 int broadcastIntentInPackage(String packageName, int uid, 11358 Intent intent, String resolvedType, IIntentReceiver resultTo, 11359 int resultCode, String resultData, Bundle map, 11360 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11361 synchronized(this) { 11362 intent = verifyBroadcastLocked(intent); 11363 11364 final long origId = Binder.clearCallingIdentity(); 11365 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11366 resultTo, resultCode, resultData, map, requiredPermission, 11367 serialized, sticky, -1, uid, userId); 11368 Binder.restoreCallingIdentity(origId); 11369 return res; 11370 } 11371 } 11372 11373 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11374 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11375 // Refuse possible leaked file descriptors 11376 if (intent != null && intent.hasFileDescriptors() == true) { 11377 throw new IllegalArgumentException("File descriptors passed in Intent"); 11378 } 11379 11380 synchronized(this) { 11381 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11382 != PackageManager.PERMISSION_GRANTED) { 11383 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11384 + Binder.getCallingPid() 11385 + ", uid=" + Binder.getCallingUid() 11386 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11387 Slog.w(TAG, msg); 11388 throw new SecurityException(msg); 11389 } 11390 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11391 if (list != null) { 11392 int N = list.size(); 11393 int i; 11394 for (i=0; i<N; i++) { 11395 if (intent.filterEquals(list.get(i))) { 11396 list.remove(i); 11397 break; 11398 } 11399 } 11400 } 11401 } 11402 } 11403 11404 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11405 String resultData, Bundle resultExtras, boolean resultAbort, 11406 boolean explicit) { 11407 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11408 if (r == null) { 11409 Slog.w(TAG, "finishReceiver called but not found on queue"); 11410 return false; 11411 } 11412 11413 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11414 explicit); 11415 } 11416 11417 public void finishReceiver(IBinder who, int resultCode, String resultData, 11418 Bundle resultExtras, boolean resultAbort) { 11419 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11420 11421 // Refuse possible leaked file descriptors 11422 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11423 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11424 } 11425 11426 final long origId = Binder.clearCallingIdentity(); 11427 try { 11428 boolean doNext = false; 11429 BroadcastRecord r = null; 11430 11431 synchronized(this) { 11432 r = broadcastRecordForReceiverLocked(who); 11433 if (r != null) { 11434 doNext = r.queue.finishReceiverLocked(r, resultCode, 11435 resultData, resultExtras, resultAbort, true); 11436 } 11437 } 11438 11439 if (doNext) { 11440 r.queue.processNextBroadcast(false); 11441 } 11442 trimApplications(); 11443 } finally { 11444 Binder.restoreCallingIdentity(origId); 11445 } 11446 } 11447 11448 // ========================================================= 11449 // INSTRUMENTATION 11450 // ========================================================= 11451 11452 public boolean startInstrumentation(ComponentName className, 11453 String profileFile, int flags, Bundle arguments, 11454 IInstrumentationWatcher watcher) { 11455 enforceNotIsolatedCaller("startInstrumentation"); 11456 // Refuse possible leaked file descriptors 11457 if (arguments != null && arguments.hasFileDescriptors()) { 11458 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11459 } 11460 11461 synchronized(this) { 11462 InstrumentationInfo ii = null; 11463 ApplicationInfo ai = null; 11464 try { 11465 ii = mContext.getPackageManager().getInstrumentationInfo( 11466 className, STOCK_PM_FLAGS); 11467 ai = mContext.getPackageManager().getApplicationInfo( 11468 ii.targetPackage, STOCK_PM_FLAGS); 11469 } catch (PackageManager.NameNotFoundException e) { 11470 } 11471 if (ii == null) { 11472 reportStartInstrumentationFailure(watcher, className, 11473 "Unable to find instrumentation info for: " + className); 11474 return false; 11475 } 11476 if (ai == null) { 11477 reportStartInstrumentationFailure(watcher, className, 11478 "Unable to find instrumentation target package: " + ii.targetPackage); 11479 return false; 11480 } 11481 11482 int match = mContext.getPackageManager().checkSignatures( 11483 ii.targetPackage, ii.packageName); 11484 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11485 String msg = "Permission Denial: starting instrumentation " 11486 + className + " from pid=" 11487 + Binder.getCallingPid() 11488 + ", uid=" + Binder.getCallingPid() 11489 + " not allowed because package " + ii.packageName 11490 + " does not have a signature matching the target " 11491 + ii.targetPackage; 11492 reportStartInstrumentationFailure(watcher, className, msg); 11493 throw new SecurityException(msg); 11494 } 11495 11496 int userId = UserId.getCallingUserId(); 11497 final long origId = Binder.clearCallingIdentity(); 11498 // Instrumentation can kill and relaunch even persistent processes 11499 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11500 ProcessRecord app = addAppLocked(ai, false); 11501 app.instrumentationClass = className; 11502 app.instrumentationInfo = ai; 11503 app.instrumentationProfileFile = profileFile; 11504 app.instrumentationArguments = arguments; 11505 app.instrumentationWatcher = watcher; 11506 app.instrumentationResultClass = className; 11507 Binder.restoreCallingIdentity(origId); 11508 } 11509 11510 return true; 11511 } 11512 11513 /** 11514 * Report errors that occur while attempting to start Instrumentation. Always writes the 11515 * error to the logs, but if somebody is watching, send the report there too. This enables 11516 * the "am" command to report errors with more information. 11517 * 11518 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11519 * @param cn The component name of the instrumentation. 11520 * @param report The error report. 11521 */ 11522 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11523 ComponentName cn, String report) { 11524 Slog.w(TAG, report); 11525 try { 11526 if (watcher != null) { 11527 Bundle results = new Bundle(); 11528 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11529 results.putString("Error", report); 11530 watcher.instrumentationStatus(cn, -1, results); 11531 } 11532 } catch (RemoteException e) { 11533 Slog.w(TAG, e); 11534 } 11535 } 11536 11537 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11538 if (app.instrumentationWatcher != null) { 11539 try { 11540 // NOTE: IInstrumentationWatcher *must* be oneway here 11541 app.instrumentationWatcher.instrumentationFinished( 11542 app.instrumentationClass, 11543 resultCode, 11544 results); 11545 } catch (RemoteException e) { 11546 } 11547 } 11548 app.instrumentationWatcher = null; 11549 app.instrumentationClass = null; 11550 app.instrumentationInfo = null; 11551 app.instrumentationProfileFile = null; 11552 app.instrumentationArguments = null; 11553 11554 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11555 } 11556 11557 public void finishInstrumentation(IApplicationThread target, 11558 int resultCode, Bundle results) { 11559 int userId = UserId.getCallingUserId(); 11560 // Refuse possible leaked file descriptors 11561 if (results != null && results.hasFileDescriptors()) { 11562 throw new IllegalArgumentException("File descriptors passed in Intent"); 11563 } 11564 11565 synchronized(this) { 11566 ProcessRecord app = getRecordForAppLocked(target); 11567 if (app == null) { 11568 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11569 return; 11570 } 11571 final long origId = Binder.clearCallingIdentity(); 11572 finishInstrumentationLocked(app, resultCode, results); 11573 Binder.restoreCallingIdentity(origId); 11574 } 11575 } 11576 11577 // ========================================================= 11578 // CONFIGURATION 11579 // ========================================================= 11580 11581 public ConfigurationInfo getDeviceConfigurationInfo() { 11582 ConfigurationInfo config = new ConfigurationInfo(); 11583 synchronized (this) { 11584 config.reqTouchScreen = mConfiguration.touchscreen; 11585 config.reqKeyboardType = mConfiguration.keyboard; 11586 config.reqNavigation = mConfiguration.navigation; 11587 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11588 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11589 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11590 } 11591 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11592 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11593 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11594 } 11595 config.reqGlEsVersion = GL_ES_VERSION; 11596 } 11597 return config; 11598 } 11599 11600 public Configuration getConfiguration() { 11601 Configuration ci; 11602 synchronized(this) { 11603 ci = new Configuration(mConfiguration); 11604 } 11605 return ci; 11606 } 11607 11608 public void updatePersistentConfiguration(Configuration values) { 11609 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11610 "updateConfiguration()"); 11611 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11612 "updateConfiguration()"); 11613 if (values == null) { 11614 throw new NullPointerException("Configuration must not be null"); 11615 } 11616 11617 synchronized(this) { 11618 final long origId = Binder.clearCallingIdentity(); 11619 updateConfigurationLocked(values, null, true, false); 11620 Binder.restoreCallingIdentity(origId); 11621 } 11622 } 11623 11624 public void updateConfiguration(Configuration values) { 11625 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11626 "updateConfiguration()"); 11627 11628 synchronized(this) { 11629 if (values == null && mWindowManager != null) { 11630 // sentinel: fetch the current configuration from the window manager 11631 values = mWindowManager.computeNewConfiguration(); 11632 } 11633 11634 if (mWindowManager != null) { 11635 mProcessList.applyDisplaySize(mWindowManager); 11636 } 11637 11638 final long origId = Binder.clearCallingIdentity(); 11639 if (values != null) { 11640 Settings.System.clearConfiguration(values); 11641 } 11642 updateConfigurationLocked(values, null, false, false); 11643 Binder.restoreCallingIdentity(origId); 11644 } 11645 } 11646 11647 /** 11648 * Do either or both things: (1) change the current configuration, and (2) 11649 * make sure the given activity is running with the (now) current 11650 * configuration. Returns true if the activity has been left running, or 11651 * false if <var>starting</var> is being destroyed to match the new 11652 * configuration. 11653 * @param persistent TODO 11654 */ 11655 boolean updateConfigurationLocked(Configuration values, 11656 ActivityRecord starting, boolean persistent, boolean initLocale) { 11657 // do nothing if we are headless 11658 if (mHeadless) return true; 11659 11660 int changes = 0; 11661 11662 boolean kept = true; 11663 11664 if (values != null) { 11665 Configuration newConfig = new Configuration(mConfiguration); 11666 changes = newConfig.updateFrom(values); 11667 if (changes != 0) { 11668 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11669 Slog.i(TAG, "Updating configuration to: " + values); 11670 } 11671 11672 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11673 11674 if (values.locale != null && !initLocale) { 11675 saveLocaleLocked(values.locale, 11676 !values.locale.equals(mConfiguration.locale), 11677 values.userSetLocale); 11678 } 11679 11680 mConfigurationSeq++; 11681 if (mConfigurationSeq <= 0) { 11682 mConfigurationSeq = 1; 11683 } 11684 newConfig.seq = mConfigurationSeq; 11685 mConfiguration = newConfig; 11686 Slog.i(TAG, "Config changed: " + newConfig); 11687 11688 final Configuration configCopy = new Configuration(mConfiguration); 11689 11690 // TODO: If our config changes, should we auto dismiss any currently 11691 // showing dialogs? 11692 mShowDialogs = shouldShowDialogs(newConfig); 11693 11694 AttributeCache ac = AttributeCache.instance(); 11695 if (ac != null) { 11696 ac.updateConfiguration(configCopy); 11697 } 11698 11699 // Make sure all resources in our process are updated 11700 // right now, so that anyone who is going to retrieve 11701 // resource values after we return will be sure to get 11702 // the new ones. This is especially important during 11703 // boot, where the first config change needs to guarantee 11704 // all resources have that config before following boot 11705 // code is executed. 11706 mSystemThread.applyConfigurationToResources(configCopy); 11707 11708 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11709 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11710 msg.obj = new Configuration(configCopy); 11711 mHandler.sendMessage(msg); 11712 } 11713 11714 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11715 ProcessRecord app = mLruProcesses.get(i); 11716 try { 11717 if (app.thread != null) { 11718 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11719 + app.processName + " new config " + mConfiguration); 11720 app.thread.scheduleConfigurationChanged(configCopy); 11721 } 11722 } catch (Exception e) { 11723 } 11724 } 11725 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11727 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11728 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11729 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11730 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11731 broadcastIntentLocked(null, null, 11732 new Intent(Intent.ACTION_LOCALE_CHANGED), 11733 null, null, 0, null, null, 11734 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11735 } 11736 } 11737 } 11738 11739 if (changes != 0 && starting == null) { 11740 // If the configuration changed, and the caller is not already 11741 // in the process of starting an activity, then find the top 11742 // activity to check if its configuration needs to change. 11743 starting = mMainStack.topRunningActivityLocked(null); 11744 } 11745 11746 if (starting != null) { 11747 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11748 // And we need to make sure at this point that all other activities 11749 // are made visible with the correct configuration. 11750 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11751 } 11752 11753 if (values != null && mWindowManager != null) { 11754 mWindowManager.setNewConfiguration(mConfiguration); 11755 } 11756 11757 return kept; 11758 } 11759 11760 /** 11761 * Decide based on the configuration whether we should shouw the ANR, 11762 * crash, etc dialogs. The idea is that if there is no affordnace to 11763 * press the on-screen buttons, we shouldn't show the dialog. 11764 * 11765 * A thought: SystemUI might also want to get told about this, the Power 11766 * dialog / global actions also might want different behaviors. 11767 */ 11768 private static final boolean shouldShowDialogs(Configuration config) { 11769 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11770 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11771 } 11772 11773 /** 11774 * Save the locale. You must be inside a synchronized (this) block. 11775 */ 11776 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11777 if(isDiff) { 11778 SystemProperties.set("user.language", l.getLanguage()); 11779 SystemProperties.set("user.region", l.getCountry()); 11780 } 11781 11782 if(isPersist) { 11783 SystemProperties.set("persist.sys.language", l.getLanguage()); 11784 SystemProperties.set("persist.sys.country", l.getCountry()); 11785 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11786 } 11787 } 11788 11789 @Override 11790 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11791 ActivityRecord srec = ActivityRecord.forToken(token); 11792 return srec != null && srec.task.affinity != null && 11793 srec.task.affinity.equals(destAffinity); 11794 } 11795 11796 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11797 Intent resultData) { 11798 ComponentName dest = destIntent.getComponent(); 11799 11800 synchronized (this) { 11801 ActivityRecord srec = ActivityRecord.forToken(token); 11802 if (srec == null) { 11803 return false; 11804 } 11805 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11806 final int start = history.indexOf(srec); 11807 if (start < 0) { 11808 // Current activity is not in history stack; do nothing. 11809 return false; 11810 } 11811 int finishTo = start - 1; 11812 ActivityRecord parent = null; 11813 boolean foundParentInTask = false; 11814 if (dest != null) { 11815 TaskRecord tr = srec.task; 11816 for (int i = start - 1; i >= 0; i--) { 11817 ActivityRecord r = history.get(i); 11818 if (tr != r.task) { 11819 // Couldn't find parent in the same task; stop at the one above this. 11820 // (Root of current task; in-app "home" behavior) 11821 // Always at least finish the current activity. 11822 finishTo = Math.min(start - 1, i + 1); 11823 parent = history.get(finishTo); 11824 break; 11825 } else if (r.info.packageName.equals(dest.getPackageName()) && 11826 r.info.name.equals(dest.getClassName())) { 11827 finishTo = i; 11828 parent = r; 11829 foundParentInTask = true; 11830 break; 11831 } 11832 } 11833 } 11834 11835 if (mController != null) { 11836 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11837 if (next != null) { 11838 // ask watcher if this is allowed 11839 boolean resumeOK = true; 11840 try { 11841 resumeOK = mController.activityResuming(next.packageName); 11842 } catch (RemoteException e) { 11843 mController = null; 11844 } 11845 11846 if (!resumeOK) { 11847 return false; 11848 } 11849 } 11850 } 11851 final long origId = Binder.clearCallingIdentity(); 11852 for (int i = start; i > finishTo; i--) { 11853 ActivityRecord r = history.get(i); 11854 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11855 "navigate-up"); 11856 // Only return the supplied result for the first activity finished 11857 resultCode = Activity.RESULT_CANCELED; 11858 resultData = null; 11859 } 11860 11861 if (parent != null && foundParentInTask) { 11862 final int parentLaunchMode = parent.info.launchMode; 11863 final int destIntentFlags = destIntent.getFlags(); 11864 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11865 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11866 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11867 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11868 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11869 } else { 11870 try { 11871 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11872 destIntent.getComponent(), 0, UserId.getCallingUserId()); 11873 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11874 null, aInfo, parent.appToken, null, 11875 0, -1, parent.launchedFromUid, 0, null, true, null); 11876 foundParentInTask = res == ActivityManager.START_SUCCESS; 11877 } catch (RemoteException e) { 11878 foundParentInTask = false; 11879 } 11880 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11881 resultData, "navigate-up"); 11882 } 11883 } 11884 Binder.restoreCallingIdentity(origId); 11885 return foundParentInTask; 11886 } 11887 } 11888 11889 public int getLaunchedFromUid(IBinder activityToken) { 11890 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11891 if (srec == null) { 11892 return -1; 11893 } 11894 return srec.launchedFromUid; 11895 } 11896 11897 // ========================================================= 11898 // LIFETIME MANAGEMENT 11899 // ========================================================= 11900 11901 // Returns which broadcast queue the app is the current [or imminent] receiver 11902 // on, or 'null' if the app is not an active broadcast recipient. 11903 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11904 BroadcastRecord r = app.curReceiver; 11905 if (r != null) { 11906 return r.queue; 11907 } 11908 11909 // It's not the current receiver, but it might be starting up to become one 11910 synchronized (this) { 11911 for (BroadcastQueue queue : mBroadcastQueues) { 11912 r = queue.mPendingBroadcast; 11913 if (r != null && r.curApp == app) { 11914 // found it; report which queue it's in 11915 return queue; 11916 } 11917 } 11918 } 11919 11920 return null; 11921 } 11922 11923 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11924 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11925 if (mAdjSeq == app.adjSeq) { 11926 // This adjustment has already been computed. If we are calling 11927 // from the top, we may have already computed our adjustment with 11928 // an earlier hidden adjustment that isn't really for us... if 11929 // so, use the new hidden adjustment. 11930 if (!recursed && app.hidden) { 11931 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 11932 } 11933 return app.curRawAdj; 11934 } 11935 11936 if (app.thread == null) { 11937 app.adjSeq = mAdjSeq; 11938 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 11939 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 11940 } 11941 11942 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 11943 app.adjSource = null; 11944 app.adjTarget = null; 11945 app.empty = false; 11946 app.hidden = false; 11947 11948 final int activitiesSize = app.activities.size(); 11949 11950 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 11951 // The max adjustment doesn't allow this app to be anything 11952 // below foreground, so it is not worth doing work for it. 11953 app.adjType = "fixed"; 11954 app.adjSeq = mAdjSeq; 11955 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 11956 app.foregroundActivities = false; 11957 app.keeping = true; 11958 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 11959 // System process can do UI, and when they do we want to have 11960 // them trim their memory after the user leaves the UI. To 11961 // facilitate this, here we need to determine whether or not it 11962 // is currently showing UI. 11963 app.systemNoUi = true; 11964 if (app == TOP_APP) { 11965 app.systemNoUi = false; 11966 } else if (activitiesSize > 0) { 11967 for (int j = 0; j < activitiesSize; j++) { 11968 final ActivityRecord r = app.activities.get(j); 11969 if (r.visible) { 11970 app.systemNoUi = false; 11971 break; 11972 } 11973 } 11974 } 11975 return (app.curAdj=app.maxAdj); 11976 } 11977 11978 app.keeping = false; 11979 app.systemNoUi = false; 11980 11981 // Determine the importance of the process, starting with most 11982 // important to least, and assign an appropriate OOM adjustment. 11983 int adj; 11984 int schedGroup; 11985 boolean foregroundActivities = false; 11986 boolean interesting = false; 11987 BroadcastQueue queue; 11988 if (app == TOP_APP) { 11989 // The last app on the list is the foreground app. 11990 adj = ProcessList.FOREGROUND_APP_ADJ; 11991 schedGroup = Process.THREAD_GROUP_DEFAULT; 11992 app.adjType = "top-activity"; 11993 foregroundActivities = true; 11994 interesting = true; 11995 } else if (app.instrumentationClass != null) { 11996 // Don't want to kill running instrumentation. 11997 adj = ProcessList.FOREGROUND_APP_ADJ; 11998 schedGroup = Process.THREAD_GROUP_DEFAULT; 11999 app.adjType = "instrumentation"; 12000 interesting = true; 12001 } else if ((queue = isReceivingBroadcast(app)) != null) { 12002 // An app that is currently receiving a broadcast also 12003 // counts as being in the foreground for OOM killer purposes. 12004 // It's placed in a sched group based on the nature of the 12005 // broadcast as reflected by which queue it's active in. 12006 adj = ProcessList.FOREGROUND_APP_ADJ; 12007 schedGroup = (queue == mFgBroadcastQueue) 12008 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12009 app.adjType = "broadcast"; 12010 } else if (app.executingServices.size() > 0) { 12011 // An app that is currently executing a service callback also 12012 // counts as being in the foreground. 12013 adj = ProcessList.FOREGROUND_APP_ADJ; 12014 schedGroup = Process.THREAD_GROUP_DEFAULT; 12015 app.adjType = "exec-service"; 12016 } else if (activitiesSize > 0) { 12017 // This app is in the background with paused activities. 12018 // We inspect activities to potentially upgrade adjustment further below. 12019 adj = hiddenAdj; 12020 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12021 app.hidden = true; 12022 app.adjType = "bg-activities"; 12023 } else { 12024 // A very not-needed process. If this is lower in the lru list, 12025 // we will push it in to the empty bucket. 12026 adj = hiddenAdj; 12027 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12028 app.hidden = true; 12029 app.empty = true; 12030 app.adjType = "bg-empty"; 12031 } 12032 12033 boolean hasStoppingActivities = false; 12034 12035 // Examine all activities if not already foreground. 12036 if (!foregroundActivities && activitiesSize > 0) { 12037 for (int j = 0; j < activitiesSize; j++) { 12038 final ActivityRecord r = app.activities.get(j); 12039 if (r.visible) { 12040 // App has a visible activity; only upgrade adjustment. 12041 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12042 adj = ProcessList.VISIBLE_APP_ADJ; 12043 app.adjType = "visible"; 12044 } 12045 schedGroup = Process.THREAD_GROUP_DEFAULT; 12046 app.hidden = false; 12047 foregroundActivities = true; 12048 break; 12049 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12050 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12051 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12052 app.adjType = "pausing"; 12053 } 12054 app.hidden = false; 12055 foregroundActivities = true; 12056 } else if (r.state == ActivityState.STOPPING) { 12057 // We will apply the actual adjustment later, because 12058 // we want to allow this process to immediately go through 12059 // any memory trimming that is in effect. 12060 app.hidden = false; 12061 foregroundActivities = true; 12062 hasStoppingActivities = true; 12063 } 12064 } 12065 } 12066 12067 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12068 if (app.foregroundServices) { 12069 // The user is aware of this app, so make it visible. 12070 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12071 app.hidden = false; 12072 app.adjType = "foreground-service"; 12073 schedGroup = Process.THREAD_GROUP_DEFAULT; 12074 } else if (app.forcingToForeground != null) { 12075 // The user is aware of this app, so make it visible. 12076 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12077 app.hidden = false; 12078 app.adjType = "force-foreground"; 12079 app.adjSource = app.forcingToForeground; 12080 schedGroup = Process.THREAD_GROUP_DEFAULT; 12081 } 12082 } 12083 12084 if (app.foregroundServices) { 12085 interesting = true; 12086 } 12087 12088 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12089 // We don't want to kill the current heavy-weight process. 12090 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12091 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12092 app.hidden = false; 12093 app.adjType = "heavy"; 12094 } 12095 12096 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12097 // This process is hosting what we currently consider to be the 12098 // home app, so we don't want to let it go into the background. 12099 adj = ProcessList.HOME_APP_ADJ; 12100 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12101 app.hidden = false; 12102 app.adjType = "home"; 12103 } 12104 12105 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12106 && app.activities.size() > 0) { 12107 // This was the previous process that showed UI to the user. 12108 // We want to try to keep it around more aggressively, to give 12109 // a good experience around switching between two apps. 12110 adj = ProcessList.PREVIOUS_APP_ADJ; 12111 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12112 app.hidden = false; 12113 app.adjType = "previous"; 12114 } 12115 12116 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12117 + " reason=" + app.adjType); 12118 12119 // By default, we use the computed adjustment. It may be changed if 12120 // there are applications dependent on our services or providers, but 12121 // this gives us a baseline and makes sure we don't get into an 12122 // infinite recursion. 12123 app.adjSeq = mAdjSeq; 12124 app.curRawAdj = app.nonStoppingAdj = adj; 12125 12126 if (mBackupTarget != null && app == mBackupTarget.app) { 12127 // If possible we want to avoid killing apps while they're being backed up 12128 if (adj > ProcessList.BACKUP_APP_ADJ) { 12129 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12130 adj = ProcessList.BACKUP_APP_ADJ; 12131 app.adjType = "backup"; 12132 app.hidden = false; 12133 } 12134 } 12135 12136 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12137 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12138 final long now = SystemClock.uptimeMillis(); 12139 // This process is more important if the top activity is 12140 // bound to the service. 12141 Iterator<ServiceRecord> jt = app.services.iterator(); 12142 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12143 ServiceRecord s = jt.next(); 12144 if (s.startRequested) { 12145 if (app.hasShownUi && app != mHomeProcess) { 12146 // If this process has shown some UI, let it immediately 12147 // go to the LRU list because it may be pretty heavy with 12148 // UI stuff. We'll tag it with a label just to help 12149 // debug and understand what is going on. 12150 if (adj > ProcessList.SERVICE_ADJ) { 12151 app.adjType = "started-bg-ui-services"; 12152 } 12153 } else { 12154 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12155 // This service has seen some activity within 12156 // recent memory, so we will keep its process ahead 12157 // of the background processes. 12158 if (adj > ProcessList.SERVICE_ADJ) { 12159 adj = ProcessList.SERVICE_ADJ; 12160 app.adjType = "started-services"; 12161 app.hidden = false; 12162 } 12163 } 12164 // If we have let the service slide into the background 12165 // state, still have some text describing what it is doing 12166 // even though the service no longer has an impact. 12167 if (adj > ProcessList.SERVICE_ADJ) { 12168 app.adjType = "started-bg-services"; 12169 } 12170 } 12171 // Don't kill this process because it is doing work; it 12172 // has said it is doing work. 12173 app.keeping = true; 12174 } 12175 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12176 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12177 Iterator<ArrayList<ConnectionRecord>> kt 12178 = s.connections.values().iterator(); 12179 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12180 ArrayList<ConnectionRecord> clist = kt.next(); 12181 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12182 // XXX should compute this based on the max of 12183 // all connected clients. 12184 ConnectionRecord cr = clist.get(i); 12185 if (cr.binding.client == app) { 12186 // Binding to ourself is not interesting. 12187 continue; 12188 } 12189 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12190 ProcessRecord client = cr.binding.client; 12191 int clientAdj = adj; 12192 int myHiddenAdj = hiddenAdj; 12193 if (myHiddenAdj > client.hiddenAdj) { 12194 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12195 myHiddenAdj = client.hiddenAdj; 12196 } else { 12197 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12198 } 12199 } 12200 clientAdj = computeOomAdjLocked( 12201 client, myHiddenAdj, TOP_APP, true, doingAll); 12202 String adjType = null; 12203 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12204 // Not doing bind OOM management, so treat 12205 // this guy more like a started service. 12206 if (app.hasShownUi && app != mHomeProcess) { 12207 // If this process has shown some UI, let it immediately 12208 // go to the LRU list because it may be pretty heavy with 12209 // UI stuff. We'll tag it with a label just to help 12210 // debug and understand what is going on. 12211 if (adj > clientAdj) { 12212 adjType = "bound-bg-ui-services"; 12213 } 12214 app.hidden = false; 12215 clientAdj = adj; 12216 } else { 12217 if (now >= (s.lastActivity 12218 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12219 // This service has not seen activity within 12220 // recent memory, so allow it to drop to the 12221 // LRU list if there is no other reason to keep 12222 // it around. We'll also tag it with a label just 12223 // to help debug and undertand what is going on. 12224 if (adj > clientAdj) { 12225 adjType = "bound-bg-services"; 12226 } 12227 clientAdj = adj; 12228 } 12229 } 12230 } 12231 if (adj > clientAdj) { 12232 // If this process has recently shown UI, and 12233 // the process that is binding to it is less 12234 // important than being visible, then we don't 12235 // care about the binding as much as we care 12236 // about letting this process get into the LRU 12237 // list to be killed and restarted if needed for 12238 // memory. 12239 if (app.hasShownUi && app != mHomeProcess 12240 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12241 adjType = "bound-bg-ui-services"; 12242 } else { 12243 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12244 |Context.BIND_IMPORTANT)) != 0) { 12245 adj = clientAdj; 12246 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12247 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12248 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12249 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12250 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12251 adj = clientAdj; 12252 } else { 12253 app.pendingUiClean = true; 12254 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12255 adj = ProcessList.VISIBLE_APP_ADJ; 12256 } 12257 } 12258 if (!client.hidden) { 12259 app.hidden = false; 12260 } 12261 if (client.keeping) { 12262 app.keeping = true; 12263 } 12264 adjType = "service"; 12265 } 12266 } 12267 if (adjType != null) { 12268 app.adjType = adjType; 12269 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12270 .REASON_SERVICE_IN_USE; 12271 app.adjSource = cr.binding.client; 12272 app.adjSourceOom = clientAdj; 12273 app.adjTarget = s.name; 12274 } 12275 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12276 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12277 schedGroup = Process.THREAD_GROUP_DEFAULT; 12278 } 12279 } 12280 } 12281 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12282 ActivityRecord a = cr.activity; 12283 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12284 (a.visible || a.state == ActivityState.RESUMED 12285 || a.state == ActivityState.PAUSING)) { 12286 adj = ProcessList.FOREGROUND_APP_ADJ; 12287 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12288 schedGroup = Process.THREAD_GROUP_DEFAULT; 12289 } 12290 app.hidden = false; 12291 app.adjType = "service"; 12292 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12293 .REASON_SERVICE_IN_USE; 12294 app.adjSource = a; 12295 app.adjSourceOom = adj; 12296 app.adjTarget = s.name; 12297 } 12298 } 12299 } 12300 } 12301 } 12302 } 12303 12304 // Finally, if this process has active services running in it, we 12305 // would like to avoid killing it unless it would prevent the current 12306 // application from running. By default we put the process in 12307 // with the rest of the background processes; as we scan through 12308 // its services we may bump it up from there. 12309 if (adj > hiddenAdj) { 12310 adj = hiddenAdj; 12311 app.hidden = false; 12312 app.adjType = "bg-services"; 12313 } 12314 } 12315 12316 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12317 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12318 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12319 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12320 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12321 ContentProviderRecord cpr = jt.next(); 12322 for (int i = cpr.connections.size()-1; 12323 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12324 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12325 i--) { 12326 ContentProviderConnection conn = cpr.connections.get(i); 12327 ProcessRecord client = conn.client; 12328 if (client == app) { 12329 // Being our own client is not interesting. 12330 continue; 12331 } 12332 int myHiddenAdj = hiddenAdj; 12333 if (myHiddenAdj > client.hiddenAdj) { 12334 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12335 myHiddenAdj = client.hiddenAdj; 12336 } else { 12337 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12338 } 12339 } 12340 int clientAdj = computeOomAdjLocked( 12341 client, myHiddenAdj, TOP_APP, true, doingAll); 12342 if (adj > clientAdj) { 12343 if (app.hasShownUi && app != mHomeProcess 12344 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12345 app.adjType = "bg-ui-provider"; 12346 } else { 12347 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12348 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12349 app.adjType = "provider"; 12350 } 12351 if (!client.hidden) { 12352 app.hidden = false; 12353 } 12354 if (client.keeping) { 12355 app.keeping = true; 12356 } 12357 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12358 .REASON_PROVIDER_IN_USE; 12359 app.adjSource = client; 12360 app.adjSourceOom = clientAdj; 12361 app.adjTarget = cpr.name; 12362 } 12363 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12364 schedGroup = Process.THREAD_GROUP_DEFAULT; 12365 } 12366 } 12367 // If the provider has external (non-framework) process 12368 // dependencies, ensure that its adjustment is at least 12369 // FOREGROUND_APP_ADJ. 12370 if (cpr.hasExternalProcessHandles()) { 12371 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12372 adj = ProcessList.FOREGROUND_APP_ADJ; 12373 schedGroup = Process.THREAD_GROUP_DEFAULT; 12374 app.hidden = false; 12375 app.keeping = true; 12376 app.adjType = "provider"; 12377 app.adjTarget = cpr.name; 12378 } 12379 } 12380 } 12381 } 12382 12383 if (adj == ProcessList.SERVICE_ADJ) { 12384 if (doingAll) { 12385 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12386 mNewNumServiceProcs++; 12387 } 12388 if (app.serviceb) { 12389 adj = ProcessList.SERVICE_B_ADJ; 12390 } 12391 } else { 12392 app.serviceb = false; 12393 } 12394 12395 app.nonStoppingAdj = adj; 12396 12397 if (hasStoppingActivities) { 12398 // Only upgrade adjustment. 12399 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12400 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12401 app.adjType = "stopping"; 12402 } 12403 } 12404 12405 app.curRawAdj = adj; 12406 12407 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12408 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12409 if (adj > app.maxAdj) { 12410 adj = app.maxAdj; 12411 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12412 schedGroup = Process.THREAD_GROUP_DEFAULT; 12413 } 12414 } 12415 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12416 app.keeping = true; 12417 } 12418 12419 if (app.hasAboveClient) { 12420 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12421 // then we need to drop its adjustment to be lower than the service's 12422 // in order to honor the request. We want to drop it by one adjustment 12423 // level... but there is special meaning applied to various levels so 12424 // we will skip some of them. 12425 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12426 // System process will not get dropped, ever 12427 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12428 adj = ProcessList.VISIBLE_APP_ADJ; 12429 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12430 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12431 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12432 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12433 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12434 adj++; 12435 } 12436 } 12437 12438 int importance = app.memImportance; 12439 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12440 app.curAdj = adj; 12441 app.curSchedGroup = schedGroup; 12442 if (!interesting) { 12443 // For this reporting, if there is not something explicitly 12444 // interesting in this process then we will push it to the 12445 // background importance. 12446 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12447 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12448 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12449 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12450 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12451 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12452 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12453 } else if (adj >= ProcessList.SERVICE_ADJ) { 12454 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12455 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12456 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12457 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12458 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12459 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12460 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12461 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12462 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12463 } else { 12464 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12465 } 12466 } 12467 12468 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12469 if (foregroundActivities != app.foregroundActivities) { 12470 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12471 } 12472 if (changes != 0) { 12473 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12474 app.memImportance = importance; 12475 app.foregroundActivities = foregroundActivities; 12476 int i = mPendingProcessChanges.size()-1; 12477 ProcessChangeItem item = null; 12478 while (i >= 0) { 12479 item = mPendingProcessChanges.get(i); 12480 if (item.pid == app.pid) { 12481 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12482 break; 12483 } 12484 i--; 12485 } 12486 if (i < 0) { 12487 // No existing item in pending changes; need a new one. 12488 final int NA = mAvailProcessChanges.size(); 12489 if (NA > 0) { 12490 item = mAvailProcessChanges.remove(NA-1); 12491 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12492 } else { 12493 item = new ProcessChangeItem(); 12494 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12495 } 12496 item.changes = 0; 12497 item.pid = app.pid; 12498 item.uid = app.info.uid; 12499 if (mPendingProcessChanges.size() == 0) { 12500 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12501 "*** Enqueueing dispatch processes changed!"); 12502 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12503 } 12504 mPendingProcessChanges.add(item); 12505 } 12506 item.changes |= changes; 12507 item.importance = importance; 12508 item.foregroundActivities = foregroundActivities; 12509 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12510 + Integer.toHexString(System.identityHashCode(item)) 12511 + " " + app.toShortString() + ": changes=" + item.changes 12512 + " importance=" + item.importance 12513 + " foreground=" + item.foregroundActivities 12514 + " type=" + app.adjType + " source=" + app.adjSource 12515 + " target=" + app.adjTarget); 12516 } 12517 12518 return app.curRawAdj; 12519 } 12520 12521 /** 12522 * Ask a given process to GC right now. 12523 */ 12524 final void performAppGcLocked(ProcessRecord app) { 12525 try { 12526 app.lastRequestedGc = SystemClock.uptimeMillis(); 12527 if (app.thread != null) { 12528 if (app.reportLowMemory) { 12529 app.reportLowMemory = false; 12530 app.thread.scheduleLowMemory(); 12531 } else { 12532 app.thread.processInBackground(); 12533 } 12534 } 12535 } catch (Exception e) { 12536 // whatever. 12537 } 12538 } 12539 12540 /** 12541 * Returns true if things are idle enough to perform GCs. 12542 */ 12543 private final boolean canGcNowLocked() { 12544 boolean processingBroadcasts = false; 12545 for (BroadcastQueue q : mBroadcastQueues) { 12546 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12547 processingBroadcasts = true; 12548 } 12549 } 12550 return !processingBroadcasts 12551 && (mSleeping || (mMainStack.mResumedActivity != null && 12552 mMainStack.mResumedActivity.idle)); 12553 } 12554 12555 /** 12556 * Perform GCs on all processes that are waiting for it, but only 12557 * if things are idle. 12558 */ 12559 final void performAppGcsLocked() { 12560 final int N = mProcessesToGc.size(); 12561 if (N <= 0) { 12562 return; 12563 } 12564 if (canGcNowLocked()) { 12565 while (mProcessesToGc.size() > 0) { 12566 ProcessRecord proc = mProcessesToGc.remove(0); 12567 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12568 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12569 <= SystemClock.uptimeMillis()) { 12570 // To avoid spamming the system, we will GC processes one 12571 // at a time, waiting a few seconds between each. 12572 performAppGcLocked(proc); 12573 scheduleAppGcsLocked(); 12574 return; 12575 } else { 12576 // It hasn't been long enough since we last GCed this 12577 // process... put it in the list to wait for its time. 12578 addProcessToGcListLocked(proc); 12579 break; 12580 } 12581 } 12582 } 12583 12584 scheduleAppGcsLocked(); 12585 } 12586 } 12587 12588 /** 12589 * If all looks good, perform GCs on all processes waiting for them. 12590 */ 12591 final void performAppGcsIfAppropriateLocked() { 12592 if (canGcNowLocked()) { 12593 performAppGcsLocked(); 12594 return; 12595 } 12596 // Still not idle, wait some more. 12597 scheduleAppGcsLocked(); 12598 } 12599 12600 /** 12601 * Schedule the execution of all pending app GCs. 12602 */ 12603 final void scheduleAppGcsLocked() { 12604 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12605 12606 if (mProcessesToGc.size() > 0) { 12607 // Schedule a GC for the time to the next process. 12608 ProcessRecord proc = mProcessesToGc.get(0); 12609 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12610 12611 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12612 long now = SystemClock.uptimeMillis(); 12613 if (when < (now+GC_TIMEOUT)) { 12614 when = now + GC_TIMEOUT; 12615 } 12616 mHandler.sendMessageAtTime(msg, when); 12617 } 12618 } 12619 12620 /** 12621 * Add a process to the array of processes waiting to be GCed. Keeps the 12622 * list in sorted order by the last GC time. The process can't already be 12623 * on the list. 12624 */ 12625 final void addProcessToGcListLocked(ProcessRecord proc) { 12626 boolean added = false; 12627 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12628 if (mProcessesToGc.get(i).lastRequestedGc < 12629 proc.lastRequestedGc) { 12630 added = true; 12631 mProcessesToGc.add(i+1, proc); 12632 break; 12633 } 12634 } 12635 if (!added) { 12636 mProcessesToGc.add(0, proc); 12637 } 12638 } 12639 12640 /** 12641 * Set up to ask a process to GC itself. This will either do it 12642 * immediately, or put it on the list of processes to gc the next 12643 * time things are idle. 12644 */ 12645 final void scheduleAppGcLocked(ProcessRecord app) { 12646 long now = SystemClock.uptimeMillis(); 12647 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12648 return; 12649 } 12650 if (!mProcessesToGc.contains(app)) { 12651 addProcessToGcListLocked(app); 12652 scheduleAppGcsLocked(); 12653 } 12654 } 12655 12656 final void checkExcessivePowerUsageLocked(boolean doKills) { 12657 updateCpuStatsNow(); 12658 12659 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12660 boolean doWakeKills = doKills; 12661 boolean doCpuKills = doKills; 12662 if (mLastPowerCheckRealtime == 0) { 12663 doWakeKills = false; 12664 } 12665 if (mLastPowerCheckUptime == 0) { 12666 doCpuKills = false; 12667 } 12668 if (stats.isScreenOn()) { 12669 doWakeKills = false; 12670 } 12671 final long curRealtime = SystemClock.elapsedRealtime(); 12672 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12673 final long curUptime = SystemClock.uptimeMillis(); 12674 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12675 mLastPowerCheckRealtime = curRealtime; 12676 mLastPowerCheckUptime = curUptime; 12677 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12678 doWakeKills = false; 12679 } 12680 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12681 doCpuKills = false; 12682 } 12683 int i = mLruProcesses.size(); 12684 while (i > 0) { 12685 i--; 12686 ProcessRecord app = mLruProcesses.get(i); 12687 if (!app.keeping) { 12688 long wtime; 12689 synchronized (stats) { 12690 wtime = stats.getProcessWakeTime(app.info.uid, 12691 app.pid, curRealtime); 12692 } 12693 long wtimeUsed = wtime - app.lastWakeTime; 12694 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12695 if (DEBUG_POWER) { 12696 StringBuilder sb = new StringBuilder(128); 12697 sb.append("Wake for "); 12698 app.toShortString(sb); 12699 sb.append(": over "); 12700 TimeUtils.formatDuration(realtimeSince, sb); 12701 sb.append(" used "); 12702 TimeUtils.formatDuration(wtimeUsed, sb); 12703 sb.append(" ("); 12704 sb.append((wtimeUsed*100)/realtimeSince); 12705 sb.append("%)"); 12706 Slog.i(TAG, sb.toString()); 12707 sb.setLength(0); 12708 sb.append("CPU for "); 12709 app.toShortString(sb); 12710 sb.append(": over "); 12711 TimeUtils.formatDuration(uptimeSince, sb); 12712 sb.append(" used "); 12713 TimeUtils.formatDuration(cputimeUsed, sb); 12714 sb.append(" ("); 12715 sb.append((cputimeUsed*100)/uptimeSince); 12716 sb.append("%)"); 12717 Slog.i(TAG, sb.toString()); 12718 } 12719 // If a process has held a wake lock for more 12720 // than 50% of the time during this period, 12721 // that sounds bad. Kill! 12722 if (doWakeKills && realtimeSince > 0 12723 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12724 synchronized (stats) { 12725 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12726 realtimeSince, wtimeUsed); 12727 } 12728 Slog.w(TAG, "Excessive wake lock in " + app.processName 12729 + " (pid " + app.pid + "): held " + wtimeUsed 12730 + " during " + realtimeSince); 12731 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12732 app.processName, app.setAdj, "excessive wake lock"); 12733 Process.killProcessQuiet(app.pid); 12734 } else if (doCpuKills && uptimeSince > 0 12735 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12736 synchronized (stats) { 12737 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12738 uptimeSince, cputimeUsed); 12739 } 12740 Slog.w(TAG, "Excessive CPU in " + app.processName 12741 + " (pid " + app.pid + "): used " + cputimeUsed 12742 + " during " + uptimeSince); 12743 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12744 app.processName, app.setAdj, "excessive cpu"); 12745 Process.killProcessQuiet(app.pid); 12746 } else { 12747 app.lastWakeTime = wtime; 12748 app.lastCpuTime = app.curCpuTime; 12749 } 12750 } 12751 } 12752 } 12753 12754 private final boolean updateOomAdjLocked( 12755 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 12756 app.hiddenAdj = hiddenAdj; 12757 12758 if (app.thread == null) { 12759 return false; 12760 } 12761 12762 final boolean wasKeeping = app.keeping; 12763 12764 boolean success = true; 12765 12766 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 12767 12768 if (app.curRawAdj != app.setRawAdj) { 12769 if (wasKeeping && !app.keeping) { 12770 // This app is no longer something we want to keep. Note 12771 // its current wake lock time to later know to kill it if 12772 // it is not behaving well. 12773 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12774 synchronized (stats) { 12775 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12776 app.pid, SystemClock.elapsedRealtime()); 12777 } 12778 app.lastCpuTime = app.curCpuTime; 12779 } 12780 12781 app.setRawAdj = app.curRawAdj; 12782 } 12783 12784 if (app.curAdj != app.setAdj) { 12785 if (Process.setOomAdj(app.pid, app.curAdj)) { 12786 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12787 TAG, "Set " + app.pid + " " + app.processName + 12788 " adj " + app.curAdj + ": " + app.adjType); 12789 app.setAdj = app.curAdj; 12790 } else { 12791 success = false; 12792 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12793 } 12794 } 12795 if (app.setSchedGroup != app.curSchedGroup) { 12796 app.setSchedGroup = app.curSchedGroup; 12797 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12798 "Setting process group of " + app.processName 12799 + " to " + app.curSchedGroup); 12800 if (app.waitingToKill != null && 12801 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12802 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12803 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12804 app.processName, app.setAdj, app.waitingToKill); 12805 app.killedBackground = true; 12806 Process.killProcessQuiet(app.pid); 12807 success = false; 12808 } else { 12809 if (true) { 12810 long oldId = Binder.clearCallingIdentity(); 12811 try { 12812 Process.setProcessGroup(app.pid, app.curSchedGroup); 12813 } catch (Exception e) { 12814 Slog.w(TAG, "Failed setting process group of " + app.pid 12815 + " to " + app.curSchedGroup); 12816 e.printStackTrace(); 12817 } finally { 12818 Binder.restoreCallingIdentity(oldId); 12819 } 12820 } else { 12821 if (app.thread != null) { 12822 try { 12823 app.thread.setSchedulingGroup(app.curSchedGroup); 12824 } catch (RemoteException e) { 12825 } 12826 } 12827 } 12828 } 12829 } 12830 return success; 12831 } 12832 12833 private final ActivityRecord resumedAppLocked() { 12834 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12835 if (resumedActivity == null || resumedActivity.app == null) { 12836 resumedActivity = mMainStack.mPausingActivity; 12837 if (resumedActivity == null || resumedActivity.app == null) { 12838 resumedActivity = mMainStack.topRunningActivityLocked(null); 12839 } 12840 } 12841 return resumedActivity; 12842 } 12843 12844 final boolean updateOomAdjLocked(ProcessRecord app) { 12845 final ActivityRecord TOP_ACT = resumedAppLocked(); 12846 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12847 int curAdj = app.curAdj; 12848 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12849 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12850 12851 mAdjSeq++; 12852 12853 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 12854 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12855 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12856 if (nowHidden != wasHidden) { 12857 // Changed to/from hidden state, so apps after it in the LRU 12858 // list may also be changed. 12859 updateOomAdjLocked(); 12860 } 12861 return success; 12862 } 12863 12864 final void updateOomAdjLocked() { 12865 final ActivityRecord TOP_ACT = resumedAppLocked(); 12866 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12867 12868 if (false) { 12869 RuntimeException e = new RuntimeException(); 12870 e.fillInStackTrace(); 12871 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12872 } 12873 12874 mAdjSeq++; 12875 mNewNumServiceProcs = 0; 12876 12877 // Let's determine how many processes we have running vs. 12878 // how many slots we have for background processes; we may want 12879 // to put multiple processes in a slot of there are enough of 12880 // them. 12881 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 12882 int factor = (mLruProcesses.size()-4)/numSlots; 12883 if (factor < 1) factor = 1; 12884 int step = 0; 12885 int numHidden = 0; 12886 int numTrimming = 0; 12887 12888 // First update the OOM adjustment for each of the 12889 // application processes based on their current state. 12890 int i = mLruProcesses.size(); 12891 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12892 while (i > 0) { 12893 i--; 12894 ProcessRecord app = mLruProcesses.get(i); 12895 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 12896 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 12897 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 12898 && app.curAdj == curHiddenAdj) { 12899 step++; 12900 if (step >= factor) { 12901 step = 0; 12902 curHiddenAdj++; 12903 } 12904 } 12905 if (!app.killedBackground) { 12906 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12907 numHidden++; 12908 if (numHidden > mProcessLimit) { 12909 Slog.i(TAG, "No longer want " + app.processName 12910 + " (pid " + app.pid + "): hidden #" + numHidden); 12911 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12912 app.processName, app.setAdj, "too many background"); 12913 app.killedBackground = true; 12914 Process.killProcessQuiet(app.pid); 12915 } 12916 } 12917 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 12918 // If this is an isolated process, and there are no 12919 // services running in it, then the process is no longer 12920 // needed. We agressively kill these because we can by 12921 // definition not re-use the same process again, and it is 12922 // good to avoid having whatever code was running in them 12923 // left sitting around after no longer needed. 12924 Slog.i(TAG, "Isolated process " + app.processName 12925 + " (pid " + app.pid + ") no longer needed"); 12926 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12927 app.processName, app.setAdj, "isolated not needed"); 12928 app.killedBackground = true; 12929 Process.killProcessQuiet(app.pid); 12930 } 12931 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12932 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12933 && !app.killedBackground) { 12934 numTrimming++; 12935 } 12936 } 12937 } 12938 12939 mNumServiceProcs = mNewNumServiceProcs; 12940 12941 // Now determine the memory trimming level of background processes. 12942 // Unfortunately we need to start at the back of the list to do this 12943 // properly. We only do this if the number of background apps we 12944 // are managing to keep around is less than half the maximum we desire; 12945 // if we are keeping a good number around, we'll let them use whatever 12946 // memory they want. 12947 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 12948 final int N = mLruProcesses.size(); 12949 factor = numTrimming/3; 12950 int minFactor = 2; 12951 if (mHomeProcess != null) minFactor++; 12952 if (mPreviousProcess != null) minFactor++; 12953 if (factor < minFactor) factor = minFactor; 12954 step = 0; 12955 int fgTrimLevel; 12956 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 12957 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 12958 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 12959 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 12960 } else { 12961 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 12962 } 12963 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 12964 for (i=0; i<N; i++) { 12965 ProcessRecord app = mLruProcesses.get(i); 12966 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12967 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12968 && !app.killedBackground) { 12969 if (app.trimMemoryLevel < curLevel && app.thread != null) { 12970 try { 12971 app.thread.scheduleTrimMemory(curLevel); 12972 } catch (RemoteException e) { 12973 } 12974 if (false) { 12975 // For now we won't do this; our memory trimming seems 12976 // to be good enough at this point that destroying 12977 // activities causes more harm than good. 12978 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 12979 && app != mHomeProcess && app != mPreviousProcess) { 12980 // Need to do this on its own message because the stack may not 12981 // be in a consistent state at this point. 12982 // For these apps we will also finish their activities 12983 // to help them free memory. 12984 mMainStack.scheduleDestroyActivities(app, false, "trim"); 12985 } 12986 } 12987 } 12988 app.trimMemoryLevel = curLevel; 12989 step++; 12990 if (step >= factor) { 12991 step = 0; 12992 switch (curLevel) { 12993 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 12994 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 12995 break; 12996 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 12997 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 12998 break; 12999 } 13000 } 13001 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13002 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13003 && app.thread != null) { 13004 try { 13005 app.thread.scheduleTrimMemory( 13006 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13007 } catch (RemoteException e) { 13008 } 13009 } 13010 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13011 } else { 13012 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13013 && app.pendingUiClean) { 13014 // If this application is now in the background and it 13015 // had done UI, then give it the special trim level to 13016 // have it free UI resources. 13017 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13018 if (app.trimMemoryLevel < level && app.thread != null) { 13019 try { 13020 app.thread.scheduleTrimMemory(level); 13021 } catch (RemoteException e) { 13022 } 13023 } 13024 app.pendingUiClean = false; 13025 } 13026 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13027 try { 13028 app.thread.scheduleTrimMemory(fgTrimLevel); 13029 } catch (RemoteException e) { 13030 } 13031 } 13032 app.trimMemoryLevel = fgTrimLevel; 13033 } 13034 } 13035 } else { 13036 final int N = mLruProcesses.size(); 13037 for (i=0; i<N; i++) { 13038 ProcessRecord app = mLruProcesses.get(i); 13039 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13040 && app.pendingUiClean) { 13041 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13042 && app.thread != null) { 13043 try { 13044 app.thread.scheduleTrimMemory( 13045 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13046 } catch (RemoteException e) { 13047 } 13048 } 13049 app.pendingUiClean = false; 13050 } 13051 app.trimMemoryLevel = 0; 13052 } 13053 } 13054 13055 if (mAlwaysFinishActivities) { 13056 // Need to do this on its own message because the stack may not 13057 // be in a consistent state at this point. 13058 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13059 } 13060 } 13061 13062 final void trimApplications() { 13063 synchronized (this) { 13064 int i; 13065 13066 // First remove any unused application processes whose package 13067 // has been removed. 13068 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13069 final ProcessRecord app = mRemovedProcesses.get(i); 13070 if (app.activities.size() == 0 13071 && app.curReceiver == null && app.services.size() == 0) { 13072 Slog.i( 13073 TAG, "Exiting empty application process " 13074 + app.processName + " (" 13075 + (app.thread != null ? app.thread.asBinder() : null) 13076 + ")\n"); 13077 if (app.pid > 0 && app.pid != MY_PID) { 13078 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13079 app.processName, app.setAdj, "empty"); 13080 Process.killProcessQuiet(app.pid); 13081 } else { 13082 try { 13083 app.thread.scheduleExit(); 13084 } catch (Exception e) { 13085 // Ignore exceptions. 13086 } 13087 } 13088 cleanUpApplicationRecordLocked(app, false, true, -1); 13089 mRemovedProcesses.remove(i); 13090 13091 if (app.persistent) { 13092 if (app.persistent) { 13093 addAppLocked(app.info, false); 13094 } 13095 } 13096 } 13097 } 13098 13099 // Now update the oom adj for all processes. 13100 updateOomAdjLocked(); 13101 } 13102 } 13103 13104 /** This method sends the specified signal to each of the persistent apps */ 13105 public void signalPersistentProcesses(int sig) throws RemoteException { 13106 if (sig != Process.SIGNAL_USR1) { 13107 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13108 } 13109 13110 synchronized (this) { 13111 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13112 != PackageManager.PERMISSION_GRANTED) { 13113 throw new SecurityException("Requires permission " 13114 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13115 } 13116 13117 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13118 ProcessRecord r = mLruProcesses.get(i); 13119 if (r.thread != null && r.persistent) { 13120 Process.sendSignal(r.pid, sig); 13121 } 13122 } 13123 } 13124 } 13125 13126 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13127 if (proc == null || proc == mProfileProc) { 13128 proc = mProfileProc; 13129 path = mProfileFile; 13130 profileType = mProfileType; 13131 clearProfilerLocked(); 13132 } 13133 if (proc == null) { 13134 return; 13135 } 13136 try { 13137 proc.thread.profilerControl(false, path, null, profileType); 13138 } catch (RemoteException e) { 13139 throw new IllegalStateException("Process disappeared"); 13140 } 13141 } 13142 13143 private void clearProfilerLocked() { 13144 if (mProfileFd != null) { 13145 try { 13146 mProfileFd.close(); 13147 } catch (IOException e) { 13148 } 13149 } 13150 mProfileApp = null; 13151 mProfileProc = null; 13152 mProfileFile = null; 13153 mProfileType = 0; 13154 mAutoStopProfiler = false; 13155 } 13156 13157 public boolean profileControl(String process, boolean start, 13158 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13159 13160 try { 13161 synchronized (this) { 13162 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13163 // its own permission. 13164 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13165 != PackageManager.PERMISSION_GRANTED) { 13166 throw new SecurityException("Requires permission " 13167 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13168 } 13169 13170 if (start && fd == null) { 13171 throw new IllegalArgumentException("null fd"); 13172 } 13173 13174 ProcessRecord proc = null; 13175 if (process != null) { 13176 try { 13177 int pid = Integer.parseInt(process); 13178 synchronized (mPidsSelfLocked) { 13179 proc = mPidsSelfLocked.get(pid); 13180 } 13181 } catch (NumberFormatException e) { 13182 } 13183 13184 if (proc == null) { 13185 HashMap<String, SparseArray<ProcessRecord>> all 13186 = mProcessNames.getMap(); 13187 SparseArray<ProcessRecord> procs = all.get(process); 13188 if (procs != null && procs.size() > 0) { 13189 proc = procs.valueAt(0); 13190 } 13191 } 13192 } 13193 13194 if (start && (proc == null || proc.thread == null)) { 13195 throw new IllegalArgumentException("Unknown process: " + process); 13196 } 13197 13198 if (start) { 13199 stopProfilerLocked(null, null, 0); 13200 setProfileApp(proc.info, proc.processName, path, fd, false); 13201 mProfileProc = proc; 13202 mProfileType = profileType; 13203 try { 13204 fd = fd.dup(); 13205 } catch (IOException e) { 13206 fd = null; 13207 } 13208 proc.thread.profilerControl(start, path, fd, profileType); 13209 fd = null; 13210 mProfileFd = null; 13211 } else { 13212 stopProfilerLocked(proc, path, profileType); 13213 if (fd != null) { 13214 try { 13215 fd.close(); 13216 } catch (IOException e) { 13217 } 13218 } 13219 } 13220 13221 return true; 13222 } 13223 } catch (RemoteException e) { 13224 throw new IllegalStateException("Process disappeared"); 13225 } finally { 13226 if (fd != null) { 13227 try { 13228 fd.close(); 13229 } catch (IOException e) { 13230 } 13231 } 13232 } 13233 } 13234 13235 public boolean dumpHeap(String process, boolean managed, 13236 String path, ParcelFileDescriptor fd) throws RemoteException { 13237 13238 try { 13239 synchronized (this) { 13240 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13241 // its own permission (same as profileControl). 13242 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13243 != PackageManager.PERMISSION_GRANTED) { 13244 throw new SecurityException("Requires permission " 13245 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13246 } 13247 13248 if (fd == null) { 13249 throw new IllegalArgumentException("null fd"); 13250 } 13251 13252 ProcessRecord proc = null; 13253 try { 13254 int pid = Integer.parseInt(process); 13255 synchronized (mPidsSelfLocked) { 13256 proc = mPidsSelfLocked.get(pid); 13257 } 13258 } catch (NumberFormatException e) { 13259 } 13260 13261 if (proc == null) { 13262 HashMap<String, SparseArray<ProcessRecord>> all 13263 = mProcessNames.getMap(); 13264 SparseArray<ProcessRecord> procs = all.get(process); 13265 if (procs != null && procs.size() > 0) { 13266 proc = procs.valueAt(0); 13267 } 13268 } 13269 13270 if (proc == null || proc.thread == null) { 13271 throw new IllegalArgumentException("Unknown process: " + process); 13272 } 13273 13274 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13275 if (!isDebuggable) { 13276 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13277 throw new SecurityException("Process not debuggable: " + proc); 13278 } 13279 } 13280 13281 proc.thread.dumpHeap(managed, path, fd); 13282 fd = null; 13283 return true; 13284 } 13285 } catch (RemoteException e) { 13286 throw new IllegalStateException("Process disappeared"); 13287 } finally { 13288 if (fd != null) { 13289 try { 13290 fd.close(); 13291 } catch (IOException e) { 13292 } 13293 } 13294 } 13295 } 13296 13297 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13298 public void monitor() { 13299 synchronized (this) { } 13300 } 13301 13302 void onCoreSettingsChange(Bundle settings) { 13303 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13304 ProcessRecord processRecord = mLruProcesses.get(i); 13305 try { 13306 if (processRecord.thread != null) { 13307 processRecord.thread.setCoreSettings(settings); 13308 } 13309 } catch (RemoteException re) { 13310 /* ignore */ 13311 } 13312 } 13313 } 13314 13315 // Multi-user methods 13316 13317 private int mCurrentUserId; 13318 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 13319 13320 public boolean switchUser(int userId) { 13321 final int callingUid = Binder.getCallingUid(); 13322 if (callingUid != 0 && callingUid != Process.myUid()) { 13323 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13324 return false; 13325 } 13326 if (mCurrentUserId == userId) 13327 return true; 13328 13329 synchronized (this) { 13330 // Check if user is already logged in, otherwise check if user exists first before 13331 // adding to the list of logged in users. 13332 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13333 if (!userExists(userId)) { 13334 return false; 13335 } 13336 mLoggedInUsers.append(userId, userId); 13337 } 13338 13339 mCurrentUserId = userId; 13340 boolean haveActivities = mMainStack.switchUser(userId); 13341 if (!haveActivities) { 13342 startHomeActivityLocked(userId); 13343 } 13344 13345 } 13346 13347 // Inform of user switch 13348 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13349 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 13350 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13351 13352 return true; 13353 } 13354 13355 @Override 13356 public UserInfo getCurrentUser() throws RemoteException { 13357 final int callingUid = Binder.getCallingUid(); 13358 if (callingUid != 0 && callingUid != Process.myUid()) { 13359 Slog.e(TAG, "Trying to get user from unauthorized app"); 13360 return null; 13361 } 13362 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 13363 } 13364 13365 private void onUserRemoved(Intent intent) { 13366 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 13367 if (extraUserId < 1) return; 13368 13369 // Kill all the processes for the user 13370 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13371 synchronized (this) { 13372 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13373 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13374 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13375 for (int i = 0; i < uids.size(); i++) { 13376 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 13377 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13378 } 13379 } 13380 } 13381 13382 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13383 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13384 false, false, true, true, extraUserId); 13385 } 13386 } 13387 } 13388 13389 private boolean userExists(int userId) { 13390 try { 13391 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 13392 return user != null; 13393 } catch (RemoteException re) { 13394 // Won't happen, in same process 13395 } 13396 13397 return false; 13398 } 13399 13400 private void checkValidCaller(int uid, int userId) { 13401 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13402 13403 throw new SecurityException("Caller uid=" + uid 13404 + " is not privileged to communicate with user=" + userId); 13405 } 13406 13407 private int applyUserId(int uid, int userId) { 13408 return UserId.getUid(userId, uid); 13409 } 13410 13411 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13412 if (info == null) return null; 13413 ApplicationInfo newInfo = new ApplicationInfo(info); 13414 newInfo.uid = applyUserId(info.uid, userId); 13415 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13416 + info.packageName; 13417 return newInfo; 13418 } 13419 13420 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13421 if (aInfo == null 13422 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 13423 return aInfo; 13424 } 13425 13426 ActivityInfo info = new ActivityInfo(aInfo); 13427 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13428 return info; 13429 } 13430} 13431