ActivityManagerService.java revision 786b44046a79d6c4c9cd07f5989d491c7196ad80
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.backup.IBackupManager; 55import android.content.ActivityNotFoundException; 56import android.content.BroadcastReceiver; 57import android.content.ClipData; 58import android.content.ComponentCallbacks2; 59import android.content.ComponentName; 60import android.content.ContentProvider; 61import android.content.ContentResolver; 62import android.content.Context; 63import android.content.DialogInterface; 64import android.content.IContentProvider; 65import android.content.IIntentReceiver; 66import android.content.IIntentSender; 67import android.content.Intent; 68import android.content.IntentFilter; 69import android.content.IntentSender; 70import android.content.pm.ActivityInfo; 71import android.content.pm.ApplicationInfo; 72import android.content.pm.ConfigurationInfo; 73import android.content.pm.IPackageDataObserver; 74import android.content.pm.IPackageManager; 75import android.content.pm.InstrumentationInfo; 76import android.content.pm.PackageInfo; 77import android.content.pm.PackageManager; 78import android.content.pm.UserInfo; 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.res.CompatibilityInfo; 85import android.content.res.Configuration; 86import android.graphics.Bitmap; 87import android.net.Proxy; 88import android.net.ProxyProperties; 89import android.net.Uri; 90import android.os.Binder; 91import android.os.Build; 92import android.os.Bundle; 93import android.os.Debug; 94import android.os.DropBoxManager; 95import android.os.Environment; 96import android.os.FileObserver; 97import android.os.FileUtils; 98import android.os.Handler; 99import android.os.IBinder; 100import android.os.IPermissionController; 101import android.os.Looper; 102import android.os.Message; 103import android.os.Parcel; 104import android.os.ParcelFileDescriptor; 105import android.os.Process; 106import android.os.RemoteCallbackList; 107import android.os.RemoteException; 108import android.os.SELinux; 109import android.os.ServiceManager; 110import android.os.StrictMode; 111import android.os.SystemClock; 112import android.os.SystemProperties; 113import android.os.UserHandle; 114import android.os.UserManager; 115import android.provider.Settings; 116import android.text.format.Time; 117import android.util.EventLog; 118import android.util.Log; 119import android.util.Pair; 120import android.util.PrintWriterPrinter; 121import android.util.Slog; 122import android.util.SparseArray; 123import android.util.SparseIntArray; 124import android.util.TimeUtils; 125import android.view.Gravity; 126import android.view.LayoutInflater; 127import android.view.View; 128import android.view.WindowManager; 129import android.view.WindowManagerPolicy; 130 131import java.io.BufferedInputStream; 132import java.io.BufferedOutputStream; 133import java.io.BufferedReader; 134import java.io.DataInputStream; 135import java.io.DataOutputStream; 136import java.io.File; 137import java.io.FileDescriptor; 138import java.io.FileInputStream; 139import java.io.FileNotFoundException; 140import java.io.FileOutputStream; 141import java.io.IOException; 142import java.io.InputStreamReader; 143import java.io.PrintWriter; 144import java.io.StringWriter; 145import java.lang.ref.WeakReference; 146import java.util.ArrayList; 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 non-hidden/empty process we last found, to help 688 * determine how to distribute hidden/empty processes next time. 689 */ 690 int mNumNonHiddenProcs = 0; 691 692 /** 693 * Keep track of the number of hidden procs, to balance oom adj 694 * distribution between those and empty procs. 695 */ 696 int mNumHiddenProcs = 0; 697 698 /** 699 * Keep track of the number of service processes we last found, to 700 * determine on the next iteration which should be B services. 701 */ 702 int mNumServiceProcs = 0; 703 int mNewNumServiceProcs = 0; 704 705 /** 706 * System monitoring: number of processes that died since the last 707 * N procs were started. 708 */ 709 int[] mProcDeaths = new int[20]; 710 711 /** 712 * This is set if we had to do a delayed dexopt of an app before launching 713 * it, to increasing the ANR timeouts in that case. 714 */ 715 boolean mDidDexOpt; 716 717 String mDebugApp = null; 718 boolean mWaitForDebugger = false; 719 boolean mDebugTransient = false; 720 String mOrigDebugApp = null; 721 boolean mOrigWaitForDebugger = false; 722 boolean mAlwaysFinishActivities = false; 723 IActivityController mController = null; 724 String mProfileApp = null; 725 ProcessRecord mProfileProc = null; 726 String mProfileFile; 727 ParcelFileDescriptor mProfileFd; 728 int mProfileType = 0; 729 boolean mAutoStopProfiler = false; 730 String mOpenGlTraceApp = null; 731 732 static class ProcessChangeItem { 733 static final int CHANGE_ACTIVITIES = 1<<0; 734 static final int CHANGE_IMPORTANCE= 1<<1; 735 int changes; 736 int uid; 737 int pid; 738 int importance; 739 boolean foregroundActivities; 740 } 741 742 final RemoteCallbackList<IProcessObserver> mProcessObservers 743 = new RemoteCallbackList<IProcessObserver>(); 744 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 745 746 final ArrayList<ProcessChangeItem> mPendingProcessChanges 747 = new ArrayList<ProcessChangeItem>(); 748 final ArrayList<ProcessChangeItem> mAvailProcessChanges 749 = new ArrayList<ProcessChangeItem>(); 750 751 /** 752 * Callback of last caller to {@link #requestPss}. 753 */ 754 Runnable mRequestPssCallback; 755 756 /** 757 * Remaining processes for which we are waiting results from the last 758 * call to {@link #requestPss}. 759 */ 760 final ArrayList<ProcessRecord> mRequestPssList 761 = new ArrayList<ProcessRecord>(); 762 763 /** 764 * Runtime statistics collection thread. This object's lock is used to 765 * protect all related state. 766 */ 767 final Thread mProcessStatsThread; 768 769 /** 770 * Used to collect process stats when showing not responding dialog. 771 * Protected by mProcessStatsThread. 772 */ 773 final ProcessStats mProcessStats = new ProcessStats( 774 MONITOR_THREAD_CPU_USAGE); 775 final AtomicLong mLastCpuTime = new AtomicLong(0); 776 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 777 778 long mLastWriteTime = 0; 779 780 /** 781 * Set to true after the system has finished booting. 782 */ 783 boolean mBooted = false; 784 785 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 786 int mProcessLimitOverride = -1; 787 788 WindowManagerService mWindowManager; 789 790 static ActivityManagerService mSelf; 791 static ActivityThread mSystemThread; 792 793 private int mCurrentUserId; 794 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 795 private UserManager mUserManager; 796 797 private final class AppDeathRecipient implements IBinder.DeathRecipient { 798 final ProcessRecord mApp; 799 final int mPid; 800 final IApplicationThread mAppThread; 801 802 AppDeathRecipient(ProcessRecord app, int pid, 803 IApplicationThread thread) { 804 if (localLOGV) Slog.v( 805 TAG, "New death recipient " + this 806 + " for thread " + thread.asBinder()); 807 mApp = app; 808 mPid = pid; 809 mAppThread = thread; 810 } 811 812 public void binderDied() { 813 if (localLOGV) Slog.v( 814 TAG, "Death received in " + this 815 + " for thread " + mAppThread.asBinder()); 816 synchronized(ActivityManagerService.this) { 817 appDiedLocked(mApp, mPid, mAppThread); 818 } 819 } 820 } 821 822 static final int SHOW_ERROR_MSG = 1; 823 static final int SHOW_NOT_RESPONDING_MSG = 2; 824 static final int SHOW_FACTORY_ERROR_MSG = 3; 825 static final int UPDATE_CONFIGURATION_MSG = 4; 826 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 827 static final int WAIT_FOR_DEBUGGER_MSG = 6; 828 static final int SERVICE_TIMEOUT_MSG = 12; 829 static final int UPDATE_TIME_ZONE = 13; 830 static final int SHOW_UID_ERROR_MSG = 14; 831 static final int IM_FEELING_LUCKY_MSG = 15; 832 static final int PROC_START_TIMEOUT_MSG = 20; 833 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 834 static final int KILL_APPLICATION_MSG = 22; 835 static final int FINALIZE_PENDING_INTENT_MSG = 23; 836 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 837 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 838 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 839 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 840 static final int CLEAR_DNS_CACHE = 28; 841 static final int UPDATE_HTTP_PROXY = 29; 842 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 843 static final int DISPATCH_PROCESSES_CHANGED = 31; 844 static final int DISPATCH_PROCESS_DIED = 32; 845 static final int REPORT_MEM_USAGE = 33; 846 847 static final int FIRST_ACTIVITY_STACK_MSG = 100; 848 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 849 static final int FIRST_COMPAT_MODE_MSG = 300; 850 851 AlertDialog mUidAlert; 852 CompatModeDialog mCompatModeDialog; 853 long mLastMemUsageReportTime = 0; 854 855 final Handler mHandler = new Handler() { 856 //public Handler() { 857 // if (localLOGV) Slog.v(TAG, "Handler started!"); 858 //} 859 860 public void handleMessage(Message msg) { 861 switch (msg.what) { 862 case SHOW_ERROR_MSG: { 863 HashMap data = (HashMap) msg.obj; 864 synchronized (ActivityManagerService.this) { 865 ProcessRecord proc = (ProcessRecord)data.get("app"); 866 if (proc != null && proc.crashDialog != null) { 867 Slog.e(TAG, "App already has crash dialog: " + proc); 868 return; 869 } 870 AppErrorResult res = (AppErrorResult) data.get("result"); 871 if (mShowDialogs && !mSleeping && !mShuttingDown) { 872 Dialog d = new AppErrorDialog(mContext, res, proc); 873 d.show(); 874 proc.crashDialog = d; 875 } else { 876 // The device is asleep, so just pretend that the user 877 // saw a crash dialog and hit "force quit". 878 res.set(0); 879 } 880 } 881 882 ensureBootCompleted(); 883 } break; 884 case SHOW_NOT_RESPONDING_MSG: { 885 synchronized (ActivityManagerService.this) { 886 HashMap data = (HashMap) msg.obj; 887 ProcessRecord proc = (ProcessRecord)data.get("app"); 888 if (proc != null && proc.anrDialog != null) { 889 Slog.e(TAG, "App already has anr dialog: " + proc); 890 return; 891 } 892 893 Intent intent = new Intent("android.intent.action.ANR"); 894 if (!mProcessesReady) { 895 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 896 | Intent.FLAG_RECEIVER_FOREGROUND); 897 } 898 broadcastIntentLocked(null, null, intent, 899 null, null, 0, null, null, null, 900 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 901 902 if (mShowDialogs) { 903 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 904 mContext, proc, (ActivityRecord)data.get("activity")); 905 d.show(); 906 proc.anrDialog = d; 907 } else { 908 // Just kill the app if there is no dialog to be shown. 909 killAppAtUsersRequest(proc, null); 910 } 911 } 912 913 ensureBootCompleted(); 914 } break; 915 case SHOW_STRICT_MODE_VIOLATION_MSG: { 916 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 917 synchronized (ActivityManagerService.this) { 918 ProcessRecord proc = (ProcessRecord) data.get("app"); 919 if (proc == null) { 920 Slog.e(TAG, "App not found when showing strict mode dialog."); 921 break; 922 } 923 if (proc.crashDialog != null) { 924 Slog.e(TAG, "App already has strict mode dialog: " + proc); 925 return; 926 } 927 AppErrorResult res = (AppErrorResult) data.get("result"); 928 if (mShowDialogs && !mSleeping && !mShuttingDown) { 929 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 930 d.show(); 931 proc.crashDialog = d; 932 } else { 933 // The device is asleep, so just pretend that the user 934 // saw a crash dialog and hit "force quit". 935 res.set(0); 936 } 937 } 938 ensureBootCompleted(); 939 } break; 940 case SHOW_FACTORY_ERROR_MSG: { 941 Dialog d = new FactoryErrorDialog( 942 mContext, msg.getData().getCharSequence("msg")); 943 d.show(); 944 ensureBootCompleted(); 945 } break; 946 case UPDATE_CONFIGURATION_MSG: { 947 final ContentResolver resolver = mContext.getContentResolver(); 948 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 949 } break; 950 case GC_BACKGROUND_PROCESSES_MSG: { 951 synchronized (ActivityManagerService.this) { 952 performAppGcsIfAppropriateLocked(); 953 } 954 } break; 955 case WAIT_FOR_DEBUGGER_MSG: { 956 synchronized (ActivityManagerService.this) { 957 ProcessRecord app = (ProcessRecord)msg.obj; 958 if (msg.arg1 != 0) { 959 if (!app.waitedForDebugger) { 960 Dialog d = new AppWaitingForDebuggerDialog( 961 ActivityManagerService.this, 962 mContext, app); 963 app.waitDialog = d; 964 app.waitedForDebugger = true; 965 d.show(); 966 } 967 } else { 968 if (app.waitDialog != null) { 969 app.waitDialog.dismiss(); 970 app.waitDialog = null; 971 } 972 } 973 } 974 } break; 975 case SERVICE_TIMEOUT_MSG: { 976 if (mDidDexOpt) { 977 mDidDexOpt = false; 978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 979 nmsg.obj = msg.obj; 980 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 981 return; 982 } 983 mServices.serviceTimeout((ProcessRecord)msg.obj); 984 } break; 985 case UPDATE_TIME_ZONE: { 986 synchronized (ActivityManagerService.this) { 987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 988 ProcessRecord r = mLruProcesses.get(i); 989 if (r.thread != null) { 990 try { 991 r.thread.updateTimeZone(); 992 } catch (RemoteException ex) { 993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 994 } 995 } 996 } 997 } 998 } break; 999 case CLEAR_DNS_CACHE: { 1000 synchronized (ActivityManagerService.this) { 1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1002 ProcessRecord r = mLruProcesses.get(i); 1003 if (r.thread != null) { 1004 try { 1005 r.thread.clearDnsCache(); 1006 } catch (RemoteException ex) { 1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1008 } 1009 } 1010 } 1011 } 1012 } break; 1013 case UPDATE_HTTP_PROXY: { 1014 ProxyProperties proxy = (ProxyProperties)msg.obj; 1015 String host = ""; 1016 String port = ""; 1017 String exclList = ""; 1018 if (proxy != null) { 1019 host = proxy.getHost(); 1020 port = Integer.toString(proxy.getPort()); 1021 exclList = proxy.getExclusionList(); 1022 } 1023 synchronized (ActivityManagerService.this) { 1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1025 ProcessRecord r = mLruProcesses.get(i); 1026 if (r.thread != null) { 1027 try { 1028 r.thread.setHttpProxy(host, port, exclList); 1029 } catch (RemoteException ex) { 1030 Slog.w(TAG, "Failed to update http proxy for: " + 1031 r.info.processName); 1032 } 1033 } 1034 } 1035 } 1036 } break; 1037 case SHOW_UID_ERROR_MSG: { 1038 String title = "System UIDs Inconsistent"; 1039 String text = "UIDs on the system are inconsistent, you need to wipe your" 1040 + " data partition or your device will be unstable."; 1041 Log.e(TAG, title + ": " + text); 1042 if (mShowDialogs) { 1043 // XXX This is a temporary dialog, no need to localize. 1044 AlertDialog d = new BaseErrorDialog(mContext); 1045 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1046 d.setCancelable(false); 1047 d.setTitle(title); 1048 d.setMessage(text); 1049 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1050 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1051 mUidAlert = d; 1052 d.show(); 1053 } 1054 } break; 1055 case IM_FEELING_LUCKY_MSG: { 1056 if (mUidAlert != null) { 1057 mUidAlert.dismiss(); 1058 mUidAlert = null; 1059 } 1060 } break; 1061 case PROC_START_TIMEOUT_MSG: { 1062 if (mDidDexOpt) { 1063 mDidDexOpt = false; 1064 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1065 nmsg.obj = msg.obj; 1066 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1067 return; 1068 } 1069 ProcessRecord app = (ProcessRecord)msg.obj; 1070 synchronized (ActivityManagerService.this) { 1071 processStartTimedOutLocked(app); 1072 } 1073 } break; 1074 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1075 synchronized (ActivityManagerService.this) { 1076 doPendingActivityLaunchesLocked(true); 1077 } 1078 } break; 1079 case KILL_APPLICATION_MSG: { 1080 synchronized (ActivityManagerService.this) { 1081 int uid = msg.arg1; 1082 boolean restart = (msg.arg2 == 1); 1083 String pkg = (String) msg.obj; 1084 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1085 UserHandle.getUserId(uid)); 1086 } 1087 } break; 1088 case FINALIZE_PENDING_INTENT_MSG: { 1089 ((PendingIntentRecord)msg.obj).completeFinalize(); 1090 } break; 1091 case POST_HEAVY_NOTIFICATION_MSG: { 1092 INotificationManager inm = NotificationManager.getService(); 1093 if (inm == null) { 1094 return; 1095 } 1096 1097 ActivityRecord root = (ActivityRecord)msg.obj; 1098 ProcessRecord process = root.app; 1099 if (process == null) { 1100 return; 1101 } 1102 1103 try { 1104 Context context = mContext.createPackageContext(process.info.packageName, 0); 1105 String text = mContext.getString(R.string.heavy_weight_notification, 1106 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1107 Notification notification = new Notification(); 1108 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1109 notification.when = 0; 1110 notification.flags = Notification.FLAG_ONGOING_EVENT; 1111 notification.tickerText = text; 1112 notification.defaults = 0; // please be quiet 1113 notification.sound = null; 1114 notification.vibrate = null; 1115 notification.setLatestEventInfo(context, text, 1116 mContext.getText(R.string.heavy_weight_notification_detail), 1117 PendingIntent.getActivity(mContext, 0, root.intent, 1118 PendingIntent.FLAG_CANCEL_CURRENT)); 1119 1120 try { 1121 int[] outId = new int[1]; 1122 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1123 notification, outId); 1124 } catch (RuntimeException e) { 1125 Slog.w(ActivityManagerService.TAG, 1126 "Error showing notification for heavy-weight app", e); 1127 } catch (RemoteException e) { 1128 } 1129 } catch (NameNotFoundException e) { 1130 Slog.w(TAG, "Unable to create context for heavy notification", e); 1131 } 1132 } break; 1133 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1134 INotificationManager inm = NotificationManager.getService(); 1135 if (inm == null) { 1136 return; 1137 } 1138 try { 1139 inm.cancelNotification("android", 1140 R.string.heavy_weight_notification); 1141 } catch (RuntimeException e) { 1142 Slog.w(ActivityManagerService.TAG, 1143 "Error canceling notification for service", e); 1144 } catch (RemoteException e) { 1145 } 1146 } break; 1147 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1148 synchronized (ActivityManagerService.this) { 1149 checkExcessivePowerUsageLocked(true); 1150 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1151 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1152 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1153 } 1154 } break; 1155 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1156 synchronized (ActivityManagerService.this) { 1157 ActivityRecord ar = (ActivityRecord)msg.obj; 1158 if (mCompatModeDialog != null) { 1159 if (mCompatModeDialog.mAppInfo.packageName.equals( 1160 ar.info.applicationInfo.packageName)) { 1161 return; 1162 } 1163 mCompatModeDialog.dismiss(); 1164 mCompatModeDialog = null; 1165 } 1166 if (ar != null && false) { 1167 if (mCompatModePackages.getPackageAskCompatModeLocked( 1168 ar.packageName)) { 1169 int mode = mCompatModePackages.computeCompatModeLocked( 1170 ar.info.applicationInfo); 1171 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1172 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1173 mCompatModeDialog = new CompatModeDialog( 1174 ActivityManagerService.this, mContext, 1175 ar.info.applicationInfo); 1176 mCompatModeDialog.show(); 1177 } 1178 } 1179 } 1180 } 1181 break; 1182 } 1183 case DISPATCH_PROCESSES_CHANGED: { 1184 dispatchProcessesChanged(); 1185 break; 1186 } 1187 case DISPATCH_PROCESS_DIED: { 1188 final int pid = msg.arg1; 1189 final int uid = msg.arg2; 1190 dispatchProcessDied(pid, uid); 1191 break; 1192 } 1193 case REPORT_MEM_USAGE: { 1194 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1195 if (!isDebuggable) { 1196 return; 1197 } 1198 synchronized (ActivityManagerService.this) { 1199 long now = SystemClock.uptimeMillis(); 1200 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1201 // Don't report more than every 5 minutes to somewhat 1202 // avoid spamming. 1203 return; 1204 } 1205 mLastMemUsageReportTime = now; 1206 } 1207 Thread thread = new Thread() { 1208 @Override public void run() { 1209 StringBuilder dropBuilder = new StringBuilder(1024); 1210 StringBuilder logBuilder = new StringBuilder(1024); 1211 StringWriter oomSw = new StringWriter(); 1212 PrintWriter oomPw = new PrintWriter(oomSw); 1213 StringWriter catSw = new StringWriter(); 1214 PrintWriter catPw = new PrintWriter(catSw); 1215 String[] emptyArgs = new String[] { }; 1216 StringBuilder tag = new StringBuilder(128); 1217 StringBuilder stack = new StringBuilder(128); 1218 tag.append("Low on memory -- "); 1219 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1220 tag, stack); 1221 dropBuilder.append(stack); 1222 dropBuilder.append('\n'); 1223 dropBuilder.append('\n'); 1224 String oomString = oomSw.toString(); 1225 dropBuilder.append(oomString); 1226 dropBuilder.append('\n'); 1227 logBuilder.append(oomString); 1228 try { 1229 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1230 "procrank", }); 1231 final InputStreamReader converter = new InputStreamReader( 1232 proc.getInputStream()); 1233 BufferedReader in = new BufferedReader(converter); 1234 String line; 1235 while (true) { 1236 line = in.readLine(); 1237 if (line == null) { 1238 break; 1239 } 1240 if (line.length() > 0) { 1241 logBuilder.append(line); 1242 logBuilder.append('\n'); 1243 } 1244 dropBuilder.append(line); 1245 dropBuilder.append('\n'); 1246 } 1247 converter.close(); 1248 } catch (IOException e) { 1249 } 1250 synchronized (ActivityManagerService.this) { 1251 catPw.println(); 1252 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1253 catPw.println(); 1254 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1255 false, false, null); 1256 catPw.println(); 1257 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1258 } 1259 dropBuilder.append(catSw.toString()); 1260 addErrorToDropBox("lowmem", null, "system_server", null, 1261 null, tag.toString(), dropBuilder.toString(), null, null); 1262 Slog.i(TAG, logBuilder.toString()); 1263 synchronized (ActivityManagerService.this) { 1264 long now = SystemClock.uptimeMillis(); 1265 if (mLastMemUsageReportTime < now) { 1266 mLastMemUsageReportTime = now; 1267 } 1268 } 1269 } 1270 }; 1271 thread.start(); 1272 break; 1273 } 1274 } 1275 } 1276 }; 1277 1278 public static void setSystemProcess() { 1279 try { 1280 ActivityManagerService m = mSelf; 1281 1282 ServiceManager.addService("activity", m, true); 1283 ServiceManager.addService("meminfo", new MemBinder(m)); 1284 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1285 ServiceManager.addService("dbinfo", new DbBinder(m)); 1286 if (MONITOR_CPU_USAGE) { 1287 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1288 } 1289 ServiceManager.addService("permission", new PermissionController(m)); 1290 1291 ApplicationInfo info = 1292 mSelf.mContext.getPackageManager().getApplicationInfo( 1293 "android", STOCK_PM_FLAGS); 1294 mSystemThread.installSystemApplicationInfo(info); 1295 1296 synchronized (mSelf) { 1297 ProcessRecord app = mSelf.newProcessRecordLocked( 1298 mSystemThread.getApplicationThread(), info, 1299 info.processName, false); 1300 app.persistent = true; 1301 app.pid = MY_PID; 1302 app.maxAdj = ProcessList.SYSTEM_ADJ; 1303 mSelf.mProcessNames.put(app.processName, app.uid, app); 1304 synchronized (mSelf.mPidsSelfLocked) { 1305 mSelf.mPidsSelfLocked.put(app.pid, app); 1306 } 1307 mSelf.updateLruProcessLocked(app, true, true); 1308 } 1309 } catch (PackageManager.NameNotFoundException e) { 1310 throw new RuntimeException( 1311 "Unable to find android system package", e); 1312 } 1313 } 1314 1315 public void setWindowManager(WindowManagerService wm) { 1316 mWindowManager = wm; 1317 } 1318 1319 public static final Context main(int factoryTest) { 1320 AThread thr = new AThread(); 1321 thr.start(); 1322 1323 synchronized (thr) { 1324 while (thr.mService == null) { 1325 try { 1326 thr.wait(); 1327 } catch (InterruptedException e) { 1328 } 1329 } 1330 } 1331 1332 ActivityManagerService m = thr.mService; 1333 mSelf = m; 1334 ActivityThread at = ActivityThread.systemMain(); 1335 mSystemThread = at; 1336 Context context = at.getSystemContext(); 1337 context.setTheme(android.R.style.Theme_Holo); 1338 m.mContext = context; 1339 m.mFactoryTest = factoryTest; 1340 m.mMainStack = new ActivityStack(m, context, true); 1341 1342 m.mBatteryStatsService.publish(context); 1343 m.mUsageStatsService.publish(context); 1344 1345 synchronized (thr) { 1346 thr.mReady = true; 1347 thr.notifyAll(); 1348 } 1349 1350 m.startRunning(null, null, null, null); 1351 1352 return context; 1353 } 1354 1355 public static ActivityManagerService self() { 1356 return mSelf; 1357 } 1358 1359 static class AThread extends Thread { 1360 ActivityManagerService mService; 1361 boolean mReady = false; 1362 1363 public AThread() { 1364 super("ActivityManager"); 1365 } 1366 1367 public void run() { 1368 Looper.prepare(); 1369 1370 android.os.Process.setThreadPriority( 1371 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1372 android.os.Process.setCanSelfBackground(false); 1373 1374 ActivityManagerService m = new ActivityManagerService(); 1375 1376 synchronized (this) { 1377 mService = m; 1378 notifyAll(); 1379 } 1380 1381 synchronized (this) { 1382 while (!mReady) { 1383 try { 1384 wait(); 1385 } catch (InterruptedException e) { 1386 } 1387 } 1388 } 1389 1390 // For debug builds, log event loop stalls to dropbox for analysis. 1391 if (StrictMode.conditionallyEnableDebugLogging()) { 1392 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1393 } 1394 1395 Looper.loop(); 1396 } 1397 } 1398 1399 static class MemBinder extends Binder { 1400 ActivityManagerService mActivityManagerService; 1401 MemBinder(ActivityManagerService activityManagerService) { 1402 mActivityManagerService = activityManagerService; 1403 } 1404 1405 @Override 1406 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1407 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1408 != PackageManager.PERMISSION_GRANTED) { 1409 pw.println("Permission Denial: can't dump meminfo from from pid=" 1410 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1411 + " without permission " + android.Manifest.permission.DUMP); 1412 return; 1413 } 1414 1415 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1416 false, null, null, null); 1417 } 1418 } 1419 1420 static class GraphicsBinder extends Binder { 1421 ActivityManagerService mActivityManagerService; 1422 GraphicsBinder(ActivityManagerService activityManagerService) { 1423 mActivityManagerService = activityManagerService; 1424 } 1425 1426 @Override 1427 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1428 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1429 != PackageManager.PERMISSION_GRANTED) { 1430 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1431 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1432 + " without permission " + android.Manifest.permission.DUMP); 1433 return; 1434 } 1435 1436 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1437 } 1438 } 1439 1440 static class DbBinder extends Binder { 1441 ActivityManagerService mActivityManagerService; 1442 DbBinder(ActivityManagerService activityManagerService) { 1443 mActivityManagerService = activityManagerService; 1444 } 1445 1446 @Override 1447 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1448 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1449 != PackageManager.PERMISSION_GRANTED) { 1450 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1451 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1452 + " without permission " + android.Manifest.permission.DUMP); 1453 return; 1454 } 1455 1456 mActivityManagerService.dumpDbInfo(fd, pw, args); 1457 } 1458 } 1459 1460 static class CpuBinder extends Binder { 1461 ActivityManagerService mActivityManagerService; 1462 CpuBinder(ActivityManagerService activityManagerService) { 1463 mActivityManagerService = activityManagerService; 1464 } 1465 1466 @Override 1467 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1468 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1469 != PackageManager.PERMISSION_GRANTED) { 1470 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1471 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1472 + " without permission " + android.Manifest.permission.DUMP); 1473 return; 1474 } 1475 1476 synchronized (mActivityManagerService.mProcessStatsThread) { 1477 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1478 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1479 SystemClock.uptimeMillis())); 1480 } 1481 } 1482 } 1483 1484 private ActivityManagerService() { 1485 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1486 1487 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1488 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1489 mBroadcastQueues[0] = mFgBroadcastQueue; 1490 mBroadcastQueues[1] = mBgBroadcastQueue; 1491 1492 mServices = new ActiveServices(this); 1493 1494 File dataDir = Environment.getDataDirectory(); 1495 File systemDir = new File(dataDir, "system"); 1496 systemDir.mkdirs(); 1497 mBatteryStatsService = new BatteryStatsService(new File( 1498 systemDir, "batterystats.bin").toString()); 1499 mBatteryStatsService.getActiveStatistics().readLocked(); 1500 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1501 mOnBattery = DEBUG_POWER ? true 1502 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1503 mBatteryStatsService.getActiveStatistics().setCallback(this); 1504 1505 mUsageStatsService = new UsageStatsService(new File( 1506 systemDir, "usagestats").toString()); 1507 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1508 1509 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1510 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1511 1512 mConfiguration.setToDefaults(); 1513 mConfiguration.locale = Locale.getDefault(); 1514 mConfigurationSeq = mConfiguration.seq = 1; 1515 mProcessStats.init(); 1516 1517 mCompatModePackages = new CompatModePackages(this, systemDir); 1518 1519 // Add ourself to the Watchdog monitors. 1520 Watchdog.getInstance().addMonitor(this); 1521 1522 mProcessStatsThread = new Thread("ProcessStats") { 1523 public void run() { 1524 while (true) { 1525 try { 1526 try { 1527 synchronized(this) { 1528 final long now = SystemClock.uptimeMillis(); 1529 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1530 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1531 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1532 // + ", write delay=" + nextWriteDelay); 1533 if (nextWriteDelay < nextCpuDelay) { 1534 nextCpuDelay = nextWriteDelay; 1535 } 1536 if (nextCpuDelay > 0) { 1537 mProcessStatsMutexFree.set(true); 1538 this.wait(nextCpuDelay); 1539 } 1540 } 1541 } catch (InterruptedException e) { 1542 } 1543 updateCpuStatsNow(); 1544 } catch (Exception e) { 1545 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1546 } 1547 } 1548 } 1549 }; 1550 mProcessStatsThread.start(); 1551 } 1552 1553 @Override 1554 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1555 throws RemoteException { 1556 if (code == SYSPROPS_TRANSACTION) { 1557 // We need to tell all apps about the system property change. 1558 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1559 synchronized(this) { 1560 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1561 final int NA = apps.size(); 1562 for (int ia=0; ia<NA; ia++) { 1563 ProcessRecord app = apps.valueAt(ia); 1564 if (app.thread != null) { 1565 procs.add(app.thread.asBinder()); 1566 } 1567 } 1568 } 1569 } 1570 1571 int N = procs.size(); 1572 for (int i=0; i<N; i++) { 1573 Parcel data2 = Parcel.obtain(); 1574 try { 1575 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1576 } catch (RemoteException e) { 1577 } 1578 data2.recycle(); 1579 } 1580 } 1581 try { 1582 return super.onTransact(code, data, reply, flags); 1583 } catch (RuntimeException e) { 1584 // The activity manager only throws security exceptions, so let's 1585 // log all others. 1586 if (!(e instanceof SecurityException)) { 1587 Slog.e(TAG, "Activity Manager Crash", e); 1588 } 1589 throw e; 1590 } 1591 } 1592 1593 void updateCpuStats() { 1594 final long now = SystemClock.uptimeMillis(); 1595 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1596 return; 1597 } 1598 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1599 synchronized (mProcessStatsThread) { 1600 mProcessStatsThread.notify(); 1601 } 1602 } 1603 } 1604 1605 void updateCpuStatsNow() { 1606 synchronized (mProcessStatsThread) { 1607 mProcessStatsMutexFree.set(false); 1608 final long now = SystemClock.uptimeMillis(); 1609 boolean haveNewCpuStats = false; 1610 1611 if (MONITOR_CPU_USAGE && 1612 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1613 mLastCpuTime.set(now); 1614 haveNewCpuStats = true; 1615 mProcessStats.update(); 1616 //Slog.i(TAG, mProcessStats.printCurrentState()); 1617 //Slog.i(TAG, "Total CPU usage: " 1618 // + mProcessStats.getTotalCpuPercent() + "%"); 1619 1620 // Slog the cpu usage if the property is set. 1621 if ("true".equals(SystemProperties.get("events.cpu"))) { 1622 int user = mProcessStats.getLastUserTime(); 1623 int system = mProcessStats.getLastSystemTime(); 1624 int iowait = mProcessStats.getLastIoWaitTime(); 1625 int irq = mProcessStats.getLastIrqTime(); 1626 int softIrq = mProcessStats.getLastSoftIrqTime(); 1627 int idle = mProcessStats.getLastIdleTime(); 1628 1629 int total = user + system + iowait + irq + softIrq + idle; 1630 if (total == 0) total = 1; 1631 1632 EventLog.writeEvent(EventLogTags.CPU, 1633 ((user+system+iowait+irq+softIrq) * 100) / total, 1634 (user * 100) / total, 1635 (system * 100) / total, 1636 (iowait * 100) / total, 1637 (irq * 100) / total, 1638 (softIrq * 100) / total); 1639 } 1640 } 1641 1642 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1643 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1644 synchronized(bstats) { 1645 synchronized(mPidsSelfLocked) { 1646 if (haveNewCpuStats) { 1647 if (mOnBattery) { 1648 int perc = bstats.startAddingCpuLocked(); 1649 int totalUTime = 0; 1650 int totalSTime = 0; 1651 final int N = mProcessStats.countStats(); 1652 for (int i=0; i<N; i++) { 1653 ProcessStats.Stats st = mProcessStats.getStats(i); 1654 if (!st.working) { 1655 continue; 1656 } 1657 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1658 int otherUTime = (st.rel_utime*perc)/100; 1659 int otherSTime = (st.rel_stime*perc)/100; 1660 totalUTime += otherUTime; 1661 totalSTime += otherSTime; 1662 if (pr != null) { 1663 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1664 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1665 st.rel_stime-otherSTime); 1666 ps.addSpeedStepTimes(cpuSpeedTimes); 1667 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1668 } else { 1669 BatteryStatsImpl.Uid.Proc ps = 1670 bstats.getProcessStatsLocked(st.name, st.pid); 1671 if (ps != null) { 1672 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1673 st.rel_stime-otherSTime); 1674 ps.addSpeedStepTimes(cpuSpeedTimes); 1675 } 1676 } 1677 } 1678 bstats.finishAddingCpuLocked(perc, totalUTime, 1679 totalSTime, cpuSpeedTimes); 1680 } 1681 } 1682 } 1683 1684 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1685 mLastWriteTime = now; 1686 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1687 } 1688 } 1689 } 1690 } 1691 1692 @Override 1693 public void batteryNeedsCpuUpdate() { 1694 updateCpuStatsNow(); 1695 } 1696 1697 @Override 1698 public void batteryPowerChanged(boolean onBattery) { 1699 // When plugging in, update the CPU stats first before changing 1700 // the plug state. 1701 updateCpuStatsNow(); 1702 synchronized (this) { 1703 synchronized(mPidsSelfLocked) { 1704 mOnBattery = DEBUG_POWER ? true : onBattery; 1705 } 1706 } 1707 } 1708 1709 /** 1710 * Initialize the application bind args. These are passed to each 1711 * process when the bindApplication() IPC is sent to the process. They're 1712 * lazily setup to make sure the services are running when they're asked for. 1713 */ 1714 private HashMap<String, IBinder> getCommonServicesLocked() { 1715 if (mAppBindArgs == null) { 1716 mAppBindArgs = new HashMap<String, IBinder>(); 1717 1718 // Setup the application init args 1719 mAppBindArgs.put("package", ServiceManager.getService("package")); 1720 mAppBindArgs.put("window", ServiceManager.getService("window")); 1721 mAppBindArgs.put(Context.ALARM_SERVICE, 1722 ServiceManager.getService(Context.ALARM_SERVICE)); 1723 } 1724 return mAppBindArgs; 1725 } 1726 1727 final void setFocusedActivityLocked(ActivityRecord r) { 1728 if (mFocusedActivity != r) { 1729 mFocusedActivity = r; 1730 if (r != null) { 1731 mWindowManager.setFocusedApp(r.appToken, true); 1732 } 1733 } 1734 } 1735 1736 private final void updateLruProcessInternalLocked(ProcessRecord app, 1737 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1738 // put it on the LRU to keep track of when it should be exited. 1739 int lrui = mLruProcesses.indexOf(app); 1740 if (lrui >= 0) mLruProcesses.remove(lrui); 1741 1742 int i = mLruProcesses.size()-1; 1743 int skipTop = 0; 1744 1745 app.lruSeq = mLruSeq; 1746 1747 // compute the new weight for this process. 1748 if (updateActivityTime) { 1749 app.lastActivityTime = SystemClock.uptimeMillis(); 1750 } 1751 if (app.activities.size() > 0) { 1752 // If this process has activities, we more strongly want to keep 1753 // it around. 1754 app.lruWeight = app.lastActivityTime; 1755 } else if (app.pubProviders.size() > 0) { 1756 // If this process contains content providers, we want to keep 1757 // it a little more strongly. 1758 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1759 // Also don't let it kick out the first few "real" hidden processes. 1760 skipTop = ProcessList.MIN_HIDDEN_APPS; 1761 } else { 1762 // If this process doesn't have activities, we less strongly 1763 // want to keep it around, and generally want to avoid getting 1764 // in front of any very recently used activities. 1765 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1766 // Also don't let it kick out the first few "real" hidden processes. 1767 skipTop = ProcessList.MIN_HIDDEN_APPS; 1768 } 1769 1770 while (i >= 0) { 1771 ProcessRecord p = mLruProcesses.get(i); 1772 // If this app shouldn't be in front of the first N background 1773 // apps, then skip over that many that are currently hidden. 1774 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1775 skipTop--; 1776 } 1777 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1778 mLruProcesses.add(i+1, app); 1779 break; 1780 } 1781 i--; 1782 } 1783 if (i < 0) { 1784 mLruProcesses.add(0, app); 1785 } 1786 1787 // If the app is currently using a content provider or service, 1788 // bump those processes as well. 1789 if (app.connections.size() > 0) { 1790 for (ConnectionRecord cr : app.connections) { 1791 if (cr.binding != null && cr.binding.service != null 1792 && cr.binding.service.app != null 1793 && cr.binding.service.app.lruSeq != mLruSeq) { 1794 updateLruProcessInternalLocked(cr.binding.service.app, false, 1795 updateActivityTime, i+1); 1796 } 1797 } 1798 } 1799 for (int j=app.conProviders.size()-1; j>=0; j--) { 1800 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1801 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1802 updateLruProcessInternalLocked(cpr.proc, false, 1803 updateActivityTime, i+1); 1804 } 1805 } 1806 1807 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1808 if (oomAdj) { 1809 updateOomAdjLocked(); 1810 } 1811 } 1812 1813 final void updateLruProcessLocked(ProcessRecord app, 1814 boolean oomAdj, boolean updateActivityTime) { 1815 mLruSeq++; 1816 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1817 } 1818 1819 final ProcessRecord getProcessRecordLocked( 1820 String processName, int uid) { 1821 if (uid == Process.SYSTEM_UID) { 1822 // The system gets to run in any process. If there are multiple 1823 // processes with the same uid, just pick the first (this 1824 // should never happen). 1825 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1826 processName); 1827 if (procs == null) return null; 1828 final int N = procs.size(); 1829 for (int i = 0; i < N; i++) { 1830 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1831 } 1832 } 1833 ProcessRecord proc = mProcessNames.get(processName, uid); 1834 return proc; 1835 } 1836 1837 void ensurePackageDexOpt(String packageName) { 1838 IPackageManager pm = AppGlobals.getPackageManager(); 1839 try { 1840 if (pm.performDexOpt(packageName)) { 1841 mDidDexOpt = true; 1842 } 1843 } catch (RemoteException e) { 1844 } 1845 } 1846 1847 boolean isNextTransitionForward() { 1848 int transit = mWindowManager.getPendingAppTransition(); 1849 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1850 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1851 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1852 } 1853 1854 final ProcessRecord startProcessLocked(String processName, 1855 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1856 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1857 boolean isolated) { 1858 ProcessRecord app; 1859 if (!isolated) { 1860 app = getProcessRecordLocked(processName, info.uid); 1861 } else { 1862 // If this is an isolated process, it can't re-use an existing process. 1863 app = null; 1864 } 1865 // We don't have to do anything more if: 1866 // (1) There is an existing application record; and 1867 // (2) The caller doesn't think it is dead, OR there is no thread 1868 // object attached to it so we know it couldn't have crashed; and 1869 // (3) There is a pid assigned to it, so it is either starting or 1870 // already running. 1871 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1872 + " app=" + app + " knownToBeDead=" + knownToBeDead 1873 + " thread=" + (app != null ? app.thread : null) 1874 + " pid=" + (app != null ? app.pid : -1)); 1875 if (app != null && app.pid > 0) { 1876 if (!knownToBeDead || app.thread == null) { 1877 // We already have the app running, or are waiting for it to 1878 // come up (we have a pid but not yet its thread), so keep it. 1879 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1880 // If this is a new package in the process, add the package to the list 1881 app.addPackage(info.packageName); 1882 return app; 1883 } else { 1884 // An application record is attached to a previous process, 1885 // clean it up now. 1886 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1887 handleAppDiedLocked(app, true, true); 1888 } 1889 } 1890 1891 String hostingNameStr = hostingName != null 1892 ? hostingName.flattenToShortString() : null; 1893 1894 if (!isolated) { 1895 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1896 // If we are in the background, then check to see if this process 1897 // is bad. If so, we will just silently fail. 1898 if (mBadProcesses.get(info.processName, info.uid) != null) { 1899 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1900 + "/" + info.processName); 1901 return null; 1902 } 1903 } else { 1904 // When the user is explicitly starting a process, then clear its 1905 // crash count so that we won't make it bad until they see at 1906 // least one crash dialog again, and make the process good again 1907 // if it had been bad. 1908 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1909 + "/" + info.processName); 1910 mProcessCrashTimes.remove(info.processName, info.uid); 1911 if (mBadProcesses.get(info.processName, info.uid) != null) { 1912 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1913 info.processName); 1914 mBadProcesses.remove(info.processName, info.uid); 1915 if (app != null) { 1916 app.bad = false; 1917 } 1918 } 1919 } 1920 } 1921 1922 if (app == null) { 1923 app = newProcessRecordLocked(null, info, processName, isolated); 1924 if (app == null) { 1925 Slog.w(TAG, "Failed making new process record for " 1926 + processName + "/" + info.uid + " isolated=" + isolated); 1927 return null; 1928 } 1929 mProcessNames.put(processName, app.uid, app); 1930 if (isolated) { 1931 mIsolatedProcesses.put(app.uid, app); 1932 } 1933 } else { 1934 // If this is a new package in the process, add the package to the list 1935 app.addPackage(info.packageName); 1936 } 1937 1938 // If the system is not ready yet, then hold off on starting this 1939 // process until it is. 1940 if (!mProcessesReady 1941 && !isAllowedWhileBooting(info) 1942 && !allowWhileBooting) { 1943 if (!mProcessesOnHold.contains(app)) { 1944 mProcessesOnHold.add(app); 1945 } 1946 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1947 return app; 1948 } 1949 1950 startProcessLocked(app, hostingType, hostingNameStr); 1951 return (app.pid != 0) ? app : null; 1952 } 1953 1954 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1955 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1956 } 1957 1958 private final void startProcessLocked(ProcessRecord app, 1959 String hostingType, String hostingNameStr) { 1960 if (app.pid > 0 && app.pid != MY_PID) { 1961 synchronized (mPidsSelfLocked) { 1962 mPidsSelfLocked.remove(app.pid); 1963 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1964 } 1965 app.setPid(0); 1966 } 1967 1968 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1969 "startProcessLocked removing on hold: " + app); 1970 mProcessesOnHold.remove(app); 1971 1972 updateCpuStats(); 1973 1974 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1975 mProcDeaths[0] = 0; 1976 1977 try { 1978 int uid = app.uid; 1979 1980 int[] gids = null; 1981 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1982 if (!app.isolated) { 1983 try { 1984 final PackageManager pm = mContext.getPackageManager(); 1985 gids = pm.getPackageGids(app.info.packageName); 1986 } catch (PackageManager.NameNotFoundException e) { 1987 Slog.w(TAG, "Unable to retrieve gids", e); 1988 } 1989 1990 if (Environment.isExternalStorageEmulated()) { 1991 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1992 } 1993 } 1994 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1995 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1996 && mTopComponent != null 1997 && app.processName.equals(mTopComponent.getPackageName())) { 1998 uid = 0; 1999 } 2000 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2001 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2002 uid = 0; 2003 } 2004 } 2005 int debugFlags = 0; 2006 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2007 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2008 // Also turn on CheckJNI for debuggable apps. It's quite 2009 // awkward to turn on otherwise. 2010 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2011 } 2012 // Run the app in safe mode if its manifest requests so or the 2013 // system is booted in safe mode. 2014 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2015 Zygote.systemInSafeMode == true) { 2016 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2017 } 2018 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2019 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2020 } 2021 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2022 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2023 } 2024 if ("1".equals(SystemProperties.get("debug.assert"))) { 2025 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2026 } 2027 2028 // Start the process. It will either succeed and return a result containing 2029 // the PID of the new process, or else throw a RuntimeException. 2030 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2031 app.processName, uid, uid, gids, debugFlags, mountExternal, 2032 app.info.targetSdkVersion, null, null); 2033 2034 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2035 synchronized (bs) { 2036 if (bs.isOnBattery()) { 2037 app.batteryStats.incStartsLocked(); 2038 } 2039 } 2040 2041 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2042 app.processName, hostingType, 2043 hostingNameStr != null ? hostingNameStr : ""); 2044 2045 if (app.persistent) { 2046 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2047 } 2048 2049 StringBuilder buf = mStringBuilder; 2050 buf.setLength(0); 2051 buf.append("Start proc "); 2052 buf.append(app.processName); 2053 buf.append(" for "); 2054 buf.append(hostingType); 2055 if (hostingNameStr != null) { 2056 buf.append(" "); 2057 buf.append(hostingNameStr); 2058 } 2059 buf.append(": pid="); 2060 buf.append(startResult.pid); 2061 buf.append(" uid="); 2062 buf.append(uid); 2063 buf.append(" gids={"); 2064 if (gids != null) { 2065 for (int gi=0; gi<gids.length; gi++) { 2066 if (gi != 0) buf.append(", "); 2067 buf.append(gids[gi]); 2068 2069 } 2070 } 2071 buf.append("}"); 2072 Slog.i(TAG, buf.toString()); 2073 app.setPid(startResult.pid); 2074 app.usingWrapper = startResult.usingWrapper; 2075 app.removed = false; 2076 synchronized (mPidsSelfLocked) { 2077 this.mPidsSelfLocked.put(startResult.pid, app); 2078 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2079 msg.obj = app; 2080 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2081 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2082 } 2083 } catch (RuntimeException e) { 2084 // XXX do better error recovery. 2085 app.setPid(0); 2086 Slog.e(TAG, "Failure starting process " + app.processName, e); 2087 } 2088 } 2089 2090 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2091 if (resumed) { 2092 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2093 } else { 2094 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2095 } 2096 } 2097 2098 boolean startHomeActivityLocked(int userId) { 2099 if (mHeadless) { 2100 // Added because none of the other calls to ensureBootCompleted seem to fire 2101 // when running headless. 2102 ensureBootCompleted(); 2103 return false; 2104 } 2105 2106 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2107 && mTopAction == null) { 2108 // We are running in factory test mode, but unable to find 2109 // the factory test app, so just sit around displaying the 2110 // error message and don't try to start anything. 2111 return false; 2112 } 2113 Intent intent = new Intent( 2114 mTopAction, 2115 mTopData != null ? Uri.parse(mTopData) : null); 2116 intent.setComponent(mTopComponent); 2117 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2118 intent.addCategory(Intent.CATEGORY_HOME); 2119 } 2120 ActivityInfo aInfo = 2121 intent.resolveActivityInfo(mContext.getPackageManager(), 2122 STOCK_PM_FLAGS); 2123 if (aInfo != null) { 2124 intent.setComponent(new ComponentName( 2125 aInfo.applicationInfo.packageName, aInfo.name)); 2126 // Don't do this if the home app is currently being 2127 // instrumented. 2128 aInfo = new ActivityInfo(aInfo); 2129 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2130 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2131 aInfo.applicationInfo.uid); 2132 if (app == null || app.instrumentationClass == null) { 2133 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2134 mMainStack.startActivityLocked(null, intent, null, aInfo, 2135 null, null, 0, 0, 0, 0, null, false, null); 2136 } 2137 } 2138 2139 return true; 2140 } 2141 2142 /** 2143 * Starts the "new version setup screen" if appropriate. 2144 */ 2145 void startSetupActivityLocked() { 2146 // Only do this once per boot. 2147 if (mCheckedForSetup) { 2148 return; 2149 } 2150 2151 // We will show this screen if the current one is a different 2152 // version than the last one shown, and we are not running in 2153 // low-level factory test mode. 2154 final ContentResolver resolver = mContext.getContentResolver(); 2155 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2156 Settings.Secure.getInt(resolver, 2157 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2158 mCheckedForSetup = true; 2159 2160 // See if we should be showing the platform update setup UI. 2161 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2162 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2163 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2164 2165 // We don't allow third party apps to replace this. 2166 ResolveInfo ri = null; 2167 for (int i=0; ris != null && i<ris.size(); i++) { 2168 if ((ris.get(i).activityInfo.applicationInfo.flags 2169 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2170 ri = ris.get(i); 2171 break; 2172 } 2173 } 2174 2175 if (ri != null) { 2176 String vers = ri.activityInfo.metaData != null 2177 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2178 : null; 2179 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2180 vers = ri.activityInfo.applicationInfo.metaData.getString( 2181 Intent.METADATA_SETUP_VERSION); 2182 } 2183 String lastVers = Settings.Secure.getString( 2184 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2185 if (vers != null && !vers.equals(lastVers)) { 2186 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2187 intent.setComponent(new ComponentName( 2188 ri.activityInfo.packageName, ri.activityInfo.name)); 2189 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2190 null, null, 0, 0, 0, 0, null, false, null); 2191 } 2192 } 2193 } 2194 } 2195 2196 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2197 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2198 } 2199 2200 void enforceNotIsolatedCaller(String caller) { 2201 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2202 throw new SecurityException("Isolated process not allowed to call " + caller); 2203 } 2204 } 2205 2206 public int getFrontActivityScreenCompatMode() { 2207 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2208 synchronized (this) { 2209 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2210 } 2211 } 2212 2213 public void setFrontActivityScreenCompatMode(int mode) { 2214 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2215 "setFrontActivityScreenCompatMode"); 2216 synchronized (this) { 2217 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2218 } 2219 } 2220 2221 public int getPackageScreenCompatMode(String packageName) { 2222 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2223 synchronized (this) { 2224 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2225 } 2226 } 2227 2228 public void setPackageScreenCompatMode(String packageName, int mode) { 2229 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2230 "setPackageScreenCompatMode"); 2231 synchronized (this) { 2232 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2233 } 2234 } 2235 2236 public boolean getPackageAskScreenCompat(String packageName) { 2237 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2238 synchronized (this) { 2239 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2240 } 2241 } 2242 2243 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2244 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2245 "setPackageAskScreenCompat"); 2246 synchronized (this) { 2247 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2248 } 2249 } 2250 2251 void reportResumedActivityLocked(ActivityRecord r) { 2252 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2253 updateUsageStats(r, true); 2254 } 2255 2256 private void dispatchProcessesChanged() { 2257 int N; 2258 synchronized (this) { 2259 N = mPendingProcessChanges.size(); 2260 if (mActiveProcessChanges.length < N) { 2261 mActiveProcessChanges = new ProcessChangeItem[N]; 2262 } 2263 mPendingProcessChanges.toArray(mActiveProcessChanges); 2264 mAvailProcessChanges.addAll(mPendingProcessChanges); 2265 mPendingProcessChanges.clear(); 2266 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2267 } 2268 int i = mProcessObservers.beginBroadcast(); 2269 while (i > 0) { 2270 i--; 2271 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2272 if (observer != null) { 2273 try { 2274 for (int j=0; j<N; j++) { 2275 ProcessChangeItem item = mActiveProcessChanges[j]; 2276 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2277 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2278 + item.pid + " uid=" + item.uid + ": " 2279 + item.foregroundActivities); 2280 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2281 item.foregroundActivities); 2282 } 2283 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2285 + item.pid + " uid=" + item.uid + ": " + item.importance); 2286 observer.onImportanceChanged(item.pid, item.uid, 2287 item.importance); 2288 } 2289 } 2290 } catch (RemoteException e) { 2291 } 2292 } 2293 } 2294 mProcessObservers.finishBroadcast(); 2295 } 2296 2297 private void dispatchProcessDied(int pid, int uid) { 2298 int i = mProcessObservers.beginBroadcast(); 2299 while (i > 0) { 2300 i--; 2301 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2302 if (observer != null) { 2303 try { 2304 observer.onProcessDied(pid, uid); 2305 } catch (RemoteException e) { 2306 } 2307 } 2308 } 2309 mProcessObservers.finishBroadcast(); 2310 } 2311 2312 final void doPendingActivityLaunchesLocked(boolean doResume) { 2313 final int N = mPendingActivityLaunches.size(); 2314 if (N <= 0) { 2315 return; 2316 } 2317 for (int i=0; i<N; i++) { 2318 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2319 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2320 pal.startFlags, doResume && i == (N-1), null); 2321 } 2322 mPendingActivityLaunches.clear(); 2323 } 2324 2325 public final int startActivity(IApplicationThread caller, 2326 Intent intent, String resolvedType, IBinder resultTo, 2327 String resultWho, int requestCode, int startFlags, 2328 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2329 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2330 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2331 } 2332 2333 public final int startActivityAsUser(IApplicationThread caller, 2334 Intent intent, String resolvedType, IBinder resultTo, 2335 String resultWho, int requestCode, int startFlags, 2336 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2337 enforceNotIsolatedCaller("startActivity"); 2338 if (userId != UserHandle.getCallingUserId()) { 2339 // Requesting a different user, make sure that they have the permission 2340 if (checkComponentPermission( 2341 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2342 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2343 == PackageManager.PERMISSION_GRANTED) { 2344 // Translate to the current user id, if caller wasn't aware 2345 if (userId == UserHandle.USER_CURRENT) { 2346 userId = mCurrentUserId; 2347 } 2348 } else { 2349 String msg = "Permission Denial: " 2350 + "Request to startActivity as user " + userId 2351 + " but is calling from user " + UserHandle.getCallingUserId() 2352 + "; this requires " 2353 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2354 Slog.w(TAG, msg); 2355 throw new SecurityException(msg); 2356 } 2357 } else { 2358 if (intent.getCategories() != null 2359 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2360 // Requesting home, set the identity to the current user 2361 // HACK! 2362 userId = mCurrentUserId; 2363 } else { 2364 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2365 // the current user's userId 2366 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2367 userId = 0; 2368 } else { 2369 userId = Binder.getOrigCallingUser(); 2370 } 2371 } 2372 } 2373 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2374 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2375 null, null, options, userId); 2376 } 2377 2378 public final WaitResult startActivityAndWait(IApplicationThread caller, 2379 Intent intent, String resolvedType, IBinder resultTo, 2380 String resultWho, int requestCode, int startFlags, String profileFile, 2381 ParcelFileDescriptor profileFd, Bundle options) { 2382 enforceNotIsolatedCaller("startActivityAndWait"); 2383 WaitResult res = new WaitResult(); 2384 int userId = Binder.getOrigCallingUser(); 2385 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2386 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2387 res, null, options, userId); 2388 return res; 2389 } 2390 2391 public final int startActivityWithConfig(IApplicationThread caller, 2392 Intent intent, String resolvedType, IBinder resultTo, 2393 String resultWho, int requestCode, int startFlags, Configuration config, 2394 Bundle options) { 2395 enforceNotIsolatedCaller("startActivityWithConfig"); 2396 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2397 resultTo, resultWho, requestCode, startFlags, 2398 null, null, null, config, options, Binder.getOrigCallingUser()); 2399 return ret; 2400 } 2401 2402 public int startActivityIntentSender(IApplicationThread caller, 2403 IntentSender intent, Intent fillInIntent, String resolvedType, 2404 IBinder resultTo, String resultWho, int requestCode, 2405 int flagsMask, int flagsValues, Bundle options) { 2406 enforceNotIsolatedCaller("startActivityIntentSender"); 2407 // Refuse possible leaked file descriptors 2408 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2409 throw new IllegalArgumentException("File descriptors passed in Intent"); 2410 } 2411 2412 IIntentSender sender = intent.getTarget(); 2413 if (!(sender instanceof PendingIntentRecord)) { 2414 throw new IllegalArgumentException("Bad PendingIntent object"); 2415 } 2416 2417 PendingIntentRecord pir = (PendingIntentRecord)sender; 2418 2419 synchronized (this) { 2420 // If this is coming from the currently resumed activity, it is 2421 // effectively saying that app switches are allowed at this point. 2422 if (mMainStack.mResumedActivity != null 2423 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2424 Binder.getCallingUid()) { 2425 mAppSwitchesAllowedTime = 0; 2426 } 2427 } 2428 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2429 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2430 return ret; 2431 } 2432 2433 public boolean startNextMatchingActivity(IBinder callingActivity, 2434 Intent intent, Bundle options) { 2435 // Refuse possible leaked file descriptors 2436 if (intent != null && intent.hasFileDescriptors() == true) { 2437 throw new IllegalArgumentException("File descriptors passed in Intent"); 2438 } 2439 2440 synchronized (this) { 2441 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2442 if (r == null) { 2443 ActivityOptions.abort(options); 2444 return false; 2445 } 2446 if (r.app == null || r.app.thread == null) { 2447 // The caller is not running... d'oh! 2448 ActivityOptions.abort(options); 2449 return false; 2450 } 2451 intent = new Intent(intent); 2452 // The caller is not allowed to change the data. 2453 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2454 // And we are resetting to find the next component... 2455 intent.setComponent(null); 2456 2457 ActivityInfo aInfo = null; 2458 try { 2459 List<ResolveInfo> resolves = 2460 AppGlobals.getPackageManager().queryIntentActivities( 2461 intent, r.resolvedType, 2462 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2463 UserHandle.getCallingUserId()); 2464 2465 // Look for the original activity in the list... 2466 final int N = resolves != null ? resolves.size() : 0; 2467 for (int i=0; i<N; i++) { 2468 ResolveInfo rInfo = resolves.get(i); 2469 if (rInfo.activityInfo.packageName.equals(r.packageName) 2470 && rInfo.activityInfo.name.equals(r.info.name)) { 2471 // We found the current one... the next matching is 2472 // after it. 2473 i++; 2474 if (i<N) { 2475 aInfo = resolves.get(i).activityInfo; 2476 } 2477 break; 2478 } 2479 } 2480 } catch (RemoteException e) { 2481 } 2482 2483 if (aInfo == null) { 2484 // Nobody who is next! 2485 ActivityOptions.abort(options); 2486 return false; 2487 } 2488 2489 intent.setComponent(new ComponentName( 2490 aInfo.applicationInfo.packageName, aInfo.name)); 2491 intent.setFlags(intent.getFlags()&~( 2492 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2493 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2494 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2495 Intent.FLAG_ACTIVITY_NEW_TASK)); 2496 2497 // Okay now we need to start the new activity, replacing the 2498 // currently running activity. This is a little tricky because 2499 // we want to start the new one as if the current one is finished, 2500 // but not finish the current one first so that there is no flicker. 2501 // And thus... 2502 final boolean wasFinishing = r.finishing; 2503 r.finishing = true; 2504 2505 // Propagate reply information over to the new activity. 2506 final ActivityRecord resultTo = r.resultTo; 2507 final String resultWho = r.resultWho; 2508 final int requestCode = r.requestCode; 2509 r.resultTo = null; 2510 if (resultTo != null) { 2511 resultTo.removeResultsLocked(r, resultWho, requestCode); 2512 } 2513 2514 final long origId = Binder.clearCallingIdentity(); 2515 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2516 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2517 resultWho, requestCode, -1, r.launchedFromUid, 0, 2518 options, false, null); 2519 Binder.restoreCallingIdentity(origId); 2520 2521 r.finishing = wasFinishing; 2522 if (res != ActivityManager.START_SUCCESS) { 2523 return false; 2524 } 2525 return true; 2526 } 2527 } 2528 2529 public final int startActivityInPackage(int uid, 2530 Intent intent, String resolvedType, IBinder resultTo, 2531 String resultWho, int requestCode, int startFlags, Bundle options) { 2532 2533 // This is so super not safe, that only the system (or okay root) 2534 // can do it. 2535 final int callingUid = Binder.getCallingUid(); 2536 if (callingUid != 0 && callingUid != Process.myUid()) { 2537 throw new SecurityException( 2538 "startActivityInPackage only available to the system"); 2539 } 2540 2541 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2542 resultTo, resultWho, requestCode, startFlags, 2543 null, null, null, null, options, UserHandle.getUserId(uid)); 2544 return ret; 2545 } 2546 2547 public final int startActivities(IApplicationThread caller, 2548 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2549 enforceNotIsolatedCaller("startActivities"); 2550 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2551 options, Binder.getOrigCallingUser()); 2552 return ret; 2553 } 2554 2555 public final int startActivitiesInPackage(int uid, 2556 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2557 Bundle options) { 2558 2559 // This is so super not safe, that only the system (or okay root) 2560 // can do it. 2561 final int callingUid = Binder.getCallingUid(); 2562 if (callingUid != 0 && callingUid != Process.myUid()) { 2563 throw new SecurityException( 2564 "startActivityInPackage only available to the system"); 2565 } 2566 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2567 options, UserHandle.getUserId(uid)); 2568 return ret; 2569 } 2570 2571 final void addRecentTaskLocked(TaskRecord task) { 2572 int N = mRecentTasks.size(); 2573 // Quick case: check if the top-most recent task is the same. 2574 if (N > 0 && mRecentTasks.get(0) == task) { 2575 return; 2576 } 2577 // Remove any existing entries that are the same kind of task. 2578 for (int i=0; i<N; i++) { 2579 TaskRecord tr = mRecentTasks.get(i); 2580 if (task.userId == tr.userId 2581 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2582 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2583 mRecentTasks.remove(i); 2584 i--; 2585 N--; 2586 if (task.intent == null) { 2587 // If the new recent task we are adding is not fully 2588 // specified, then replace it with the existing recent task. 2589 task = tr; 2590 } 2591 } 2592 } 2593 if (N >= MAX_RECENT_TASKS) { 2594 mRecentTasks.remove(N-1); 2595 } 2596 mRecentTasks.add(0, task); 2597 } 2598 2599 public void setRequestedOrientation(IBinder token, 2600 int requestedOrientation) { 2601 synchronized (this) { 2602 ActivityRecord r = mMainStack.isInStackLocked(token); 2603 if (r == null) { 2604 return; 2605 } 2606 final long origId = Binder.clearCallingIdentity(); 2607 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2608 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2609 mConfiguration, 2610 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2611 if (config != null) { 2612 r.frozenBeforeDestroy = true; 2613 if (!updateConfigurationLocked(config, r, false, false)) { 2614 mMainStack.resumeTopActivityLocked(null); 2615 } 2616 } 2617 Binder.restoreCallingIdentity(origId); 2618 } 2619 } 2620 2621 public int getRequestedOrientation(IBinder token) { 2622 synchronized (this) { 2623 ActivityRecord r = mMainStack.isInStackLocked(token); 2624 if (r == null) { 2625 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2626 } 2627 return mWindowManager.getAppOrientation(r.appToken); 2628 } 2629 } 2630 2631 /** 2632 * This is the internal entry point for handling Activity.finish(). 2633 * 2634 * @param token The Binder token referencing the Activity we want to finish. 2635 * @param resultCode Result code, if any, from this Activity. 2636 * @param resultData Result data (Intent), if any, from this Activity. 2637 * 2638 * @return Returns true if the activity successfully finished, or false if it is still running. 2639 */ 2640 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2641 // Refuse possible leaked file descriptors 2642 if (resultData != null && resultData.hasFileDescriptors() == true) { 2643 throw new IllegalArgumentException("File descriptors passed in Intent"); 2644 } 2645 2646 synchronized(this) { 2647 if (mController != null) { 2648 // Find the first activity that is not finishing. 2649 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2650 if (next != null) { 2651 // ask watcher if this is allowed 2652 boolean resumeOK = true; 2653 try { 2654 resumeOK = mController.activityResuming(next.packageName); 2655 } catch (RemoteException e) { 2656 mController = null; 2657 } 2658 2659 if (!resumeOK) { 2660 return false; 2661 } 2662 } 2663 } 2664 final long origId = Binder.clearCallingIdentity(); 2665 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2666 resultData, "app-request"); 2667 Binder.restoreCallingIdentity(origId); 2668 return res; 2669 } 2670 } 2671 2672 public final void finishHeavyWeightApp() { 2673 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2674 != PackageManager.PERMISSION_GRANTED) { 2675 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2676 + Binder.getCallingPid() 2677 + ", uid=" + Binder.getCallingUid() 2678 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2679 Slog.w(TAG, msg); 2680 throw new SecurityException(msg); 2681 } 2682 2683 synchronized(this) { 2684 if (mHeavyWeightProcess == null) { 2685 return; 2686 } 2687 2688 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2689 mHeavyWeightProcess.activities); 2690 for (int i=0; i<activities.size(); i++) { 2691 ActivityRecord r = activities.get(i); 2692 if (!r.finishing) { 2693 int index = mMainStack.indexOfTokenLocked(r.appToken); 2694 if (index >= 0) { 2695 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2696 null, "finish-heavy"); 2697 } 2698 } 2699 } 2700 2701 mHeavyWeightProcess = null; 2702 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2703 } 2704 } 2705 2706 public void crashApplication(int uid, int initialPid, String packageName, 2707 String message) { 2708 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2709 != PackageManager.PERMISSION_GRANTED) { 2710 String msg = "Permission Denial: crashApplication() from pid=" 2711 + Binder.getCallingPid() 2712 + ", uid=" + Binder.getCallingUid() 2713 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2714 Slog.w(TAG, msg); 2715 throw new SecurityException(msg); 2716 } 2717 2718 synchronized(this) { 2719 ProcessRecord proc = null; 2720 2721 // Figure out which process to kill. We don't trust that initialPid 2722 // still has any relation to current pids, so must scan through the 2723 // list. 2724 synchronized (mPidsSelfLocked) { 2725 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2726 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2727 if (p.uid != uid) { 2728 continue; 2729 } 2730 if (p.pid == initialPid) { 2731 proc = p; 2732 break; 2733 } 2734 for (String str : p.pkgList) { 2735 if (str.equals(packageName)) { 2736 proc = p; 2737 } 2738 } 2739 } 2740 } 2741 2742 if (proc == null) { 2743 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2744 + " initialPid=" + initialPid 2745 + " packageName=" + packageName); 2746 return; 2747 } 2748 2749 if (proc.thread != null) { 2750 if (proc.pid == Process.myPid()) { 2751 Log.w(TAG, "crashApplication: trying to crash self!"); 2752 return; 2753 } 2754 long ident = Binder.clearCallingIdentity(); 2755 try { 2756 proc.thread.scheduleCrash(message); 2757 } catch (RemoteException e) { 2758 } 2759 Binder.restoreCallingIdentity(ident); 2760 } 2761 } 2762 } 2763 2764 public final void finishSubActivity(IBinder token, String resultWho, 2765 int requestCode) { 2766 synchronized(this) { 2767 final long origId = Binder.clearCallingIdentity(); 2768 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2769 Binder.restoreCallingIdentity(origId); 2770 } 2771 } 2772 2773 public boolean finishActivityAffinity(IBinder token) { 2774 synchronized(this) { 2775 final long origId = Binder.clearCallingIdentity(); 2776 boolean res = mMainStack.finishActivityAffinityLocked(token); 2777 Binder.restoreCallingIdentity(origId); 2778 return res; 2779 } 2780 } 2781 2782 public boolean willActivityBeVisible(IBinder token) { 2783 synchronized(this) { 2784 int i; 2785 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2786 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2787 if (r.appToken == token) { 2788 return true; 2789 } 2790 if (r.fullscreen && !r.finishing) { 2791 return false; 2792 } 2793 } 2794 return true; 2795 } 2796 } 2797 2798 public void overridePendingTransition(IBinder token, String packageName, 2799 int enterAnim, int exitAnim) { 2800 synchronized(this) { 2801 ActivityRecord self = mMainStack.isInStackLocked(token); 2802 if (self == null) { 2803 return; 2804 } 2805 2806 final long origId = Binder.clearCallingIdentity(); 2807 2808 if (self.state == ActivityState.RESUMED 2809 || self.state == ActivityState.PAUSING) { 2810 mWindowManager.overridePendingAppTransition(packageName, 2811 enterAnim, exitAnim, null); 2812 } 2813 2814 Binder.restoreCallingIdentity(origId); 2815 } 2816 } 2817 2818 /** 2819 * Main function for removing an existing process from the activity manager 2820 * as a result of that process going away. Clears out all connections 2821 * to the process. 2822 */ 2823 private final void handleAppDiedLocked(ProcessRecord app, 2824 boolean restarting, boolean allowRestart) { 2825 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2826 if (!restarting) { 2827 mLruProcesses.remove(app); 2828 } 2829 2830 if (mProfileProc == app) { 2831 clearProfilerLocked(); 2832 } 2833 2834 // Just in case... 2835 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2836 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2837 mMainStack.mPausingActivity = null; 2838 } 2839 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2840 mMainStack.mLastPausedActivity = null; 2841 } 2842 2843 // Remove this application's activities from active lists. 2844 mMainStack.removeHistoryRecordsForAppLocked(app); 2845 2846 boolean atTop = true; 2847 boolean hasVisibleActivities = false; 2848 2849 // Clean out the history list. 2850 int i = mMainStack.mHistory.size(); 2851 if (localLOGV) Slog.v( 2852 TAG, "Removing app " + app + " from history with " + i + " entries"); 2853 while (i > 0) { 2854 i--; 2855 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2856 if (localLOGV) Slog.v( 2857 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2858 if (r.app == app) { 2859 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2860 if (ActivityStack.DEBUG_ADD_REMOVE) { 2861 RuntimeException here = new RuntimeException("here"); 2862 here.fillInStackTrace(); 2863 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2864 + ": haveState=" + r.haveState 2865 + " stateNotNeeded=" + r.stateNotNeeded 2866 + " finishing=" + r.finishing 2867 + " state=" + r.state, here); 2868 } 2869 if (!r.finishing) { 2870 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2871 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2872 System.identityHashCode(r), 2873 r.task.taskId, r.shortComponentName, 2874 "proc died without state saved"); 2875 } 2876 mMainStack.removeActivityFromHistoryLocked(r); 2877 2878 } else { 2879 // We have the current state for this activity, so 2880 // it can be restarted later when needed. 2881 if (localLOGV) Slog.v( 2882 TAG, "Keeping entry, setting app to null"); 2883 if (r.visible) { 2884 hasVisibleActivities = true; 2885 } 2886 r.app = null; 2887 r.nowVisible = false; 2888 if (!r.haveState) { 2889 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2890 "App died, clearing saved state of " + r); 2891 r.icicle = null; 2892 } 2893 } 2894 2895 r.stack.cleanUpActivityLocked(r, true, true); 2896 } 2897 atTop = false; 2898 } 2899 2900 app.activities.clear(); 2901 2902 if (app.instrumentationClass != null) { 2903 Slog.w(TAG, "Crash of app " + app.processName 2904 + " running instrumentation " + app.instrumentationClass); 2905 Bundle info = new Bundle(); 2906 info.putString("shortMsg", "Process crashed."); 2907 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2908 } 2909 2910 if (!restarting) { 2911 if (!mMainStack.resumeTopActivityLocked(null)) { 2912 // If there was nothing to resume, and we are not already 2913 // restarting this process, but there is a visible activity that 2914 // is hosted by the process... then make sure all visible 2915 // activities are running, taking care of restarting this 2916 // process. 2917 if (hasVisibleActivities) { 2918 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2919 } 2920 } 2921 } 2922 } 2923 2924 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2925 IBinder threadBinder = thread.asBinder(); 2926 // Find the application record. 2927 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2928 ProcessRecord rec = mLruProcesses.get(i); 2929 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2930 return i; 2931 } 2932 } 2933 return -1; 2934 } 2935 2936 final ProcessRecord getRecordForAppLocked( 2937 IApplicationThread thread) { 2938 if (thread == null) { 2939 return null; 2940 } 2941 2942 int appIndex = getLRURecordIndexForAppLocked(thread); 2943 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2944 } 2945 2946 final void appDiedLocked(ProcessRecord app, int pid, 2947 IApplicationThread thread) { 2948 2949 mProcDeaths[0]++; 2950 2951 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2952 synchronized (stats) { 2953 stats.noteProcessDiedLocked(app.info.uid, pid); 2954 } 2955 2956 // Clean up already done if the process has been re-started. 2957 if (app.pid == pid && app.thread != null && 2958 app.thread.asBinder() == thread.asBinder()) { 2959 if (!app.killedBackground) { 2960 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2961 + ") has died."); 2962 } 2963 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2964 if (localLOGV) Slog.v( 2965 TAG, "Dying app: " + app + ", pid: " + pid 2966 + ", thread: " + thread.asBinder()); 2967 boolean doLowMem = app.instrumentationClass == null; 2968 handleAppDiedLocked(app, false, true); 2969 2970 if (doLowMem) { 2971 // If there are no longer any background processes running, 2972 // and the app that died was not running instrumentation, 2973 // then tell everyone we are now low on memory. 2974 boolean haveBg = false; 2975 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2976 ProcessRecord rec = mLruProcesses.get(i); 2977 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2978 haveBg = true; 2979 break; 2980 } 2981 } 2982 2983 if (!haveBg) { 2984 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2985 long now = SystemClock.uptimeMillis(); 2986 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2987 ProcessRecord rec = mLruProcesses.get(i); 2988 if (rec != app && rec.thread != null && 2989 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2990 // The low memory report is overriding any current 2991 // state for a GC request. Make sure to do 2992 // heavy/important/visible/foreground processes first. 2993 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2994 rec.lastRequestedGc = 0; 2995 } else { 2996 rec.lastRequestedGc = rec.lastLowMemory; 2997 } 2998 rec.reportLowMemory = true; 2999 rec.lastLowMemory = now; 3000 mProcessesToGc.remove(rec); 3001 addProcessToGcListLocked(rec); 3002 } 3003 } 3004 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3005 scheduleAppGcsLocked(); 3006 } 3007 } 3008 } else if (app.pid != pid) { 3009 // A new process has already been started. 3010 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3011 + ") has died and restarted (pid " + app.pid + ")."); 3012 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3013 } else if (DEBUG_PROCESSES) { 3014 Slog.d(TAG, "Received spurious death notification for thread " 3015 + thread.asBinder()); 3016 } 3017 } 3018 3019 /** 3020 * If a stack trace dump file is configured, dump process stack traces. 3021 * @param clearTraces causes the dump file to be erased prior to the new 3022 * traces being written, if true; when false, the new traces will be 3023 * appended to any existing file content. 3024 * @param firstPids of dalvik VM processes to dump stack traces for first 3025 * @param lastPids of dalvik VM processes to dump stack traces for last 3026 * @param nativeProcs optional list of native process names to dump stack crawls 3027 * @return file containing stack traces, or null if no dump file is configured 3028 */ 3029 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3030 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3031 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3032 if (tracesPath == null || tracesPath.length() == 0) { 3033 return null; 3034 } 3035 3036 File tracesFile = new File(tracesPath); 3037 try { 3038 File tracesDir = tracesFile.getParentFile(); 3039 if (!tracesDir.exists()) { 3040 tracesFile.mkdirs(); 3041 if (!SELinux.restorecon(tracesDir)) { 3042 return null; 3043 } 3044 } 3045 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3046 3047 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3048 tracesFile.createNewFile(); 3049 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3050 } catch (IOException e) { 3051 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3052 return null; 3053 } 3054 3055 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3056 return tracesFile; 3057 } 3058 3059 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3060 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3061 // Use a FileObserver to detect when traces finish writing. 3062 // The order of traces is considered important to maintain for legibility. 3063 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3064 public synchronized void onEvent(int event, String path) { notify(); } 3065 }; 3066 3067 try { 3068 observer.startWatching(); 3069 3070 // First collect all of the stacks of the most important pids. 3071 if (firstPids != null) { 3072 try { 3073 int num = firstPids.size(); 3074 for (int i = 0; i < num; i++) { 3075 synchronized (observer) { 3076 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3077 observer.wait(200); // Wait for write-close, give up after 200msec 3078 } 3079 } 3080 } catch (InterruptedException e) { 3081 Log.wtf(TAG, e); 3082 } 3083 } 3084 3085 // Next measure CPU usage. 3086 if (processStats != null) { 3087 processStats.init(); 3088 System.gc(); 3089 processStats.update(); 3090 try { 3091 synchronized (processStats) { 3092 processStats.wait(500); // measure over 1/2 second. 3093 } 3094 } catch (InterruptedException e) { 3095 } 3096 processStats.update(); 3097 3098 // We'll take the stack crawls of just the top apps using CPU. 3099 final int N = processStats.countWorkingStats(); 3100 int numProcs = 0; 3101 for (int i=0; i<N && numProcs<5; i++) { 3102 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3103 if (lastPids.indexOfKey(stats.pid) >= 0) { 3104 numProcs++; 3105 try { 3106 synchronized (observer) { 3107 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3108 observer.wait(200); // Wait for write-close, give up after 200msec 3109 } 3110 } catch (InterruptedException e) { 3111 Log.wtf(TAG, e); 3112 } 3113 3114 } 3115 } 3116 } 3117 3118 } finally { 3119 observer.stopWatching(); 3120 } 3121 3122 if (nativeProcs != null) { 3123 int[] pids = Process.getPidsForCommands(nativeProcs); 3124 if (pids != null) { 3125 for (int pid : pids) { 3126 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3127 } 3128 } 3129 } 3130 } 3131 3132 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3133 if (true || IS_USER_BUILD) { 3134 return; 3135 } 3136 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3137 if (tracesPath == null || tracesPath.length() == 0) { 3138 return; 3139 } 3140 3141 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3142 StrictMode.allowThreadDiskWrites(); 3143 try { 3144 final File tracesFile = new File(tracesPath); 3145 final File tracesDir = tracesFile.getParentFile(); 3146 final File tracesTmp = new File(tracesDir, "__tmp__"); 3147 try { 3148 if (!tracesDir.exists()) { 3149 tracesFile.mkdirs(); 3150 if (!SELinux.restorecon(tracesDir.getPath())) { 3151 return; 3152 } 3153 } 3154 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3155 3156 if (tracesFile.exists()) { 3157 tracesTmp.delete(); 3158 tracesFile.renameTo(tracesTmp); 3159 } 3160 StringBuilder sb = new StringBuilder(); 3161 Time tobj = new Time(); 3162 tobj.set(System.currentTimeMillis()); 3163 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3164 sb.append(": "); 3165 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3166 sb.append(" since "); 3167 sb.append(msg); 3168 FileOutputStream fos = new FileOutputStream(tracesFile); 3169 fos.write(sb.toString().getBytes()); 3170 if (app == null) { 3171 fos.write("\n*** No application process!".getBytes()); 3172 } 3173 fos.close(); 3174 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3175 } catch (IOException e) { 3176 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3177 return; 3178 } 3179 3180 if (app != null) { 3181 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3182 firstPids.add(app.pid); 3183 dumpStackTraces(tracesPath, firstPids, null, null, null); 3184 } 3185 3186 File lastTracesFile = null; 3187 File curTracesFile = null; 3188 for (int i=9; i>=0; i--) { 3189 String name = String.format("slow%02d.txt", i); 3190 curTracesFile = new File(tracesDir, name); 3191 if (curTracesFile.exists()) { 3192 if (lastTracesFile != null) { 3193 curTracesFile.renameTo(lastTracesFile); 3194 } else { 3195 curTracesFile.delete(); 3196 } 3197 } 3198 lastTracesFile = curTracesFile; 3199 } 3200 tracesFile.renameTo(curTracesFile); 3201 if (tracesTmp.exists()) { 3202 tracesTmp.renameTo(tracesFile); 3203 } 3204 } finally { 3205 StrictMode.setThreadPolicy(oldPolicy); 3206 } 3207 } 3208 3209 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3210 ActivityRecord parent, final String annotation) { 3211 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3212 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3213 3214 if (mController != null) { 3215 try { 3216 // 0 == continue, -1 = kill process immediately 3217 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3218 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3219 } catch (RemoteException e) { 3220 mController = null; 3221 } 3222 } 3223 3224 long anrTime = SystemClock.uptimeMillis(); 3225 if (MONITOR_CPU_USAGE) { 3226 updateCpuStatsNow(); 3227 } 3228 3229 synchronized (this) { 3230 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3231 if (mShuttingDown) { 3232 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3233 return; 3234 } else if (app.notResponding) { 3235 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3236 return; 3237 } else if (app.crashing) { 3238 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3239 return; 3240 } 3241 3242 // In case we come through here for the same app before completing 3243 // this one, mark as anring now so we will bail out. 3244 app.notResponding = true; 3245 3246 // Log the ANR to the event log. 3247 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3248 annotation); 3249 3250 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3251 firstPids.add(app.pid); 3252 3253 int parentPid = app.pid; 3254 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3255 if (parentPid != app.pid) firstPids.add(parentPid); 3256 3257 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3258 3259 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3260 ProcessRecord r = mLruProcesses.get(i); 3261 if (r != null && r.thread != null) { 3262 int pid = r.pid; 3263 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3264 if (r.persistent) { 3265 firstPids.add(pid); 3266 } else { 3267 lastPids.put(pid, Boolean.TRUE); 3268 } 3269 } 3270 } 3271 } 3272 } 3273 3274 // Log the ANR to the main log. 3275 StringBuilder info = new StringBuilder(); 3276 info.setLength(0); 3277 info.append("ANR in ").append(app.processName); 3278 if (activity != null && activity.shortComponentName != null) { 3279 info.append(" (").append(activity.shortComponentName).append(")"); 3280 } 3281 info.append("\n"); 3282 if (annotation != null) { 3283 info.append("Reason: ").append(annotation).append("\n"); 3284 } 3285 if (parent != null && parent != activity) { 3286 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3287 } 3288 3289 final ProcessStats processStats = new ProcessStats(true); 3290 3291 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3292 3293 String cpuInfo = null; 3294 if (MONITOR_CPU_USAGE) { 3295 updateCpuStatsNow(); 3296 synchronized (mProcessStatsThread) { 3297 cpuInfo = mProcessStats.printCurrentState(anrTime); 3298 } 3299 info.append(processStats.printCurrentLoad()); 3300 info.append(cpuInfo); 3301 } 3302 3303 info.append(processStats.printCurrentState(anrTime)); 3304 3305 Slog.e(TAG, info.toString()); 3306 if (tracesFile == null) { 3307 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3308 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3309 } 3310 3311 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3312 cpuInfo, tracesFile, null); 3313 3314 if (mController != null) { 3315 try { 3316 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3317 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3318 if (res != 0) { 3319 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3320 return; 3321 } 3322 } catch (RemoteException e) { 3323 mController = null; 3324 } 3325 } 3326 3327 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3328 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3329 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3330 3331 synchronized (this) { 3332 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3333 Slog.w(TAG, "Killing " + app + ": background ANR"); 3334 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3335 app.processName, app.setAdj, "background ANR"); 3336 Process.killProcessQuiet(app.pid); 3337 return; 3338 } 3339 3340 // Set the app's notResponding state, and look up the errorReportReceiver 3341 makeAppNotRespondingLocked(app, 3342 activity != null ? activity.shortComponentName : null, 3343 annotation != null ? "ANR " + annotation : "ANR", 3344 info.toString()); 3345 3346 // Bring up the infamous App Not Responding dialog 3347 Message msg = Message.obtain(); 3348 HashMap map = new HashMap(); 3349 msg.what = SHOW_NOT_RESPONDING_MSG; 3350 msg.obj = map; 3351 map.put("app", app); 3352 if (activity != null) { 3353 map.put("activity", activity); 3354 } 3355 3356 mHandler.sendMessage(msg); 3357 } 3358 } 3359 3360 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3361 if (!mLaunchWarningShown) { 3362 mLaunchWarningShown = true; 3363 mHandler.post(new Runnable() { 3364 @Override 3365 public void run() { 3366 synchronized (ActivityManagerService.this) { 3367 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3368 d.show(); 3369 mHandler.postDelayed(new Runnable() { 3370 @Override 3371 public void run() { 3372 synchronized (ActivityManagerService.this) { 3373 d.dismiss(); 3374 mLaunchWarningShown = false; 3375 } 3376 } 3377 }, 4000); 3378 } 3379 } 3380 }); 3381 } 3382 } 3383 3384 public boolean clearApplicationUserData(final String packageName, 3385 final IPackageDataObserver observer, final int userId) { 3386 enforceNotIsolatedCaller("clearApplicationUserData"); 3387 int uid = Binder.getCallingUid(); 3388 int pid = Binder.getCallingPid(); 3389 long callingId = Binder.clearCallingIdentity(); 3390 try { 3391 IPackageManager pm = AppGlobals.getPackageManager(); 3392 int pkgUid = -1; 3393 synchronized(this) { 3394 try { 3395 pkgUid = pm.getPackageUid(packageName, userId); 3396 } catch (RemoteException e) { 3397 } 3398 if (pkgUid == -1) { 3399 Slog.w(TAG, "Invalid packageName:" + packageName); 3400 return false; 3401 } 3402 if (uid == pkgUid || checkComponentPermission( 3403 android.Manifest.permission.CLEAR_APP_USER_DATA, 3404 pid, uid, -1, true) 3405 == PackageManager.PERMISSION_GRANTED) { 3406 forceStopPackageLocked(packageName, pkgUid); 3407 } else { 3408 throw new SecurityException(pid+" does not have permission:"+ 3409 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3410 "for process:"+packageName); 3411 } 3412 } 3413 3414 try { 3415 //clear application user data 3416 pm.clearApplicationUserData(packageName, observer, userId); 3417 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3418 Uri.fromParts("package", packageName, null)); 3419 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3420 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3421 null, null, 0, null, null, null, false, false, userId); 3422 } catch (RemoteException e) { 3423 } 3424 } finally { 3425 Binder.restoreCallingIdentity(callingId); 3426 } 3427 return true; 3428 } 3429 3430 public void killBackgroundProcesses(final String packageName) { 3431 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3432 != PackageManager.PERMISSION_GRANTED && 3433 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3434 != PackageManager.PERMISSION_GRANTED) { 3435 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3436 + Binder.getCallingPid() 3437 + ", uid=" + Binder.getCallingUid() 3438 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3439 Slog.w(TAG, msg); 3440 throw new SecurityException(msg); 3441 } 3442 3443 int userId = UserHandle.getCallingUserId(); 3444 long callingId = Binder.clearCallingIdentity(); 3445 try { 3446 IPackageManager pm = AppGlobals.getPackageManager(); 3447 int pkgUid = -1; 3448 synchronized(this) { 3449 try { 3450 pkgUid = pm.getPackageUid(packageName, userId); 3451 } catch (RemoteException e) { 3452 } 3453 if (pkgUid == -1) { 3454 Slog.w(TAG, "Invalid packageName: " + packageName); 3455 return; 3456 } 3457 killPackageProcessesLocked(packageName, pkgUid, 3458 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3459 } 3460 } finally { 3461 Binder.restoreCallingIdentity(callingId); 3462 } 3463 } 3464 3465 public void killAllBackgroundProcesses() { 3466 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3467 != PackageManager.PERMISSION_GRANTED) { 3468 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3469 + Binder.getCallingPid() 3470 + ", uid=" + Binder.getCallingUid() 3471 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3472 Slog.w(TAG, msg); 3473 throw new SecurityException(msg); 3474 } 3475 3476 long callingId = Binder.clearCallingIdentity(); 3477 try { 3478 synchronized(this) { 3479 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3480 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3481 final int NA = apps.size(); 3482 for (int ia=0; ia<NA; ia++) { 3483 ProcessRecord app = apps.valueAt(ia); 3484 if (app.persistent) { 3485 // we don't kill persistent processes 3486 continue; 3487 } 3488 if (app.removed) { 3489 procs.add(app); 3490 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3491 app.removed = true; 3492 procs.add(app); 3493 } 3494 } 3495 } 3496 3497 int N = procs.size(); 3498 for (int i=0; i<N; i++) { 3499 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3500 } 3501 } 3502 } finally { 3503 Binder.restoreCallingIdentity(callingId); 3504 } 3505 } 3506 3507 public void forceStopPackage(final String packageName) { 3508 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3509 != PackageManager.PERMISSION_GRANTED) { 3510 String msg = "Permission Denial: forceStopPackage() from pid=" 3511 + Binder.getCallingPid() 3512 + ", uid=" + Binder.getCallingUid() 3513 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3514 Slog.w(TAG, msg); 3515 throw new SecurityException(msg); 3516 } 3517 final int userId = UserHandle.getCallingUserId(); 3518 long callingId = Binder.clearCallingIdentity(); 3519 try { 3520 IPackageManager pm = AppGlobals.getPackageManager(); 3521 int pkgUid = -1; 3522 synchronized(this) { 3523 try { 3524 pkgUid = pm.getPackageUid(packageName, userId); 3525 } catch (RemoteException e) { 3526 } 3527 if (pkgUid == -1) { 3528 Slog.w(TAG, "Invalid packageName: " + packageName); 3529 return; 3530 } 3531 forceStopPackageLocked(packageName, pkgUid); 3532 try { 3533 pm.setPackageStoppedState(packageName, true, userId); 3534 } catch (RemoteException e) { 3535 } catch (IllegalArgumentException e) { 3536 Slog.w(TAG, "Failed trying to unstop package " 3537 + packageName + ": " + e); 3538 } 3539 } 3540 } finally { 3541 Binder.restoreCallingIdentity(callingId); 3542 } 3543 } 3544 3545 /* 3546 * The pkg name and uid have to be specified. 3547 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3548 */ 3549 public void killApplicationWithUid(String pkg, int uid) { 3550 if (pkg == null) { 3551 return; 3552 } 3553 // Make sure the uid is valid. 3554 if (uid < 0) { 3555 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3556 return; 3557 } 3558 int callerUid = Binder.getCallingUid(); 3559 // Only the system server can kill an application 3560 if (callerUid == Process.SYSTEM_UID) { 3561 // Post an aysnc message to kill the application 3562 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3563 msg.arg1 = uid; 3564 msg.arg2 = 0; 3565 msg.obj = pkg; 3566 mHandler.sendMessage(msg); 3567 } else { 3568 throw new SecurityException(callerUid + " cannot kill pkg: " + 3569 pkg); 3570 } 3571 } 3572 3573 public void closeSystemDialogs(String reason) { 3574 enforceNotIsolatedCaller("closeSystemDialogs"); 3575 3576 final int uid = Binder.getCallingUid(); 3577 final long origId = Binder.clearCallingIdentity(); 3578 synchronized (this) { 3579 closeSystemDialogsLocked(uid, reason); 3580 } 3581 Binder.restoreCallingIdentity(origId); 3582 } 3583 3584 void closeSystemDialogsLocked(int callingUid, String reason) { 3585 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3586 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3587 if (reason != null) { 3588 intent.putExtra("reason", reason); 3589 } 3590 mWindowManager.closeSystemDialogs(reason); 3591 3592 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3593 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3594 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3595 r.stack.finishActivityLocked(r, i, 3596 Activity.RESULT_CANCELED, null, "close-sys"); 3597 } 3598 } 3599 3600 broadcastIntentLocked(null, null, intent, null, 3601 null, 0, null, null, null, false, false, -1, 3602 callingUid, 0 /* TODO: Verify */); 3603 } 3604 3605 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3606 throws RemoteException { 3607 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3608 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3609 for (int i=pids.length-1; i>=0; i--) { 3610 infos[i] = new Debug.MemoryInfo(); 3611 Debug.getMemoryInfo(pids[i], infos[i]); 3612 } 3613 return infos; 3614 } 3615 3616 public long[] getProcessPss(int[] pids) throws RemoteException { 3617 enforceNotIsolatedCaller("getProcessPss"); 3618 long[] pss = new long[pids.length]; 3619 for (int i=pids.length-1; i>=0; i--) { 3620 pss[i] = Debug.getPss(pids[i]); 3621 } 3622 return pss; 3623 } 3624 3625 public void killApplicationProcess(String processName, int uid) { 3626 if (processName == null) { 3627 return; 3628 } 3629 3630 int callerUid = Binder.getCallingUid(); 3631 // Only the system server can kill an application 3632 if (callerUid == Process.SYSTEM_UID) { 3633 synchronized (this) { 3634 ProcessRecord app = getProcessRecordLocked(processName, uid); 3635 if (app != null && app.thread != null) { 3636 try { 3637 app.thread.scheduleSuicide(); 3638 } catch (RemoteException e) { 3639 // If the other end already died, then our work here is done. 3640 } 3641 } else { 3642 Slog.w(TAG, "Process/uid not found attempting kill of " 3643 + processName + " / " + uid); 3644 } 3645 } 3646 } else { 3647 throw new SecurityException(callerUid + " cannot kill app process: " + 3648 processName); 3649 } 3650 } 3651 3652 private void forceStopPackageLocked(final String packageName, int uid) { 3653 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3654 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3655 Uri.fromParts("package", packageName, null)); 3656 if (!mProcessesReady) { 3657 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3658 } 3659 intent.putExtra(Intent.EXTRA_UID, uid); 3660 broadcastIntentLocked(null, null, intent, 3661 null, null, 0, null, null, null, 3662 false, false, 3663 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3664 } 3665 3666 private final boolean killPackageProcessesLocked(String packageName, int uid, 3667 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3668 boolean evenPersistent, String reason) { 3669 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3670 3671 // Remove all processes this package may have touched: all with the 3672 // same UID (except for the system or root user), and all whose name 3673 // matches the package name. 3674 final String procNamePrefix = packageName + ":"; 3675 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3676 final int NA = apps.size(); 3677 for (int ia=0; ia<NA; ia++) { 3678 ProcessRecord app = apps.valueAt(ia); 3679 if (app.persistent && !evenPersistent) { 3680 // we don't kill persistent processes 3681 continue; 3682 } 3683 if (app.removed) { 3684 if (doit) { 3685 procs.add(app); 3686 } 3687 // If uid is specified and the uid and process name match 3688 // Or, the uid is not specified and the process name matches 3689 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3690 || ((app.processName.equals(packageName) 3691 || app.processName.startsWith(procNamePrefix)) 3692 && uid < 0))) { 3693 if (app.setAdj >= minOomAdj) { 3694 if (!doit) { 3695 return true; 3696 } 3697 app.removed = true; 3698 procs.add(app); 3699 } 3700 } 3701 } 3702 } 3703 3704 int N = procs.size(); 3705 for (int i=0; i<N; i++) { 3706 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3707 } 3708 return N > 0; 3709 } 3710 3711 private final boolean forceStopPackageLocked(String name, int uid, 3712 boolean callerWillRestart, boolean purgeCache, boolean doit, 3713 boolean evenPersistent, int userId) { 3714 int i; 3715 int N; 3716 3717 if (uid < 0) { 3718 try { 3719 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3720 } catch (RemoteException e) { 3721 } 3722 } 3723 3724 if (doit) { 3725 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3726 3727 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3728 while (badApps.hasNext()) { 3729 SparseArray<Long> ba = badApps.next(); 3730 if (ba.get(uid) != null) { 3731 badApps.remove(); 3732 } 3733 } 3734 } 3735 3736 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3737 callerWillRestart, false, doit, evenPersistent, "force stop"); 3738 3739 TaskRecord lastTask = null; 3740 for (i=0; i<mMainStack.mHistory.size(); i++) { 3741 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3742 final boolean samePackage = r.packageName.equals(name); 3743 if (r.userId == userId 3744 && (samePackage || r.task == lastTask) 3745 && (r.app == null || evenPersistent || !r.app.persistent)) { 3746 if (!doit) { 3747 if (r.finishing) { 3748 // If this activity is just finishing, then it is not 3749 // interesting as far as something to stop. 3750 continue; 3751 } 3752 return true; 3753 } 3754 didSomething = true; 3755 Slog.i(TAG, " Force finishing activity " + r); 3756 if (samePackage) { 3757 if (r.app != null) { 3758 r.app.removed = true; 3759 } 3760 r.app = null; 3761 } 3762 lastTask = r.task; 3763 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3764 null, "force-stop", true)) { 3765 i--; 3766 } 3767 } 3768 } 3769 3770 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3771 if (!doit) { 3772 return true; 3773 } 3774 didSomething = true; 3775 } 3776 3777 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3778 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3779 if (provider.info.packageName.equals(name) 3780 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3781 if (!doit) { 3782 return true; 3783 } 3784 didSomething = true; 3785 providers.add(provider); 3786 } 3787 } 3788 3789 N = providers.size(); 3790 for (i=0; i<N; i++) { 3791 removeDyingProviderLocked(null, providers.get(i), true); 3792 } 3793 3794 if (doit) { 3795 if (purgeCache) { 3796 AttributeCache ac = AttributeCache.instance(); 3797 if (ac != null) { 3798 ac.removePackage(name); 3799 } 3800 } 3801 if (mBooted) { 3802 mMainStack.resumeTopActivityLocked(null); 3803 mMainStack.scheduleIdleLocked(); 3804 } 3805 } 3806 3807 return didSomething; 3808 } 3809 3810 private final boolean removeProcessLocked(ProcessRecord app, 3811 boolean callerWillRestart, boolean allowRestart, String reason) { 3812 final String name = app.processName; 3813 final int uid = app.uid; 3814 if (DEBUG_PROCESSES) Slog.d( 3815 TAG, "Force removing proc " + app.toShortString() + " (" + name 3816 + "/" + uid + ")"); 3817 3818 mProcessNames.remove(name, uid); 3819 mIsolatedProcesses.remove(app.uid); 3820 if (mHeavyWeightProcess == app) { 3821 mHeavyWeightProcess = null; 3822 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3823 } 3824 boolean needRestart = false; 3825 if (app.pid > 0 && app.pid != MY_PID) { 3826 int pid = app.pid; 3827 synchronized (mPidsSelfLocked) { 3828 mPidsSelfLocked.remove(pid); 3829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3830 } 3831 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3832 handleAppDiedLocked(app, true, allowRestart); 3833 mLruProcesses.remove(app); 3834 Process.killProcessQuiet(pid); 3835 3836 if (app.persistent && !app.isolated) { 3837 if (!callerWillRestart) { 3838 addAppLocked(app.info, false); 3839 } else { 3840 needRestart = true; 3841 } 3842 } 3843 } else { 3844 mRemovedProcesses.add(app); 3845 } 3846 3847 return needRestart; 3848 } 3849 3850 private final void processStartTimedOutLocked(ProcessRecord app) { 3851 final int pid = app.pid; 3852 boolean gone = false; 3853 synchronized (mPidsSelfLocked) { 3854 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3855 if (knownApp != null && knownApp.thread == null) { 3856 mPidsSelfLocked.remove(pid); 3857 gone = true; 3858 } 3859 } 3860 3861 if (gone) { 3862 Slog.w(TAG, "Process " + app + " failed to attach"); 3863 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3864 app.processName); 3865 mProcessNames.remove(app.processName, app.uid); 3866 mIsolatedProcesses.remove(app.uid); 3867 if (mHeavyWeightProcess == app) { 3868 mHeavyWeightProcess = null; 3869 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3870 } 3871 // Take care of any launching providers waiting for this process. 3872 checkAppInLaunchingProvidersLocked(app, true); 3873 // Take care of any services that are waiting for the process. 3874 mServices.processStartTimedOutLocked(app); 3875 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3876 app.processName, app.setAdj, "start timeout"); 3877 Process.killProcessQuiet(pid); 3878 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3879 Slog.w(TAG, "Unattached app died before backup, skipping"); 3880 try { 3881 IBackupManager bm = IBackupManager.Stub.asInterface( 3882 ServiceManager.getService(Context.BACKUP_SERVICE)); 3883 bm.agentDisconnected(app.info.packageName); 3884 } catch (RemoteException e) { 3885 // Can't happen; the backup manager is local 3886 } 3887 } 3888 if (isPendingBroadcastProcessLocked(pid)) { 3889 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3890 skipPendingBroadcastLocked(pid); 3891 } 3892 } else { 3893 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3894 } 3895 } 3896 3897 private final boolean attachApplicationLocked(IApplicationThread thread, 3898 int pid) { 3899 3900 // Find the application record that is being attached... either via 3901 // the pid if we are running in multiple processes, or just pull the 3902 // next app record if we are emulating process with anonymous threads. 3903 ProcessRecord app; 3904 if (pid != MY_PID && pid >= 0) { 3905 synchronized (mPidsSelfLocked) { 3906 app = mPidsSelfLocked.get(pid); 3907 } 3908 } else { 3909 app = null; 3910 } 3911 3912 if (app == null) { 3913 Slog.w(TAG, "No pending application record for pid " + pid 3914 + " (IApplicationThread " + thread + "); dropping process"); 3915 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3916 if (pid > 0 && pid != MY_PID) { 3917 Process.killProcessQuiet(pid); 3918 } else { 3919 try { 3920 thread.scheduleExit(); 3921 } catch (Exception e) { 3922 // Ignore exceptions. 3923 } 3924 } 3925 return false; 3926 } 3927 3928 // If this application record is still attached to a previous 3929 // process, clean it up now. 3930 if (app.thread != null) { 3931 handleAppDiedLocked(app, true, true); 3932 } 3933 3934 // Tell the process all about itself. 3935 3936 if (localLOGV) Slog.v( 3937 TAG, "Binding process pid " + pid + " to record " + app); 3938 3939 String processName = app.processName; 3940 try { 3941 AppDeathRecipient adr = new AppDeathRecipient( 3942 app, pid, thread); 3943 thread.asBinder().linkToDeath(adr, 0); 3944 app.deathRecipient = adr; 3945 } catch (RemoteException e) { 3946 app.resetPackageList(); 3947 startProcessLocked(app, "link fail", processName); 3948 return false; 3949 } 3950 3951 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3952 3953 app.thread = thread; 3954 app.curAdj = app.setAdj = -100; 3955 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3956 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3957 app.forcingToForeground = null; 3958 app.foregroundServices = false; 3959 app.hasShownUi = false; 3960 app.debugging = false; 3961 3962 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3963 3964 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3965 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3966 3967 if (!normalMode) { 3968 Slog.i(TAG, "Launching preboot mode app: " + app); 3969 } 3970 3971 if (localLOGV) Slog.v( 3972 TAG, "New app record " + app 3973 + " thread=" + thread.asBinder() + " pid=" + pid); 3974 try { 3975 int testMode = IApplicationThread.DEBUG_OFF; 3976 if (mDebugApp != null && mDebugApp.equals(processName)) { 3977 testMode = mWaitForDebugger 3978 ? IApplicationThread.DEBUG_WAIT 3979 : IApplicationThread.DEBUG_ON; 3980 app.debugging = true; 3981 if (mDebugTransient) { 3982 mDebugApp = mOrigDebugApp; 3983 mWaitForDebugger = mOrigWaitForDebugger; 3984 } 3985 } 3986 String profileFile = app.instrumentationProfileFile; 3987 ParcelFileDescriptor profileFd = null; 3988 boolean profileAutoStop = false; 3989 if (mProfileApp != null && mProfileApp.equals(processName)) { 3990 mProfileProc = app; 3991 profileFile = mProfileFile; 3992 profileFd = mProfileFd; 3993 profileAutoStop = mAutoStopProfiler; 3994 } 3995 boolean enableOpenGlTrace = false; 3996 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3997 enableOpenGlTrace = true; 3998 mOpenGlTraceApp = null; 3999 } 4000 4001 // If the app is being launched for restore or full backup, set it up specially 4002 boolean isRestrictedBackupMode = false; 4003 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4004 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4005 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4006 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4007 } 4008 4009 ensurePackageDexOpt(app.instrumentationInfo != null 4010 ? app.instrumentationInfo.packageName 4011 : app.info.packageName); 4012 if (app.instrumentationClass != null) { 4013 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4014 } 4015 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4016 + processName + " with config " + mConfiguration); 4017 ApplicationInfo appInfo = app.instrumentationInfo != null 4018 ? app.instrumentationInfo : app.info; 4019 app.compat = compatibilityInfoForPackageLocked(appInfo); 4020 if (profileFd != null) { 4021 profileFd = profileFd.dup(); 4022 } 4023 thread.bindApplication(processName, appInfo, providers, 4024 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4025 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4026 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4027 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4028 mCoreSettingsObserver.getCoreSettingsLocked()); 4029 updateLruProcessLocked(app, false, true); 4030 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4031 } catch (Exception e) { 4032 // todo: Yikes! What should we do? For now we will try to 4033 // start another process, but that could easily get us in 4034 // an infinite loop of restarting processes... 4035 Slog.w(TAG, "Exception thrown during bind!", e); 4036 4037 app.resetPackageList(); 4038 app.unlinkDeathRecipient(); 4039 startProcessLocked(app, "bind fail", processName); 4040 return false; 4041 } 4042 4043 // Remove this record from the list of starting applications. 4044 mPersistentStartingProcesses.remove(app); 4045 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4046 "Attach application locked removing on hold: " + app); 4047 mProcessesOnHold.remove(app); 4048 4049 boolean badApp = false; 4050 boolean didSomething = false; 4051 4052 // See if the top visible activity is waiting to run in this process... 4053 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4054 if (hr != null && normalMode) { 4055 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4056 && processName.equals(hr.processName)) { 4057 try { 4058 if (mHeadless) { 4059 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4060 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4061 didSomething = true; 4062 } 4063 } catch (Exception e) { 4064 Slog.w(TAG, "Exception in new application when starting activity " 4065 + hr.intent.getComponent().flattenToShortString(), e); 4066 badApp = true; 4067 } 4068 } else { 4069 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4070 } 4071 } 4072 4073 // Find any services that should be running in this process... 4074 if (!badApp) { 4075 try { 4076 didSomething |= mServices.attachApplicationLocked(app, processName); 4077 } catch (Exception e) { 4078 badApp = true; 4079 } 4080 } 4081 4082 // Check if a next-broadcast receiver is in this process... 4083 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4084 try { 4085 didSomething = sendPendingBroadcastsLocked(app); 4086 } catch (Exception e) { 4087 // If the app died trying to launch the receiver we declare it 'bad' 4088 badApp = true; 4089 } 4090 } 4091 4092 // Check whether the next backup agent is in this process... 4093 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4094 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4095 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4096 try { 4097 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4098 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4099 mBackupTarget.backupMode); 4100 } catch (Exception e) { 4101 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4102 e.printStackTrace(); 4103 } 4104 } 4105 4106 if (badApp) { 4107 // todo: Also need to kill application to deal with all 4108 // kinds of exceptions. 4109 handleAppDiedLocked(app, false, true); 4110 return false; 4111 } 4112 4113 if (!didSomething) { 4114 updateOomAdjLocked(); 4115 } 4116 4117 return true; 4118 } 4119 4120 public final void attachApplication(IApplicationThread thread) { 4121 synchronized (this) { 4122 int callingPid = Binder.getCallingPid(); 4123 final long origId = Binder.clearCallingIdentity(); 4124 attachApplicationLocked(thread, callingPid); 4125 Binder.restoreCallingIdentity(origId); 4126 } 4127 } 4128 4129 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4130 final long origId = Binder.clearCallingIdentity(); 4131 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4132 if (stopProfiling) { 4133 synchronized (this) { 4134 if (mProfileProc == r.app) { 4135 if (mProfileFd != null) { 4136 try { 4137 mProfileFd.close(); 4138 } catch (IOException e) { 4139 } 4140 clearProfilerLocked(); 4141 } 4142 } 4143 } 4144 } 4145 Binder.restoreCallingIdentity(origId); 4146 } 4147 4148 void enableScreenAfterBoot() { 4149 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4150 SystemClock.uptimeMillis()); 4151 mWindowManager.enableScreenAfterBoot(); 4152 4153 synchronized (this) { 4154 updateEventDispatchingLocked(); 4155 } 4156 } 4157 4158 public void showBootMessage(final CharSequence msg, final boolean always) { 4159 enforceNotIsolatedCaller("showBootMessage"); 4160 mWindowManager.showBootMessage(msg, always); 4161 } 4162 4163 public void dismissKeyguardOnNextActivity() { 4164 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4165 final long token = Binder.clearCallingIdentity(); 4166 try { 4167 synchronized (this) { 4168 if (mLockScreenShown) { 4169 mLockScreenShown = false; 4170 comeOutOfSleepIfNeededLocked(); 4171 } 4172 mMainStack.dismissKeyguardOnNextActivityLocked(); 4173 } 4174 } finally { 4175 Binder.restoreCallingIdentity(token); 4176 } 4177 } 4178 4179 final void finishBooting() { 4180 IntentFilter pkgFilter = new IntentFilter(); 4181 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4182 pkgFilter.addDataScheme("package"); 4183 mContext.registerReceiver(new BroadcastReceiver() { 4184 @Override 4185 public void onReceive(Context context, Intent intent) { 4186 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4187 if (pkgs != null) { 4188 for (String pkg : pkgs) { 4189 synchronized (ActivityManagerService.this) { 4190 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4191 setResultCode(Activity.RESULT_OK); 4192 return; 4193 } 4194 } 4195 } 4196 } 4197 } 4198 }, pkgFilter); 4199 4200 IntentFilter userFilter = new IntentFilter(); 4201 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4202 mContext.registerReceiver(new BroadcastReceiver() { 4203 @Override 4204 public void onReceive(Context context, Intent intent) { 4205 onUserRemoved(intent); 4206 } 4207 }, userFilter); 4208 4209 synchronized (this) { 4210 // Ensure that any processes we had put on hold are now started 4211 // up. 4212 final int NP = mProcessesOnHold.size(); 4213 if (NP > 0) { 4214 ArrayList<ProcessRecord> procs = 4215 new ArrayList<ProcessRecord>(mProcessesOnHold); 4216 for (int ip=0; ip<NP; ip++) { 4217 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4218 + procs.get(ip)); 4219 startProcessLocked(procs.get(ip), "on-hold", null); 4220 } 4221 } 4222 4223 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4224 // Start looking for apps that are abusing wake locks. 4225 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4226 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4227 // Tell anyone interested that we are done booting! 4228 SystemProperties.set("sys.boot_completed", "1"); 4229 SystemProperties.set("dev.bootcomplete", "1"); 4230 List<UserInfo> users = getUserManager().getUsers(); 4231 for (UserInfo user : users) { 4232 broadcastIntentLocked(null, null, 4233 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4234 null, null, 0, null, null, 4235 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4236 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4237 } 4238 } 4239 } 4240 } 4241 4242 final void ensureBootCompleted() { 4243 boolean booting; 4244 boolean enableScreen; 4245 synchronized (this) { 4246 booting = mBooting; 4247 mBooting = false; 4248 enableScreen = !mBooted; 4249 mBooted = true; 4250 } 4251 4252 if (booting) { 4253 finishBooting(); 4254 } 4255 4256 if (enableScreen) { 4257 enableScreenAfterBoot(); 4258 } 4259 } 4260 4261 public final void activityPaused(IBinder token) { 4262 final long origId = Binder.clearCallingIdentity(); 4263 mMainStack.activityPaused(token, false); 4264 Binder.restoreCallingIdentity(origId); 4265 } 4266 4267 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4268 CharSequence description) { 4269 if (localLOGV) Slog.v( 4270 TAG, "Activity stopped: token=" + token); 4271 4272 // Refuse possible leaked file descriptors 4273 if (icicle != null && icicle.hasFileDescriptors()) { 4274 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4275 } 4276 4277 ActivityRecord r = null; 4278 4279 final long origId = Binder.clearCallingIdentity(); 4280 4281 synchronized (this) { 4282 r = mMainStack.isInStackLocked(token); 4283 if (r != null) { 4284 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4285 } 4286 } 4287 4288 if (r != null) { 4289 sendPendingThumbnail(r, null, null, null, false); 4290 } 4291 4292 trimApplications(); 4293 4294 Binder.restoreCallingIdentity(origId); 4295 } 4296 4297 public final void activityDestroyed(IBinder token) { 4298 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4299 mMainStack.activityDestroyed(token); 4300 } 4301 4302 public String getCallingPackage(IBinder token) { 4303 synchronized (this) { 4304 ActivityRecord r = getCallingRecordLocked(token); 4305 return r != null && r.app != null ? r.info.packageName : null; 4306 } 4307 } 4308 4309 public ComponentName getCallingActivity(IBinder token) { 4310 synchronized (this) { 4311 ActivityRecord r = getCallingRecordLocked(token); 4312 return r != null ? r.intent.getComponent() : null; 4313 } 4314 } 4315 4316 private ActivityRecord getCallingRecordLocked(IBinder token) { 4317 ActivityRecord r = mMainStack.isInStackLocked(token); 4318 if (r == null) { 4319 return null; 4320 } 4321 return r.resultTo; 4322 } 4323 4324 public ComponentName getActivityClassForToken(IBinder token) { 4325 synchronized(this) { 4326 ActivityRecord r = mMainStack.isInStackLocked(token); 4327 if (r == null) { 4328 return null; 4329 } 4330 return r.intent.getComponent(); 4331 } 4332 } 4333 4334 public String getPackageForToken(IBinder token) { 4335 synchronized(this) { 4336 ActivityRecord r = mMainStack.isInStackLocked(token); 4337 if (r == null) { 4338 return null; 4339 } 4340 return r.packageName; 4341 } 4342 } 4343 4344 public IIntentSender getIntentSender(int type, 4345 String packageName, IBinder token, String resultWho, 4346 int requestCode, Intent[] intents, String[] resolvedTypes, 4347 int flags, Bundle options) { 4348 enforceNotIsolatedCaller("getIntentSender"); 4349 // Refuse possible leaked file descriptors 4350 if (intents != null) { 4351 if (intents.length < 1) { 4352 throw new IllegalArgumentException("Intents array length must be >= 1"); 4353 } 4354 for (int i=0; i<intents.length; i++) { 4355 Intent intent = intents[i]; 4356 if (intent != null) { 4357 if (intent.hasFileDescriptors()) { 4358 throw new IllegalArgumentException("File descriptors passed in Intent"); 4359 } 4360 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4361 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4362 throw new IllegalArgumentException( 4363 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4364 } 4365 intents[i] = new Intent(intent); 4366 } 4367 } 4368 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4369 throw new IllegalArgumentException( 4370 "Intent array length does not match resolvedTypes length"); 4371 } 4372 } 4373 if (options != null) { 4374 if (options.hasFileDescriptors()) { 4375 throw new IllegalArgumentException("File descriptors passed in options"); 4376 } 4377 } 4378 4379 synchronized(this) { 4380 int callingUid = Binder.getCallingUid(); 4381 try { 4382 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4383 int uid = AppGlobals.getPackageManager() 4384 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4385 if (!UserHandle.isSameApp(callingUid, uid)) { 4386 String msg = "Permission Denial: getIntentSender() from pid=" 4387 + Binder.getCallingPid() 4388 + ", uid=" + Binder.getCallingUid() 4389 + ", (need uid=" + uid + ")" 4390 + " is not allowed to send as package " + packageName; 4391 Slog.w(TAG, msg); 4392 throw new SecurityException(msg); 4393 } 4394 } 4395 4396 if (DEBUG_MU) 4397 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4398 + Binder.getOrigCallingUid()); 4399 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4400 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4401 4402 } catch (RemoteException e) { 4403 throw new SecurityException(e); 4404 } 4405 } 4406 } 4407 4408 IIntentSender getIntentSenderLocked(int type, 4409 String packageName, int callingUid, IBinder token, String resultWho, 4410 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4411 Bundle options) { 4412 if (DEBUG_MU) 4413 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4414 ActivityRecord activity = null; 4415 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4416 activity = mMainStack.isInStackLocked(token); 4417 if (activity == null) { 4418 return null; 4419 } 4420 if (activity.finishing) { 4421 return null; 4422 } 4423 } 4424 4425 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4426 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4427 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4428 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4429 |PendingIntent.FLAG_UPDATE_CURRENT); 4430 4431 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4432 type, packageName, activity, resultWho, 4433 requestCode, intents, resolvedTypes, flags, options); 4434 WeakReference<PendingIntentRecord> ref; 4435 ref = mIntentSenderRecords.get(key); 4436 PendingIntentRecord rec = ref != null ? ref.get() : null; 4437 if (rec != null) { 4438 if (!cancelCurrent) { 4439 if (updateCurrent) { 4440 if (rec.key.requestIntent != null) { 4441 rec.key.requestIntent.replaceExtras(intents != null ? 4442 intents[intents.length - 1] : null); 4443 } 4444 if (intents != null) { 4445 intents[intents.length-1] = rec.key.requestIntent; 4446 rec.key.allIntents = intents; 4447 rec.key.allResolvedTypes = resolvedTypes; 4448 } else { 4449 rec.key.allIntents = null; 4450 rec.key.allResolvedTypes = null; 4451 } 4452 } 4453 return rec; 4454 } 4455 rec.canceled = true; 4456 mIntentSenderRecords.remove(key); 4457 } 4458 if (noCreate) { 4459 return rec; 4460 } 4461 rec = new PendingIntentRecord(this, key, callingUid); 4462 mIntentSenderRecords.put(key, rec.ref); 4463 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4464 if (activity.pendingResults == null) { 4465 activity.pendingResults 4466 = new HashSet<WeakReference<PendingIntentRecord>>(); 4467 } 4468 activity.pendingResults.add(rec.ref); 4469 } 4470 return rec; 4471 } 4472 4473 public void cancelIntentSender(IIntentSender sender) { 4474 if (!(sender instanceof PendingIntentRecord)) { 4475 return; 4476 } 4477 synchronized(this) { 4478 PendingIntentRecord rec = (PendingIntentRecord)sender; 4479 try { 4480 int uid = AppGlobals.getPackageManager() 4481 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4482 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4483 String msg = "Permission Denial: cancelIntentSender() from pid=" 4484 + Binder.getCallingPid() 4485 + ", uid=" + Binder.getCallingUid() 4486 + " is not allowed to cancel packges " 4487 + rec.key.packageName; 4488 Slog.w(TAG, msg); 4489 throw new SecurityException(msg); 4490 } 4491 } catch (RemoteException e) { 4492 throw new SecurityException(e); 4493 } 4494 cancelIntentSenderLocked(rec, true); 4495 } 4496 } 4497 4498 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4499 rec.canceled = true; 4500 mIntentSenderRecords.remove(rec.key); 4501 if (cleanActivity && rec.key.activity != null) { 4502 rec.key.activity.pendingResults.remove(rec.ref); 4503 } 4504 } 4505 4506 public String getPackageForIntentSender(IIntentSender pendingResult) { 4507 if (!(pendingResult instanceof PendingIntentRecord)) { 4508 return null; 4509 } 4510 try { 4511 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4512 return res.key.packageName; 4513 } catch (ClassCastException e) { 4514 } 4515 return null; 4516 } 4517 4518 public int getUidForIntentSender(IIntentSender sender) { 4519 if (sender instanceof PendingIntentRecord) { 4520 try { 4521 PendingIntentRecord res = (PendingIntentRecord)sender; 4522 return res.uid; 4523 } catch (ClassCastException e) { 4524 } 4525 } 4526 return -1; 4527 } 4528 4529 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4530 if (!(pendingResult instanceof PendingIntentRecord)) { 4531 return false; 4532 } 4533 try { 4534 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4535 if (res.key.allIntents == null) { 4536 return false; 4537 } 4538 for (int i=0; i<res.key.allIntents.length; i++) { 4539 Intent intent = res.key.allIntents[i]; 4540 if (intent.getPackage() != null && intent.getComponent() != null) { 4541 return false; 4542 } 4543 } 4544 return true; 4545 } catch (ClassCastException e) { 4546 } 4547 return false; 4548 } 4549 4550 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4551 if (!(pendingResult instanceof PendingIntentRecord)) { 4552 return false; 4553 } 4554 try { 4555 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4556 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4557 return true; 4558 } 4559 return false; 4560 } catch (ClassCastException e) { 4561 } 4562 return false; 4563 } 4564 4565 public void setProcessLimit(int max) { 4566 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4567 "setProcessLimit()"); 4568 synchronized (this) { 4569 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4570 mProcessLimitOverride = max; 4571 } 4572 trimApplications(); 4573 } 4574 4575 public int getProcessLimit() { 4576 synchronized (this) { 4577 return mProcessLimitOverride; 4578 } 4579 } 4580 4581 void foregroundTokenDied(ForegroundToken token) { 4582 synchronized (ActivityManagerService.this) { 4583 synchronized (mPidsSelfLocked) { 4584 ForegroundToken cur 4585 = mForegroundProcesses.get(token.pid); 4586 if (cur != token) { 4587 return; 4588 } 4589 mForegroundProcesses.remove(token.pid); 4590 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4591 if (pr == null) { 4592 return; 4593 } 4594 pr.forcingToForeground = null; 4595 pr.foregroundServices = false; 4596 } 4597 updateOomAdjLocked(); 4598 } 4599 } 4600 4601 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4602 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4603 "setProcessForeground()"); 4604 synchronized(this) { 4605 boolean changed = false; 4606 4607 synchronized (mPidsSelfLocked) { 4608 ProcessRecord pr = mPidsSelfLocked.get(pid); 4609 if (pr == null && isForeground) { 4610 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4611 return; 4612 } 4613 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4614 if (oldToken != null) { 4615 oldToken.token.unlinkToDeath(oldToken, 0); 4616 mForegroundProcesses.remove(pid); 4617 if (pr != null) { 4618 pr.forcingToForeground = null; 4619 } 4620 changed = true; 4621 } 4622 if (isForeground && token != null) { 4623 ForegroundToken newToken = new ForegroundToken() { 4624 public void binderDied() { 4625 foregroundTokenDied(this); 4626 } 4627 }; 4628 newToken.pid = pid; 4629 newToken.token = token; 4630 try { 4631 token.linkToDeath(newToken, 0); 4632 mForegroundProcesses.put(pid, newToken); 4633 pr.forcingToForeground = token; 4634 changed = true; 4635 } catch (RemoteException e) { 4636 // If the process died while doing this, we will later 4637 // do the cleanup with the process death link. 4638 } 4639 } 4640 } 4641 4642 if (changed) { 4643 updateOomAdjLocked(); 4644 } 4645 } 4646 } 4647 4648 // ========================================================= 4649 // PERMISSIONS 4650 // ========================================================= 4651 4652 static class PermissionController extends IPermissionController.Stub { 4653 ActivityManagerService mActivityManagerService; 4654 PermissionController(ActivityManagerService activityManagerService) { 4655 mActivityManagerService = activityManagerService; 4656 } 4657 4658 public boolean checkPermission(String permission, int pid, int uid) { 4659 return mActivityManagerService.checkPermission(permission, pid, 4660 uid) == PackageManager.PERMISSION_GRANTED; 4661 } 4662 } 4663 4664 /** 4665 * This can be called with or without the global lock held. 4666 */ 4667 int checkComponentPermission(String permission, int pid, int uid, 4668 int owningUid, boolean exported) { 4669 // We might be performing an operation on behalf of an indirect binder 4670 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4671 // client identity accordingly before proceeding. 4672 Identity tlsIdentity = sCallerIdentity.get(); 4673 if (tlsIdentity != null) { 4674 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4675 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4676 uid = tlsIdentity.uid; 4677 pid = tlsIdentity.pid; 4678 } 4679 4680 if (pid == MY_PID) { 4681 return PackageManager.PERMISSION_GRANTED; 4682 } 4683 4684 return ActivityManager.checkComponentPermission(permission, uid, 4685 owningUid, exported); 4686 } 4687 4688 /** 4689 * As the only public entry point for permissions checking, this method 4690 * can enforce the semantic that requesting a check on a null global 4691 * permission is automatically denied. (Internally a null permission 4692 * string is used when calling {@link #checkComponentPermission} in cases 4693 * when only uid-based security is needed.) 4694 * 4695 * This can be called with or without the global lock held. 4696 */ 4697 public int checkPermission(String permission, int pid, int uid) { 4698 if (permission == null) { 4699 return PackageManager.PERMISSION_DENIED; 4700 } 4701 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4702 } 4703 4704 /** 4705 * Binder IPC calls go through the public entry point. 4706 * This can be called with or without the global lock held. 4707 */ 4708 int checkCallingPermission(String permission) { 4709 return checkPermission(permission, 4710 Binder.getCallingPid(), 4711 UserHandle.getAppId(Binder.getCallingUid())); 4712 } 4713 4714 /** 4715 * This can be called with or without the global lock held. 4716 */ 4717 void enforceCallingPermission(String permission, String func) { 4718 if (checkCallingPermission(permission) 4719 == PackageManager.PERMISSION_GRANTED) { 4720 return; 4721 } 4722 4723 String msg = "Permission Denial: " + func + " from pid=" 4724 + Binder.getCallingPid() 4725 + ", uid=" + Binder.getCallingUid() 4726 + " requires " + permission; 4727 Slog.w(TAG, msg); 4728 throw new SecurityException(msg); 4729 } 4730 4731 /** 4732 * Determine if UID is holding permissions required to access {@link Uri} in 4733 * the given {@link ProviderInfo}. Final permission checking is always done 4734 * in {@link ContentProvider}. 4735 */ 4736 private final boolean checkHoldingPermissionsLocked( 4737 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4738 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4739 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4740 4741 if (pi.applicationInfo.uid == uid) { 4742 return true; 4743 } else if (!pi.exported) { 4744 return false; 4745 } 4746 4747 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4748 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4749 try { 4750 // check if target holds top-level <provider> permissions 4751 if (!readMet && pi.readPermission != null 4752 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4753 readMet = true; 4754 } 4755 if (!writeMet && pi.writePermission != null 4756 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4757 writeMet = true; 4758 } 4759 4760 // track if unprotected read/write is allowed; any denied 4761 // <path-permission> below removes this ability 4762 boolean allowDefaultRead = pi.readPermission == null; 4763 boolean allowDefaultWrite = pi.writePermission == null; 4764 4765 // check if target holds any <path-permission> that match uri 4766 final PathPermission[] pps = pi.pathPermissions; 4767 if (pps != null) { 4768 final String path = uri.getPath(); 4769 int i = pps.length; 4770 while (i > 0 && (!readMet || !writeMet)) { 4771 i--; 4772 PathPermission pp = pps[i]; 4773 if (pp.match(path)) { 4774 if (!readMet) { 4775 final String pprperm = pp.getReadPermission(); 4776 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4777 + pprperm + " for " + pp.getPath() 4778 + ": match=" + pp.match(path) 4779 + " check=" + pm.checkUidPermission(pprperm, uid)); 4780 if (pprperm != null) { 4781 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4782 readMet = true; 4783 } else { 4784 allowDefaultRead = false; 4785 } 4786 } 4787 } 4788 if (!writeMet) { 4789 final String ppwperm = pp.getWritePermission(); 4790 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4791 + ppwperm + " for " + pp.getPath() 4792 + ": match=" + pp.match(path) 4793 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4794 if (ppwperm != null) { 4795 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4796 writeMet = true; 4797 } else { 4798 allowDefaultWrite = false; 4799 } 4800 } 4801 } 4802 } 4803 } 4804 } 4805 4806 // grant unprotected <provider> read/write, if not blocked by 4807 // <path-permission> above 4808 if (allowDefaultRead) readMet = true; 4809 if (allowDefaultWrite) writeMet = true; 4810 4811 } catch (RemoteException e) { 4812 return false; 4813 } 4814 4815 return readMet && writeMet; 4816 } 4817 4818 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4819 int modeFlags) { 4820 // Root gets to do everything. 4821 if (uid == 0) { 4822 return true; 4823 } 4824 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4825 if (perms == null) return false; 4826 UriPermission perm = perms.get(uri); 4827 if (perm == null) return false; 4828 return (modeFlags&perm.modeFlags) == modeFlags; 4829 } 4830 4831 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4832 enforceNotIsolatedCaller("checkUriPermission"); 4833 4834 // Another redirected-binder-call permissions check as in 4835 // {@link checkComponentPermission}. 4836 Identity tlsIdentity = sCallerIdentity.get(); 4837 if (tlsIdentity != null) { 4838 uid = tlsIdentity.uid; 4839 pid = tlsIdentity.pid; 4840 } 4841 4842 uid = UserHandle.getAppId(uid); 4843 // Our own process gets to do everything. 4844 if (pid == MY_PID) { 4845 return PackageManager.PERMISSION_GRANTED; 4846 } 4847 synchronized(this) { 4848 return checkUriPermissionLocked(uri, uid, modeFlags) 4849 ? PackageManager.PERMISSION_GRANTED 4850 : PackageManager.PERMISSION_DENIED; 4851 } 4852 } 4853 4854 /** 4855 * Check if the targetPkg can be granted permission to access uri by 4856 * the callingUid using the given modeFlags. Throws a security exception 4857 * if callingUid is not allowed to do this. Returns the uid of the target 4858 * if the URI permission grant should be performed; returns -1 if it is not 4859 * needed (for example targetPkg already has permission to access the URI). 4860 * If you already know the uid of the target, you can supply it in 4861 * lastTargetUid else set that to -1. 4862 */ 4863 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4864 Uri uri, int modeFlags, int lastTargetUid) { 4865 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4866 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4867 if (modeFlags == 0) { 4868 return -1; 4869 } 4870 4871 if (targetPkg != null) { 4872 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4873 "Checking grant " + targetPkg + " permission to " + uri); 4874 } 4875 4876 final IPackageManager pm = AppGlobals.getPackageManager(); 4877 4878 // If this is not a content: uri, we can't do anything with it. 4879 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4880 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4881 "Can't grant URI permission for non-content URI: " + uri); 4882 return -1; 4883 } 4884 4885 String name = uri.getAuthority(); 4886 ProviderInfo pi = null; 4887 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4888 UserHandle.getUserId(callingUid)); 4889 if (cpr != null) { 4890 pi = cpr.info; 4891 } else { 4892 try { 4893 pi = pm.resolveContentProvider(name, 4894 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4895 } catch (RemoteException ex) { 4896 } 4897 } 4898 if (pi == null) { 4899 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4900 return -1; 4901 } 4902 4903 int targetUid = lastTargetUid; 4904 if (targetUid < 0 && targetPkg != null) { 4905 try { 4906 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4907 if (targetUid < 0) { 4908 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4909 "Can't grant URI permission no uid for: " + targetPkg); 4910 return -1; 4911 } 4912 } catch (RemoteException ex) { 4913 return -1; 4914 } 4915 } 4916 4917 if (targetUid >= 0) { 4918 // First... does the target actually need this permission? 4919 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4920 // No need to grant the target this permission. 4921 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4922 "Target " + targetPkg + " already has full permission to " + uri); 4923 return -1; 4924 } 4925 } else { 4926 // First... there is no target package, so can anyone access it? 4927 boolean allowed = pi.exported; 4928 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4929 if (pi.readPermission != null) { 4930 allowed = false; 4931 } 4932 } 4933 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4934 if (pi.writePermission != null) { 4935 allowed = false; 4936 } 4937 } 4938 if (allowed) { 4939 return -1; 4940 } 4941 } 4942 4943 // Second... is the provider allowing granting of URI permissions? 4944 if (!pi.grantUriPermissions) { 4945 throw new SecurityException("Provider " + pi.packageName 4946 + "/" + pi.name 4947 + " does not allow granting of Uri permissions (uri " 4948 + uri + ")"); 4949 } 4950 if (pi.uriPermissionPatterns != null) { 4951 final int N = pi.uriPermissionPatterns.length; 4952 boolean allowed = false; 4953 for (int i=0; i<N; i++) { 4954 if (pi.uriPermissionPatterns[i] != null 4955 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4956 allowed = true; 4957 break; 4958 } 4959 } 4960 if (!allowed) { 4961 throw new SecurityException("Provider " + pi.packageName 4962 + "/" + pi.name 4963 + " does not allow granting of permission to path of Uri " 4964 + uri); 4965 } 4966 } 4967 4968 // Third... does the caller itself have permission to access 4969 // this uri? 4970 if (callingUid != Process.myUid()) { 4971 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4972 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4973 throw new SecurityException("Uid " + callingUid 4974 + " does not have permission to uri " + uri); 4975 } 4976 } 4977 } 4978 4979 return targetUid; 4980 } 4981 4982 public int checkGrantUriPermission(int callingUid, String targetPkg, 4983 Uri uri, int modeFlags) { 4984 enforceNotIsolatedCaller("checkGrantUriPermission"); 4985 synchronized(this) { 4986 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4987 } 4988 } 4989 4990 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4991 Uri uri, int modeFlags, UriPermissionOwner owner) { 4992 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4993 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4994 if (modeFlags == 0) { 4995 return; 4996 } 4997 4998 // So here we are: the caller has the assumed permission 4999 // to the uri, and the target doesn't. Let's now give this to 5000 // the target. 5001 5002 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5003 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5004 5005 HashMap<Uri, UriPermission> targetUris 5006 = mGrantedUriPermissions.get(targetUid); 5007 if (targetUris == null) { 5008 targetUris = new HashMap<Uri, UriPermission>(); 5009 mGrantedUriPermissions.put(targetUid, targetUris); 5010 } 5011 5012 UriPermission perm = targetUris.get(uri); 5013 if (perm == null) { 5014 perm = new UriPermission(targetUid, uri); 5015 targetUris.put(uri, perm); 5016 } 5017 5018 perm.modeFlags |= modeFlags; 5019 if (owner == null) { 5020 perm.globalModeFlags |= modeFlags; 5021 } else { 5022 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5023 perm.readOwners.add(owner); 5024 owner.addReadPermission(perm); 5025 } 5026 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5027 perm.writeOwners.add(owner); 5028 owner.addWritePermission(perm); 5029 } 5030 } 5031 } 5032 5033 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5034 int modeFlags, UriPermissionOwner owner) { 5035 if (targetPkg == null) { 5036 throw new NullPointerException("targetPkg"); 5037 } 5038 5039 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5040 if (targetUid < 0) { 5041 return; 5042 } 5043 5044 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5045 } 5046 5047 static class NeededUriGrants extends ArrayList<Uri> { 5048 final String targetPkg; 5049 final int targetUid; 5050 final int flags; 5051 5052 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5053 targetPkg = _targetPkg; 5054 targetUid = _targetUid; 5055 flags = _flags; 5056 } 5057 } 5058 5059 /** 5060 * Like checkGrantUriPermissionLocked, but takes an Intent. 5061 */ 5062 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5063 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5065 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5066 + " clip=" + (intent != null ? intent.getClipData() : null) 5067 + " from " + intent + "; flags=0x" 5068 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5069 5070 if (targetPkg == null) { 5071 throw new NullPointerException("targetPkg"); 5072 } 5073 5074 if (intent == null) { 5075 return null; 5076 } 5077 Uri data = intent.getData(); 5078 ClipData clip = intent.getClipData(); 5079 if (data == null && clip == null) { 5080 return null; 5081 } 5082 if (data != null) { 5083 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5084 mode, needed != null ? needed.targetUid : -1); 5085 if (target > 0) { 5086 if (needed == null) { 5087 needed = new NeededUriGrants(targetPkg, target, mode); 5088 } 5089 needed.add(data); 5090 } 5091 } 5092 if (clip != null) { 5093 for (int i=0; i<clip.getItemCount(); i++) { 5094 Uri uri = clip.getItemAt(i).getUri(); 5095 if (uri != null) { 5096 int target = -1; 5097 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5098 mode, needed != null ? needed.targetUid : -1); 5099 if (target > 0) { 5100 if (needed == null) { 5101 needed = new NeededUriGrants(targetPkg, target, mode); 5102 } 5103 needed.add(uri); 5104 } 5105 } else { 5106 Intent clipIntent = clip.getItemAt(i).getIntent(); 5107 if (clipIntent != null) { 5108 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5109 callingUid, targetPkg, clipIntent, mode, needed); 5110 if (newNeeded != null) { 5111 needed = newNeeded; 5112 } 5113 } 5114 } 5115 } 5116 } 5117 5118 return needed; 5119 } 5120 5121 /** 5122 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5123 */ 5124 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5125 UriPermissionOwner owner) { 5126 if (needed != null) { 5127 for (int i=0; i<needed.size(); i++) { 5128 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5129 needed.get(i), needed.flags, owner); 5130 } 5131 } 5132 } 5133 5134 void grantUriPermissionFromIntentLocked(int callingUid, 5135 String targetPkg, Intent intent, UriPermissionOwner owner) { 5136 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5137 intent, intent != null ? intent.getFlags() : 0, null); 5138 if (needed == null) { 5139 return; 5140 } 5141 5142 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5143 } 5144 5145 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5146 Uri uri, int modeFlags) { 5147 enforceNotIsolatedCaller("grantUriPermission"); 5148 synchronized(this) { 5149 final ProcessRecord r = getRecordForAppLocked(caller); 5150 if (r == null) { 5151 throw new SecurityException("Unable to find app for caller " 5152 + caller 5153 + " when granting permission to uri " + uri); 5154 } 5155 if (targetPkg == null) { 5156 throw new IllegalArgumentException("null target"); 5157 } 5158 if (uri == null) { 5159 throw new IllegalArgumentException("null uri"); 5160 } 5161 5162 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5163 null); 5164 } 5165 } 5166 5167 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5168 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5169 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5170 HashMap<Uri, UriPermission> perms 5171 = mGrantedUriPermissions.get(perm.uid); 5172 if (perms != null) { 5173 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5174 "Removing " + perm.uid + " permission to " + perm.uri); 5175 perms.remove(perm.uri); 5176 if (perms.size() == 0) { 5177 mGrantedUriPermissions.remove(perm.uid); 5178 } 5179 } 5180 } 5181 } 5182 5183 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5184 int modeFlags) { 5185 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5186 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5187 if (modeFlags == 0) { 5188 return; 5189 } 5190 5191 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5192 "Revoking all granted permissions to " + uri); 5193 5194 final IPackageManager pm = AppGlobals.getPackageManager(); 5195 5196 final String authority = uri.getAuthority(); 5197 ProviderInfo pi = null; 5198 int userId = UserHandle.getUserId(callingUid); 5199 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5200 if (cpr != null) { 5201 pi = cpr.info; 5202 } else { 5203 try { 5204 pi = pm.resolveContentProvider(authority, 5205 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5206 } catch (RemoteException ex) { 5207 } 5208 } 5209 if (pi == null) { 5210 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5211 return; 5212 } 5213 5214 // Does the caller have this permission on the URI? 5215 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5216 // Right now, if you are not the original owner of the permission, 5217 // you are not allowed to revoke it. 5218 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5219 throw new SecurityException("Uid " + callingUid 5220 + " does not have permission to uri " + uri); 5221 //} 5222 } 5223 5224 // Go through all of the permissions and remove any that match. 5225 final List<String> SEGMENTS = uri.getPathSegments(); 5226 if (SEGMENTS != null) { 5227 final int NS = SEGMENTS.size(); 5228 int N = mGrantedUriPermissions.size(); 5229 for (int i=0; i<N; i++) { 5230 HashMap<Uri, UriPermission> perms 5231 = mGrantedUriPermissions.valueAt(i); 5232 Iterator<UriPermission> it = perms.values().iterator(); 5233 toploop: 5234 while (it.hasNext()) { 5235 UriPermission perm = it.next(); 5236 Uri targetUri = perm.uri; 5237 if (!authority.equals(targetUri.getAuthority())) { 5238 continue; 5239 } 5240 List<String> targetSegments = targetUri.getPathSegments(); 5241 if (targetSegments == null) { 5242 continue; 5243 } 5244 if (targetSegments.size() < NS) { 5245 continue; 5246 } 5247 for (int j=0; j<NS; j++) { 5248 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5249 continue toploop; 5250 } 5251 } 5252 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5253 "Revoking " + perm.uid + " permission to " + perm.uri); 5254 perm.clearModes(modeFlags); 5255 if (perm.modeFlags == 0) { 5256 it.remove(); 5257 } 5258 } 5259 if (perms.size() == 0) { 5260 mGrantedUriPermissions.remove( 5261 mGrantedUriPermissions.keyAt(i)); 5262 N--; 5263 i--; 5264 } 5265 } 5266 } 5267 } 5268 5269 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5270 int modeFlags) { 5271 enforceNotIsolatedCaller("revokeUriPermission"); 5272 synchronized(this) { 5273 final ProcessRecord r = getRecordForAppLocked(caller); 5274 if (r == null) { 5275 throw new SecurityException("Unable to find app for caller " 5276 + caller 5277 + " when revoking permission to uri " + uri); 5278 } 5279 if (uri == null) { 5280 Slog.w(TAG, "revokeUriPermission: null uri"); 5281 return; 5282 } 5283 5284 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5285 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5286 if (modeFlags == 0) { 5287 return; 5288 } 5289 5290 final IPackageManager pm = AppGlobals.getPackageManager(); 5291 5292 final String authority = uri.getAuthority(); 5293 ProviderInfo pi = null; 5294 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5295 if (cpr != null) { 5296 pi = cpr.info; 5297 } else { 5298 try { 5299 pi = pm.resolveContentProvider(authority, 5300 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5301 } catch (RemoteException ex) { 5302 } 5303 } 5304 if (pi == null) { 5305 Slog.w(TAG, "No content provider found for permission revoke: " 5306 + uri.toSafeString()); 5307 return; 5308 } 5309 5310 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5311 } 5312 } 5313 5314 @Override 5315 public IBinder newUriPermissionOwner(String name) { 5316 enforceNotIsolatedCaller("newUriPermissionOwner"); 5317 synchronized(this) { 5318 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5319 return owner.getExternalTokenLocked(); 5320 } 5321 } 5322 5323 @Override 5324 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5325 Uri uri, int modeFlags) { 5326 synchronized(this) { 5327 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5328 if (owner == null) { 5329 throw new IllegalArgumentException("Unknown owner: " + token); 5330 } 5331 if (fromUid != Binder.getCallingUid()) { 5332 if (Binder.getCallingUid() != Process.myUid()) { 5333 // Only system code can grant URI permissions on behalf 5334 // of other users. 5335 throw new SecurityException("nice try"); 5336 } 5337 } 5338 if (targetPkg == null) { 5339 throw new IllegalArgumentException("null target"); 5340 } 5341 if (uri == null) { 5342 throw new IllegalArgumentException("null uri"); 5343 } 5344 5345 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5346 } 5347 } 5348 5349 @Override 5350 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5351 synchronized(this) { 5352 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5353 if (owner == null) { 5354 throw new IllegalArgumentException("Unknown owner: " + token); 5355 } 5356 5357 if (uri == null) { 5358 owner.removeUriPermissionsLocked(mode); 5359 } else { 5360 owner.removeUriPermissionLocked(uri, mode); 5361 } 5362 } 5363 } 5364 5365 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5366 synchronized (this) { 5367 ProcessRecord app = 5368 who != null ? getRecordForAppLocked(who) : null; 5369 if (app == null) return; 5370 5371 Message msg = Message.obtain(); 5372 msg.what = WAIT_FOR_DEBUGGER_MSG; 5373 msg.obj = app; 5374 msg.arg1 = waiting ? 1 : 0; 5375 mHandler.sendMessage(msg); 5376 } 5377 } 5378 5379 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5380 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5381 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5382 outInfo.availMem = Process.getFreeMemory(); 5383 outInfo.totalMem = Process.getTotalMemory(); 5384 outInfo.threshold = homeAppMem; 5385 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5386 outInfo.hiddenAppThreshold = hiddenAppMem; 5387 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5388 ProcessList.SERVICE_ADJ); 5389 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5390 ProcessList.VISIBLE_APP_ADJ); 5391 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5392 ProcessList.FOREGROUND_APP_ADJ); 5393 } 5394 5395 // ========================================================= 5396 // TASK MANAGEMENT 5397 // ========================================================= 5398 5399 public List getTasks(int maxNum, int flags, 5400 IThumbnailReceiver receiver) { 5401 ArrayList list = new ArrayList(); 5402 5403 PendingThumbnailsRecord pending = null; 5404 IApplicationThread topThumbnail = null; 5405 ActivityRecord topRecord = null; 5406 5407 synchronized(this) { 5408 if (localLOGV) Slog.v( 5409 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5410 + ", receiver=" + receiver); 5411 5412 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5413 != PackageManager.PERMISSION_GRANTED) { 5414 if (receiver != null) { 5415 // If the caller wants to wait for pending thumbnails, 5416 // it ain't gonna get them. 5417 try { 5418 receiver.finished(); 5419 } catch (RemoteException ex) { 5420 } 5421 } 5422 String msg = "Permission Denial: getTasks() from pid=" 5423 + Binder.getCallingPid() 5424 + ", uid=" + Binder.getCallingUid() 5425 + " requires " + android.Manifest.permission.GET_TASKS; 5426 Slog.w(TAG, msg); 5427 throw new SecurityException(msg); 5428 } 5429 5430 int pos = mMainStack.mHistory.size()-1; 5431 ActivityRecord next = 5432 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5433 ActivityRecord top = null; 5434 TaskRecord curTask = null; 5435 int numActivities = 0; 5436 int numRunning = 0; 5437 while (pos >= 0 && maxNum > 0) { 5438 final ActivityRecord r = next; 5439 pos--; 5440 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5441 5442 // Initialize state for next task if needed. 5443 if (top == null || 5444 (top.state == ActivityState.INITIALIZING 5445 && top.task == r.task)) { 5446 top = r; 5447 curTask = r.task; 5448 numActivities = numRunning = 0; 5449 } 5450 5451 // Add 'r' into the current task. 5452 numActivities++; 5453 if (r.app != null && r.app.thread != null) { 5454 numRunning++; 5455 } 5456 5457 if (localLOGV) Slog.v( 5458 TAG, r.intent.getComponent().flattenToShortString() 5459 + ": task=" + r.task); 5460 5461 // If the next one is a different task, generate a new 5462 // TaskInfo entry for what we have. 5463 if (next == null || next.task != curTask) { 5464 ActivityManager.RunningTaskInfo ci 5465 = new ActivityManager.RunningTaskInfo(); 5466 ci.id = curTask.taskId; 5467 ci.baseActivity = r.intent.getComponent(); 5468 ci.topActivity = top.intent.getComponent(); 5469 if (top.thumbHolder != null) { 5470 ci.description = top.thumbHolder.lastDescription; 5471 } 5472 ci.numActivities = numActivities; 5473 ci.numRunning = numRunning; 5474 //System.out.println( 5475 // "#" + maxNum + ": " + " descr=" + ci.description); 5476 if (ci.thumbnail == null && receiver != null) { 5477 if (localLOGV) Slog.v( 5478 TAG, "State=" + top.state + "Idle=" + top.idle 5479 + " app=" + top.app 5480 + " thr=" + (top.app != null ? top.app.thread : null)); 5481 if (top.state == ActivityState.RESUMED 5482 || top.state == ActivityState.PAUSING) { 5483 if (top.idle && top.app != null 5484 && top.app.thread != null) { 5485 topRecord = top; 5486 topThumbnail = top.app.thread; 5487 } else { 5488 top.thumbnailNeeded = true; 5489 } 5490 } 5491 if (pending == null) { 5492 pending = new PendingThumbnailsRecord(receiver); 5493 } 5494 pending.pendingRecords.add(top); 5495 } 5496 list.add(ci); 5497 maxNum--; 5498 top = null; 5499 } 5500 } 5501 5502 if (pending != null) { 5503 mPendingThumbnails.add(pending); 5504 } 5505 } 5506 5507 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5508 5509 if (topThumbnail != null) { 5510 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5511 try { 5512 topThumbnail.requestThumbnail(topRecord.appToken); 5513 } catch (Exception e) { 5514 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5515 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5516 } 5517 } 5518 5519 if (pending == null && receiver != null) { 5520 // In this case all thumbnails were available and the client 5521 // is being asked to be told when the remaining ones come in... 5522 // which is unusually, since the top-most currently running 5523 // activity should never have a canned thumbnail! Oh well. 5524 try { 5525 receiver.finished(); 5526 } catch (RemoteException ex) { 5527 } 5528 } 5529 5530 return list; 5531 } 5532 5533 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5534 int flags, int userId) { 5535 final int callingUid = Binder.getCallingUid(); 5536 if (userId != UserHandle.getCallingUserId()) { 5537 // Check if the caller is holding permissions for cross-user requests. 5538 if (checkComponentPermission( 5539 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5540 Binder.getCallingPid(), callingUid, -1, true) 5541 != PackageManager.PERMISSION_GRANTED) { 5542 String msg = "Permission Denial: " 5543 + "Request to get recent tasks for user " + userId 5544 + " but is calling from user " + UserHandle.getUserId(callingUid) 5545 + "; this requires " 5546 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5547 Slog.w(TAG, msg); 5548 throw new SecurityException(msg); 5549 } else { 5550 if (userId == UserHandle.USER_CURRENT) { 5551 userId = mCurrentUserId; 5552 } 5553 } 5554 } 5555 5556 synchronized (this) { 5557 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5558 "getRecentTasks()"); 5559 final boolean detailed = checkCallingPermission( 5560 android.Manifest.permission.GET_DETAILED_TASKS) 5561 == PackageManager.PERMISSION_GRANTED; 5562 5563 IPackageManager pm = AppGlobals.getPackageManager(); 5564 5565 final int N = mRecentTasks.size(); 5566 ArrayList<ActivityManager.RecentTaskInfo> res 5567 = new ArrayList<ActivityManager.RecentTaskInfo>( 5568 maxNum < N ? maxNum : N); 5569 for (int i=0; i<N && maxNum > 0; i++) { 5570 TaskRecord tr = mRecentTasks.get(i); 5571 // Only add calling user's recent tasks 5572 if (tr.userId != userId) continue; 5573 // Return the entry if desired by the caller. We always return 5574 // the first entry, because callers always expect this to be the 5575 // foreground app. We may filter others if the caller has 5576 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5577 // we should exclude the entry. 5578 5579 if (i == 0 5580 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5581 || (tr.intent == null) 5582 || ((tr.intent.getFlags() 5583 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5584 ActivityManager.RecentTaskInfo rti 5585 = new ActivityManager.RecentTaskInfo(); 5586 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5587 rti.persistentId = tr.taskId; 5588 rti.baseIntent = new Intent( 5589 tr.intent != null ? tr.intent : tr.affinityIntent); 5590 if (!detailed) { 5591 rti.baseIntent.replaceExtras((Bundle)null); 5592 } 5593 rti.origActivity = tr.origActivity; 5594 rti.description = tr.lastDescription; 5595 5596 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5597 // Check whether this activity is currently available. 5598 try { 5599 if (rti.origActivity != null) { 5600 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5601 == null) { 5602 continue; 5603 } 5604 } else if (rti.baseIntent != null) { 5605 if (pm.queryIntentActivities(rti.baseIntent, 5606 null, 0, userId) == null) { 5607 continue; 5608 } 5609 } 5610 } catch (RemoteException e) { 5611 // Will never happen. 5612 } 5613 } 5614 5615 res.add(rti); 5616 maxNum--; 5617 } 5618 } 5619 return res; 5620 } 5621 } 5622 5623 private TaskRecord taskForIdLocked(int id) { 5624 final int N = mRecentTasks.size(); 5625 for (int i=0; i<N; i++) { 5626 TaskRecord tr = mRecentTasks.get(i); 5627 if (tr.taskId == id) { 5628 return tr; 5629 } 5630 } 5631 return null; 5632 } 5633 5634 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5635 synchronized (this) { 5636 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5637 "getTaskThumbnails()"); 5638 TaskRecord tr = taskForIdLocked(id); 5639 if (tr != null) { 5640 return mMainStack.getTaskThumbnailsLocked(tr); 5641 } 5642 } 5643 return null; 5644 } 5645 5646 public boolean removeSubTask(int taskId, int subTaskIndex) { 5647 synchronized (this) { 5648 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5649 "removeSubTask()"); 5650 long ident = Binder.clearCallingIdentity(); 5651 try { 5652 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5653 true) != null; 5654 } finally { 5655 Binder.restoreCallingIdentity(ident); 5656 } 5657 } 5658 } 5659 5660 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5661 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5662 Intent baseIntent = new Intent( 5663 tr.intent != null ? tr.intent : tr.affinityIntent); 5664 ComponentName component = baseIntent.getComponent(); 5665 if (component == null) { 5666 Slog.w(TAG, "Now component for base intent of task: " + tr); 5667 return; 5668 } 5669 5670 // Find any running services associated with this app. 5671 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5672 5673 if (killProcesses) { 5674 // Find any running processes associated with this app. 5675 final String pkg = component.getPackageName(); 5676 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5677 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5678 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5679 for (int i=0; i<uids.size(); i++) { 5680 ProcessRecord proc = uids.valueAt(i); 5681 if (proc.userId != tr.userId) { 5682 continue; 5683 } 5684 if (!proc.pkgList.contains(pkg)) { 5685 continue; 5686 } 5687 procs.add(proc); 5688 } 5689 } 5690 5691 // Kill the running processes. 5692 for (int i=0; i<procs.size(); i++) { 5693 ProcessRecord pr = procs.get(i); 5694 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5695 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5696 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5697 pr.processName, pr.setAdj, "remove task"); 5698 pr.killedBackground = true; 5699 Process.killProcessQuiet(pr.pid); 5700 } else { 5701 pr.waitingToKill = "remove task"; 5702 } 5703 } 5704 } 5705 } 5706 5707 public boolean removeTask(int taskId, int flags) { 5708 synchronized (this) { 5709 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5710 "removeTask()"); 5711 long ident = Binder.clearCallingIdentity(); 5712 try { 5713 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5714 false); 5715 if (r != null) { 5716 mRecentTasks.remove(r.task); 5717 cleanUpRemovedTaskLocked(r.task, flags); 5718 return true; 5719 } else { 5720 TaskRecord tr = null; 5721 int i=0; 5722 while (i < mRecentTasks.size()) { 5723 TaskRecord t = mRecentTasks.get(i); 5724 if (t.taskId == taskId) { 5725 tr = t; 5726 break; 5727 } 5728 i++; 5729 } 5730 if (tr != null) { 5731 if (tr.numActivities <= 0) { 5732 // Caller is just removing a recent task that is 5733 // not actively running. That is easy! 5734 mRecentTasks.remove(i); 5735 cleanUpRemovedTaskLocked(tr, flags); 5736 return true; 5737 } else { 5738 Slog.w(TAG, "removeTask: task " + taskId 5739 + " does not have activities to remove, " 5740 + " but numActivities=" + tr.numActivities 5741 + ": " + tr); 5742 } 5743 } 5744 } 5745 } finally { 5746 Binder.restoreCallingIdentity(ident); 5747 } 5748 } 5749 return false; 5750 } 5751 5752 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5753 int j; 5754 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5755 TaskRecord jt = startTask; 5756 5757 // First look backwards 5758 for (j=startIndex-1; j>=0; j--) { 5759 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5760 if (r.task != jt) { 5761 jt = r.task; 5762 if (affinity.equals(jt.affinity)) { 5763 return j; 5764 } 5765 } 5766 } 5767 5768 // Now look forwards 5769 final int N = mMainStack.mHistory.size(); 5770 jt = startTask; 5771 for (j=startIndex+1; j<N; j++) { 5772 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5773 if (r.task != jt) { 5774 if (affinity.equals(jt.affinity)) { 5775 return j; 5776 } 5777 jt = r.task; 5778 } 5779 } 5780 5781 // Might it be at the top? 5782 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5783 return N-1; 5784 } 5785 5786 return -1; 5787 } 5788 5789 /** 5790 * TODO: Add mController hook 5791 */ 5792 public void moveTaskToFront(int task, int flags, Bundle options) { 5793 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5794 "moveTaskToFront()"); 5795 5796 synchronized(this) { 5797 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5798 Binder.getCallingUid(), "Task to front")) { 5799 ActivityOptions.abort(options); 5800 return; 5801 } 5802 final long origId = Binder.clearCallingIdentity(); 5803 try { 5804 TaskRecord tr = taskForIdLocked(task); 5805 if (tr != null) { 5806 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5807 mMainStack.mUserLeaving = true; 5808 } 5809 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5810 // Caller wants the home activity moved with it. To accomplish this, 5811 // we'll just move the home task to the top first. 5812 mMainStack.moveHomeToFrontLocked(); 5813 } 5814 mMainStack.moveTaskToFrontLocked(tr, null, options); 5815 return; 5816 } 5817 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5818 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5819 if (hr.task.taskId == task) { 5820 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5821 mMainStack.mUserLeaving = true; 5822 } 5823 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5824 // Caller wants the home activity moved with it. To accomplish this, 5825 // we'll just move the home task to the top first. 5826 mMainStack.moveHomeToFrontLocked(); 5827 } 5828 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5829 return; 5830 } 5831 } 5832 } finally { 5833 Binder.restoreCallingIdentity(origId); 5834 } 5835 ActivityOptions.abort(options); 5836 } 5837 } 5838 5839 public void moveTaskToBack(int task) { 5840 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5841 "moveTaskToBack()"); 5842 5843 synchronized(this) { 5844 if (mMainStack.mResumedActivity != null 5845 && mMainStack.mResumedActivity.task.taskId == task) { 5846 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5847 Binder.getCallingUid(), "Task to back")) { 5848 return; 5849 } 5850 } 5851 final long origId = Binder.clearCallingIdentity(); 5852 mMainStack.moveTaskToBackLocked(task, null); 5853 Binder.restoreCallingIdentity(origId); 5854 } 5855 } 5856 5857 /** 5858 * Moves an activity, and all of the other activities within the same task, to the bottom 5859 * of the history stack. The activity's order within the task is unchanged. 5860 * 5861 * @param token A reference to the activity we wish to move 5862 * @param nonRoot If false then this only works if the activity is the root 5863 * of a task; if true it will work for any activity in a task. 5864 * @return Returns true if the move completed, false if not. 5865 */ 5866 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5867 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5868 synchronized(this) { 5869 final long origId = Binder.clearCallingIdentity(); 5870 int taskId = getTaskForActivityLocked(token, !nonRoot); 5871 if (taskId >= 0) { 5872 return mMainStack.moveTaskToBackLocked(taskId, null); 5873 } 5874 Binder.restoreCallingIdentity(origId); 5875 } 5876 return false; 5877 } 5878 5879 public void moveTaskBackwards(int task) { 5880 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5881 "moveTaskBackwards()"); 5882 5883 synchronized(this) { 5884 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5885 Binder.getCallingUid(), "Task backwards")) { 5886 return; 5887 } 5888 final long origId = Binder.clearCallingIdentity(); 5889 moveTaskBackwardsLocked(task); 5890 Binder.restoreCallingIdentity(origId); 5891 } 5892 } 5893 5894 private final void moveTaskBackwardsLocked(int task) { 5895 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5896 } 5897 5898 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5899 synchronized(this) { 5900 return getTaskForActivityLocked(token, onlyRoot); 5901 } 5902 } 5903 5904 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5905 final int N = mMainStack.mHistory.size(); 5906 TaskRecord lastTask = null; 5907 for (int i=0; i<N; i++) { 5908 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5909 if (r.appToken == token) { 5910 if (!onlyRoot || lastTask != r.task) { 5911 return r.task.taskId; 5912 } 5913 return -1; 5914 } 5915 lastTask = r.task; 5916 } 5917 5918 return -1; 5919 } 5920 5921 // ========================================================= 5922 // THUMBNAILS 5923 // ========================================================= 5924 5925 public void reportThumbnail(IBinder token, 5926 Bitmap thumbnail, CharSequence description) { 5927 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5928 final long origId = Binder.clearCallingIdentity(); 5929 sendPendingThumbnail(null, token, thumbnail, description, true); 5930 Binder.restoreCallingIdentity(origId); 5931 } 5932 5933 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5934 Bitmap thumbnail, CharSequence description, boolean always) { 5935 TaskRecord task = null; 5936 ArrayList receivers = null; 5937 5938 //System.out.println("Send pending thumbnail: " + r); 5939 5940 synchronized(this) { 5941 if (r == null) { 5942 r = mMainStack.isInStackLocked(token); 5943 if (r == null) { 5944 return; 5945 } 5946 } 5947 if (thumbnail == null && r.thumbHolder != null) { 5948 thumbnail = r.thumbHolder.lastThumbnail; 5949 description = r.thumbHolder.lastDescription; 5950 } 5951 if (thumbnail == null && !always) { 5952 // If there is no thumbnail, and this entry is not actually 5953 // going away, then abort for now and pick up the next 5954 // thumbnail we get. 5955 return; 5956 } 5957 task = r.task; 5958 5959 int N = mPendingThumbnails.size(); 5960 int i=0; 5961 while (i<N) { 5962 PendingThumbnailsRecord pr = 5963 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5964 //System.out.println("Looking in " + pr.pendingRecords); 5965 if (pr.pendingRecords.remove(r)) { 5966 if (receivers == null) { 5967 receivers = new ArrayList(); 5968 } 5969 receivers.add(pr); 5970 if (pr.pendingRecords.size() == 0) { 5971 pr.finished = true; 5972 mPendingThumbnails.remove(i); 5973 N--; 5974 continue; 5975 } 5976 } 5977 i++; 5978 } 5979 } 5980 5981 if (receivers != null) { 5982 final int N = receivers.size(); 5983 for (int i=0; i<N; i++) { 5984 try { 5985 PendingThumbnailsRecord pr = 5986 (PendingThumbnailsRecord)receivers.get(i); 5987 pr.receiver.newThumbnail( 5988 task != null ? task.taskId : -1, thumbnail, description); 5989 if (pr.finished) { 5990 pr.receiver.finished(); 5991 } 5992 } catch (Exception e) { 5993 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5994 } 5995 } 5996 } 5997 } 5998 5999 // ========================================================= 6000 // CONTENT PROVIDERS 6001 // ========================================================= 6002 6003 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6004 List<ProviderInfo> providers = null; 6005 try { 6006 providers = AppGlobals.getPackageManager(). 6007 queryContentProviders(app.processName, app.uid, 6008 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6009 } catch (RemoteException ex) { 6010 } 6011 if (DEBUG_MU) 6012 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6013 int userId = app.userId; 6014 if (providers != null) { 6015 int N = providers.size(); 6016 for (int i=0; i<N; i++) { 6017 ProviderInfo cpi = 6018 (ProviderInfo)providers.get(i); 6019 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6020 cpi.name, cpi.flags); 6021 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6022 // This is a singleton provider, but a user besides the 6023 // default user is asking to initialize a process it runs 6024 // in... well, no, it doesn't actually run in this process, 6025 // it runs in the process of the default user. Get rid of it. 6026 providers.remove(i); 6027 N--; 6028 continue; 6029 } 6030 6031 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6032 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6033 if (cpr == null) { 6034 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6035 mProviderMap.putProviderByClass(comp, cpr); 6036 } 6037 if (DEBUG_MU) 6038 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6039 app.pubProviders.put(cpi.name, cpr); 6040 app.addPackage(cpi.applicationInfo.packageName); 6041 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6042 } 6043 } 6044 return providers; 6045 } 6046 6047 /** 6048 * Check if {@link ProcessRecord} has a possible chance at accessing the 6049 * given {@link ProviderInfo}. Final permission checking is always done 6050 * in {@link ContentProvider}. 6051 */ 6052 private final String checkContentProviderPermissionLocked( 6053 ProviderInfo cpi, ProcessRecord r) { 6054 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6055 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6056 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6057 cpi.applicationInfo.uid, cpi.exported) 6058 == PackageManager.PERMISSION_GRANTED) { 6059 return null; 6060 } 6061 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6062 cpi.applicationInfo.uid, cpi.exported) 6063 == PackageManager.PERMISSION_GRANTED) { 6064 return null; 6065 } 6066 6067 PathPermission[] pps = cpi.pathPermissions; 6068 if (pps != null) { 6069 int i = pps.length; 6070 while (i > 0) { 6071 i--; 6072 PathPermission pp = pps[i]; 6073 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6074 cpi.applicationInfo.uid, cpi.exported) 6075 == PackageManager.PERMISSION_GRANTED) { 6076 return null; 6077 } 6078 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6079 cpi.applicationInfo.uid, cpi.exported) 6080 == PackageManager.PERMISSION_GRANTED) { 6081 return null; 6082 } 6083 } 6084 } 6085 6086 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6087 if (perms != null) { 6088 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6089 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6090 return null; 6091 } 6092 } 6093 } 6094 6095 String msg; 6096 if (!cpi.exported) { 6097 msg = "Permission Denial: opening provider " + cpi.name 6098 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6099 + ", uid=" + callingUid + ") that is not exported from uid " 6100 + cpi.applicationInfo.uid; 6101 } else { 6102 msg = "Permission Denial: opening provider " + cpi.name 6103 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6104 + ", uid=" + callingUid + ") requires " 6105 + cpi.readPermission + " or " + cpi.writePermission; 6106 } 6107 Slog.w(TAG, msg); 6108 return msg; 6109 } 6110 6111 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6112 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6113 if (r != null) { 6114 for (int i=0; i<r.conProviders.size(); i++) { 6115 ContentProviderConnection conn = r.conProviders.get(i); 6116 if (conn.provider == cpr) { 6117 if (DEBUG_PROVIDER) Slog.v(TAG, 6118 "Adding provider requested by " 6119 + r.processName + " from process " 6120 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6121 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6122 if (stable) { 6123 conn.stableCount++; 6124 conn.numStableIncs++; 6125 } else { 6126 conn.unstableCount++; 6127 conn.numUnstableIncs++; 6128 } 6129 return conn; 6130 } 6131 } 6132 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6133 if (stable) { 6134 conn.stableCount = 1; 6135 conn.numStableIncs = 1; 6136 } else { 6137 conn.unstableCount = 1; 6138 conn.numUnstableIncs = 1; 6139 } 6140 cpr.connections.add(conn); 6141 r.conProviders.add(conn); 6142 return conn; 6143 } 6144 cpr.addExternalProcessHandleLocked(externalProcessToken); 6145 return null; 6146 } 6147 6148 boolean decProviderCountLocked(ContentProviderConnection conn, 6149 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6150 if (conn != null) { 6151 cpr = conn.provider; 6152 if (DEBUG_PROVIDER) Slog.v(TAG, 6153 "Removing provider requested by " 6154 + conn.client.processName + " from process " 6155 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6156 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6157 if (stable) { 6158 conn.stableCount--; 6159 } else { 6160 conn.unstableCount--; 6161 } 6162 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6163 cpr.connections.remove(conn); 6164 conn.client.conProviders.remove(conn); 6165 return true; 6166 } 6167 return false; 6168 } 6169 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6170 return false; 6171 } 6172 6173 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6174 String name, IBinder token, boolean stable) { 6175 ContentProviderRecord cpr; 6176 ContentProviderConnection conn = null; 6177 ProviderInfo cpi = null; 6178 6179 synchronized(this) { 6180 ProcessRecord r = null; 6181 if (caller != null) { 6182 r = getRecordForAppLocked(caller); 6183 if (r == null) { 6184 throw new SecurityException( 6185 "Unable to find app for caller " + caller 6186 + " (pid=" + Binder.getCallingPid() 6187 + ") when getting content provider " + name); 6188 } 6189 } 6190 6191 // First check if this content provider has been published... 6192 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6193 cpr = mProviderMap.getProviderByName(name, userId); 6194 boolean providerRunning = cpr != null; 6195 if (providerRunning) { 6196 cpi = cpr.info; 6197 String msg; 6198 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6199 throw new SecurityException(msg); 6200 } 6201 6202 if (r != null && cpr.canRunHere(r)) { 6203 // This provider has been published or is in the process 6204 // of being published... but it is also allowed to run 6205 // in the caller's process, so don't make a connection 6206 // and just let the caller instantiate its own instance. 6207 ContentProviderHolder holder = cpr.newHolder(null); 6208 // don't give caller the provider object, it needs 6209 // to make its own. 6210 holder.provider = null; 6211 return holder; 6212 } 6213 6214 final long origId = Binder.clearCallingIdentity(); 6215 6216 // In this case the provider instance already exists, so we can 6217 // return it right away. 6218 conn = incProviderCountLocked(r, cpr, token, stable); 6219 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6220 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6221 // If this is a perceptible app accessing the provider, 6222 // make sure to count it as being accessed and thus 6223 // back up on the LRU list. This is good because 6224 // content providers are often expensive to start. 6225 updateLruProcessLocked(cpr.proc, false, true); 6226 } 6227 } 6228 6229 if (cpr.proc != null) { 6230 if (false) { 6231 if (cpr.name.flattenToShortString().equals( 6232 "com.android.providers.calendar/.CalendarProvider2")) { 6233 Slog.v(TAG, "****************** KILLING " 6234 + cpr.name.flattenToShortString()); 6235 Process.killProcess(cpr.proc.pid); 6236 } 6237 } 6238 boolean success = updateOomAdjLocked(cpr.proc); 6239 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6240 // NOTE: there is still a race here where a signal could be 6241 // pending on the process even though we managed to update its 6242 // adj level. Not sure what to do about this, but at least 6243 // the race is now smaller. 6244 if (!success) { 6245 // Uh oh... it looks like the provider's process 6246 // has been killed on us. We need to wait for a new 6247 // process to be started, and make sure its death 6248 // doesn't kill our process. 6249 Slog.i(TAG, 6250 "Existing provider " + cpr.name.flattenToShortString() 6251 + " is crashing; detaching " + r); 6252 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6253 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6254 if (!lastRef) { 6255 // This wasn't the last ref our process had on 6256 // the provider... we have now been killed, bail. 6257 return null; 6258 } 6259 providerRunning = false; 6260 conn = null; 6261 } 6262 } 6263 6264 Binder.restoreCallingIdentity(origId); 6265 } 6266 6267 boolean singleton; 6268 if (!providerRunning) { 6269 try { 6270 cpi = AppGlobals.getPackageManager(). 6271 resolveContentProvider(name, 6272 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6273 } catch (RemoteException ex) { 6274 } 6275 if (cpi == null) { 6276 return null; 6277 } 6278 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6279 cpi.name, cpi.flags); 6280 if (singleton) { 6281 userId = 0; 6282 } 6283 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6284 6285 String msg; 6286 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6287 throw new SecurityException(msg); 6288 } 6289 6290 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6291 && !cpi.processName.equals("system")) { 6292 // If this content provider does not run in the system 6293 // process, and the system is not yet ready to run other 6294 // processes, then fail fast instead of hanging. 6295 throw new IllegalArgumentException( 6296 "Attempt to launch content provider before system ready"); 6297 } 6298 6299 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6300 cpr = mProviderMap.getProviderByClass(comp, userId); 6301 final boolean firstClass = cpr == null; 6302 if (firstClass) { 6303 try { 6304 ApplicationInfo ai = 6305 AppGlobals.getPackageManager(). 6306 getApplicationInfo( 6307 cpi.applicationInfo.packageName, 6308 STOCK_PM_FLAGS, userId); 6309 if (ai == null) { 6310 Slog.w(TAG, "No package info for content provider " 6311 + cpi.name); 6312 return null; 6313 } 6314 ai = getAppInfoForUser(ai, userId); 6315 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6316 } catch (RemoteException ex) { 6317 // pm is in same process, this will never happen. 6318 } 6319 } 6320 6321 if (r != null && cpr.canRunHere(r)) { 6322 // If this is a multiprocess provider, then just return its 6323 // info and allow the caller to instantiate it. Only do 6324 // this if the provider is the same user as the caller's 6325 // process, or can run as root (so can be in any process). 6326 return cpr.newHolder(null); 6327 } 6328 6329 if (DEBUG_PROVIDER) { 6330 RuntimeException e = new RuntimeException("here"); 6331 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6332 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6333 } 6334 6335 // This is single process, and our app is now connecting to it. 6336 // See if we are already in the process of launching this 6337 // provider. 6338 final int N = mLaunchingProviders.size(); 6339 int i; 6340 for (i=0; i<N; i++) { 6341 if (mLaunchingProviders.get(i) == cpr) { 6342 break; 6343 } 6344 } 6345 6346 // If the provider is not already being launched, then get it 6347 // started. 6348 if (i >= N) { 6349 final long origId = Binder.clearCallingIdentity(); 6350 6351 try { 6352 // Content provider is now in use, its package can't be stopped. 6353 try { 6354 AppGlobals.getPackageManager().setPackageStoppedState( 6355 cpr.appInfo.packageName, false, userId); 6356 } catch (RemoteException e) { 6357 } catch (IllegalArgumentException e) { 6358 Slog.w(TAG, "Failed trying to unstop package " 6359 + cpr.appInfo.packageName + ": " + e); 6360 } 6361 6362 ProcessRecord proc = startProcessLocked(cpi.processName, 6363 cpr.appInfo, false, 0, "content provider", 6364 new ComponentName(cpi.applicationInfo.packageName, 6365 cpi.name), false, false); 6366 if (proc == null) { 6367 Slog.w(TAG, "Unable to launch app " 6368 + cpi.applicationInfo.packageName + "/" 6369 + cpi.applicationInfo.uid + " for provider " 6370 + name + ": process is bad"); 6371 return null; 6372 } 6373 cpr.launchingApp = proc; 6374 mLaunchingProviders.add(cpr); 6375 } finally { 6376 Binder.restoreCallingIdentity(origId); 6377 } 6378 } 6379 6380 // Make sure the provider is published (the same provider class 6381 // may be published under multiple names). 6382 if (firstClass) { 6383 mProviderMap.putProviderByClass(comp, cpr); 6384 } 6385 6386 mProviderMap.putProviderByName(name, cpr); 6387 conn = incProviderCountLocked(r, cpr, token, stable); 6388 if (conn != null) { 6389 conn.waiting = true; 6390 } 6391 } 6392 } 6393 6394 // Wait for the provider to be published... 6395 synchronized (cpr) { 6396 while (cpr.provider == null) { 6397 if (cpr.launchingApp == null) { 6398 Slog.w(TAG, "Unable to launch app " 6399 + cpi.applicationInfo.packageName + "/" 6400 + cpi.applicationInfo.uid + " for provider " 6401 + name + ": launching app became null"); 6402 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6403 cpi.applicationInfo.packageName, 6404 cpi.applicationInfo.uid, name); 6405 return null; 6406 } 6407 try { 6408 if (DEBUG_MU) { 6409 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6410 + cpr.launchingApp); 6411 } 6412 if (conn != null) { 6413 conn.waiting = true; 6414 } 6415 cpr.wait(); 6416 } catch (InterruptedException ex) { 6417 } finally { 6418 if (conn != null) { 6419 conn.waiting = false; 6420 } 6421 } 6422 } 6423 } 6424 return cpr != null ? cpr.newHolder(conn) : null; 6425 } 6426 6427 public final ContentProviderHolder getContentProvider( 6428 IApplicationThread caller, String name, boolean stable) { 6429 enforceNotIsolatedCaller("getContentProvider"); 6430 if (caller == null) { 6431 String msg = "null IApplicationThread when getting content provider " 6432 + name; 6433 Slog.w(TAG, msg); 6434 throw new SecurityException(msg); 6435 } 6436 6437 return getContentProviderImpl(caller, name, null, stable); 6438 } 6439 6440 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6441 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6442 "Do not have permission in call getContentProviderExternal()"); 6443 return getContentProviderExternalUnchecked(name, token); 6444 } 6445 6446 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6447 return getContentProviderImpl(null, name, token, true); 6448 } 6449 6450 /** 6451 * Drop a content provider from a ProcessRecord's bookkeeping 6452 * @param cpr 6453 */ 6454 public void removeContentProvider(IBinder connection, boolean stable) { 6455 enforceNotIsolatedCaller("removeContentProvider"); 6456 synchronized (this) { 6457 ContentProviderConnection conn; 6458 try { 6459 conn = (ContentProviderConnection)connection; 6460 } catch (ClassCastException e) { 6461 String msg ="removeContentProvider: " + connection 6462 + " not a ContentProviderConnection"; 6463 Slog.w(TAG, msg); 6464 throw new IllegalArgumentException(msg); 6465 } 6466 if (conn == null) { 6467 throw new NullPointerException("connection is null"); 6468 } 6469 if (decProviderCountLocked(conn, null, null, stable)) { 6470 updateOomAdjLocked(); 6471 } 6472 } 6473 } 6474 6475 public void removeContentProviderExternal(String name, IBinder token) { 6476 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6477 "Do not have permission in call removeContentProviderExternal()"); 6478 removeContentProviderExternalUnchecked(name, token); 6479 } 6480 6481 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6482 synchronized (this) { 6483 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6484 Binder.getOrigCallingUser()); 6485 if(cpr == null) { 6486 //remove from mProvidersByClass 6487 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6488 return; 6489 } 6490 6491 //update content provider record entry info 6492 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6493 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6494 Binder.getOrigCallingUser()); 6495 if (localCpr.hasExternalProcessHandles()) { 6496 if (localCpr.removeExternalProcessHandleLocked(token)) { 6497 updateOomAdjLocked(); 6498 } else { 6499 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6500 + " with no external reference for token: " 6501 + token + "."); 6502 } 6503 } else { 6504 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6505 + " with no external references."); 6506 } 6507 } 6508 } 6509 6510 public final void publishContentProviders(IApplicationThread caller, 6511 List<ContentProviderHolder> providers) { 6512 if (providers == null) { 6513 return; 6514 } 6515 6516 enforceNotIsolatedCaller("publishContentProviders"); 6517 synchronized (this) { 6518 final ProcessRecord r = getRecordForAppLocked(caller); 6519 if (DEBUG_MU) 6520 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6521 if (r == null) { 6522 throw new SecurityException( 6523 "Unable to find app for caller " + caller 6524 + " (pid=" + Binder.getCallingPid() 6525 + ") when publishing content providers"); 6526 } 6527 6528 final long origId = Binder.clearCallingIdentity(); 6529 6530 final int N = providers.size(); 6531 for (int i=0; i<N; i++) { 6532 ContentProviderHolder src = providers.get(i); 6533 if (src == null || src.info == null || src.provider == null) { 6534 continue; 6535 } 6536 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6537 if (DEBUG_MU) 6538 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6539 if (dst != null) { 6540 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6541 mProviderMap.putProviderByClass(comp, dst); 6542 String names[] = dst.info.authority.split(";"); 6543 for (int j = 0; j < names.length; j++) { 6544 mProviderMap.putProviderByName(names[j], dst); 6545 } 6546 6547 int NL = mLaunchingProviders.size(); 6548 int j; 6549 for (j=0; j<NL; j++) { 6550 if (mLaunchingProviders.get(j) == dst) { 6551 mLaunchingProviders.remove(j); 6552 j--; 6553 NL--; 6554 } 6555 } 6556 synchronized (dst) { 6557 dst.provider = src.provider; 6558 dst.proc = r; 6559 dst.notifyAll(); 6560 } 6561 updateOomAdjLocked(r); 6562 } 6563 } 6564 6565 Binder.restoreCallingIdentity(origId); 6566 } 6567 } 6568 6569 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6570 ContentProviderConnection conn; 6571 try { 6572 conn = (ContentProviderConnection)connection; 6573 } catch (ClassCastException e) { 6574 String msg ="refContentProvider: " + connection 6575 + " not a ContentProviderConnection"; 6576 Slog.w(TAG, msg); 6577 throw new IllegalArgumentException(msg); 6578 } 6579 if (conn == null) { 6580 throw new NullPointerException("connection is null"); 6581 } 6582 6583 synchronized (this) { 6584 if (stable > 0) { 6585 conn.numStableIncs += stable; 6586 } 6587 stable = conn.stableCount + stable; 6588 if (stable < 0) { 6589 throw new IllegalStateException("stableCount < 0: " + stable); 6590 } 6591 6592 if (unstable > 0) { 6593 conn.numUnstableIncs += unstable; 6594 } 6595 unstable = conn.unstableCount + unstable; 6596 if (unstable < 0) { 6597 throw new IllegalStateException("unstableCount < 0: " + unstable); 6598 } 6599 6600 if ((stable+unstable) <= 0) { 6601 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6602 + stable + " unstable=" + unstable); 6603 } 6604 conn.stableCount = stable; 6605 conn.unstableCount = unstable; 6606 return !conn.dead; 6607 } 6608 } 6609 6610 public void unstableProviderDied(IBinder connection) { 6611 ContentProviderConnection conn; 6612 try { 6613 conn = (ContentProviderConnection)connection; 6614 } catch (ClassCastException e) { 6615 String msg ="refContentProvider: " + connection 6616 + " not a ContentProviderConnection"; 6617 Slog.w(TAG, msg); 6618 throw new IllegalArgumentException(msg); 6619 } 6620 if (conn == null) { 6621 throw new NullPointerException("connection is null"); 6622 } 6623 6624 // Safely retrieve the content provider associated with the connection. 6625 IContentProvider provider; 6626 synchronized (this) { 6627 provider = conn.provider.provider; 6628 } 6629 6630 if (provider == null) { 6631 // Um, yeah, we're way ahead of you. 6632 return; 6633 } 6634 6635 // Make sure the caller is being honest with us. 6636 if (provider.asBinder().pingBinder()) { 6637 // Er, no, still looks good to us. 6638 synchronized (this) { 6639 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6640 + " says " + conn + " died, but we don't agree"); 6641 return; 6642 } 6643 } 6644 6645 // Well look at that! It's dead! 6646 synchronized (this) { 6647 if (conn.provider.provider != provider) { 6648 // But something changed... good enough. 6649 return; 6650 } 6651 6652 ProcessRecord proc = conn.provider.proc; 6653 if (proc == null || proc.thread == null) { 6654 // Seems like the process is already cleaned up. 6655 return; 6656 } 6657 6658 // As far as we're concerned, this is just like receiving a 6659 // death notification... just a bit prematurely. 6660 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6661 + ") early provider death"); 6662 final long ident = Binder.clearCallingIdentity(); 6663 try { 6664 appDiedLocked(proc, proc.pid, proc.thread); 6665 } finally { 6666 Binder.restoreCallingIdentity(ident); 6667 } 6668 } 6669 } 6670 6671 public static final void installSystemProviders() { 6672 List<ProviderInfo> providers; 6673 synchronized (mSelf) { 6674 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6675 providers = mSelf.generateApplicationProvidersLocked(app); 6676 if (providers != null) { 6677 for (int i=providers.size()-1; i>=0; i--) { 6678 ProviderInfo pi = (ProviderInfo)providers.get(i); 6679 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6680 Slog.w(TAG, "Not installing system proc provider " + pi.name 6681 + ": not system .apk"); 6682 providers.remove(i); 6683 } 6684 } 6685 } 6686 } 6687 if (providers != null) { 6688 mSystemThread.installSystemProviders(providers); 6689 } 6690 6691 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6692 6693 mSelf.mUsageStatsService.monitorPackages(); 6694 } 6695 6696 /** 6697 * Allows app to retrieve the MIME type of a URI without having permission 6698 * to access its content provider. 6699 * 6700 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6701 * 6702 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6703 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6704 */ 6705 public String getProviderMimeType(Uri uri) { 6706 enforceNotIsolatedCaller("getProviderMimeType"); 6707 final String name = uri.getAuthority(); 6708 final long ident = Binder.clearCallingIdentity(); 6709 ContentProviderHolder holder = null; 6710 6711 try { 6712 holder = getContentProviderExternalUnchecked(name, null); 6713 if (holder != null) { 6714 return holder.provider.getType(uri); 6715 } 6716 } catch (RemoteException e) { 6717 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6718 return null; 6719 } finally { 6720 if (holder != null) { 6721 removeContentProviderExternalUnchecked(name, null); 6722 } 6723 Binder.restoreCallingIdentity(ident); 6724 } 6725 6726 return null; 6727 } 6728 6729 // ========================================================= 6730 // GLOBAL MANAGEMENT 6731 // ========================================================= 6732 6733 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6734 ApplicationInfo info, String customProcess, boolean isolated) { 6735 String proc = customProcess != null ? customProcess : info.processName; 6736 BatteryStatsImpl.Uid.Proc ps = null; 6737 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6738 int uid = info.uid; 6739 if (isolated) { 6740 int userId = UserHandle.getUserId(uid); 6741 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6742 uid = 0; 6743 while (true) { 6744 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6745 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6746 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6747 } 6748 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6749 mNextIsolatedProcessUid++; 6750 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6751 // No process for this uid, use it. 6752 break; 6753 } 6754 stepsLeft--; 6755 if (stepsLeft <= 0) { 6756 return null; 6757 } 6758 } 6759 } 6760 synchronized (stats) { 6761 ps = stats.getProcessStatsLocked(info.uid, proc); 6762 } 6763 return new ProcessRecord(ps, thread, info, proc, uid); 6764 } 6765 6766 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6767 ProcessRecord app; 6768 if (!isolated) { 6769 app = getProcessRecordLocked(info.processName, info.uid); 6770 } else { 6771 app = null; 6772 } 6773 6774 if (app == null) { 6775 app = newProcessRecordLocked(null, info, null, isolated); 6776 mProcessNames.put(info.processName, app.uid, app); 6777 if (isolated) { 6778 mIsolatedProcesses.put(app.uid, app); 6779 } 6780 updateLruProcessLocked(app, true, true); 6781 } 6782 6783 // This package really, really can not be stopped. 6784 try { 6785 AppGlobals.getPackageManager().setPackageStoppedState( 6786 info.packageName, false, UserHandle.getUserId(app.uid)); 6787 } catch (RemoteException e) { 6788 } catch (IllegalArgumentException e) { 6789 Slog.w(TAG, "Failed trying to unstop package " 6790 + info.packageName + ": " + e); 6791 } 6792 6793 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6794 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6795 app.persistent = true; 6796 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6797 } 6798 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6799 mPersistentStartingProcesses.add(app); 6800 startProcessLocked(app, "added application", app.processName); 6801 } 6802 6803 return app; 6804 } 6805 6806 public void unhandledBack() { 6807 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6808 "unhandledBack()"); 6809 6810 synchronized(this) { 6811 int count = mMainStack.mHistory.size(); 6812 if (DEBUG_SWITCH) Slog.d( 6813 TAG, "Performing unhandledBack(): stack size = " + count); 6814 if (count > 1) { 6815 final long origId = Binder.clearCallingIdentity(); 6816 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6817 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6818 Binder.restoreCallingIdentity(origId); 6819 } 6820 } 6821 } 6822 6823 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6824 enforceNotIsolatedCaller("openContentUri"); 6825 String name = uri.getAuthority(); 6826 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6827 ParcelFileDescriptor pfd = null; 6828 if (cph != null) { 6829 // We record the binder invoker's uid in thread-local storage before 6830 // going to the content provider to open the file. Later, in the code 6831 // that handles all permissions checks, we look for this uid and use 6832 // that rather than the Activity Manager's own uid. The effect is that 6833 // we do the check against the caller's permissions even though it looks 6834 // to the content provider like the Activity Manager itself is making 6835 // the request. 6836 sCallerIdentity.set(new Identity( 6837 Binder.getCallingPid(), Binder.getCallingUid())); 6838 try { 6839 pfd = cph.provider.openFile(uri, "r"); 6840 } catch (FileNotFoundException e) { 6841 // do nothing; pfd will be returned null 6842 } finally { 6843 // Ensure that whatever happens, we clean up the identity state 6844 sCallerIdentity.remove(); 6845 } 6846 6847 // We've got the fd now, so we're done with the provider. 6848 removeContentProviderExternalUnchecked(name, null); 6849 } else { 6850 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6851 } 6852 return pfd; 6853 } 6854 6855 // Actually is sleeping or shutting down or whatever else in the future 6856 // is an inactive state. 6857 public boolean isSleeping() { 6858 return mSleeping || mShuttingDown; 6859 } 6860 6861 public void goingToSleep() { 6862 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6863 != PackageManager.PERMISSION_GRANTED) { 6864 throw new SecurityException("Requires permission " 6865 + android.Manifest.permission.DEVICE_POWER); 6866 } 6867 6868 synchronized(this) { 6869 mWentToSleep = true; 6870 updateEventDispatchingLocked(); 6871 6872 if (!mSleeping) { 6873 mSleeping = true; 6874 mMainStack.stopIfSleepingLocked(); 6875 6876 // Initialize the wake times of all processes. 6877 checkExcessivePowerUsageLocked(false); 6878 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6879 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6880 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6881 } 6882 } 6883 } 6884 6885 public boolean shutdown(int timeout) { 6886 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6887 != PackageManager.PERMISSION_GRANTED) { 6888 throw new SecurityException("Requires permission " 6889 + android.Manifest.permission.SHUTDOWN); 6890 } 6891 6892 boolean timedout = false; 6893 6894 synchronized(this) { 6895 mShuttingDown = true; 6896 updateEventDispatchingLocked(); 6897 6898 if (mMainStack.mResumedActivity != null) { 6899 mMainStack.stopIfSleepingLocked(); 6900 final long endTime = System.currentTimeMillis() + timeout; 6901 while (mMainStack.mResumedActivity != null 6902 || mMainStack.mPausingActivity != null) { 6903 long delay = endTime - System.currentTimeMillis(); 6904 if (delay <= 0) { 6905 Slog.w(TAG, "Activity manager shutdown timed out"); 6906 timedout = true; 6907 break; 6908 } 6909 try { 6910 this.wait(); 6911 } catch (InterruptedException e) { 6912 } 6913 } 6914 } 6915 } 6916 6917 mUsageStatsService.shutdown(); 6918 mBatteryStatsService.shutdown(); 6919 6920 return timedout; 6921 } 6922 6923 public final void activitySlept(IBinder token) { 6924 if (localLOGV) Slog.v( 6925 TAG, "Activity slept: token=" + token); 6926 6927 ActivityRecord r = null; 6928 6929 final long origId = Binder.clearCallingIdentity(); 6930 6931 synchronized (this) { 6932 r = mMainStack.isInStackLocked(token); 6933 if (r != null) { 6934 mMainStack.activitySleptLocked(r); 6935 } 6936 } 6937 6938 Binder.restoreCallingIdentity(origId); 6939 } 6940 6941 private void comeOutOfSleepIfNeededLocked() { 6942 if (!mWentToSleep && !mLockScreenShown) { 6943 if (mSleeping) { 6944 mSleeping = false; 6945 mMainStack.awakeFromSleepingLocked(); 6946 mMainStack.resumeTopActivityLocked(null); 6947 } 6948 } 6949 } 6950 6951 public void wakingUp() { 6952 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6953 != PackageManager.PERMISSION_GRANTED) { 6954 throw new SecurityException("Requires permission " 6955 + android.Manifest.permission.DEVICE_POWER); 6956 } 6957 6958 synchronized(this) { 6959 mWentToSleep = false; 6960 updateEventDispatchingLocked(); 6961 comeOutOfSleepIfNeededLocked(); 6962 } 6963 } 6964 6965 private void updateEventDispatchingLocked() { 6966 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6967 } 6968 6969 public void setLockScreenShown(boolean shown) { 6970 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6971 != PackageManager.PERMISSION_GRANTED) { 6972 throw new SecurityException("Requires permission " 6973 + android.Manifest.permission.DEVICE_POWER); 6974 } 6975 6976 synchronized(this) { 6977 mLockScreenShown = shown; 6978 comeOutOfSleepIfNeededLocked(); 6979 } 6980 } 6981 6982 public void stopAppSwitches() { 6983 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6984 != PackageManager.PERMISSION_GRANTED) { 6985 throw new SecurityException("Requires permission " 6986 + android.Manifest.permission.STOP_APP_SWITCHES); 6987 } 6988 6989 synchronized(this) { 6990 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6991 + APP_SWITCH_DELAY_TIME; 6992 mDidAppSwitch = false; 6993 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6994 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6995 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6996 } 6997 } 6998 6999 public void resumeAppSwitches() { 7000 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7001 != PackageManager.PERMISSION_GRANTED) { 7002 throw new SecurityException("Requires permission " 7003 + android.Manifest.permission.STOP_APP_SWITCHES); 7004 } 7005 7006 synchronized(this) { 7007 // Note that we don't execute any pending app switches... we will 7008 // let those wait until either the timeout, or the next start 7009 // activity request. 7010 mAppSwitchesAllowedTime = 0; 7011 } 7012 } 7013 7014 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7015 String name) { 7016 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7017 return true; 7018 } 7019 7020 final int perm = checkComponentPermission( 7021 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7022 callingUid, -1, true); 7023 if (perm == PackageManager.PERMISSION_GRANTED) { 7024 return true; 7025 } 7026 7027 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7028 return false; 7029 } 7030 7031 public void setDebugApp(String packageName, boolean waitForDebugger, 7032 boolean persistent) { 7033 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7034 "setDebugApp()"); 7035 7036 // Note that this is not really thread safe if there are multiple 7037 // callers into it at the same time, but that's not a situation we 7038 // care about. 7039 if (persistent) { 7040 final ContentResolver resolver = mContext.getContentResolver(); 7041 Settings.System.putString( 7042 resolver, Settings.System.DEBUG_APP, 7043 packageName); 7044 Settings.System.putInt( 7045 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7046 waitForDebugger ? 1 : 0); 7047 } 7048 7049 synchronized (this) { 7050 if (!persistent) { 7051 mOrigDebugApp = mDebugApp; 7052 mOrigWaitForDebugger = mWaitForDebugger; 7053 } 7054 mDebugApp = packageName; 7055 mWaitForDebugger = waitForDebugger; 7056 mDebugTransient = !persistent; 7057 if (packageName != null) { 7058 final long origId = Binder.clearCallingIdentity(); 7059 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7060 Binder.restoreCallingIdentity(origId); 7061 } 7062 } 7063 } 7064 7065 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7066 synchronized (this) { 7067 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7068 if (!isDebuggable) { 7069 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7070 throw new SecurityException("Process not debuggable: " + app.packageName); 7071 } 7072 } 7073 7074 mOpenGlTraceApp = processName; 7075 } 7076 } 7077 7078 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7079 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7080 synchronized (this) { 7081 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7082 if (!isDebuggable) { 7083 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7084 throw new SecurityException("Process not debuggable: " + app.packageName); 7085 } 7086 } 7087 mProfileApp = processName; 7088 mProfileFile = profileFile; 7089 if (mProfileFd != null) { 7090 try { 7091 mProfileFd.close(); 7092 } catch (IOException e) { 7093 } 7094 mProfileFd = null; 7095 } 7096 mProfileFd = profileFd; 7097 mProfileType = 0; 7098 mAutoStopProfiler = autoStopProfiler; 7099 } 7100 } 7101 7102 public void setAlwaysFinish(boolean enabled) { 7103 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7104 "setAlwaysFinish()"); 7105 7106 Settings.System.putInt( 7107 mContext.getContentResolver(), 7108 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7109 7110 synchronized (this) { 7111 mAlwaysFinishActivities = enabled; 7112 } 7113 } 7114 7115 public void setActivityController(IActivityController controller) { 7116 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7117 "setActivityController()"); 7118 synchronized (this) { 7119 mController = controller; 7120 } 7121 } 7122 7123 public boolean isUserAMonkey() { 7124 // For now the fact that there is a controller implies 7125 // we have a monkey. 7126 synchronized (this) { 7127 return mController != null; 7128 } 7129 } 7130 7131 public void registerProcessObserver(IProcessObserver observer) { 7132 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7133 "registerProcessObserver()"); 7134 synchronized (this) { 7135 mProcessObservers.register(observer); 7136 } 7137 } 7138 7139 public void unregisterProcessObserver(IProcessObserver observer) { 7140 synchronized (this) { 7141 mProcessObservers.unregister(observer); 7142 } 7143 } 7144 7145 public void setImmersive(IBinder token, boolean immersive) { 7146 synchronized(this) { 7147 ActivityRecord r = mMainStack.isInStackLocked(token); 7148 if (r == null) { 7149 throw new IllegalArgumentException(); 7150 } 7151 r.immersive = immersive; 7152 } 7153 } 7154 7155 public boolean isImmersive(IBinder token) { 7156 synchronized (this) { 7157 ActivityRecord r = mMainStack.isInStackLocked(token); 7158 if (r == null) { 7159 throw new IllegalArgumentException(); 7160 } 7161 return r.immersive; 7162 } 7163 } 7164 7165 public boolean isTopActivityImmersive() { 7166 enforceNotIsolatedCaller("startActivity"); 7167 synchronized (this) { 7168 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7169 return (r != null) ? r.immersive : false; 7170 } 7171 } 7172 7173 public final void enterSafeMode() { 7174 synchronized(this) { 7175 // It only makes sense to do this before the system is ready 7176 // and started launching other packages. 7177 if (!mSystemReady) { 7178 try { 7179 AppGlobals.getPackageManager().enterSafeMode(); 7180 } catch (RemoteException e) { 7181 } 7182 } 7183 } 7184 } 7185 7186 public final void showSafeModeOverlay() { 7187 View v = LayoutInflater.from(mContext).inflate( 7188 com.android.internal.R.layout.safe_mode, null); 7189 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7190 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7191 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7192 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7193 lp.gravity = Gravity.BOTTOM | Gravity.START; 7194 lp.format = v.getBackground().getOpacity(); 7195 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7196 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7197 ((WindowManager)mContext.getSystemService( 7198 Context.WINDOW_SERVICE)).addView(v, lp); 7199 } 7200 7201 public void noteWakeupAlarm(IIntentSender sender) { 7202 if (!(sender instanceof PendingIntentRecord)) { 7203 return; 7204 } 7205 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7206 synchronized (stats) { 7207 if (mBatteryStatsService.isOnBattery()) { 7208 mBatteryStatsService.enforceCallingPermission(); 7209 PendingIntentRecord rec = (PendingIntentRecord)sender; 7210 int MY_UID = Binder.getCallingUid(); 7211 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7212 BatteryStatsImpl.Uid.Pkg pkg = 7213 stats.getPackageStatsLocked(uid, rec.key.packageName); 7214 pkg.incWakeupsLocked(); 7215 } 7216 } 7217 } 7218 7219 public boolean killPids(int[] pids, String pReason, boolean secure) { 7220 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7221 throw new SecurityException("killPids only available to the system"); 7222 } 7223 String reason = (pReason == null) ? "Unknown" : pReason; 7224 // XXX Note: don't acquire main activity lock here, because the window 7225 // manager calls in with its locks held. 7226 7227 boolean killed = false; 7228 synchronized (mPidsSelfLocked) { 7229 int[] types = new int[pids.length]; 7230 int worstType = 0; 7231 for (int i=0; i<pids.length; i++) { 7232 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7233 if (proc != null) { 7234 int type = proc.setAdj; 7235 types[i] = type; 7236 if (type > worstType) { 7237 worstType = type; 7238 } 7239 } 7240 } 7241 7242 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7243 // then constrain it so we will kill all hidden procs. 7244 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7245 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7246 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7247 } 7248 7249 // If this is not a secure call, don't let it kill processes that 7250 // are important. 7251 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7252 worstType = ProcessList.SERVICE_ADJ; 7253 } 7254 7255 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7256 for (int i=0; i<pids.length; i++) { 7257 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7258 if (proc == null) { 7259 continue; 7260 } 7261 int adj = proc.setAdj; 7262 if (adj >= worstType && !proc.killedBackground) { 7263 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7264 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7265 proc.processName, adj, reason); 7266 killed = true; 7267 proc.killedBackground = true; 7268 Process.killProcessQuiet(pids[i]); 7269 } 7270 } 7271 } 7272 return killed; 7273 } 7274 7275 @Override 7276 public boolean killProcessesBelowForeground(String reason) { 7277 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7278 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7279 } 7280 7281 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7282 } 7283 7284 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7285 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7286 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7287 } 7288 7289 boolean killed = false; 7290 synchronized (mPidsSelfLocked) { 7291 final int size = mPidsSelfLocked.size(); 7292 for (int i = 0; i < size; i++) { 7293 final int pid = mPidsSelfLocked.keyAt(i); 7294 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7295 if (proc == null) continue; 7296 7297 final int adj = proc.setAdj; 7298 if (adj > belowAdj && !proc.killedBackground) { 7299 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7300 EventLog.writeEvent( 7301 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7302 killed = true; 7303 proc.killedBackground = true; 7304 Process.killProcessQuiet(pid); 7305 } 7306 } 7307 } 7308 return killed; 7309 } 7310 7311 public final void startRunning(String pkg, String cls, String action, 7312 String data) { 7313 synchronized(this) { 7314 if (mStartRunning) { 7315 return; 7316 } 7317 mStartRunning = true; 7318 mTopComponent = pkg != null && cls != null 7319 ? new ComponentName(pkg, cls) : null; 7320 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7321 mTopData = data; 7322 if (!mSystemReady) { 7323 return; 7324 } 7325 } 7326 7327 systemReady(null); 7328 } 7329 7330 private void retrieveSettings() { 7331 final ContentResolver resolver = mContext.getContentResolver(); 7332 String debugApp = Settings.System.getString( 7333 resolver, Settings.System.DEBUG_APP); 7334 boolean waitForDebugger = Settings.System.getInt( 7335 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7336 boolean alwaysFinishActivities = Settings.System.getInt( 7337 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7338 7339 Configuration configuration = new Configuration(); 7340 Settings.System.getConfiguration(resolver, configuration); 7341 7342 synchronized (this) { 7343 mDebugApp = mOrigDebugApp = debugApp; 7344 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7345 mAlwaysFinishActivities = alwaysFinishActivities; 7346 // This happens before any activities are started, so we can 7347 // change mConfiguration in-place. 7348 updateConfigurationLocked(configuration, null, false, true); 7349 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7350 } 7351 } 7352 7353 public boolean testIsSystemReady() { 7354 // no need to synchronize(this) just to read & return the value 7355 return mSystemReady; 7356 } 7357 7358 private static File getCalledPreBootReceiversFile() { 7359 File dataDir = Environment.getDataDirectory(); 7360 File systemDir = new File(dataDir, "system"); 7361 File fname = new File(systemDir, "called_pre_boots.dat"); 7362 return fname; 7363 } 7364 7365 static final int LAST_DONE_VERSION = 10000; 7366 7367 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7368 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7369 File file = getCalledPreBootReceiversFile(); 7370 FileInputStream fis = null; 7371 try { 7372 fis = new FileInputStream(file); 7373 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7374 int fvers = dis.readInt(); 7375 if (fvers == LAST_DONE_VERSION) { 7376 String vers = dis.readUTF(); 7377 String codename = dis.readUTF(); 7378 String build = dis.readUTF(); 7379 if (android.os.Build.VERSION.RELEASE.equals(vers) 7380 && android.os.Build.VERSION.CODENAME.equals(codename) 7381 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7382 int num = dis.readInt(); 7383 while (num > 0) { 7384 num--; 7385 String pkg = dis.readUTF(); 7386 String cls = dis.readUTF(); 7387 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7388 } 7389 } 7390 } 7391 } catch (FileNotFoundException e) { 7392 } catch (IOException e) { 7393 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7394 } finally { 7395 if (fis != null) { 7396 try { 7397 fis.close(); 7398 } catch (IOException e) { 7399 } 7400 } 7401 } 7402 return lastDoneReceivers; 7403 } 7404 7405 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7406 File file = getCalledPreBootReceiversFile(); 7407 FileOutputStream fos = null; 7408 DataOutputStream dos = null; 7409 try { 7410 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7411 fos = new FileOutputStream(file); 7412 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7413 dos.writeInt(LAST_DONE_VERSION); 7414 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7415 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7416 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7417 dos.writeInt(list.size()); 7418 for (int i=0; i<list.size(); i++) { 7419 dos.writeUTF(list.get(i).getPackageName()); 7420 dos.writeUTF(list.get(i).getClassName()); 7421 } 7422 } catch (IOException e) { 7423 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7424 file.delete(); 7425 } finally { 7426 FileUtils.sync(fos); 7427 if (dos != null) { 7428 try { 7429 dos.close(); 7430 } catch (IOException e) { 7431 // TODO Auto-generated catch block 7432 e.printStackTrace(); 7433 } 7434 } 7435 } 7436 } 7437 7438 public void systemReady(final Runnable goingCallback) { 7439 synchronized(this) { 7440 if (mSystemReady) { 7441 if (goingCallback != null) goingCallback.run(); 7442 return; 7443 } 7444 7445 // Check to see if there are any update receivers to run. 7446 if (!mDidUpdate) { 7447 if (mWaitingUpdate) { 7448 return; 7449 } 7450 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7451 List<ResolveInfo> ris = null; 7452 try { 7453 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7454 intent, null, 0, 0); 7455 } catch (RemoteException e) { 7456 } 7457 if (ris != null) { 7458 for (int i=ris.size()-1; i>=0; i--) { 7459 if ((ris.get(i).activityInfo.applicationInfo.flags 7460 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7461 ris.remove(i); 7462 } 7463 } 7464 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7465 7466 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7467 7468 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7469 for (int i=0; i<ris.size(); i++) { 7470 ActivityInfo ai = ris.get(i).activityInfo; 7471 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7472 if (lastDoneReceivers.contains(comp)) { 7473 ris.remove(i); 7474 i--; 7475 } 7476 } 7477 7478 for (int i=0; i<ris.size(); i++) { 7479 ActivityInfo ai = ris.get(i).activityInfo; 7480 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7481 doneReceivers.add(comp); 7482 intent.setComponent(comp); 7483 IIntentReceiver finisher = null; 7484 if (i == ris.size()-1) { 7485 finisher = new IIntentReceiver.Stub() { 7486 public void performReceive(Intent intent, int resultCode, 7487 String data, Bundle extras, boolean ordered, 7488 boolean sticky) { 7489 // The raw IIntentReceiver interface is called 7490 // with the AM lock held, so redispatch to 7491 // execute our code without the lock. 7492 mHandler.post(new Runnable() { 7493 public void run() { 7494 synchronized (ActivityManagerService.this) { 7495 mDidUpdate = true; 7496 } 7497 writeLastDonePreBootReceivers(doneReceivers); 7498 showBootMessage(mContext.getText( 7499 R.string.android_upgrading_complete), 7500 false); 7501 systemReady(goingCallback); 7502 } 7503 }); 7504 } 7505 }; 7506 } 7507 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7508 /* TODO: Send this to all users */ 7509 broadcastIntentLocked(null, null, intent, null, finisher, 7510 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7511 0 /* UserId zero */); 7512 if (finisher != null) { 7513 mWaitingUpdate = true; 7514 } 7515 } 7516 } 7517 if (mWaitingUpdate) { 7518 return; 7519 } 7520 mDidUpdate = true; 7521 } 7522 7523 mSystemReady = true; 7524 if (!mStartRunning) { 7525 return; 7526 } 7527 } 7528 7529 ArrayList<ProcessRecord> procsToKill = null; 7530 synchronized(mPidsSelfLocked) { 7531 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7532 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7533 if (!isAllowedWhileBooting(proc.info)){ 7534 if (procsToKill == null) { 7535 procsToKill = new ArrayList<ProcessRecord>(); 7536 } 7537 procsToKill.add(proc); 7538 } 7539 } 7540 } 7541 7542 synchronized(this) { 7543 if (procsToKill != null) { 7544 for (int i=procsToKill.size()-1; i>=0; i--) { 7545 ProcessRecord proc = procsToKill.get(i); 7546 Slog.i(TAG, "Removing system update proc: " + proc); 7547 removeProcessLocked(proc, true, false, "system update done"); 7548 } 7549 } 7550 7551 // Now that we have cleaned up any update processes, we 7552 // are ready to start launching real processes and know that 7553 // we won't trample on them any more. 7554 mProcessesReady = true; 7555 } 7556 7557 Slog.i(TAG, "System now ready"); 7558 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7559 SystemClock.uptimeMillis()); 7560 7561 synchronized(this) { 7562 // Make sure we have no pre-ready processes sitting around. 7563 7564 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7565 ResolveInfo ri = mContext.getPackageManager() 7566 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7567 STOCK_PM_FLAGS); 7568 CharSequence errorMsg = null; 7569 if (ri != null) { 7570 ActivityInfo ai = ri.activityInfo; 7571 ApplicationInfo app = ai.applicationInfo; 7572 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7573 mTopAction = Intent.ACTION_FACTORY_TEST; 7574 mTopData = null; 7575 mTopComponent = new ComponentName(app.packageName, 7576 ai.name); 7577 } else { 7578 errorMsg = mContext.getResources().getText( 7579 com.android.internal.R.string.factorytest_not_system); 7580 } 7581 } else { 7582 errorMsg = mContext.getResources().getText( 7583 com.android.internal.R.string.factorytest_no_action); 7584 } 7585 if (errorMsg != null) { 7586 mTopAction = null; 7587 mTopData = null; 7588 mTopComponent = null; 7589 Message msg = Message.obtain(); 7590 msg.what = SHOW_FACTORY_ERROR_MSG; 7591 msg.getData().putCharSequence("msg", errorMsg); 7592 mHandler.sendMessage(msg); 7593 } 7594 } 7595 } 7596 7597 retrieveSettings(); 7598 7599 if (goingCallback != null) goingCallback.run(); 7600 7601 synchronized (this) { 7602 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7603 try { 7604 List apps = AppGlobals.getPackageManager(). 7605 getPersistentApplications(STOCK_PM_FLAGS); 7606 if (apps != null) { 7607 int N = apps.size(); 7608 int i; 7609 for (i=0; i<N; i++) { 7610 ApplicationInfo info 7611 = (ApplicationInfo)apps.get(i); 7612 if (info != null && 7613 !info.packageName.equals("android")) { 7614 addAppLocked(info, false); 7615 } 7616 } 7617 } 7618 } catch (RemoteException ex) { 7619 // pm is in same process, this will never happen. 7620 } 7621 } 7622 7623 // Start up initial activity. 7624 mBooting = true; 7625 7626 try { 7627 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7628 Message msg = Message.obtain(); 7629 msg.what = SHOW_UID_ERROR_MSG; 7630 mHandler.sendMessage(msg); 7631 } 7632 } catch (RemoteException e) { 7633 } 7634 7635 mMainStack.resumeTopActivityLocked(null); 7636 } 7637 } 7638 7639 private boolean makeAppCrashingLocked(ProcessRecord app, 7640 String shortMsg, String longMsg, String stackTrace) { 7641 app.crashing = true; 7642 app.crashingReport = generateProcessError(app, 7643 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7644 startAppProblemLocked(app); 7645 app.stopFreezingAllLocked(); 7646 return handleAppCrashLocked(app); 7647 } 7648 7649 private void makeAppNotRespondingLocked(ProcessRecord app, 7650 String activity, String shortMsg, String longMsg) { 7651 app.notResponding = true; 7652 app.notRespondingReport = generateProcessError(app, 7653 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7654 activity, shortMsg, longMsg, null); 7655 startAppProblemLocked(app); 7656 app.stopFreezingAllLocked(); 7657 } 7658 7659 /** 7660 * Generate a process error record, suitable for attachment to a ProcessRecord. 7661 * 7662 * @param app The ProcessRecord in which the error occurred. 7663 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7664 * ActivityManager.AppErrorStateInfo 7665 * @param activity The activity associated with the crash, if known. 7666 * @param shortMsg Short message describing the crash. 7667 * @param longMsg Long message describing the crash. 7668 * @param stackTrace Full crash stack trace, may be null. 7669 * 7670 * @return Returns a fully-formed AppErrorStateInfo record. 7671 */ 7672 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7673 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7674 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7675 7676 report.condition = condition; 7677 report.processName = app.processName; 7678 report.pid = app.pid; 7679 report.uid = app.info.uid; 7680 report.tag = activity; 7681 report.shortMsg = shortMsg; 7682 report.longMsg = longMsg; 7683 report.stackTrace = stackTrace; 7684 7685 return report; 7686 } 7687 7688 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7689 synchronized (this) { 7690 app.crashing = false; 7691 app.crashingReport = null; 7692 app.notResponding = false; 7693 app.notRespondingReport = null; 7694 if (app.anrDialog == fromDialog) { 7695 app.anrDialog = null; 7696 } 7697 if (app.waitDialog == fromDialog) { 7698 app.waitDialog = null; 7699 } 7700 if (app.pid > 0 && app.pid != MY_PID) { 7701 handleAppCrashLocked(app); 7702 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7703 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7704 app.processName, app.setAdj, "user's request after error"); 7705 Process.killProcessQuiet(app.pid); 7706 } 7707 } 7708 } 7709 7710 private boolean handleAppCrashLocked(ProcessRecord app) { 7711 if (mHeadless) { 7712 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7713 return false; 7714 } 7715 long now = SystemClock.uptimeMillis(); 7716 7717 Long crashTime; 7718 if (!app.isolated) { 7719 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7720 } else { 7721 crashTime = null; 7722 } 7723 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7724 // This process loses! 7725 Slog.w(TAG, "Process " + app.info.processName 7726 + " has crashed too many times: killing!"); 7727 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7728 app.info.processName, app.uid); 7729 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7730 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7731 if (r.app == app) { 7732 Slog.w(TAG, " Force finishing activity " 7733 + r.intent.getComponent().flattenToShortString()); 7734 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7735 } 7736 } 7737 if (!app.persistent) { 7738 // We don't want to start this process again until the user 7739 // explicitly does so... but for persistent process, we really 7740 // need to keep it running. If a persistent process is actually 7741 // repeatedly crashing, then badness for everyone. 7742 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7743 app.info.processName); 7744 if (!app.isolated) { 7745 // XXX We don't have a way to mark isolated processes 7746 // as bad, since they don't have a peristent identity. 7747 mBadProcesses.put(app.info.processName, app.uid, now); 7748 mProcessCrashTimes.remove(app.info.processName, app.uid); 7749 } 7750 app.bad = true; 7751 app.removed = true; 7752 // Don't let services in this process be restarted and potentially 7753 // annoy the user repeatedly. Unless it is persistent, since those 7754 // processes run critical code. 7755 removeProcessLocked(app, false, false, "crash"); 7756 mMainStack.resumeTopActivityLocked(null); 7757 return false; 7758 } 7759 mMainStack.resumeTopActivityLocked(null); 7760 } else { 7761 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7762 if (r != null && r.app == app) { 7763 // If the top running activity is from this crashing 7764 // process, then terminate it to avoid getting in a loop. 7765 Slog.w(TAG, " Force finishing activity " 7766 + r.intent.getComponent().flattenToShortString()); 7767 int index = mMainStack.indexOfActivityLocked(r); 7768 r.stack.finishActivityLocked(r, index, 7769 Activity.RESULT_CANCELED, null, "crashed"); 7770 // Also terminate any activities below it that aren't yet 7771 // stopped, to avoid a situation where one will get 7772 // re-start our crashing activity once it gets resumed again. 7773 index--; 7774 if (index >= 0) { 7775 r = (ActivityRecord)mMainStack.mHistory.get(index); 7776 if (r.state == ActivityState.RESUMED 7777 || r.state == ActivityState.PAUSING 7778 || r.state == ActivityState.PAUSED) { 7779 if (!r.isHomeActivity || mHomeProcess != r.app) { 7780 Slog.w(TAG, " Force finishing activity " 7781 + r.intent.getComponent().flattenToShortString()); 7782 r.stack.finishActivityLocked(r, index, 7783 Activity.RESULT_CANCELED, null, "crashed"); 7784 } 7785 } 7786 } 7787 } 7788 } 7789 7790 // Bump up the crash count of any services currently running in the proc. 7791 if (app.services.size() != 0) { 7792 // Any services running in the application need to be placed 7793 // back in the pending list. 7794 Iterator<ServiceRecord> it = app.services.iterator(); 7795 while (it.hasNext()) { 7796 ServiceRecord sr = it.next(); 7797 sr.crashCount++; 7798 } 7799 } 7800 7801 // If the crashing process is what we consider to be the "home process" and it has been 7802 // replaced by a third-party app, clear the package preferred activities from packages 7803 // with a home activity running in the process to prevent a repeatedly crashing app 7804 // from blocking the user to manually clear the list. 7805 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7806 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7807 Iterator it = mHomeProcess.activities.iterator(); 7808 while (it.hasNext()) { 7809 ActivityRecord r = (ActivityRecord)it.next(); 7810 if (r.isHomeActivity) { 7811 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7812 try { 7813 ActivityThread.getPackageManager() 7814 .clearPackagePreferredActivities(r.packageName); 7815 } catch (RemoteException c) { 7816 // pm is in same process, this will never happen. 7817 } 7818 } 7819 } 7820 } 7821 7822 if (!app.isolated) { 7823 // XXX Can't keep track of crash times for isolated processes, 7824 // because they don't have a perisistent identity. 7825 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7826 } 7827 7828 return true; 7829 } 7830 7831 void startAppProblemLocked(ProcessRecord app) { 7832 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7833 mContext, app.info.packageName, app.info.flags); 7834 skipCurrentReceiverLocked(app); 7835 } 7836 7837 void skipCurrentReceiverLocked(ProcessRecord app) { 7838 for (BroadcastQueue queue : mBroadcastQueues) { 7839 queue.skipCurrentReceiverLocked(app); 7840 } 7841 } 7842 7843 /** 7844 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7845 * The application process will exit immediately after this call returns. 7846 * @param app object of the crashing app, null for the system server 7847 * @param crashInfo describing the exception 7848 */ 7849 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7850 ProcessRecord r = findAppProcess(app, "Crash"); 7851 final String processName = app == null ? "system_server" 7852 : (r == null ? "unknown" : r.processName); 7853 7854 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7855 processName, 7856 r == null ? -1 : r.info.flags, 7857 crashInfo.exceptionClassName, 7858 crashInfo.exceptionMessage, 7859 crashInfo.throwFileName, 7860 crashInfo.throwLineNumber); 7861 7862 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7863 7864 crashApplication(r, crashInfo); 7865 } 7866 7867 public void handleApplicationStrictModeViolation( 7868 IBinder app, 7869 int violationMask, 7870 StrictMode.ViolationInfo info) { 7871 ProcessRecord r = findAppProcess(app, "StrictMode"); 7872 if (r == null) { 7873 return; 7874 } 7875 7876 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7877 Integer stackFingerprint = info.hashCode(); 7878 boolean logIt = true; 7879 synchronized (mAlreadyLoggedViolatedStacks) { 7880 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7881 logIt = false; 7882 // TODO: sub-sample into EventLog for these, with 7883 // the info.durationMillis? Then we'd get 7884 // the relative pain numbers, without logging all 7885 // the stack traces repeatedly. We'd want to do 7886 // likewise in the client code, which also does 7887 // dup suppression, before the Binder call. 7888 } else { 7889 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7890 mAlreadyLoggedViolatedStacks.clear(); 7891 } 7892 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7893 } 7894 } 7895 if (logIt) { 7896 logStrictModeViolationToDropBox(r, info); 7897 } 7898 } 7899 7900 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7901 AppErrorResult result = new AppErrorResult(); 7902 synchronized (this) { 7903 final long origId = Binder.clearCallingIdentity(); 7904 7905 Message msg = Message.obtain(); 7906 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7907 HashMap<String, Object> data = new HashMap<String, Object>(); 7908 data.put("result", result); 7909 data.put("app", r); 7910 data.put("violationMask", violationMask); 7911 data.put("info", info); 7912 msg.obj = data; 7913 mHandler.sendMessage(msg); 7914 7915 Binder.restoreCallingIdentity(origId); 7916 } 7917 int res = result.get(); 7918 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7919 } 7920 } 7921 7922 // Depending on the policy in effect, there could be a bunch of 7923 // these in quick succession so we try to batch these together to 7924 // minimize disk writes, number of dropbox entries, and maximize 7925 // compression, by having more fewer, larger records. 7926 private void logStrictModeViolationToDropBox( 7927 ProcessRecord process, 7928 StrictMode.ViolationInfo info) { 7929 if (info == null) { 7930 return; 7931 } 7932 final boolean isSystemApp = process == null || 7933 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7934 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7935 final String processName = process == null ? "unknown" : process.processName; 7936 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7937 final DropBoxManager dbox = (DropBoxManager) 7938 mContext.getSystemService(Context.DROPBOX_SERVICE); 7939 7940 // Exit early if the dropbox isn't configured to accept this report type. 7941 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7942 7943 boolean bufferWasEmpty; 7944 boolean needsFlush; 7945 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7946 synchronized (sb) { 7947 bufferWasEmpty = sb.length() == 0; 7948 appendDropBoxProcessHeaders(process, processName, sb); 7949 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7950 sb.append("System-App: ").append(isSystemApp).append("\n"); 7951 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7952 if (info.violationNumThisLoop != 0) { 7953 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7954 } 7955 if (info.numAnimationsRunning != 0) { 7956 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7957 } 7958 if (info.broadcastIntentAction != null) { 7959 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7960 } 7961 if (info.durationMillis != -1) { 7962 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7963 } 7964 if (info.numInstances != -1) { 7965 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7966 } 7967 if (info.tags != null) { 7968 for (String tag : info.tags) { 7969 sb.append("Span-Tag: ").append(tag).append("\n"); 7970 } 7971 } 7972 sb.append("\n"); 7973 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7974 sb.append(info.crashInfo.stackTrace); 7975 } 7976 sb.append("\n"); 7977 7978 // Only buffer up to ~64k. Various logging bits truncate 7979 // things at 128k. 7980 needsFlush = (sb.length() > 64 * 1024); 7981 } 7982 7983 // Flush immediately if the buffer's grown too large, or this 7984 // is a non-system app. Non-system apps are isolated with a 7985 // different tag & policy and not batched. 7986 // 7987 // Batching is useful during internal testing with 7988 // StrictMode settings turned up high. Without batching, 7989 // thousands of separate files could be created on boot. 7990 if (!isSystemApp || needsFlush) { 7991 new Thread("Error dump: " + dropboxTag) { 7992 @Override 7993 public void run() { 7994 String report; 7995 synchronized (sb) { 7996 report = sb.toString(); 7997 sb.delete(0, sb.length()); 7998 sb.trimToSize(); 7999 } 8000 if (report.length() != 0) { 8001 dbox.addText(dropboxTag, report); 8002 } 8003 } 8004 }.start(); 8005 return; 8006 } 8007 8008 // System app batching: 8009 if (!bufferWasEmpty) { 8010 // An existing dropbox-writing thread is outstanding, so 8011 // we don't need to start it up. The existing thread will 8012 // catch the buffer appends we just did. 8013 return; 8014 } 8015 8016 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8017 // (After this point, we shouldn't access AMS internal data structures.) 8018 new Thread("Error dump: " + dropboxTag) { 8019 @Override 8020 public void run() { 8021 // 5 second sleep to let stacks arrive and be batched together 8022 try { 8023 Thread.sleep(5000); // 5 seconds 8024 } catch (InterruptedException e) {} 8025 8026 String errorReport; 8027 synchronized (mStrictModeBuffer) { 8028 errorReport = mStrictModeBuffer.toString(); 8029 if (errorReport.length() == 0) { 8030 return; 8031 } 8032 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8033 mStrictModeBuffer.trimToSize(); 8034 } 8035 dbox.addText(dropboxTag, errorReport); 8036 } 8037 }.start(); 8038 } 8039 8040 /** 8041 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8042 * @param app object of the crashing app, null for the system server 8043 * @param tag reported by the caller 8044 * @param crashInfo describing the context of the error 8045 * @return true if the process should exit immediately (WTF is fatal) 8046 */ 8047 public boolean handleApplicationWtf(IBinder app, String tag, 8048 ApplicationErrorReport.CrashInfo crashInfo) { 8049 ProcessRecord r = findAppProcess(app, "WTF"); 8050 final String processName = app == null ? "system_server" 8051 : (r == null ? "unknown" : r.processName); 8052 8053 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8054 processName, 8055 r == null ? -1 : r.info.flags, 8056 tag, crashInfo.exceptionMessage); 8057 8058 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8059 8060 if (r != null && r.pid != Process.myPid() && 8061 Settings.Secure.getInt(mContext.getContentResolver(), 8062 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8063 crashApplication(r, crashInfo); 8064 return true; 8065 } else { 8066 return false; 8067 } 8068 } 8069 8070 /** 8071 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8072 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8073 */ 8074 private ProcessRecord findAppProcess(IBinder app, String reason) { 8075 if (app == null) { 8076 return null; 8077 } 8078 8079 synchronized (this) { 8080 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8081 final int NA = apps.size(); 8082 for (int ia=0; ia<NA; ia++) { 8083 ProcessRecord p = apps.valueAt(ia); 8084 if (p.thread != null && p.thread.asBinder() == app) { 8085 return p; 8086 } 8087 } 8088 } 8089 8090 Slog.w(TAG, "Can't find mystery application for " + reason 8091 + " from pid=" + Binder.getCallingPid() 8092 + " uid=" + Binder.getCallingUid() + ": " + app); 8093 return null; 8094 } 8095 } 8096 8097 /** 8098 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8099 * to append various headers to the dropbox log text. 8100 */ 8101 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8102 StringBuilder sb) { 8103 // Watchdog thread ends up invoking this function (with 8104 // a null ProcessRecord) to add the stack file to dropbox. 8105 // Do not acquire a lock on this (am) in such cases, as it 8106 // could cause a potential deadlock, if and when watchdog 8107 // is invoked due to unavailability of lock on am and it 8108 // would prevent watchdog from killing system_server. 8109 if (process == null) { 8110 sb.append("Process: ").append(processName).append("\n"); 8111 return; 8112 } 8113 // Note: ProcessRecord 'process' is guarded by the service 8114 // instance. (notably process.pkgList, which could otherwise change 8115 // concurrently during execution of this method) 8116 synchronized (this) { 8117 sb.append("Process: ").append(processName).append("\n"); 8118 int flags = process.info.flags; 8119 IPackageManager pm = AppGlobals.getPackageManager(); 8120 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8121 for (String pkg : process.pkgList) { 8122 sb.append("Package: ").append(pkg); 8123 try { 8124 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8125 if (pi != null) { 8126 sb.append(" v").append(pi.versionCode); 8127 if (pi.versionName != null) { 8128 sb.append(" (").append(pi.versionName).append(")"); 8129 } 8130 } 8131 } catch (RemoteException e) { 8132 Slog.e(TAG, "Error getting package info: " + pkg, e); 8133 } 8134 sb.append("\n"); 8135 } 8136 } 8137 } 8138 8139 private static String processClass(ProcessRecord process) { 8140 if (process == null || process.pid == MY_PID) { 8141 return "system_server"; 8142 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8143 return "system_app"; 8144 } else { 8145 return "data_app"; 8146 } 8147 } 8148 8149 /** 8150 * Write a description of an error (crash, WTF, ANR) to the drop box. 8151 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8152 * @param process which caused the error, null means the system server 8153 * @param activity which triggered the error, null if unknown 8154 * @param parent activity related to the error, null if unknown 8155 * @param subject line related to the error, null if absent 8156 * @param report in long form describing the error, null if absent 8157 * @param logFile to include in the report, null if none 8158 * @param crashInfo giving an application stack trace, null if absent 8159 */ 8160 public void addErrorToDropBox(String eventType, 8161 ProcessRecord process, String processName, ActivityRecord activity, 8162 ActivityRecord parent, String subject, 8163 final String report, final File logFile, 8164 final ApplicationErrorReport.CrashInfo crashInfo) { 8165 // NOTE -- this must never acquire the ActivityManagerService lock, 8166 // otherwise the watchdog may be prevented from resetting the system. 8167 8168 final String dropboxTag = processClass(process) + "_" + eventType; 8169 final DropBoxManager dbox = (DropBoxManager) 8170 mContext.getSystemService(Context.DROPBOX_SERVICE); 8171 8172 // Exit early if the dropbox isn't configured to accept this report type. 8173 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8174 8175 final StringBuilder sb = new StringBuilder(1024); 8176 appendDropBoxProcessHeaders(process, processName, sb); 8177 if (activity != null) { 8178 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8179 } 8180 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8181 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8182 } 8183 if (parent != null && parent != activity) { 8184 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8185 } 8186 if (subject != null) { 8187 sb.append("Subject: ").append(subject).append("\n"); 8188 } 8189 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8190 if (Debug.isDebuggerConnected()) { 8191 sb.append("Debugger: Connected\n"); 8192 } 8193 sb.append("\n"); 8194 8195 // Do the rest in a worker thread to avoid blocking the caller on I/O 8196 // (After this point, we shouldn't access AMS internal data structures.) 8197 Thread worker = new Thread("Error dump: " + dropboxTag) { 8198 @Override 8199 public void run() { 8200 if (report != null) { 8201 sb.append(report); 8202 } 8203 if (logFile != null) { 8204 try { 8205 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8206 } catch (IOException e) { 8207 Slog.e(TAG, "Error reading " + logFile, e); 8208 } 8209 } 8210 if (crashInfo != null && crashInfo.stackTrace != null) { 8211 sb.append(crashInfo.stackTrace); 8212 } 8213 8214 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8215 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8216 if (lines > 0) { 8217 sb.append("\n"); 8218 8219 // Merge several logcat streams, and take the last N lines 8220 InputStreamReader input = null; 8221 try { 8222 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8223 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8224 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8225 8226 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8227 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8228 input = new InputStreamReader(logcat.getInputStream()); 8229 8230 int num; 8231 char[] buf = new char[8192]; 8232 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8233 } catch (IOException e) { 8234 Slog.e(TAG, "Error running logcat", e); 8235 } finally { 8236 if (input != null) try { input.close(); } catch (IOException e) {} 8237 } 8238 } 8239 8240 dbox.addText(dropboxTag, sb.toString()); 8241 } 8242 }; 8243 8244 if (process == null) { 8245 // If process is null, we are being called from some internal code 8246 // and may be about to die -- run this synchronously. 8247 worker.run(); 8248 } else { 8249 worker.start(); 8250 } 8251 } 8252 8253 /** 8254 * Bring up the "unexpected error" dialog box for a crashing app. 8255 * Deal with edge cases (intercepts from instrumented applications, 8256 * ActivityController, error intent receivers, that sort of thing). 8257 * @param r the application crashing 8258 * @param crashInfo describing the failure 8259 */ 8260 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8261 long timeMillis = System.currentTimeMillis(); 8262 String shortMsg = crashInfo.exceptionClassName; 8263 String longMsg = crashInfo.exceptionMessage; 8264 String stackTrace = crashInfo.stackTrace; 8265 if (shortMsg != null && longMsg != null) { 8266 longMsg = shortMsg + ": " + longMsg; 8267 } else if (shortMsg != null) { 8268 longMsg = shortMsg; 8269 } 8270 8271 AppErrorResult result = new AppErrorResult(); 8272 synchronized (this) { 8273 if (mController != null) { 8274 try { 8275 String name = r != null ? r.processName : null; 8276 int pid = r != null ? r.pid : Binder.getCallingPid(); 8277 if (!mController.appCrashed(name, pid, 8278 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8279 Slog.w(TAG, "Force-killing crashed app " + name 8280 + " at watcher's request"); 8281 Process.killProcess(pid); 8282 return; 8283 } 8284 } catch (RemoteException e) { 8285 mController = null; 8286 } 8287 } 8288 8289 final long origId = Binder.clearCallingIdentity(); 8290 8291 // If this process is running instrumentation, finish it. 8292 if (r != null && r.instrumentationClass != null) { 8293 Slog.w(TAG, "Error in app " + r.processName 8294 + " running instrumentation " + r.instrumentationClass + ":"); 8295 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8296 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8297 Bundle info = new Bundle(); 8298 info.putString("shortMsg", shortMsg); 8299 info.putString("longMsg", longMsg); 8300 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8301 Binder.restoreCallingIdentity(origId); 8302 return; 8303 } 8304 8305 // If we can't identify the process or it's already exceeded its crash quota, 8306 // quit right away without showing a crash dialog. 8307 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8308 Binder.restoreCallingIdentity(origId); 8309 return; 8310 } 8311 8312 Message msg = Message.obtain(); 8313 msg.what = SHOW_ERROR_MSG; 8314 HashMap data = new HashMap(); 8315 data.put("result", result); 8316 data.put("app", r); 8317 msg.obj = data; 8318 mHandler.sendMessage(msg); 8319 8320 Binder.restoreCallingIdentity(origId); 8321 } 8322 8323 int res = result.get(); 8324 8325 Intent appErrorIntent = null; 8326 synchronized (this) { 8327 if (r != null && !r.isolated) { 8328 // XXX Can't keep track of crash time for isolated processes, 8329 // since they don't have a persistent identity. 8330 mProcessCrashTimes.put(r.info.processName, r.uid, 8331 SystemClock.uptimeMillis()); 8332 } 8333 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8334 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8335 } 8336 } 8337 8338 if (appErrorIntent != null) { 8339 try { 8340 mContext.startActivity(appErrorIntent); 8341 } catch (ActivityNotFoundException e) { 8342 Slog.w(TAG, "bug report receiver dissappeared", e); 8343 } 8344 } 8345 } 8346 8347 Intent createAppErrorIntentLocked(ProcessRecord r, 8348 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8349 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8350 if (report == null) { 8351 return null; 8352 } 8353 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8354 result.setComponent(r.errorReportReceiver); 8355 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8356 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8357 return result; 8358 } 8359 8360 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8361 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8362 if (r.errorReportReceiver == null) { 8363 return null; 8364 } 8365 8366 if (!r.crashing && !r.notResponding) { 8367 return null; 8368 } 8369 8370 ApplicationErrorReport report = new ApplicationErrorReport(); 8371 report.packageName = r.info.packageName; 8372 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8373 report.processName = r.processName; 8374 report.time = timeMillis; 8375 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8376 8377 if (r.crashing) { 8378 report.type = ApplicationErrorReport.TYPE_CRASH; 8379 report.crashInfo = crashInfo; 8380 } else if (r.notResponding) { 8381 report.type = ApplicationErrorReport.TYPE_ANR; 8382 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8383 8384 report.anrInfo.activity = r.notRespondingReport.tag; 8385 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8386 report.anrInfo.info = r.notRespondingReport.longMsg; 8387 } 8388 8389 return report; 8390 } 8391 8392 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8393 enforceNotIsolatedCaller("getProcessesInErrorState"); 8394 // assume our apps are happy - lazy create the list 8395 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8396 8397 final boolean allUsers = ActivityManager.checkUidPermission( 8398 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8399 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8400 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8401 8402 synchronized (this) { 8403 8404 // iterate across all processes 8405 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8406 ProcessRecord app = mLruProcesses.get(i); 8407 if (!allUsers && app.userId != userId) { 8408 continue; 8409 } 8410 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8411 // This one's in trouble, so we'll generate a report for it 8412 // crashes are higher priority (in case there's a crash *and* an anr) 8413 ActivityManager.ProcessErrorStateInfo report = null; 8414 if (app.crashing) { 8415 report = app.crashingReport; 8416 } else if (app.notResponding) { 8417 report = app.notRespondingReport; 8418 } 8419 8420 if (report != null) { 8421 if (errList == null) { 8422 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8423 } 8424 errList.add(report); 8425 } else { 8426 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8427 " crashing = " + app.crashing + 8428 " notResponding = " + app.notResponding); 8429 } 8430 } 8431 } 8432 } 8433 8434 return errList; 8435 } 8436 8437 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8438 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8439 if (currApp != null) { 8440 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8441 } 8442 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8443 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8444 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8445 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8446 if (currApp != null) { 8447 currApp.lru = 0; 8448 } 8449 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8450 } else if (adj >= ProcessList.SERVICE_ADJ) { 8451 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8452 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8453 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8454 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8455 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8456 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8457 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8458 } else { 8459 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8460 } 8461 } 8462 8463 private void fillInProcMemInfo(ProcessRecord app, 8464 ActivityManager.RunningAppProcessInfo outInfo) { 8465 outInfo.pid = app.pid; 8466 outInfo.uid = app.info.uid; 8467 if (mHeavyWeightProcess == app) { 8468 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8469 } 8470 if (app.persistent) { 8471 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8472 } 8473 if (app.hasActivities) { 8474 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8475 } 8476 outInfo.lastTrimLevel = app.trimMemoryLevel; 8477 int adj = app.curAdj; 8478 outInfo.importance = oomAdjToImportance(adj, outInfo); 8479 outInfo.importanceReasonCode = app.adjTypeCode; 8480 } 8481 8482 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8483 enforceNotIsolatedCaller("getRunningAppProcesses"); 8484 // Lazy instantiation of list 8485 List<ActivityManager.RunningAppProcessInfo> runList = null; 8486 final boolean allUsers = ActivityManager.checkUidPermission( 8487 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8488 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8489 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8490 synchronized (this) { 8491 // Iterate across all processes 8492 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8493 ProcessRecord app = mLruProcesses.get(i); 8494 if (!allUsers && app.userId != userId) { 8495 continue; 8496 } 8497 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8498 // Generate process state info for running application 8499 ActivityManager.RunningAppProcessInfo currApp = 8500 new ActivityManager.RunningAppProcessInfo(app.processName, 8501 app.pid, app.getPackageList()); 8502 fillInProcMemInfo(app, currApp); 8503 if (app.adjSource instanceof ProcessRecord) { 8504 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8505 currApp.importanceReasonImportance = oomAdjToImportance( 8506 app.adjSourceOom, null); 8507 } else if (app.adjSource instanceof ActivityRecord) { 8508 ActivityRecord r = (ActivityRecord)app.adjSource; 8509 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8510 } 8511 if (app.adjTarget instanceof ComponentName) { 8512 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8513 } 8514 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8515 // + " lru=" + currApp.lru); 8516 if (runList == null) { 8517 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8518 } 8519 runList.add(currApp); 8520 } 8521 } 8522 } 8523 return runList; 8524 } 8525 8526 public List<ApplicationInfo> getRunningExternalApplications() { 8527 enforceNotIsolatedCaller("getRunningExternalApplications"); 8528 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8529 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8530 if (runningApps != null && runningApps.size() > 0) { 8531 Set<String> extList = new HashSet<String>(); 8532 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8533 if (app.pkgList != null) { 8534 for (String pkg : app.pkgList) { 8535 extList.add(pkg); 8536 } 8537 } 8538 } 8539 IPackageManager pm = AppGlobals.getPackageManager(); 8540 for (String pkg : extList) { 8541 try { 8542 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8543 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8544 retList.add(info); 8545 } 8546 } catch (RemoteException e) { 8547 } 8548 } 8549 } 8550 return retList; 8551 } 8552 8553 @Override 8554 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8555 enforceNotIsolatedCaller("getMyMemoryState"); 8556 synchronized (this) { 8557 ProcessRecord proc; 8558 synchronized (mPidsSelfLocked) { 8559 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8560 } 8561 fillInProcMemInfo(proc, outInfo); 8562 } 8563 } 8564 8565 @Override 8566 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8567 if (checkCallingPermission(android.Manifest.permission.DUMP) 8568 != PackageManager.PERMISSION_GRANTED) { 8569 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8570 + Binder.getCallingPid() 8571 + ", uid=" + Binder.getCallingUid() 8572 + " without permission " 8573 + android.Manifest.permission.DUMP); 8574 return; 8575 } 8576 8577 boolean dumpAll = false; 8578 boolean dumpClient = false; 8579 String dumpPackage = null; 8580 8581 int opti = 0; 8582 while (opti < args.length) { 8583 String opt = args[opti]; 8584 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8585 break; 8586 } 8587 opti++; 8588 if ("-a".equals(opt)) { 8589 dumpAll = true; 8590 } else if ("-c".equals(opt)) { 8591 dumpClient = true; 8592 } else if ("-h".equals(opt)) { 8593 pw.println("Activity manager dump options:"); 8594 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8595 pw.println(" cmd may be one of:"); 8596 pw.println(" a[ctivities]: activity stack state"); 8597 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8598 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8599 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8600 pw.println(" o[om]: out of memory management"); 8601 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8602 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8603 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8604 pw.println(" service [COMP_SPEC]: service client-side state"); 8605 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8606 pw.println(" all: dump all activities"); 8607 pw.println(" top: dump the top activity"); 8608 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8609 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8610 pw.println(" a partial substring in a component name, a"); 8611 pw.println(" hex object identifier."); 8612 pw.println(" -a: include all available server state."); 8613 pw.println(" -c: include client state."); 8614 return; 8615 } else { 8616 pw.println("Unknown argument: " + opt + "; use -h for help"); 8617 } 8618 } 8619 8620 long origId = Binder.clearCallingIdentity(); 8621 boolean more = false; 8622 // Is the caller requesting to dump a particular piece of data? 8623 if (opti < args.length) { 8624 String cmd = args[opti]; 8625 opti++; 8626 if ("activities".equals(cmd) || "a".equals(cmd)) { 8627 synchronized (this) { 8628 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8629 } 8630 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8631 String[] newArgs; 8632 String name; 8633 if (opti >= args.length) { 8634 name = null; 8635 newArgs = EMPTY_STRING_ARRAY; 8636 } else { 8637 name = args[opti]; 8638 opti++; 8639 newArgs = new String[args.length - opti]; 8640 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8641 args.length - opti); 8642 } 8643 synchronized (this) { 8644 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8645 } 8646 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8647 String[] newArgs; 8648 String name; 8649 if (opti >= args.length) { 8650 name = null; 8651 newArgs = EMPTY_STRING_ARRAY; 8652 } else { 8653 name = args[opti]; 8654 opti++; 8655 newArgs = new String[args.length - opti]; 8656 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8657 args.length - opti); 8658 } 8659 synchronized (this) { 8660 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8661 } 8662 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8663 String[] newArgs; 8664 String name; 8665 if (opti >= args.length) { 8666 name = null; 8667 newArgs = EMPTY_STRING_ARRAY; 8668 } else { 8669 name = args[opti]; 8670 opti++; 8671 newArgs = new String[args.length - opti]; 8672 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8673 args.length - opti); 8674 } 8675 synchronized (this) { 8676 dumpProcessesLocked(fd, pw, args, opti, true, name); 8677 } 8678 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8679 synchronized (this) { 8680 dumpOomLocked(fd, pw, args, opti, true); 8681 } 8682 } else if ("provider".equals(cmd)) { 8683 String[] newArgs; 8684 String name; 8685 if (opti >= args.length) { 8686 name = null; 8687 newArgs = EMPTY_STRING_ARRAY; 8688 } else { 8689 name = args[opti]; 8690 opti++; 8691 newArgs = new String[args.length - opti]; 8692 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8693 } 8694 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8695 pw.println("No providers match: " + name); 8696 pw.println("Use -h for help."); 8697 } 8698 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8699 synchronized (this) { 8700 dumpProvidersLocked(fd, pw, args, opti, true, null); 8701 } 8702 } else if ("service".equals(cmd)) { 8703 String[] newArgs; 8704 String name; 8705 if (opti >= args.length) { 8706 name = null; 8707 newArgs = EMPTY_STRING_ARRAY; 8708 } else { 8709 name = args[opti]; 8710 opti++; 8711 newArgs = new String[args.length - opti]; 8712 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8713 args.length - opti); 8714 } 8715 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8716 pw.println("No services match: " + name); 8717 pw.println("Use -h for help."); 8718 } 8719 } else if ("package".equals(cmd)) { 8720 String[] newArgs; 8721 if (opti >= args.length) { 8722 pw.println("package: no package name specified"); 8723 pw.println("Use -h for help."); 8724 } else { 8725 dumpPackage = args[opti]; 8726 opti++; 8727 newArgs = new String[args.length - opti]; 8728 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8729 args.length - opti); 8730 args = newArgs; 8731 opti = 0; 8732 more = true; 8733 } 8734 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8735 synchronized (this) { 8736 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8737 } 8738 } else { 8739 // Dumping a single activity? 8740 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8741 pw.println("Bad activity command, or no activities match: " + cmd); 8742 pw.println("Use -h for help."); 8743 } 8744 } 8745 if (!more) { 8746 Binder.restoreCallingIdentity(origId); 8747 return; 8748 } 8749 } 8750 8751 // No piece of data specified, dump everything. 8752 synchronized (this) { 8753 boolean needSep; 8754 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8755 if (needSep) { 8756 pw.println(" "); 8757 } 8758 if (dumpAll) { 8759 pw.println("-------------------------------------------------------------------------------"); 8760 } 8761 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8762 if (needSep) { 8763 pw.println(" "); 8764 } 8765 if (dumpAll) { 8766 pw.println("-------------------------------------------------------------------------------"); 8767 } 8768 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8769 if (needSep) { 8770 pw.println(" "); 8771 } 8772 if (dumpAll) { 8773 pw.println("-------------------------------------------------------------------------------"); 8774 } 8775 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8776 if (needSep) { 8777 pw.println(" "); 8778 } 8779 if (dumpAll) { 8780 pw.println("-------------------------------------------------------------------------------"); 8781 } 8782 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8783 if (needSep) { 8784 pw.println(" "); 8785 } 8786 if (dumpAll) { 8787 pw.println("-------------------------------------------------------------------------------"); 8788 } 8789 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8790 } 8791 Binder.restoreCallingIdentity(origId); 8792 } 8793 8794 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8795 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8796 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8797 pw.println(" Main stack:"); 8798 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8799 dumpPackage); 8800 pw.println(" "); 8801 pw.println(" Running activities (most recent first):"); 8802 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8803 dumpPackage); 8804 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8805 pw.println(" "); 8806 pw.println(" Activities waiting for another to become visible:"); 8807 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8808 !dumpAll, false, dumpPackage); 8809 } 8810 if (mMainStack.mStoppingActivities.size() > 0) { 8811 pw.println(" "); 8812 pw.println(" Activities waiting to stop:"); 8813 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8814 !dumpAll, false, dumpPackage); 8815 } 8816 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8817 pw.println(" "); 8818 pw.println(" Activities waiting to sleep:"); 8819 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8820 !dumpAll, false, dumpPackage); 8821 } 8822 if (mMainStack.mFinishingActivities.size() > 0) { 8823 pw.println(" "); 8824 pw.println(" Activities waiting to finish:"); 8825 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8826 !dumpAll, false, dumpPackage); 8827 } 8828 8829 pw.println(" "); 8830 if (mMainStack.mPausingActivity != null) { 8831 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8832 } 8833 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8834 pw.println(" mFocusedActivity: " + mFocusedActivity); 8835 if (dumpAll) { 8836 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8837 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8838 pw.println(" mDismissKeyguardOnNextActivity: " 8839 + mMainStack.mDismissKeyguardOnNextActivity); 8840 } 8841 8842 if (mRecentTasks.size() > 0) { 8843 pw.println(); 8844 pw.println(" Recent tasks:"); 8845 8846 final int N = mRecentTasks.size(); 8847 for (int i=0; i<N; i++) { 8848 TaskRecord tr = mRecentTasks.get(i); 8849 if (dumpPackage != null) { 8850 if (tr.realActivity == null || 8851 !dumpPackage.equals(tr.realActivity)) { 8852 continue; 8853 } 8854 } 8855 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8856 pw.println(tr); 8857 if (dumpAll) { 8858 mRecentTasks.get(i).dump(pw, " "); 8859 } 8860 } 8861 } 8862 8863 if (dumpAll) { 8864 pw.println(" "); 8865 pw.println(" mCurTask: " + mCurTask); 8866 } 8867 8868 return true; 8869 } 8870 8871 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8872 int opti, boolean dumpAll, String dumpPackage) { 8873 boolean needSep = false; 8874 int numPers = 0; 8875 8876 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8877 8878 if (dumpAll) { 8879 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8880 final int NA = procs.size(); 8881 for (int ia=0; ia<NA; ia++) { 8882 ProcessRecord r = procs.valueAt(ia); 8883 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8884 continue; 8885 } 8886 if (!needSep) { 8887 pw.println(" All known processes:"); 8888 needSep = true; 8889 } 8890 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8891 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8892 pw.print(" "); pw.println(r); 8893 r.dump(pw, " "); 8894 if (r.persistent) { 8895 numPers++; 8896 } 8897 } 8898 } 8899 } 8900 8901 if (mIsolatedProcesses.size() > 0) { 8902 if (needSep) pw.println(" "); 8903 needSep = true; 8904 pw.println(" Isolated process list (sorted by uid):"); 8905 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8906 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8907 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8908 continue; 8909 } 8910 pw.println(String.format("%sIsolated #%2d: %s", 8911 " ", i, r.toString())); 8912 } 8913 } 8914 8915 if (mLruProcesses.size() > 0) { 8916 if (needSep) pw.println(" "); 8917 needSep = true; 8918 pw.println(" Process LRU list (sorted by oom_adj):"); 8919 dumpProcessOomList(pw, this, mLruProcesses, " ", 8920 "Proc", "PERS", false, dumpPackage); 8921 needSep = true; 8922 } 8923 8924 if (dumpAll) { 8925 synchronized (mPidsSelfLocked) { 8926 boolean printed = false; 8927 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8928 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8929 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8930 continue; 8931 } 8932 if (!printed) { 8933 if (needSep) pw.println(" "); 8934 needSep = true; 8935 pw.println(" PID mappings:"); 8936 printed = true; 8937 } 8938 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8939 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8940 } 8941 } 8942 } 8943 8944 if (mForegroundProcesses.size() > 0) { 8945 synchronized (mPidsSelfLocked) { 8946 boolean printed = false; 8947 for (int i=0; i<mForegroundProcesses.size(); i++) { 8948 ProcessRecord r = mPidsSelfLocked.get( 8949 mForegroundProcesses.valueAt(i).pid); 8950 if (dumpPackage != null && (r == null 8951 || !dumpPackage.equals(r.info.packageName))) { 8952 continue; 8953 } 8954 if (!printed) { 8955 if (needSep) pw.println(" "); 8956 needSep = true; 8957 pw.println(" Foreground Processes:"); 8958 printed = true; 8959 } 8960 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8961 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8962 } 8963 } 8964 } 8965 8966 if (mPersistentStartingProcesses.size() > 0) { 8967 if (needSep) pw.println(" "); 8968 needSep = true; 8969 pw.println(" Persisent processes that are starting:"); 8970 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8971 "Starting Norm", "Restarting PERS", dumpPackage); 8972 } 8973 8974 if (mRemovedProcesses.size() > 0) { 8975 if (needSep) pw.println(" "); 8976 needSep = true; 8977 pw.println(" Processes that are being removed:"); 8978 dumpProcessList(pw, this, mRemovedProcesses, " ", 8979 "Removed Norm", "Removed PERS", dumpPackage); 8980 } 8981 8982 if (mProcessesOnHold.size() > 0) { 8983 if (needSep) pw.println(" "); 8984 needSep = true; 8985 pw.println(" Processes that are on old until the system is ready:"); 8986 dumpProcessList(pw, this, mProcessesOnHold, " ", 8987 "OnHold Norm", "OnHold PERS", dumpPackage); 8988 } 8989 8990 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8991 8992 if (mProcessCrashTimes.getMap().size() > 0) { 8993 boolean printed = false; 8994 long now = SystemClock.uptimeMillis(); 8995 for (Map.Entry<String, SparseArray<Long>> procs 8996 : mProcessCrashTimes.getMap().entrySet()) { 8997 String pname = procs.getKey(); 8998 SparseArray<Long> uids = procs.getValue(); 8999 final int N = uids.size(); 9000 for (int i=0; i<N; i++) { 9001 int puid = uids.keyAt(i); 9002 ProcessRecord r = mProcessNames.get(pname, puid); 9003 if (dumpPackage != null && (r == null 9004 || !dumpPackage.equals(r.info.packageName))) { 9005 continue; 9006 } 9007 if (!printed) { 9008 if (needSep) pw.println(" "); 9009 needSep = true; 9010 pw.println(" Time since processes crashed:"); 9011 printed = true; 9012 } 9013 pw.print(" Process "); pw.print(pname); 9014 pw.print(" uid "); pw.print(puid); 9015 pw.print(": last crashed "); 9016 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9017 pw.println(" ago"); 9018 } 9019 } 9020 } 9021 9022 if (mBadProcesses.getMap().size() > 0) { 9023 boolean printed = false; 9024 for (Map.Entry<String, SparseArray<Long>> procs 9025 : mBadProcesses.getMap().entrySet()) { 9026 String pname = procs.getKey(); 9027 SparseArray<Long> uids = procs.getValue(); 9028 final int N = uids.size(); 9029 for (int i=0; i<N; i++) { 9030 int puid = uids.keyAt(i); 9031 ProcessRecord r = mProcessNames.get(pname, puid); 9032 if (dumpPackage != null && (r == null 9033 || !dumpPackage.equals(r.info.packageName))) { 9034 continue; 9035 } 9036 if (!printed) { 9037 if (needSep) pw.println(" "); 9038 needSep = true; 9039 pw.println(" Bad processes:"); 9040 } 9041 pw.print(" Bad process "); pw.print(pname); 9042 pw.print(" uid "); pw.print(puid); 9043 pw.print(": crashed at time "); 9044 pw.println(uids.valueAt(i)); 9045 } 9046 } 9047 } 9048 9049 pw.println(); 9050 pw.println(" mHomeProcess: " + mHomeProcess); 9051 pw.println(" mPreviousProcess: " + mPreviousProcess); 9052 if (dumpAll) { 9053 StringBuilder sb = new StringBuilder(128); 9054 sb.append(" mPreviousProcessVisibleTime: "); 9055 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9056 pw.println(sb); 9057 } 9058 if (mHeavyWeightProcess != null) { 9059 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9060 } 9061 pw.println(" mConfiguration: " + mConfiguration); 9062 if (dumpAll) { 9063 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9064 if (mCompatModePackages.getPackages().size() > 0) { 9065 boolean printed = false; 9066 for (Map.Entry<String, Integer> entry 9067 : mCompatModePackages.getPackages().entrySet()) { 9068 String pkg = entry.getKey(); 9069 int mode = entry.getValue(); 9070 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9071 continue; 9072 } 9073 if (!printed) { 9074 pw.println(" mScreenCompatPackages:"); 9075 printed = true; 9076 } 9077 pw.print(" "); pw.print(pkg); pw.print(": "); 9078 pw.print(mode); pw.println(); 9079 } 9080 } 9081 } 9082 if (mSleeping || mWentToSleep || mLockScreenShown) { 9083 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9084 + " mLockScreenShown " + mLockScreenShown); 9085 } 9086 if (mShuttingDown) { 9087 pw.println(" mShuttingDown=" + mShuttingDown); 9088 } 9089 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9090 || mOrigWaitForDebugger) { 9091 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9092 + " mDebugTransient=" + mDebugTransient 9093 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9094 } 9095 if (mOpenGlTraceApp != null) { 9096 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9097 } 9098 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9099 || mProfileFd != null) { 9100 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9101 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9102 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9103 + mAutoStopProfiler); 9104 } 9105 if (mAlwaysFinishActivities || mController != null) { 9106 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9107 + " mController=" + mController); 9108 } 9109 if (dumpAll) { 9110 pw.println(" Total persistent processes: " + numPers); 9111 pw.println(" mStartRunning=" + mStartRunning 9112 + " mProcessesReady=" + mProcessesReady 9113 + " mSystemReady=" + mSystemReady); 9114 pw.println(" mBooting=" + mBooting 9115 + " mBooted=" + mBooted 9116 + " mFactoryTest=" + mFactoryTest); 9117 pw.print(" mLastPowerCheckRealtime="); 9118 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9119 pw.println(""); 9120 pw.print(" mLastPowerCheckUptime="); 9121 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9122 pw.println(""); 9123 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9124 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9125 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9126 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9127 + " mNumHiddenProcs=" + mNumHiddenProcs 9128 + " mNumServiceProcs=" + mNumServiceProcs 9129 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9130 } 9131 9132 return true; 9133 } 9134 9135 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9136 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9137 if (mProcessesToGc.size() > 0) { 9138 boolean printed = false; 9139 long now = SystemClock.uptimeMillis(); 9140 for (int i=0; i<mProcessesToGc.size(); i++) { 9141 ProcessRecord proc = mProcessesToGc.get(i); 9142 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9143 continue; 9144 } 9145 if (!printed) { 9146 if (needSep) pw.println(" "); 9147 needSep = true; 9148 pw.println(" Processes that are waiting to GC:"); 9149 printed = true; 9150 } 9151 pw.print(" Process "); pw.println(proc); 9152 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9153 pw.print(", last gced="); 9154 pw.print(now-proc.lastRequestedGc); 9155 pw.print(" ms ago, last lowMem="); 9156 pw.print(now-proc.lastLowMemory); 9157 pw.println(" ms ago"); 9158 9159 } 9160 } 9161 return needSep; 9162 } 9163 9164 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9165 int opti, boolean dumpAll) { 9166 boolean needSep = false; 9167 9168 if (mLruProcesses.size() > 0) { 9169 if (needSep) pw.println(" "); 9170 needSep = true; 9171 pw.println(" OOM levels:"); 9172 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9173 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9174 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9175 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9176 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9177 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9178 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9179 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9180 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9181 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9182 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9183 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9184 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9185 9186 if (needSep) pw.println(" "); 9187 needSep = true; 9188 pw.println(" Process OOM control:"); 9189 dumpProcessOomList(pw, this, mLruProcesses, " ", 9190 "Proc", "PERS", true, null); 9191 needSep = true; 9192 } 9193 9194 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9195 9196 pw.println(); 9197 pw.println(" mHomeProcess: " + mHomeProcess); 9198 pw.println(" mPreviousProcess: " + mPreviousProcess); 9199 if (mHeavyWeightProcess != null) { 9200 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9201 } 9202 9203 return true; 9204 } 9205 9206 /** 9207 * There are three ways to call this: 9208 * - no provider specified: dump all the providers 9209 * - a flattened component name that matched an existing provider was specified as the 9210 * first arg: dump that one provider 9211 * - the first arg isn't the flattened component name of an existing provider: 9212 * dump all providers whose component contains the first arg as a substring 9213 */ 9214 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9215 int opti, boolean dumpAll) { 9216 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9217 } 9218 9219 static class ItemMatcher { 9220 ArrayList<ComponentName> components; 9221 ArrayList<String> strings; 9222 ArrayList<Integer> objects; 9223 boolean all; 9224 9225 ItemMatcher() { 9226 all = true; 9227 } 9228 9229 void build(String name) { 9230 ComponentName componentName = ComponentName.unflattenFromString(name); 9231 if (componentName != null) { 9232 if (components == null) { 9233 components = new ArrayList<ComponentName>(); 9234 } 9235 components.add(componentName); 9236 all = false; 9237 } else { 9238 int objectId = 0; 9239 // Not a '/' separated full component name; maybe an object ID? 9240 try { 9241 objectId = Integer.parseInt(name, 16); 9242 if (objects == null) { 9243 objects = new ArrayList<Integer>(); 9244 } 9245 objects.add(objectId); 9246 all = false; 9247 } catch (RuntimeException e) { 9248 // Not an integer; just do string match. 9249 if (strings == null) { 9250 strings = new ArrayList<String>(); 9251 } 9252 strings.add(name); 9253 all = false; 9254 } 9255 } 9256 } 9257 9258 int build(String[] args, int opti) { 9259 for (; opti<args.length; opti++) { 9260 String name = args[opti]; 9261 if ("--".equals(name)) { 9262 return opti+1; 9263 } 9264 build(name); 9265 } 9266 return opti; 9267 } 9268 9269 boolean match(Object object, ComponentName comp) { 9270 if (all) { 9271 return true; 9272 } 9273 if (components != null) { 9274 for (int i=0; i<components.size(); i++) { 9275 if (components.get(i).equals(comp)) { 9276 return true; 9277 } 9278 } 9279 } 9280 if (objects != null) { 9281 for (int i=0; i<objects.size(); i++) { 9282 if (System.identityHashCode(object) == objects.get(i)) { 9283 return true; 9284 } 9285 } 9286 } 9287 if (strings != null) { 9288 String flat = comp.flattenToString(); 9289 for (int i=0; i<strings.size(); i++) { 9290 if (flat.contains(strings.get(i))) { 9291 return true; 9292 } 9293 } 9294 } 9295 return false; 9296 } 9297 } 9298 9299 /** 9300 * There are three things that cmd can be: 9301 * - a flattened component name that matches an existing activity 9302 * - the cmd arg isn't the flattened component name of an existing activity: 9303 * dump all activity whose component contains the cmd as a substring 9304 * - A hex number of the ActivityRecord object instance. 9305 */ 9306 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9307 int opti, boolean dumpAll) { 9308 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9309 9310 if ("all".equals(name)) { 9311 synchronized (this) { 9312 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9313 activities.add(r1); 9314 } 9315 } 9316 } else if ("top".equals(name)) { 9317 synchronized (this) { 9318 final int N = mMainStack.mHistory.size(); 9319 if (N > 0) { 9320 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9321 } 9322 } 9323 } else { 9324 ItemMatcher matcher = new ItemMatcher(); 9325 matcher.build(name); 9326 9327 synchronized (this) { 9328 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9329 if (matcher.match(r1, r1.intent.getComponent())) { 9330 activities.add(r1); 9331 } 9332 } 9333 } 9334 } 9335 9336 if (activities.size() <= 0) { 9337 return false; 9338 } 9339 9340 String[] newArgs = new String[args.length - opti]; 9341 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9342 9343 TaskRecord lastTask = null; 9344 boolean needSep = false; 9345 for (int i=activities.size()-1; i>=0; i--) { 9346 ActivityRecord r = (ActivityRecord)activities.get(i); 9347 if (needSep) { 9348 pw.println(); 9349 } 9350 needSep = true; 9351 synchronized (this) { 9352 if (lastTask != r.task) { 9353 lastTask = r.task; 9354 pw.print("TASK "); pw.print(lastTask.affinity); 9355 pw.print(" id="); pw.println(lastTask.taskId); 9356 if (dumpAll) { 9357 lastTask.dump(pw, " "); 9358 } 9359 } 9360 } 9361 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9362 } 9363 return true; 9364 } 9365 9366 /** 9367 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9368 * there is a thread associated with the activity. 9369 */ 9370 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9371 final ActivityRecord r, String[] args, boolean dumpAll) { 9372 String innerPrefix = prefix + " "; 9373 synchronized (this) { 9374 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9375 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9376 pw.print(" pid="); 9377 if (r.app != null) pw.println(r.app.pid); 9378 else pw.println("(not running)"); 9379 if (dumpAll) { 9380 r.dump(pw, innerPrefix); 9381 } 9382 } 9383 if (r.app != null && r.app.thread != null) { 9384 // flush anything that is already in the PrintWriter since the thread is going 9385 // to write to the file descriptor directly 9386 pw.flush(); 9387 try { 9388 TransferPipe tp = new TransferPipe(); 9389 try { 9390 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9391 r.appToken, innerPrefix, args); 9392 tp.go(fd); 9393 } finally { 9394 tp.kill(); 9395 } 9396 } catch (IOException e) { 9397 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9398 } catch (RemoteException e) { 9399 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9400 } 9401 } 9402 } 9403 9404 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9405 int opti, boolean dumpAll, String dumpPackage) { 9406 boolean needSep = false; 9407 boolean onlyHistory = false; 9408 9409 if ("history".equals(dumpPackage)) { 9410 onlyHistory = true; 9411 dumpPackage = null; 9412 } 9413 9414 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9415 if (!onlyHistory && dumpAll) { 9416 if (mRegisteredReceivers.size() > 0) { 9417 boolean printed = false; 9418 Iterator it = mRegisteredReceivers.values().iterator(); 9419 while (it.hasNext()) { 9420 ReceiverList r = (ReceiverList)it.next(); 9421 if (dumpPackage != null && (r.app == null || 9422 !dumpPackage.equals(r.app.info.packageName))) { 9423 continue; 9424 } 9425 if (!printed) { 9426 pw.println(" Registered Receivers:"); 9427 needSep = true; 9428 printed = true; 9429 } 9430 pw.print(" * "); pw.println(r); 9431 r.dump(pw, " "); 9432 } 9433 } 9434 9435 if (mReceiverResolver.dump(pw, needSep ? 9436 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9437 " ", dumpPackage, false)) { 9438 needSep = true; 9439 } 9440 } 9441 9442 for (BroadcastQueue q : mBroadcastQueues) { 9443 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9444 } 9445 9446 needSep = true; 9447 9448 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9449 if (needSep) { 9450 pw.println(); 9451 } 9452 needSep = true; 9453 pw.println(" Sticky broadcasts:"); 9454 StringBuilder sb = new StringBuilder(128); 9455 for (Map.Entry<String, ArrayList<Intent>> ent 9456 : mStickyBroadcasts.entrySet()) { 9457 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9458 if (dumpAll) { 9459 pw.println(":"); 9460 ArrayList<Intent> intents = ent.getValue(); 9461 final int N = intents.size(); 9462 for (int i=0; i<N; i++) { 9463 sb.setLength(0); 9464 sb.append(" Intent: "); 9465 intents.get(i).toShortString(sb, false, true, false, false); 9466 pw.println(sb.toString()); 9467 Bundle bundle = intents.get(i).getExtras(); 9468 if (bundle != null) { 9469 pw.print(" "); 9470 pw.println(bundle.toString()); 9471 } 9472 } 9473 } else { 9474 pw.println(""); 9475 } 9476 } 9477 needSep = true; 9478 } 9479 9480 if (!onlyHistory && dumpAll) { 9481 pw.println(); 9482 for (BroadcastQueue queue : mBroadcastQueues) { 9483 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9484 + queue.mBroadcastsScheduled); 9485 } 9486 pw.println(" mHandler:"); 9487 mHandler.dump(new PrintWriterPrinter(pw), " "); 9488 needSep = true; 9489 } 9490 9491 return needSep; 9492 } 9493 9494 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9495 int opti, boolean dumpAll, String dumpPackage) { 9496 boolean needSep = true; 9497 9498 ItemMatcher matcher = new ItemMatcher(); 9499 matcher.build(args, opti); 9500 9501 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9502 9503 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9504 9505 if (mLaunchingProviders.size() > 0) { 9506 boolean printed = false; 9507 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9508 ContentProviderRecord r = mLaunchingProviders.get(i); 9509 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9510 continue; 9511 } 9512 if (!printed) { 9513 if (needSep) pw.println(" "); 9514 needSep = true; 9515 pw.println(" Launching content providers:"); 9516 printed = true; 9517 } 9518 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9519 pw.println(r); 9520 } 9521 } 9522 9523 if (mGrantedUriPermissions.size() > 0) { 9524 if (needSep) pw.println(); 9525 needSep = true; 9526 pw.println("Granted Uri Permissions:"); 9527 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9528 int uid = mGrantedUriPermissions.keyAt(i); 9529 HashMap<Uri, UriPermission> perms 9530 = mGrantedUriPermissions.valueAt(i); 9531 pw.print(" * UID "); pw.print(uid); 9532 pw.println(" holds:"); 9533 for (UriPermission perm : perms.values()) { 9534 pw.print(" "); pw.println(perm); 9535 if (dumpAll) { 9536 perm.dump(pw, " "); 9537 } 9538 } 9539 } 9540 needSep = true; 9541 } 9542 9543 return needSep; 9544 } 9545 9546 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9547 int opti, boolean dumpAll, String dumpPackage) { 9548 boolean needSep = false; 9549 9550 if (mIntentSenderRecords.size() > 0) { 9551 boolean printed = false; 9552 Iterator<WeakReference<PendingIntentRecord>> it 9553 = mIntentSenderRecords.values().iterator(); 9554 while (it.hasNext()) { 9555 WeakReference<PendingIntentRecord> ref = it.next(); 9556 PendingIntentRecord rec = ref != null ? ref.get(): null; 9557 if (dumpPackage != null && (rec == null 9558 || !dumpPackage.equals(rec.key.packageName))) { 9559 continue; 9560 } 9561 if (!printed) { 9562 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9563 printed = true; 9564 } 9565 needSep = true; 9566 if (rec != null) { 9567 pw.print(" * "); pw.println(rec); 9568 if (dumpAll) { 9569 rec.dump(pw, " "); 9570 } 9571 } else { 9572 pw.print(" * "); pw.println(ref); 9573 } 9574 } 9575 } 9576 9577 return needSep; 9578 } 9579 9580 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9581 String prefix, String label, boolean complete, boolean brief, boolean client, 9582 String dumpPackage) { 9583 TaskRecord lastTask = null; 9584 boolean needNL = false; 9585 final String innerPrefix = prefix + " "; 9586 final String[] args = new String[0]; 9587 for (int i=list.size()-1; i>=0; i--) { 9588 final ActivityRecord r = (ActivityRecord)list.get(i); 9589 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9590 continue; 9591 } 9592 final boolean full = !brief && (complete || !r.isInHistory()); 9593 if (needNL) { 9594 pw.println(" "); 9595 needNL = false; 9596 } 9597 if (lastTask != r.task) { 9598 lastTask = r.task; 9599 pw.print(prefix); 9600 pw.print(full ? "* " : " "); 9601 pw.println(lastTask); 9602 if (full) { 9603 lastTask.dump(pw, prefix + " "); 9604 } else if (complete) { 9605 // Complete + brief == give a summary. Isn't that obvious?!? 9606 if (lastTask.intent != null) { 9607 pw.print(prefix); pw.print(" "); 9608 pw.println(lastTask.intent.toInsecureStringWithClip()); 9609 } 9610 } 9611 } 9612 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9613 pw.print(" #"); pw.print(i); pw.print(": "); 9614 pw.println(r); 9615 if (full) { 9616 r.dump(pw, innerPrefix); 9617 } else if (complete) { 9618 // Complete + brief == give a summary. Isn't that obvious?!? 9619 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9620 if (r.app != null) { 9621 pw.print(innerPrefix); pw.println(r.app); 9622 } 9623 } 9624 if (client && r.app != null && r.app.thread != null) { 9625 // flush anything that is already in the PrintWriter since the thread is going 9626 // to write to the file descriptor directly 9627 pw.flush(); 9628 try { 9629 TransferPipe tp = new TransferPipe(); 9630 try { 9631 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9632 r.appToken, innerPrefix, args); 9633 // Short timeout, since blocking here can 9634 // deadlock with the application. 9635 tp.go(fd, 2000); 9636 } finally { 9637 tp.kill(); 9638 } 9639 } catch (IOException e) { 9640 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9641 } catch (RemoteException e) { 9642 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9643 } 9644 needNL = true; 9645 } 9646 } 9647 } 9648 9649 private static String buildOomTag(String prefix, String space, int val, int base) { 9650 if (val == base) { 9651 if (space == null) return prefix; 9652 return prefix + " "; 9653 } 9654 return prefix + "+" + Integer.toString(val-base); 9655 } 9656 9657 private static final int dumpProcessList(PrintWriter pw, 9658 ActivityManagerService service, List list, 9659 String prefix, String normalLabel, String persistentLabel, 9660 String dumpPackage) { 9661 int numPers = 0; 9662 final int N = list.size()-1; 9663 for (int i=N; i>=0; i--) { 9664 ProcessRecord r = (ProcessRecord)list.get(i); 9665 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9666 continue; 9667 } 9668 pw.println(String.format("%s%s #%2d: %s", 9669 prefix, (r.persistent ? persistentLabel : normalLabel), 9670 i, r.toString())); 9671 if (r.persistent) { 9672 numPers++; 9673 } 9674 } 9675 return numPers; 9676 } 9677 9678 private static final boolean dumpProcessOomList(PrintWriter pw, 9679 ActivityManagerService service, List<ProcessRecord> origList, 9680 String prefix, String normalLabel, String persistentLabel, 9681 boolean inclDetails, String dumpPackage) { 9682 9683 ArrayList<Pair<ProcessRecord, Integer>> list 9684 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9685 for (int i=0; i<origList.size(); i++) { 9686 ProcessRecord r = origList.get(i); 9687 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9688 continue; 9689 } 9690 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9691 } 9692 9693 if (list.size() <= 0) { 9694 return false; 9695 } 9696 9697 Comparator<Pair<ProcessRecord, Integer>> comparator 9698 = new Comparator<Pair<ProcessRecord, Integer>>() { 9699 @Override 9700 public int compare(Pair<ProcessRecord, Integer> object1, 9701 Pair<ProcessRecord, Integer> object2) { 9702 if (object1.first.setAdj != object2.first.setAdj) { 9703 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9704 } 9705 if (object1.second.intValue() != object2.second.intValue()) { 9706 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9707 } 9708 return 0; 9709 } 9710 }; 9711 9712 Collections.sort(list, comparator); 9713 9714 final long curRealtime = SystemClock.elapsedRealtime(); 9715 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9716 final long curUptime = SystemClock.uptimeMillis(); 9717 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9718 9719 for (int i=list.size()-1; i>=0; i--) { 9720 ProcessRecord r = list.get(i).first; 9721 String oomAdj; 9722 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9723 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9724 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9725 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9726 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9727 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9728 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9729 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9730 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9731 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9732 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9733 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9734 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9735 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9736 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9737 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9738 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9739 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9740 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9741 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9742 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9743 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9744 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9745 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9746 } else { 9747 oomAdj = Integer.toString(r.setAdj); 9748 } 9749 String schedGroup; 9750 switch (r.setSchedGroup) { 9751 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9752 schedGroup = "B"; 9753 break; 9754 case Process.THREAD_GROUP_DEFAULT: 9755 schedGroup = "F"; 9756 break; 9757 default: 9758 schedGroup = Integer.toString(r.setSchedGroup); 9759 break; 9760 } 9761 String foreground; 9762 if (r.foregroundActivities) { 9763 foreground = "A"; 9764 } else if (r.foregroundServices) { 9765 foreground = "S"; 9766 } else { 9767 foreground = " "; 9768 } 9769 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9770 prefix, (r.persistent ? persistentLabel : normalLabel), 9771 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9772 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9773 if (r.adjSource != null || r.adjTarget != null) { 9774 pw.print(prefix); 9775 pw.print(" "); 9776 if (r.adjTarget instanceof ComponentName) { 9777 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9778 } else if (r.adjTarget != null) { 9779 pw.print(r.adjTarget.toString()); 9780 } else { 9781 pw.print("{null}"); 9782 } 9783 pw.print("<="); 9784 if (r.adjSource instanceof ProcessRecord) { 9785 pw.print("Proc{"); 9786 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9787 pw.println("}"); 9788 } else if (r.adjSource != null) { 9789 pw.println(r.adjSource.toString()); 9790 } else { 9791 pw.println("{null}"); 9792 } 9793 } 9794 if (inclDetails) { 9795 pw.print(prefix); 9796 pw.print(" "); 9797 pw.print("oom: max="); pw.print(r.maxAdj); 9798 pw.print(" hidden="); pw.print(r.hiddenAdj); 9799 pw.print(" empty="); pw.print(r.emptyAdj); 9800 pw.print(" curRaw="); pw.print(r.curRawAdj); 9801 pw.print(" setRaw="); pw.print(r.setRawAdj); 9802 pw.print(" cur="); pw.print(r.curAdj); 9803 pw.print(" set="); pw.println(r.setAdj); 9804 pw.print(prefix); 9805 pw.print(" "); 9806 pw.print("keeping="); pw.print(r.keeping); 9807 pw.print(" hidden="); pw.print(r.hidden); 9808 pw.print(" empty="); pw.print(r.empty); 9809 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9810 9811 if (!r.keeping) { 9812 if (r.lastWakeTime != 0) { 9813 long wtime; 9814 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9815 synchronized (stats) { 9816 wtime = stats.getProcessWakeTime(r.info.uid, 9817 r.pid, curRealtime); 9818 } 9819 long timeUsed = wtime - r.lastWakeTime; 9820 pw.print(prefix); 9821 pw.print(" "); 9822 pw.print("keep awake over "); 9823 TimeUtils.formatDuration(realtimeSince, pw); 9824 pw.print(" used "); 9825 TimeUtils.formatDuration(timeUsed, pw); 9826 pw.print(" ("); 9827 pw.print((timeUsed*100)/realtimeSince); 9828 pw.println("%)"); 9829 } 9830 if (r.lastCpuTime != 0) { 9831 long timeUsed = r.curCpuTime - r.lastCpuTime; 9832 pw.print(prefix); 9833 pw.print(" "); 9834 pw.print("run cpu over "); 9835 TimeUtils.formatDuration(uptimeSince, pw); 9836 pw.print(" used "); 9837 TimeUtils.formatDuration(timeUsed, pw); 9838 pw.print(" ("); 9839 pw.print((timeUsed*100)/uptimeSince); 9840 pw.println("%)"); 9841 } 9842 } 9843 } 9844 } 9845 return true; 9846 } 9847 9848 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9849 ArrayList<ProcessRecord> procs; 9850 synchronized (this) { 9851 if (args != null && args.length > start 9852 && args[start].charAt(0) != '-') { 9853 procs = new ArrayList<ProcessRecord>(); 9854 int pid = -1; 9855 try { 9856 pid = Integer.parseInt(args[start]); 9857 } catch (NumberFormatException e) { 9858 9859 } 9860 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9861 ProcessRecord proc = mLruProcesses.get(i); 9862 if (proc.pid == pid) { 9863 procs.add(proc); 9864 } else if (proc.processName.equals(args[start])) { 9865 procs.add(proc); 9866 } 9867 } 9868 if (procs.size() <= 0) { 9869 pw.println("No process found for: " + args[start]); 9870 return null; 9871 } 9872 } else { 9873 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9874 } 9875 } 9876 return procs; 9877 } 9878 9879 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9880 PrintWriter pw, String[] args) { 9881 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9882 if (procs == null) { 9883 return; 9884 } 9885 9886 long uptime = SystemClock.uptimeMillis(); 9887 long realtime = SystemClock.elapsedRealtime(); 9888 pw.println("Applications Graphics Acceleration Info:"); 9889 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9890 9891 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9892 ProcessRecord r = procs.get(i); 9893 if (r.thread != null) { 9894 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9895 pw.flush(); 9896 try { 9897 TransferPipe tp = new TransferPipe(); 9898 try { 9899 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9900 tp.go(fd); 9901 } finally { 9902 tp.kill(); 9903 } 9904 } catch (IOException e) { 9905 pw.println("Failure while dumping the app: " + r); 9906 pw.flush(); 9907 } catch (RemoteException e) { 9908 pw.println("Got a RemoteException while dumping the app " + r); 9909 pw.flush(); 9910 } 9911 } 9912 } 9913 } 9914 9915 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9916 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9917 if (procs == null) { 9918 return; 9919 } 9920 9921 pw.println("Applications Database Info:"); 9922 9923 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9924 ProcessRecord r = procs.get(i); 9925 if (r.thread != null) { 9926 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9927 pw.flush(); 9928 try { 9929 TransferPipe tp = new TransferPipe(); 9930 try { 9931 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9932 tp.go(fd); 9933 } finally { 9934 tp.kill(); 9935 } 9936 } catch (IOException e) { 9937 pw.println("Failure while dumping the app: " + r); 9938 pw.flush(); 9939 } catch (RemoteException e) { 9940 pw.println("Got a RemoteException while dumping the app " + r); 9941 pw.flush(); 9942 } 9943 } 9944 } 9945 } 9946 9947 final static class MemItem { 9948 final String label; 9949 final String shortLabel; 9950 final long pss; 9951 final int id; 9952 ArrayList<MemItem> subitems; 9953 9954 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9955 label = _label; 9956 shortLabel = _shortLabel; 9957 pss = _pss; 9958 id = _id; 9959 } 9960 } 9961 9962 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9963 boolean sort) { 9964 if (sort) { 9965 Collections.sort(items, new Comparator<MemItem>() { 9966 @Override 9967 public int compare(MemItem lhs, MemItem rhs) { 9968 if (lhs.pss < rhs.pss) { 9969 return 1; 9970 } else if (lhs.pss > rhs.pss) { 9971 return -1; 9972 } 9973 return 0; 9974 } 9975 }); 9976 } 9977 9978 for (int i=0; i<items.size(); i++) { 9979 MemItem mi = items.get(i); 9980 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9981 if (mi.subitems != null) { 9982 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9983 } 9984 } 9985 } 9986 9987 // These are in KB. 9988 static final long[] DUMP_MEM_BUCKETS = new long[] { 9989 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9990 120*1024, 160*1024, 200*1024, 9991 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9992 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9993 }; 9994 9995 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9996 boolean stackLike) { 9997 int start = label.lastIndexOf('.'); 9998 if (start >= 0) start++; 9999 else start = 0; 10000 int end = label.length(); 10001 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10002 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10003 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10004 out.append(bucket); 10005 out.append(stackLike ? "MB." : "MB "); 10006 out.append(label, start, end); 10007 return; 10008 } 10009 } 10010 out.append(memKB/1024); 10011 out.append(stackLike ? "MB." : "MB "); 10012 out.append(label, start, end); 10013 } 10014 10015 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10016 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10017 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10018 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10019 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10020 }; 10021 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10022 "System", "Persistent", "Foreground", 10023 "Visible", "Perceptible", "Heavy Weight", 10024 "Backup", "A Services", "Home", "Previous", 10025 "B Services", "Background" 10026 }; 10027 10028 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10029 PrintWriter pw, String prefix, String[] args, boolean brief, 10030 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10031 boolean dumpAll = false; 10032 boolean oomOnly = false; 10033 10034 int opti = 0; 10035 while (opti < args.length) { 10036 String opt = args[opti]; 10037 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10038 break; 10039 } 10040 opti++; 10041 if ("-a".equals(opt)) { 10042 dumpAll = true; 10043 } else if ("--oom".equals(opt)) { 10044 oomOnly = true; 10045 } else if ("-h".equals(opt)) { 10046 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10047 pw.println(" -a: include all available information for each process."); 10048 pw.println(" --oom: only show processes organized by oom adj."); 10049 pw.println("If [process] is specified it can be the name or "); 10050 pw.println("pid of a specific process to dump."); 10051 return; 10052 } else { 10053 pw.println("Unknown argument: " + opt + "; use -h for help"); 10054 } 10055 } 10056 10057 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10058 if (procs == null) { 10059 return; 10060 } 10061 10062 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10063 long uptime = SystemClock.uptimeMillis(); 10064 long realtime = SystemClock.elapsedRealtime(); 10065 10066 if (procs.size() == 1 || isCheckinRequest) { 10067 dumpAll = true; 10068 } 10069 10070 if (isCheckinRequest) { 10071 // short checkin version 10072 pw.println(uptime + "," + realtime); 10073 pw.flush(); 10074 } else { 10075 pw.println("Applications Memory Usage (kB):"); 10076 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10077 } 10078 10079 String[] innerArgs = new String[args.length-opti]; 10080 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10081 10082 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10083 long nativePss=0, dalvikPss=0, otherPss=0; 10084 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10085 10086 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10087 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10088 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10089 10090 long totalPss = 0; 10091 10092 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10093 ProcessRecord r = procs.get(i); 10094 if (r.thread != null) { 10095 if (!isCheckinRequest && dumpAll) { 10096 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10097 pw.flush(); 10098 } 10099 Debug.MemoryInfo mi = null; 10100 if (dumpAll) { 10101 try { 10102 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10103 } catch (RemoteException e) { 10104 if (!isCheckinRequest) { 10105 pw.println("Got RemoteException!"); 10106 pw.flush(); 10107 } 10108 } 10109 } else { 10110 mi = new Debug.MemoryInfo(); 10111 Debug.getMemoryInfo(r.pid, mi); 10112 } 10113 10114 if (!isCheckinRequest && mi != null) { 10115 long myTotalPss = mi.getTotalPss(); 10116 totalPss += myTotalPss; 10117 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10118 r.processName, myTotalPss, 0); 10119 procMems.add(pssItem); 10120 10121 nativePss += mi.nativePss; 10122 dalvikPss += mi.dalvikPss; 10123 otherPss += mi.otherPss; 10124 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10125 long mem = mi.getOtherPss(j); 10126 miscPss[j] += mem; 10127 otherPss -= mem; 10128 } 10129 10130 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10131 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10132 || oomIndex == (oomPss.length-1)) { 10133 oomPss[oomIndex] += myTotalPss; 10134 if (oomProcs[oomIndex] == null) { 10135 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10136 } 10137 oomProcs[oomIndex].add(pssItem); 10138 break; 10139 } 10140 } 10141 } 10142 } 10143 } 10144 10145 if (!isCheckinRequest && procs.size() > 1) { 10146 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10147 10148 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10149 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10150 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10151 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10152 String label = Debug.MemoryInfo.getOtherLabel(j); 10153 catMems.add(new MemItem(label, label, miscPss[j], j)); 10154 } 10155 10156 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10157 for (int j=0; j<oomPss.length; j++) { 10158 if (oomPss[j] != 0) { 10159 String label = DUMP_MEM_OOM_LABEL[j]; 10160 MemItem item = new MemItem(label, label, oomPss[j], 10161 DUMP_MEM_OOM_ADJ[j]); 10162 item.subitems = oomProcs[j]; 10163 oomMems.add(item); 10164 } 10165 } 10166 10167 if (outTag != null || outStack != null) { 10168 if (outTag != null) { 10169 appendMemBucket(outTag, totalPss, "total", false); 10170 } 10171 if (outStack != null) { 10172 appendMemBucket(outStack, totalPss, "total", true); 10173 } 10174 boolean firstLine = true; 10175 for (int i=0; i<oomMems.size(); i++) { 10176 MemItem miCat = oomMems.get(i); 10177 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10178 continue; 10179 } 10180 if (miCat.id < ProcessList.SERVICE_ADJ 10181 || miCat.id == ProcessList.HOME_APP_ADJ 10182 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10183 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10184 outTag.append(" / "); 10185 } 10186 if (outStack != null) { 10187 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10188 if (firstLine) { 10189 outStack.append(":"); 10190 firstLine = false; 10191 } 10192 outStack.append("\n\t at "); 10193 } else { 10194 outStack.append("$"); 10195 } 10196 } 10197 for (int j=0; j<miCat.subitems.size(); j++) { 10198 MemItem mi = miCat.subitems.get(j); 10199 if (j > 0) { 10200 if (outTag != null) { 10201 outTag.append(" "); 10202 } 10203 if (outStack != null) { 10204 outStack.append("$"); 10205 } 10206 } 10207 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10208 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10209 } 10210 if (outStack != null) { 10211 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10212 } 10213 } 10214 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10215 outStack.append("("); 10216 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10217 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10218 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10219 outStack.append(":"); 10220 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10221 } 10222 } 10223 outStack.append(")"); 10224 } 10225 } 10226 } 10227 } 10228 10229 if (!brief && !oomOnly) { 10230 pw.println(); 10231 pw.println("Total PSS by process:"); 10232 dumpMemItems(pw, " ", procMems, true); 10233 pw.println(); 10234 } 10235 pw.println("Total PSS by OOM adjustment:"); 10236 dumpMemItems(pw, " ", oomMems, false); 10237 if (!oomOnly) { 10238 PrintWriter out = categoryPw != null ? categoryPw : pw; 10239 out.println(); 10240 out.println("Total PSS by category:"); 10241 dumpMemItems(out, " ", catMems, true); 10242 } 10243 pw.println(); 10244 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10245 final int[] SINGLE_LONG_FORMAT = new int[] { 10246 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10247 }; 10248 long[] longOut = new long[1]; 10249 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10250 SINGLE_LONG_FORMAT, null, longOut, null); 10251 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10252 longOut[0] = 0; 10253 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10254 SINGLE_LONG_FORMAT, null, longOut, null); 10255 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10256 longOut[0] = 0; 10257 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10258 SINGLE_LONG_FORMAT, null, longOut, null); 10259 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10260 longOut[0] = 0; 10261 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10262 SINGLE_LONG_FORMAT, null, longOut, null); 10263 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10264 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10265 pw.print(shared); pw.println(" kB"); 10266 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10267 pw.print(voltile); pw.println(" kB volatile"); 10268 } 10269 } 10270 10271 /** 10272 * Searches array of arguments for the specified string 10273 * @param args array of argument strings 10274 * @param value value to search for 10275 * @return true if the value is contained in the array 10276 */ 10277 private static boolean scanArgs(String[] args, String value) { 10278 if (args != null) { 10279 for (String arg : args) { 10280 if (value.equals(arg)) { 10281 return true; 10282 } 10283 } 10284 } 10285 return false; 10286 } 10287 10288 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10289 ContentProviderRecord cpr, boolean always) { 10290 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10291 10292 if (!inLaunching || always) { 10293 synchronized (cpr) { 10294 cpr.launchingApp = null; 10295 cpr.notifyAll(); 10296 } 10297 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10298 String names[] = cpr.info.authority.split(";"); 10299 for (int j = 0; j < names.length; j++) { 10300 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10301 } 10302 } 10303 10304 for (int i=0; i<cpr.connections.size(); i++) { 10305 ContentProviderConnection conn = cpr.connections.get(i); 10306 if (conn.waiting) { 10307 // If this connection is waiting for the provider, then we don't 10308 // need to mess with its process unless we are always removing 10309 // or for some reason the provider is not currently launching. 10310 if (inLaunching && !always) { 10311 continue; 10312 } 10313 } 10314 ProcessRecord capp = conn.client; 10315 conn.dead = true; 10316 if (conn.stableCount > 0) { 10317 if (!capp.persistent && capp.thread != null 10318 && capp.pid != 0 10319 && capp.pid != MY_PID) { 10320 Slog.i(TAG, "Kill " + capp.processName 10321 + " (pid " + capp.pid + "): provider " + cpr.info.name 10322 + " in dying process " + (proc != null ? proc.processName : "??")); 10323 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10324 capp.processName, capp.setAdj, "dying provider " 10325 + cpr.name.toShortString()); 10326 Process.killProcessQuiet(capp.pid); 10327 } 10328 } else if (capp.thread != null && conn.provider.provider != null) { 10329 try { 10330 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10331 } catch (RemoteException e) { 10332 } 10333 // In the protocol here, we don't expect the client to correctly 10334 // clean up this connection, we'll just remove it. 10335 cpr.connections.remove(i); 10336 conn.client.conProviders.remove(conn); 10337 } 10338 } 10339 10340 if (inLaunching && always) { 10341 mLaunchingProviders.remove(cpr); 10342 } 10343 return inLaunching; 10344 } 10345 10346 /** 10347 * Main code for cleaning up a process when it has gone away. This is 10348 * called both as a result of the process dying, or directly when stopping 10349 * a process when running in single process mode. 10350 */ 10351 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10352 boolean restarting, boolean allowRestart, int index) { 10353 if (index >= 0) { 10354 mLruProcesses.remove(index); 10355 } 10356 10357 mProcessesToGc.remove(app); 10358 10359 // Dismiss any open dialogs. 10360 if (app.crashDialog != null) { 10361 app.crashDialog.dismiss(); 10362 app.crashDialog = null; 10363 } 10364 if (app.anrDialog != null) { 10365 app.anrDialog.dismiss(); 10366 app.anrDialog = null; 10367 } 10368 if (app.waitDialog != null) { 10369 app.waitDialog.dismiss(); 10370 app.waitDialog = null; 10371 } 10372 10373 app.crashing = false; 10374 app.notResponding = false; 10375 10376 app.resetPackageList(); 10377 app.unlinkDeathRecipient(); 10378 app.thread = null; 10379 app.forcingToForeground = null; 10380 app.foregroundServices = false; 10381 app.foregroundActivities = false; 10382 app.hasShownUi = false; 10383 app.hasAboveClient = false; 10384 10385 mServices.killServicesLocked(app, allowRestart); 10386 10387 boolean restart = false; 10388 10389 // Remove published content providers. 10390 if (!app.pubProviders.isEmpty()) { 10391 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10392 while (it.hasNext()) { 10393 ContentProviderRecord cpr = it.next(); 10394 10395 final boolean always = app.bad || !allowRestart; 10396 if (removeDyingProviderLocked(app, cpr, always) || always) { 10397 // We left the provider in the launching list, need to 10398 // restart it. 10399 restart = true; 10400 } 10401 10402 cpr.provider = null; 10403 cpr.proc = null; 10404 } 10405 app.pubProviders.clear(); 10406 } 10407 10408 // Take care of any launching providers waiting for this process. 10409 if (checkAppInLaunchingProvidersLocked(app, false)) { 10410 restart = true; 10411 } 10412 10413 // Unregister from connected content providers. 10414 if (!app.conProviders.isEmpty()) { 10415 for (int i=0; i<app.conProviders.size(); i++) { 10416 ContentProviderConnection conn = app.conProviders.get(i); 10417 conn.provider.connections.remove(conn); 10418 } 10419 app.conProviders.clear(); 10420 } 10421 10422 // At this point there may be remaining entries in mLaunchingProviders 10423 // where we were the only one waiting, so they are no longer of use. 10424 // Look for these and clean up if found. 10425 // XXX Commented out for now. Trying to figure out a way to reproduce 10426 // the actual situation to identify what is actually going on. 10427 if (false) { 10428 for (int i=0; i<mLaunchingProviders.size(); i++) { 10429 ContentProviderRecord cpr = (ContentProviderRecord) 10430 mLaunchingProviders.get(i); 10431 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10432 synchronized (cpr) { 10433 cpr.launchingApp = null; 10434 cpr.notifyAll(); 10435 } 10436 } 10437 } 10438 } 10439 10440 skipCurrentReceiverLocked(app); 10441 10442 // Unregister any receivers. 10443 if (app.receivers.size() > 0) { 10444 Iterator<ReceiverList> it = app.receivers.iterator(); 10445 while (it.hasNext()) { 10446 removeReceiverLocked(it.next()); 10447 } 10448 app.receivers.clear(); 10449 } 10450 10451 // If the app is undergoing backup, tell the backup manager about it 10452 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10453 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10454 try { 10455 IBackupManager bm = IBackupManager.Stub.asInterface( 10456 ServiceManager.getService(Context.BACKUP_SERVICE)); 10457 bm.agentDisconnected(app.info.packageName); 10458 } catch (RemoteException e) { 10459 // can't happen; backup manager is local 10460 } 10461 } 10462 10463 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10464 ProcessChangeItem item = mPendingProcessChanges.get(i); 10465 if (item.pid == app.pid) { 10466 mPendingProcessChanges.remove(i); 10467 mAvailProcessChanges.add(item); 10468 } 10469 } 10470 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10471 10472 // If the caller is restarting this app, then leave it in its 10473 // current lists and let the caller take care of it. 10474 if (restarting) { 10475 return; 10476 } 10477 10478 if (!app.persistent || app.isolated) { 10479 if (DEBUG_PROCESSES) Slog.v(TAG, 10480 "Removing non-persistent process during cleanup: " + app); 10481 mProcessNames.remove(app.processName, app.uid); 10482 mIsolatedProcesses.remove(app.uid); 10483 if (mHeavyWeightProcess == app) { 10484 mHeavyWeightProcess = null; 10485 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10486 } 10487 } else if (!app.removed) { 10488 // This app is persistent, so we need to keep its record around. 10489 // If it is not already on the pending app list, add it there 10490 // and start a new process for it. 10491 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10492 mPersistentStartingProcesses.add(app); 10493 restart = true; 10494 } 10495 } 10496 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10497 "Clean-up removing on hold: " + app); 10498 mProcessesOnHold.remove(app); 10499 10500 if (app == mHomeProcess) { 10501 mHomeProcess = null; 10502 } 10503 if (app == mPreviousProcess) { 10504 mPreviousProcess = null; 10505 } 10506 10507 if (restart && !app.isolated) { 10508 // We have components that still need to be running in the 10509 // process, so re-launch it. 10510 mProcessNames.put(app.processName, app.uid, app); 10511 startProcessLocked(app, "restart", app.processName); 10512 } else if (app.pid > 0 && app.pid != MY_PID) { 10513 // Goodbye! 10514 synchronized (mPidsSelfLocked) { 10515 mPidsSelfLocked.remove(app.pid); 10516 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10517 } 10518 app.setPid(0); 10519 } 10520 } 10521 10522 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10523 // Look through the content providers we are waiting to have launched, 10524 // and if any run in this process then either schedule a restart of 10525 // the process or kill the client waiting for it if this process has 10526 // gone bad. 10527 int NL = mLaunchingProviders.size(); 10528 boolean restart = false; 10529 for (int i=0; i<NL; i++) { 10530 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10531 if (cpr.launchingApp == app) { 10532 if (!alwaysBad && !app.bad) { 10533 restart = true; 10534 } else { 10535 removeDyingProviderLocked(app, cpr, true); 10536 NL = mLaunchingProviders.size(); 10537 } 10538 } 10539 } 10540 return restart; 10541 } 10542 10543 // ========================================================= 10544 // SERVICES 10545 // ========================================================= 10546 10547 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10548 int flags) { 10549 enforceNotIsolatedCaller("getServices"); 10550 synchronized (this) { 10551 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10552 } 10553 } 10554 10555 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10556 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10557 synchronized (this) { 10558 return mServices.getRunningServiceControlPanelLocked(name); 10559 } 10560 } 10561 10562 public ComponentName startService(IApplicationThread caller, Intent service, 10563 String resolvedType, int userId) { 10564 enforceNotIsolatedCaller("startService"); 10565 // Refuse possible leaked file descriptors 10566 if (service != null && service.hasFileDescriptors() == true) { 10567 throw new IllegalArgumentException("File descriptors passed in Intent"); 10568 } 10569 10570 if (DEBUG_SERVICE) 10571 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10572 synchronized(this) { 10573 final int callingPid = Binder.getCallingPid(); 10574 final int callingUid = Binder.getCallingUid(); 10575 checkValidCaller(callingUid, userId); 10576 final long origId = Binder.clearCallingIdentity(); 10577 ComponentName res = mServices.startServiceLocked(caller, service, 10578 resolvedType, callingPid, callingUid, userId); 10579 Binder.restoreCallingIdentity(origId); 10580 return res; 10581 } 10582 } 10583 10584 ComponentName startServiceInPackage(int uid, 10585 Intent service, String resolvedType) { 10586 synchronized(this) { 10587 if (DEBUG_SERVICE) 10588 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10589 final long origId = Binder.clearCallingIdentity(); 10590 ComponentName res = mServices.startServiceLocked(null, service, 10591 resolvedType, -1, uid, UserHandle.getUserId(uid)); 10592 Binder.restoreCallingIdentity(origId); 10593 return res; 10594 } 10595 } 10596 10597 public int stopService(IApplicationThread caller, Intent service, 10598 String resolvedType, int userId) { 10599 enforceNotIsolatedCaller("stopService"); 10600 // Refuse possible leaked file descriptors 10601 if (service != null && service.hasFileDescriptors() == true) { 10602 throw new IllegalArgumentException("File descriptors passed in Intent"); 10603 } 10604 10605 checkValidCaller(Binder.getCallingUid(), userId); 10606 10607 synchronized(this) { 10608 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10609 } 10610 } 10611 10612 public IBinder peekService(Intent service, String resolvedType) { 10613 enforceNotIsolatedCaller("peekService"); 10614 // Refuse possible leaked file descriptors 10615 if (service != null && service.hasFileDescriptors() == true) { 10616 throw new IllegalArgumentException("File descriptors passed in Intent"); 10617 } 10618 synchronized(this) { 10619 return mServices.peekServiceLocked(service, resolvedType); 10620 } 10621 } 10622 10623 public boolean stopServiceToken(ComponentName className, IBinder token, 10624 int startId) { 10625 synchronized(this) { 10626 return mServices.stopServiceTokenLocked(className, token, startId); 10627 } 10628 } 10629 10630 public void setServiceForeground(ComponentName className, IBinder token, 10631 int id, Notification notification, boolean removeNotification) { 10632 synchronized(this) { 10633 mServices.setServiceForegroundLocked(className, token, id, notification, 10634 removeNotification); 10635 } 10636 } 10637 10638 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10639 String className, int flags) { 10640 boolean result = false; 10641 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10642 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10643 if (ActivityManager.checkUidPermission( 10644 android.Manifest.permission.INTERACT_ACROSS_USERS, 10645 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10646 ComponentName comp = new ComponentName(aInfo.packageName, className); 10647 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10648 + " requests FLAG_SINGLE_USER, but app does not hold " 10649 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10650 Slog.w(TAG, msg); 10651 throw new SecurityException(msg); 10652 } 10653 result = true; 10654 } 10655 } else if (componentProcessName == aInfo.packageName) { 10656 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10657 } else if ("system".equals(componentProcessName)) { 10658 result = true; 10659 } 10660 if (DEBUG_MU) { 10661 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10662 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10663 } 10664 return result; 10665 } 10666 10667 public int bindService(IApplicationThread caller, IBinder token, 10668 Intent service, String resolvedType, 10669 IServiceConnection connection, int flags, int userId) { 10670 enforceNotIsolatedCaller("bindService"); 10671 // Refuse possible leaked file descriptors 10672 if (service != null && service.hasFileDescriptors() == true) { 10673 throw new IllegalArgumentException("File descriptors passed in Intent"); 10674 } 10675 10676 checkValidCaller(Binder.getCallingUid(), userId); 10677 10678 synchronized(this) { 10679 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10680 connection, flags, userId); 10681 } 10682 } 10683 10684 public boolean unbindService(IServiceConnection connection) { 10685 synchronized (this) { 10686 return mServices.unbindServiceLocked(connection); 10687 } 10688 } 10689 10690 public void publishService(IBinder token, Intent intent, IBinder service) { 10691 // Refuse possible leaked file descriptors 10692 if (intent != null && intent.hasFileDescriptors() == true) { 10693 throw new IllegalArgumentException("File descriptors passed in Intent"); 10694 } 10695 10696 synchronized(this) { 10697 if (!(token instanceof ServiceRecord)) { 10698 throw new IllegalArgumentException("Invalid service token"); 10699 } 10700 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10701 } 10702 } 10703 10704 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10705 // Refuse possible leaked file descriptors 10706 if (intent != null && intent.hasFileDescriptors() == true) { 10707 throw new IllegalArgumentException("File descriptors passed in Intent"); 10708 } 10709 10710 synchronized(this) { 10711 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10712 } 10713 } 10714 10715 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10716 synchronized(this) { 10717 if (!(token instanceof ServiceRecord)) { 10718 throw new IllegalArgumentException("Invalid service token"); 10719 } 10720 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10721 } 10722 } 10723 10724 // ========================================================= 10725 // BACKUP AND RESTORE 10726 // ========================================================= 10727 10728 // Cause the target app to be launched if necessary and its backup agent 10729 // instantiated. The backup agent will invoke backupAgentCreated() on the 10730 // activity manager to announce its creation. 10731 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10732 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10733 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10734 10735 synchronized(this) { 10736 // !!! TODO: currently no check here that we're already bound 10737 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10738 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10739 synchronized (stats) { 10740 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10741 } 10742 10743 // Backup agent is now in use, its package can't be stopped. 10744 try { 10745 AppGlobals.getPackageManager().setPackageStoppedState( 10746 app.packageName, false, UserHandle.getUserId(app.uid)); 10747 } catch (RemoteException e) { 10748 } catch (IllegalArgumentException e) { 10749 Slog.w(TAG, "Failed trying to unstop package " 10750 + app.packageName + ": " + e); 10751 } 10752 10753 BackupRecord r = new BackupRecord(ss, app, backupMode); 10754 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10755 ? new ComponentName(app.packageName, app.backupAgentName) 10756 : new ComponentName("android", "FullBackupAgent"); 10757 // startProcessLocked() returns existing proc's record if it's already running 10758 ProcessRecord proc = startProcessLocked(app.processName, app, 10759 false, 0, "backup", hostingName, false, false); 10760 if (proc == null) { 10761 Slog.e(TAG, "Unable to start backup agent process " + r); 10762 return false; 10763 } 10764 10765 r.app = proc; 10766 mBackupTarget = r; 10767 mBackupAppName = app.packageName; 10768 10769 // Try not to kill the process during backup 10770 updateOomAdjLocked(proc); 10771 10772 // If the process is already attached, schedule the creation of the backup agent now. 10773 // If it is not yet live, this will be done when it attaches to the framework. 10774 if (proc.thread != null) { 10775 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10776 try { 10777 proc.thread.scheduleCreateBackupAgent(app, 10778 compatibilityInfoForPackageLocked(app), backupMode); 10779 } catch (RemoteException e) { 10780 // Will time out on the backup manager side 10781 } 10782 } else { 10783 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10784 } 10785 // Invariants: at this point, the target app process exists and the application 10786 // is either already running or in the process of coming up. mBackupTarget and 10787 // mBackupAppName describe the app, so that when it binds back to the AM we 10788 // know that it's scheduled for a backup-agent operation. 10789 } 10790 10791 return true; 10792 } 10793 10794 // A backup agent has just come up 10795 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10796 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10797 + " = " + agent); 10798 10799 synchronized(this) { 10800 if (!agentPackageName.equals(mBackupAppName)) { 10801 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10802 return; 10803 } 10804 } 10805 10806 long oldIdent = Binder.clearCallingIdentity(); 10807 try { 10808 IBackupManager bm = IBackupManager.Stub.asInterface( 10809 ServiceManager.getService(Context.BACKUP_SERVICE)); 10810 bm.agentConnected(agentPackageName, agent); 10811 } catch (RemoteException e) { 10812 // can't happen; the backup manager service is local 10813 } catch (Exception e) { 10814 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10815 e.printStackTrace(); 10816 } finally { 10817 Binder.restoreCallingIdentity(oldIdent); 10818 } 10819 } 10820 10821 // done with this agent 10822 public void unbindBackupAgent(ApplicationInfo appInfo) { 10823 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10824 if (appInfo == null) { 10825 Slog.w(TAG, "unbind backup agent for null app"); 10826 return; 10827 } 10828 10829 synchronized(this) { 10830 if (mBackupAppName == null) { 10831 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10832 return; 10833 } 10834 10835 if (!mBackupAppName.equals(appInfo.packageName)) { 10836 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10837 return; 10838 } 10839 10840 ProcessRecord proc = mBackupTarget.app; 10841 mBackupTarget = null; 10842 mBackupAppName = null; 10843 10844 // Not backing this app up any more; reset its OOM adjustment 10845 updateOomAdjLocked(proc); 10846 10847 // If the app crashed during backup, 'thread' will be null here 10848 if (proc.thread != null) { 10849 try { 10850 proc.thread.scheduleDestroyBackupAgent(appInfo, 10851 compatibilityInfoForPackageLocked(appInfo)); 10852 } catch (Exception e) { 10853 Slog.e(TAG, "Exception when unbinding backup agent:"); 10854 e.printStackTrace(); 10855 } 10856 } 10857 } 10858 } 10859 // ========================================================= 10860 // BROADCASTS 10861 // ========================================================= 10862 10863 private final List getStickiesLocked(String action, IntentFilter filter, 10864 List cur) { 10865 final ContentResolver resolver = mContext.getContentResolver(); 10866 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10867 if (list == null) { 10868 return cur; 10869 } 10870 int N = list.size(); 10871 for (int i=0; i<N; i++) { 10872 Intent intent = list.get(i); 10873 if (filter.match(resolver, intent, true, TAG) >= 0) { 10874 if (cur == null) { 10875 cur = new ArrayList<Intent>(); 10876 } 10877 cur.add(intent); 10878 } 10879 } 10880 return cur; 10881 } 10882 10883 boolean isPendingBroadcastProcessLocked(int pid) { 10884 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10885 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10886 } 10887 10888 void skipPendingBroadcastLocked(int pid) { 10889 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10890 for (BroadcastQueue queue : mBroadcastQueues) { 10891 queue.skipPendingBroadcastLocked(pid); 10892 } 10893 } 10894 10895 // The app just attached; send any pending broadcasts that it should receive 10896 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10897 boolean didSomething = false; 10898 for (BroadcastQueue queue : mBroadcastQueues) { 10899 didSomething |= queue.sendPendingBroadcastsLocked(app); 10900 } 10901 return didSomething; 10902 } 10903 10904 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10905 IIntentReceiver receiver, IntentFilter filter, String permission) { 10906 enforceNotIsolatedCaller("registerReceiver"); 10907 int callingUid; 10908 synchronized(this) { 10909 ProcessRecord callerApp = null; 10910 if (caller != null) { 10911 callerApp = getRecordForAppLocked(caller); 10912 if (callerApp == null) { 10913 throw new SecurityException( 10914 "Unable to find app for caller " + caller 10915 + " (pid=" + Binder.getCallingPid() 10916 + ") when registering receiver " + receiver); 10917 } 10918 if (callerApp.info.uid != Process.SYSTEM_UID && 10919 !callerApp.pkgList.contains(callerPackage)) { 10920 throw new SecurityException("Given caller package " + callerPackage 10921 + " is not running in process " + callerApp); 10922 } 10923 callingUid = callerApp.info.uid; 10924 } else { 10925 callerPackage = null; 10926 callingUid = Binder.getCallingUid(); 10927 } 10928 10929 List allSticky = null; 10930 10931 // Look for any matching sticky broadcasts... 10932 Iterator actions = filter.actionsIterator(); 10933 if (actions != null) { 10934 while (actions.hasNext()) { 10935 String action = (String)actions.next(); 10936 allSticky = getStickiesLocked(action, filter, allSticky); 10937 } 10938 } else { 10939 allSticky = getStickiesLocked(null, filter, allSticky); 10940 } 10941 10942 // The first sticky in the list is returned directly back to 10943 // the client. 10944 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10945 10946 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10947 + ": " + sticky); 10948 10949 if (receiver == null) { 10950 return sticky; 10951 } 10952 10953 ReceiverList rl 10954 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10955 if (rl == null) { 10956 rl = new ReceiverList(this, callerApp, 10957 Binder.getCallingPid(), 10958 Binder.getCallingUid(), receiver); 10959 if (rl.app != null) { 10960 rl.app.receivers.add(rl); 10961 } else { 10962 try { 10963 receiver.asBinder().linkToDeath(rl, 0); 10964 } catch (RemoteException e) { 10965 return sticky; 10966 } 10967 rl.linkedToDeath = true; 10968 } 10969 mRegisteredReceivers.put(receiver.asBinder(), rl); 10970 } 10971 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10972 permission, callingUid); 10973 rl.add(bf); 10974 if (!bf.debugCheck()) { 10975 Slog.w(TAG, "==> For Dynamic broadast"); 10976 } 10977 mReceiverResolver.addFilter(bf); 10978 10979 // Enqueue broadcasts for all existing stickies that match 10980 // this filter. 10981 if (allSticky != null) { 10982 ArrayList receivers = new ArrayList(); 10983 receivers.add(bf); 10984 10985 int N = allSticky.size(); 10986 for (int i=0; i<N; i++) { 10987 Intent intent = (Intent)allSticky.get(i); 10988 BroadcastQueue queue = broadcastQueueForIntent(intent); 10989 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10990 null, -1, -1, null, receivers, null, 0, null, null, 10991 false, true, true, false, -1); 10992 queue.enqueueParallelBroadcastLocked(r); 10993 queue.scheduleBroadcastsLocked(); 10994 } 10995 } 10996 10997 return sticky; 10998 } 10999 } 11000 11001 public void unregisterReceiver(IIntentReceiver receiver) { 11002 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11003 11004 final long origId = Binder.clearCallingIdentity(); 11005 try { 11006 boolean doTrim = false; 11007 11008 synchronized(this) { 11009 ReceiverList rl 11010 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11011 if (rl != null) { 11012 if (rl.curBroadcast != null) { 11013 BroadcastRecord r = rl.curBroadcast; 11014 final boolean doNext = finishReceiverLocked( 11015 receiver.asBinder(), r.resultCode, r.resultData, 11016 r.resultExtras, r.resultAbort, true); 11017 if (doNext) { 11018 doTrim = true; 11019 r.queue.processNextBroadcast(false); 11020 } 11021 } 11022 11023 if (rl.app != null) { 11024 rl.app.receivers.remove(rl); 11025 } 11026 removeReceiverLocked(rl); 11027 if (rl.linkedToDeath) { 11028 rl.linkedToDeath = false; 11029 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11030 } 11031 } 11032 } 11033 11034 // If we actually concluded any broadcasts, we might now be able 11035 // to trim the recipients' apps from our working set 11036 if (doTrim) { 11037 trimApplications(); 11038 return; 11039 } 11040 11041 } finally { 11042 Binder.restoreCallingIdentity(origId); 11043 } 11044 } 11045 11046 void removeReceiverLocked(ReceiverList rl) { 11047 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11048 int N = rl.size(); 11049 for (int i=0; i<N; i++) { 11050 mReceiverResolver.removeFilter(rl.get(i)); 11051 } 11052 } 11053 11054 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11055 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11056 ProcessRecord r = mLruProcesses.get(i); 11057 if (r.thread != null) { 11058 try { 11059 r.thread.dispatchPackageBroadcast(cmd, packages); 11060 } catch (RemoteException ex) { 11061 } 11062 } 11063 } 11064 } 11065 11066 private final int broadcastIntentLocked(ProcessRecord callerApp, 11067 String callerPackage, Intent intent, String resolvedType, 11068 IIntentReceiver resultTo, int resultCode, String resultData, 11069 Bundle map, String requiredPermission, 11070 boolean ordered, boolean sticky, int callingPid, int callingUid, 11071 int userId) { 11072 intent = new Intent(intent); 11073 11074 // By default broadcasts do not go to stopped apps. 11075 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11076 11077 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11078 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11079 + " ordered=" + ordered + " userid=" + userId); 11080 if ((resultTo != null) && !ordered) { 11081 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11082 } 11083 11084 boolean onlySendToCaller = false; 11085 11086 // If the caller is trying to send this broadcast to a different 11087 // user, verify that is allowed. 11088 if (UserHandle.getUserId(callingUid) != userId) { 11089 if (checkComponentPermission( 11090 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11091 callingPid, callingUid, -1, true) 11092 != PackageManager.PERMISSION_GRANTED) { 11093 if (checkComponentPermission( 11094 android.Manifest.permission.INTERACT_ACROSS_USERS, 11095 callingPid, callingUid, -1, true) 11096 == PackageManager.PERMISSION_GRANTED) { 11097 onlySendToCaller = true; 11098 } else { 11099 String msg = "Permission Denial: " + intent.getAction() 11100 + " broadcast from " + callerPackage 11101 + " asks to send as user " + userId 11102 + " but is calling from user " + UserHandle.getUserId(callingUid) 11103 + "; this requires " 11104 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11105 Slog.w(TAG, msg); 11106 throw new SecurityException(msg); 11107 } 11108 } 11109 } 11110 11111 // Handle special intents: if this broadcast is from the package 11112 // manager about a package being removed, we need to remove all of 11113 // its activities from the history stack. 11114 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11115 intent.getAction()); 11116 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11117 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11118 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11119 || uidRemoved) { 11120 if (checkComponentPermission( 11121 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11122 callingPid, callingUid, -1, true) 11123 == PackageManager.PERMISSION_GRANTED) { 11124 if (uidRemoved) { 11125 final Bundle intentExtras = intent.getExtras(); 11126 final int uid = intentExtras != null 11127 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11128 if (uid >= 0) { 11129 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11130 synchronized (bs) { 11131 bs.removeUidStatsLocked(uid); 11132 } 11133 } 11134 } else { 11135 // If resources are unvailble just force stop all 11136 // those packages and flush the attribute cache as well. 11137 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11138 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11139 if (list != null && (list.length > 0)) { 11140 for (String pkg : list) { 11141 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11142 } 11143 sendPackageBroadcastLocked( 11144 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11145 } 11146 } else { 11147 Uri data = intent.getData(); 11148 String ssp; 11149 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11150 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11151 forceStopPackageLocked(ssp, 11152 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11153 false, userId); 11154 } 11155 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11156 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11157 new String[] {ssp}); 11158 } 11159 } 11160 } 11161 } 11162 } else { 11163 String msg = "Permission Denial: " + intent.getAction() 11164 + " broadcast from " + callerPackage + " (pid=" + callingPid 11165 + ", uid=" + callingUid + ")" 11166 + " requires " 11167 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11168 Slog.w(TAG, msg); 11169 throw new SecurityException(msg); 11170 } 11171 11172 // Special case for adding a package: by default turn on compatibility 11173 // mode. 11174 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11175 Uri data = intent.getData(); 11176 String ssp; 11177 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11178 mCompatModePackages.handlePackageAddedLocked(ssp, 11179 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11180 } 11181 } 11182 11183 /* 11184 * If this is the time zone changed action, queue up a message that will reset the timezone 11185 * of all currently running processes. This message will get queued up before the broadcast 11186 * happens. 11187 */ 11188 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11189 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11190 } 11191 11192 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11193 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11194 } 11195 11196 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11197 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11198 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11199 } 11200 11201 /* 11202 * Prevent non-system code (defined here to be non-persistent 11203 * processes) from sending protected broadcasts. 11204 */ 11205 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11206 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11207 callingUid == 0) { 11208 // Always okay. 11209 } else if (callerApp == null || !callerApp.persistent) { 11210 try { 11211 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11212 intent.getAction())) { 11213 String msg = "Permission Denial: not allowed to send broadcast " 11214 + intent.getAction() + " from pid=" 11215 + callingPid + ", uid=" + callingUid; 11216 Slog.w(TAG, msg); 11217 throw new SecurityException(msg); 11218 } 11219 } catch (RemoteException e) { 11220 Slog.w(TAG, "Remote exception", e); 11221 return ActivityManager.BROADCAST_SUCCESS; 11222 } 11223 } 11224 11225 // Add to the sticky list if requested. 11226 if (sticky) { 11227 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11228 callingPid, callingUid) 11229 != PackageManager.PERMISSION_GRANTED) { 11230 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11231 + callingPid + ", uid=" + callingUid 11232 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11233 Slog.w(TAG, msg); 11234 throw new SecurityException(msg); 11235 } 11236 if (requiredPermission != null) { 11237 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11238 + " and enforce permission " + requiredPermission); 11239 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11240 } 11241 if (intent.getComponent() != null) { 11242 throw new SecurityException( 11243 "Sticky broadcasts can't target a specific component"); 11244 } 11245 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11246 if (list == null) { 11247 list = new ArrayList<Intent>(); 11248 mStickyBroadcasts.put(intent.getAction(), list); 11249 } 11250 int N = list.size(); 11251 int i; 11252 for (i=0; i<N; i++) { 11253 if (intent.filterEquals(list.get(i))) { 11254 // This sticky already exists, replace it. 11255 list.set(i, new Intent(intent)); 11256 break; 11257 } 11258 } 11259 if (i >= N) { 11260 list.add(new Intent(intent)); 11261 } 11262 } 11263 11264 // Figure out who all will receive this broadcast. 11265 List receivers = null; 11266 List<BroadcastFilter> registeredReceivers = null; 11267 try { 11268 // Need to resolve the intent to interested receivers... 11269 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11270 == 0) { 11271 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11272 intent, resolvedType, STOCK_PM_FLAGS, userId); 11273 } 11274 if (intent.getComponent() == null) { 11275 registeredReceivers = mReceiverResolver.queryIntent(intent, 11276 resolvedType, false, userId); 11277 } 11278 } catch (RemoteException ex) { 11279 // pm is in same process, this will never happen. 11280 } 11281 11282 final boolean replacePending = 11283 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11284 11285 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11286 + " replacePending=" + replacePending); 11287 11288 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11289 if (!ordered && NR > 0) { 11290 // If we are not serializing this broadcast, then send the 11291 // registered receivers separately so they don't wait for the 11292 // components to be launched. 11293 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11294 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11295 callerPackage, callingPid, callingUid, requiredPermission, 11296 registeredReceivers, resultTo, resultCode, resultData, map, 11297 ordered, sticky, false, onlySendToCaller, userId); 11298 if (DEBUG_BROADCAST) Slog.v( 11299 TAG, "Enqueueing parallel broadcast " + r); 11300 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11301 if (!replaced) { 11302 queue.enqueueParallelBroadcastLocked(r); 11303 queue.scheduleBroadcastsLocked(); 11304 } 11305 registeredReceivers = null; 11306 NR = 0; 11307 } 11308 11309 // Merge into one list. 11310 int ir = 0; 11311 if (receivers != null) { 11312 // A special case for PACKAGE_ADDED: do not allow the package 11313 // being added to see this broadcast. This prevents them from 11314 // using this as a back door to get run as soon as they are 11315 // installed. Maybe in the future we want to have a special install 11316 // broadcast or such for apps, but we'd like to deliberately make 11317 // this decision. 11318 String skipPackages[] = null; 11319 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11320 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11321 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11322 Uri data = intent.getData(); 11323 if (data != null) { 11324 String pkgName = data.getSchemeSpecificPart(); 11325 if (pkgName != null) { 11326 skipPackages = new String[] { pkgName }; 11327 } 11328 } 11329 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11330 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11331 } 11332 if (skipPackages != null && (skipPackages.length > 0)) { 11333 for (String skipPackage : skipPackages) { 11334 if (skipPackage != null) { 11335 int NT = receivers.size(); 11336 for (int it=0; it<NT; it++) { 11337 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11338 if (curt.activityInfo.packageName.equals(skipPackage)) { 11339 receivers.remove(it); 11340 it--; 11341 NT--; 11342 } 11343 } 11344 } 11345 } 11346 } 11347 11348 int NT = receivers != null ? receivers.size() : 0; 11349 int it = 0; 11350 ResolveInfo curt = null; 11351 BroadcastFilter curr = null; 11352 while (it < NT && ir < NR) { 11353 if (curt == null) { 11354 curt = (ResolveInfo)receivers.get(it); 11355 } 11356 if (curr == null) { 11357 curr = registeredReceivers.get(ir); 11358 } 11359 if (curr.getPriority() >= curt.priority) { 11360 // Insert this broadcast record into the final list. 11361 receivers.add(it, curr); 11362 ir++; 11363 curr = null; 11364 it++; 11365 NT++; 11366 } else { 11367 // Skip to the next ResolveInfo in the final list. 11368 it++; 11369 curt = null; 11370 } 11371 } 11372 } 11373 while (ir < NR) { 11374 if (receivers == null) { 11375 receivers = new ArrayList(); 11376 } 11377 receivers.add(registeredReceivers.get(ir)); 11378 ir++; 11379 } 11380 11381 if ((receivers != null && receivers.size() > 0) 11382 || resultTo != null) { 11383 BroadcastQueue queue = broadcastQueueForIntent(intent); 11384 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11385 callerPackage, callingPid, callingUid, requiredPermission, 11386 receivers, resultTo, resultCode, resultData, map, ordered, 11387 sticky, false, onlySendToCaller, userId); 11388 if (DEBUG_BROADCAST) Slog.v( 11389 TAG, "Enqueueing ordered broadcast " + r 11390 + ": prev had " + queue.mOrderedBroadcasts.size()); 11391 if (DEBUG_BROADCAST) { 11392 int seq = r.intent.getIntExtra("seq", -1); 11393 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11394 } 11395 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11396 if (!replaced) { 11397 queue.enqueueOrderedBroadcastLocked(r); 11398 queue.scheduleBroadcastsLocked(); 11399 } 11400 } 11401 11402 return ActivityManager.BROADCAST_SUCCESS; 11403 } 11404 11405 final Intent verifyBroadcastLocked(Intent intent) { 11406 // Refuse possible leaked file descriptors 11407 if (intent != null && intent.hasFileDescriptors() == true) { 11408 throw new IllegalArgumentException("File descriptors passed in Intent"); 11409 } 11410 11411 int flags = intent.getFlags(); 11412 11413 if (!mProcessesReady) { 11414 // if the caller really truly claims to know what they're doing, go 11415 // ahead and allow the broadcast without launching any receivers 11416 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11417 intent = new Intent(intent); 11418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11419 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11420 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11421 + " before boot completion"); 11422 throw new IllegalStateException("Cannot broadcast before boot completed"); 11423 } 11424 } 11425 11426 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11427 throw new IllegalArgumentException( 11428 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11429 } 11430 11431 return intent; 11432 } 11433 11434 public final int broadcastIntent(IApplicationThread caller, 11435 Intent intent, String resolvedType, IIntentReceiver resultTo, 11436 int resultCode, String resultData, Bundle map, 11437 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11438 enforceNotIsolatedCaller("broadcastIntent"); 11439 synchronized(this) { 11440 intent = verifyBroadcastLocked(intent); 11441 11442 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11443 final int callingPid = Binder.getCallingPid(); 11444 final int callingUid = Binder.getCallingUid(); 11445 final long origId = Binder.clearCallingIdentity(); 11446 int res = broadcastIntentLocked(callerApp, 11447 callerApp != null ? callerApp.info.packageName : null, 11448 intent, resolvedType, resultTo, 11449 resultCode, resultData, map, requiredPermission, serialized, sticky, 11450 callingPid, callingUid, userId); 11451 Binder.restoreCallingIdentity(origId); 11452 return res; 11453 } 11454 } 11455 11456 int broadcastIntentInPackage(String packageName, int uid, 11457 Intent intent, String resolvedType, IIntentReceiver resultTo, 11458 int resultCode, String resultData, Bundle map, 11459 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11460 synchronized(this) { 11461 intent = verifyBroadcastLocked(intent); 11462 11463 final long origId = Binder.clearCallingIdentity(); 11464 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11465 resultTo, resultCode, resultData, map, requiredPermission, 11466 serialized, sticky, -1, uid, userId); 11467 Binder.restoreCallingIdentity(origId); 11468 return res; 11469 } 11470 } 11471 11472 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11473 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11474 // Refuse possible leaked file descriptors 11475 if (intent != null && intent.hasFileDescriptors() == true) { 11476 throw new IllegalArgumentException("File descriptors passed in Intent"); 11477 } 11478 11479 synchronized(this) { 11480 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11481 != PackageManager.PERMISSION_GRANTED) { 11482 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11483 + Binder.getCallingPid() 11484 + ", uid=" + Binder.getCallingUid() 11485 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11486 Slog.w(TAG, msg); 11487 throw new SecurityException(msg); 11488 } 11489 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11490 if (list != null) { 11491 int N = list.size(); 11492 int i; 11493 for (i=0; i<N; i++) { 11494 if (intent.filterEquals(list.get(i))) { 11495 list.remove(i); 11496 break; 11497 } 11498 } 11499 } 11500 } 11501 } 11502 11503 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11504 String resultData, Bundle resultExtras, boolean resultAbort, 11505 boolean explicit) { 11506 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11507 if (r == null) { 11508 Slog.w(TAG, "finishReceiver called but not found on queue"); 11509 return false; 11510 } 11511 11512 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11513 explicit); 11514 } 11515 11516 public void finishReceiver(IBinder who, int resultCode, String resultData, 11517 Bundle resultExtras, boolean resultAbort) { 11518 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11519 11520 // Refuse possible leaked file descriptors 11521 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11522 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11523 } 11524 11525 final long origId = Binder.clearCallingIdentity(); 11526 try { 11527 boolean doNext = false; 11528 BroadcastRecord r = null; 11529 11530 synchronized(this) { 11531 r = broadcastRecordForReceiverLocked(who); 11532 if (r != null) { 11533 doNext = r.queue.finishReceiverLocked(r, resultCode, 11534 resultData, resultExtras, resultAbort, true); 11535 } 11536 } 11537 11538 if (doNext) { 11539 r.queue.processNextBroadcast(false); 11540 } 11541 trimApplications(); 11542 } finally { 11543 Binder.restoreCallingIdentity(origId); 11544 } 11545 } 11546 11547 // ========================================================= 11548 // INSTRUMENTATION 11549 // ========================================================= 11550 11551 public boolean startInstrumentation(ComponentName className, 11552 String profileFile, int flags, Bundle arguments, 11553 IInstrumentationWatcher watcher) { 11554 enforceNotIsolatedCaller("startInstrumentation"); 11555 // Refuse possible leaked file descriptors 11556 if (arguments != null && arguments.hasFileDescriptors()) { 11557 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11558 } 11559 11560 synchronized(this) { 11561 InstrumentationInfo ii = null; 11562 ApplicationInfo ai = null; 11563 try { 11564 ii = mContext.getPackageManager().getInstrumentationInfo( 11565 className, STOCK_PM_FLAGS); 11566 ai = mContext.getPackageManager().getApplicationInfo( 11567 ii.targetPackage, STOCK_PM_FLAGS); 11568 } catch (PackageManager.NameNotFoundException e) { 11569 } 11570 if (ii == null) { 11571 reportStartInstrumentationFailure(watcher, className, 11572 "Unable to find instrumentation info for: " + className); 11573 return false; 11574 } 11575 if (ai == null) { 11576 reportStartInstrumentationFailure(watcher, className, 11577 "Unable to find instrumentation target package: " + ii.targetPackage); 11578 return false; 11579 } 11580 11581 int match = mContext.getPackageManager().checkSignatures( 11582 ii.targetPackage, ii.packageName); 11583 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11584 String msg = "Permission Denial: starting instrumentation " 11585 + className + " from pid=" 11586 + Binder.getCallingPid() 11587 + ", uid=" + Binder.getCallingPid() 11588 + " not allowed because package " + ii.packageName 11589 + " does not have a signature matching the target " 11590 + ii.targetPackage; 11591 reportStartInstrumentationFailure(watcher, className, msg); 11592 throw new SecurityException(msg); 11593 } 11594 11595 int userId = UserHandle.getCallingUserId(); 11596 final long origId = Binder.clearCallingIdentity(); 11597 // Instrumentation can kill and relaunch even persistent processes 11598 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11599 ProcessRecord app = addAppLocked(ai, false); 11600 app.instrumentationClass = className; 11601 app.instrumentationInfo = ai; 11602 app.instrumentationProfileFile = profileFile; 11603 app.instrumentationArguments = arguments; 11604 app.instrumentationWatcher = watcher; 11605 app.instrumentationResultClass = className; 11606 Binder.restoreCallingIdentity(origId); 11607 } 11608 11609 return true; 11610 } 11611 11612 /** 11613 * Report errors that occur while attempting to start Instrumentation. Always writes the 11614 * error to the logs, but if somebody is watching, send the report there too. This enables 11615 * the "am" command to report errors with more information. 11616 * 11617 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11618 * @param cn The component name of the instrumentation. 11619 * @param report The error report. 11620 */ 11621 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11622 ComponentName cn, String report) { 11623 Slog.w(TAG, report); 11624 try { 11625 if (watcher != null) { 11626 Bundle results = new Bundle(); 11627 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11628 results.putString("Error", report); 11629 watcher.instrumentationStatus(cn, -1, results); 11630 } 11631 } catch (RemoteException e) { 11632 Slog.w(TAG, e); 11633 } 11634 } 11635 11636 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11637 if (app.instrumentationWatcher != null) { 11638 try { 11639 // NOTE: IInstrumentationWatcher *must* be oneway here 11640 app.instrumentationWatcher.instrumentationFinished( 11641 app.instrumentationClass, 11642 resultCode, 11643 results); 11644 } catch (RemoteException e) { 11645 } 11646 } 11647 app.instrumentationWatcher = null; 11648 app.instrumentationClass = null; 11649 app.instrumentationInfo = null; 11650 app.instrumentationProfileFile = null; 11651 app.instrumentationArguments = null; 11652 11653 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11654 } 11655 11656 public void finishInstrumentation(IApplicationThread target, 11657 int resultCode, Bundle results) { 11658 int userId = UserHandle.getCallingUserId(); 11659 // Refuse possible leaked file descriptors 11660 if (results != null && results.hasFileDescriptors()) { 11661 throw new IllegalArgumentException("File descriptors passed in Intent"); 11662 } 11663 11664 synchronized(this) { 11665 ProcessRecord app = getRecordForAppLocked(target); 11666 if (app == null) { 11667 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11668 return; 11669 } 11670 final long origId = Binder.clearCallingIdentity(); 11671 finishInstrumentationLocked(app, resultCode, results); 11672 Binder.restoreCallingIdentity(origId); 11673 } 11674 } 11675 11676 // ========================================================= 11677 // CONFIGURATION 11678 // ========================================================= 11679 11680 public ConfigurationInfo getDeviceConfigurationInfo() { 11681 ConfigurationInfo config = new ConfigurationInfo(); 11682 synchronized (this) { 11683 config.reqTouchScreen = mConfiguration.touchscreen; 11684 config.reqKeyboardType = mConfiguration.keyboard; 11685 config.reqNavigation = mConfiguration.navigation; 11686 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11687 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11688 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11689 } 11690 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11691 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11692 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11693 } 11694 config.reqGlEsVersion = GL_ES_VERSION; 11695 } 11696 return config; 11697 } 11698 11699 public Configuration getConfiguration() { 11700 Configuration ci; 11701 synchronized(this) { 11702 ci = new Configuration(mConfiguration); 11703 } 11704 return ci; 11705 } 11706 11707 public void updatePersistentConfiguration(Configuration values) { 11708 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11709 "updateConfiguration()"); 11710 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11711 "updateConfiguration()"); 11712 if (values == null) { 11713 throw new NullPointerException("Configuration must not be null"); 11714 } 11715 11716 synchronized(this) { 11717 final long origId = Binder.clearCallingIdentity(); 11718 updateConfigurationLocked(values, null, true, false); 11719 Binder.restoreCallingIdentity(origId); 11720 } 11721 } 11722 11723 public void updateConfiguration(Configuration values) { 11724 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11725 "updateConfiguration()"); 11726 11727 synchronized(this) { 11728 if (values == null && mWindowManager != null) { 11729 // sentinel: fetch the current configuration from the window manager 11730 values = mWindowManager.computeNewConfiguration(); 11731 } 11732 11733 if (mWindowManager != null) { 11734 mProcessList.applyDisplaySize(mWindowManager); 11735 } 11736 11737 final long origId = Binder.clearCallingIdentity(); 11738 if (values != null) { 11739 Settings.System.clearConfiguration(values); 11740 } 11741 updateConfigurationLocked(values, null, false, false); 11742 Binder.restoreCallingIdentity(origId); 11743 } 11744 } 11745 11746 /** 11747 * Do either or both things: (1) change the current configuration, and (2) 11748 * make sure the given activity is running with the (now) current 11749 * configuration. Returns true if the activity has been left running, or 11750 * false if <var>starting</var> is being destroyed to match the new 11751 * configuration. 11752 * @param persistent TODO 11753 */ 11754 boolean updateConfigurationLocked(Configuration values, 11755 ActivityRecord starting, boolean persistent, boolean initLocale) { 11756 // do nothing if we are headless 11757 if (mHeadless) return true; 11758 11759 int changes = 0; 11760 11761 boolean kept = true; 11762 11763 if (values != null) { 11764 Configuration newConfig = new Configuration(mConfiguration); 11765 changes = newConfig.updateFrom(values); 11766 if (changes != 0) { 11767 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11768 Slog.i(TAG, "Updating configuration to: " + values); 11769 } 11770 11771 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11772 11773 if (values.locale != null && !initLocale) { 11774 saveLocaleLocked(values.locale, 11775 !values.locale.equals(mConfiguration.locale), 11776 values.userSetLocale); 11777 } 11778 11779 mConfigurationSeq++; 11780 if (mConfigurationSeq <= 0) { 11781 mConfigurationSeq = 1; 11782 } 11783 newConfig.seq = mConfigurationSeq; 11784 mConfiguration = newConfig; 11785 Slog.i(TAG, "Config changed: " + newConfig); 11786 11787 final Configuration configCopy = new Configuration(mConfiguration); 11788 11789 // TODO: If our config changes, should we auto dismiss any currently 11790 // showing dialogs? 11791 mShowDialogs = shouldShowDialogs(newConfig); 11792 11793 AttributeCache ac = AttributeCache.instance(); 11794 if (ac != null) { 11795 ac.updateConfiguration(configCopy); 11796 } 11797 11798 // Make sure all resources in our process are updated 11799 // right now, so that anyone who is going to retrieve 11800 // resource values after we return will be sure to get 11801 // the new ones. This is especially important during 11802 // boot, where the first config change needs to guarantee 11803 // all resources have that config before following boot 11804 // code is executed. 11805 mSystemThread.applyConfigurationToResources(configCopy); 11806 11807 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11808 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11809 msg.obj = new Configuration(configCopy); 11810 mHandler.sendMessage(msg); 11811 } 11812 11813 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11814 ProcessRecord app = mLruProcesses.get(i); 11815 try { 11816 if (app.thread != null) { 11817 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11818 + app.processName + " new config " + mConfiguration); 11819 app.thread.scheduleConfigurationChanged(configCopy); 11820 } 11821 } catch (Exception e) { 11822 } 11823 } 11824 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11825 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11826 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11827 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11828 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11829 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11830 broadcastIntentLocked(null, null, 11831 new Intent(Intent.ACTION_LOCALE_CHANGED), 11832 null, null, 0, null, null, 11833 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11834 } 11835 } 11836 } 11837 11838 if (changes != 0 && starting == null) { 11839 // If the configuration changed, and the caller is not already 11840 // in the process of starting an activity, then find the top 11841 // activity to check if its configuration needs to change. 11842 starting = mMainStack.topRunningActivityLocked(null); 11843 } 11844 11845 if (starting != null) { 11846 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11847 // And we need to make sure at this point that all other activities 11848 // are made visible with the correct configuration. 11849 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11850 } 11851 11852 if (values != null && mWindowManager != null) { 11853 mWindowManager.setNewConfiguration(mConfiguration); 11854 } 11855 11856 return kept; 11857 } 11858 11859 /** 11860 * Decide based on the configuration whether we should shouw the ANR, 11861 * crash, etc dialogs. The idea is that if there is no affordnace to 11862 * press the on-screen buttons, we shouldn't show the dialog. 11863 * 11864 * A thought: SystemUI might also want to get told about this, the Power 11865 * dialog / global actions also might want different behaviors. 11866 */ 11867 private static final boolean shouldShowDialogs(Configuration config) { 11868 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11869 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11870 } 11871 11872 /** 11873 * Save the locale. You must be inside a synchronized (this) block. 11874 */ 11875 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11876 if(isDiff) { 11877 SystemProperties.set("user.language", l.getLanguage()); 11878 SystemProperties.set("user.region", l.getCountry()); 11879 } 11880 11881 if(isPersist) { 11882 SystemProperties.set("persist.sys.language", l.getLanguage()); 11883 SystemProperties.set("persist.sys.country", l.getCountry()); 11884 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11885 } 11886 } 11887 11888 @Override 11889 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11890 ActivityRecord srec = ActivityRecord.forToken(token); 11891 return srec != null && srec.task.affinity != null && 11892 srec.task.affinity.equals(destAffinity); 11893 } 11894 11895 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11896 Intent resultData) { 11897 ComponentName dest = destIntent.getComponent(); 11898 11899 synchronized (this) { 11900 ActivityRecord srec = ActivityRecord.forToken(token); 11901 if (srec == null) { 11902 return false; 11903 } 11904 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11905 final int start = history.indexOf(srec); 11906 if (start < 0) { 11907 // Current activity is not in history stack; do nothing. 11908 return false; 11909 } 11910 int finishTo = start - 1; 11911 ActivityRecord parent = null; 11912 boolean foundParentInTask = false; 11913 if (dest != null) { 11914 TaskRecord tr = srec.task; 11915 for (int i = start - 1; i >= 0; i--) { 11916 ActivityRecord r = history.get(i); 11917 if (tr != r.task) { 11918 // Couldn't find parent in the same task; stop at the one above this. 11919 // (Root of current task; in-app "home" behavior) 11920 // Always at least finish the current activity. 11921 finishTo = Math.min(start - 1, i + 1); 11922 parent = history.get(finishTo); 11923 break; 11924 } else if (r.info.packageName.equals(dest.getPackageName()) && 11925 r.info.name.equals(dest.getClassName())) { 11926 finishTo = i; 11927 parent = r; 11928 foundParentInTask = true; 11929 break; 11930 } 11931 } 11932 } 11933 11934 if (mController != null) { 11935 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11936 if (next != null) { 11937 // ask watcher if this is allowed 11938 boolean resumeOK = true; 11939 try { 11940 resumeOK = mController.activityResuming(next.packageName); 11941 } catch (RemoteException e) { 11942 mController = null; 11943 } 11944 11945 if (!resumeOK) { 11946 return false; 11947 } 11948 } 11949 } 11950 final long origId = Binder.clearCallingIdentity(); 11951 for (int i = start; i > finishTo; i--) { 11952 ActivityRecord r = history.get(i); 11953 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11954 "navigate-up"); 11955 // Only return the supplied result for the first activity finished 11956 resultCode = Activity.RESULT_CANCELED; 11957 resultData = null; 11958 } 11959 11960 if (parent != null && foundParentInTask) { 11961 final int parentLaunchMode = parent.info.launchMode; 11962 final int destIntentFlags = destIntent.getFlags(); 11963 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11964 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11965 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11966 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11967 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11968 } else { 11969 try { 11970 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11971 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11972 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11973 null, aInfo, parent.appToken, null, 11974 0, -1, parent.launchedFromUid, 0, null, true, null); 11975 foundParentInTask = res == ActivityManager.START_SUCCESS; 11976 } catch (RemoteException e) { 11977 foundParentInTask = false; 11978 } 11979 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11980 resultData, "navigate-up"); 11981 } 11982 } 11983 Binder.restoreCallingIdentity(origId); 11984 return foundParentInTask; 11985 } 11986 } 11987 11988 public int getLaunchedFromUid(IBinder activityToken) { 11989 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11990 if (srec == null) { 11991 return -1; 11992 } 11993 return srec.launchedFromUid; 11994 } 11995 11996 // ========================================================= 11997 // LIFETIME MANAGEMENT 11998 // ========================================================= 11999 12000 // Returns which broadcast queue the app is the current [or imminent] receiver 12001 // on, or 'null' if the app is not an active broadcast recipient. 12002 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12003 BroadcastRecord r = app.curReceiver; 12004 if (r != null) { 12005 return r.queue; 12006 } 12007 12008 // It's not the current receiver, but it might be starting up to become one 12009 synchronized (this) { 12010 for (BroadcastQueue queue : mBroadcastQueues) { 12011 r = queue.mPendingBroadcast; 12012 if (r != null && r.curApp == app) { 12013 // found it; report which queue it's in 12014 return queue; 12015 } 12016 } 12017 } 12018 12019 return null; 12020 } 12021 12022 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12023 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12024 if (mAdjSeq == app.adjSeq) { 12025 // This adjustment has already been computed. If we are calling 12026 // from the top, we may have already computed our adjustment with 12027 // an earlier hidden adjustment that isn't really for us... if 12028 // so, use the new hidden adjustment. 12029 if (!recursed && app.hidden) { 12030 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12031 app.hasActivities ? hiddenAdj : emptyAdj; 12032 } 12033 return app.curRawAdj; 12034 } 12035 12036 if (app.thread == null) { 12037 app.adjSeq = mAdjSeq; 12038 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12039 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12040 } 12041 12042 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12043 app.adjSource = null; 12044 app.adjTarget = null; 12045 app.empty = false; 12046 app.hidden = false; 12047 12048 final int activitiesSize = app.activities.size(); 12049 12050 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12051 // The max adjustment doesn't allow this app to be anything 12052 // below foreground, so it is not worth doing work for it. 12053 app.adjType = "fixed"; 12054 app.adjSeq = mAdjSeq; 12055 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12056 app.hasActivities = false; 12057 app.foregroundActivities = false; 12058 app.keeping = true; 12059 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12060 // System process can do UI, and when they do we want to have 12061 // them trim their memory after the user leaves the UI. To 12062 // facilitate this, here we need to determine whether or not it 12063 // is currently showing UI. 12064 app.systemNoUi = true; 12065 if (app == TOP_APP) { 12066 app.systemNoUi = false; 12067 app.hasActivities = true; 12068 } else if (activitiesSize > 0) { 12069 for (int j = 0; j < activitiesSize; j++) { 12070 final ActivityRecord r = app.activities.get(j); 12071 if (r.visible) { 12072 app.systemNoUi = false; 12073 } 12074 if (r.app == app) { 12075 app.hasActivities = true; 12076 } 12077 } 12078 } 12079 return (app.curAdj=app.maxAdj); 12080 } 12081 12082 app.keeping = false; 12083 app.systemNoUi = false; 12084 app.hasActivities = false; 12085 12086 // Determine the importance of the process, starting with most 12087 // important to least, and assign an appropriate OOM adjustment. 12088 int adj; 12089 int schedGroup; 12090 boolean foregroundActivities = false; 12091 boolean interesting = false; 12092 BroadcastQueue queue; 12093 if (app == TOP_APP) { 12094 // The last app on the list is the foreground app. 12095 adj = ProcessList.FOREGROUND_APP_ADJ; 12096 schedGroup = Process.THREAD_GROUP_DEFAULT; 12097 app.adjType = "top-activity"; 12098 foregroundActivities = true; 12099 interesting = true; 12100 app.hasActivities = true; 12101 } else if (app.instrumentationClass != null) { 12102 // Don't want to kill running instrumentation. 12103 adj = ProcessList.FOREGROUND_APP_ADJ; 12104 schedGroup = Process.THREAD_GROUP_DEFAULT; 12105 app.adjType = "instrumentation"; 12106 interesting = true; 12107 } else if ((queue = isReceivingBroadcast(app)) != null) { 12108 // An app that is currently receiving a broadcast also 12109 // counts as being in the foreground for OOM killer purposes. 12110 // It's placed in a sched group based on the nature of the 12111 // broadcast as reflected by which queue it's active in. 12112 adj = ProcessList.FOREGROUND_APP_ADJ; 12113 schedGroup = (queue == mFgBroadcastQueue) 12114 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12115 app.adjType = "broadcast"; 12116 } else if (app.executingServices.size() > 0) { 12117 // An app that is currently executing a service callback also 12118 // counts as being in the foreground. 12119 adj = ProcessList.FOREGROUND_APP_ADJ; 12120 schedGroup = Process.THREAD_GROUP_DEFAULT; 12121 app.adjType = "exec-service"; 12122 } else { 12123 // Assume process is hidden (has activities); we will correct 12124 // later if this is not the case. 12125 adj = hiddenAdj; 12126 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12127 app.hidden = true; 12128 app.adjType = "bg-activities"; 12129 } 12130 12131 boolean hasStoppingActivities = false; 12132 12133 // Examine all activities if not already foreground. 12134 if (!foregroundActivities && activitiesSize > 0) { 12135 for (int j = 0; j < activitiesSize; j++) { 12136 final ActivityRecord r = app.activities.get(j); 12137 if (r.visible) { 12138 // App has a visible activity; only upgrade adjustment. 12139 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12140 adj = ProcessList.VISIBLE_APP_ADJ; 12141 app.adjType = "visible"; 12142 } 12143 schedGroup = Process.THREAD_GROUP_DEFAULT; 12144 app.hidden = false; 12145 app.hasActivities = true; 12146 foregroundActivities = true; 12147 break; 12148 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12149 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12150 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12151 app.adjType = "pausing"; 12152 } 12153 app.hidden = false; 12154 foregroundActivities = true; 12155 } else if (r.state == ActivityState.STOPPING) { 12156 // We will apply the actual adjustment later, because 12157 // we want to allow this process to immediately go through 12158 // any memory trimming that is in effect. 12159 app.hidden = false; 12160 foregroundActivities = true; 12161 hasStoppingActivities = true; 12162 } 12163 if (r.app == app) { 12164 app.hasActivities = true; 12165 } 12166 } 12167 } 12168 12169 if (adj == hiddenAdj && !app.hasActivities) { 12170 // Whoops, this process is completely empty as far as we know 12171 // at this point. 12172 adj = emptyAdj; 12173 app.empty = true; 12174 app.adjType = "bg-empty"; 12175 } 12176 12177 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12178 if (app.foregroundServices) { 12179 // The user is aware of this app, so make it visible. 12180 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12181 app.hidden = false; 12182 app.adjType = "foreground-service"; 12183 schedGroup = Process.THREAD_GROUP_DEFAULT; 12184 } else if (app.forcingToForeground != null) { 12185 // The user is aware of this app, so make it visible. 12186 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12187 app.hidden = false; 12188 app.adjType = "force-foreground"; 12189 app.adjSource = app.forcingToForeground; 12190 schedGroup = Process.THREAD_GROUP_DEFAULT; 12191 } 12192 } 12193 12194 if (app.foregroundServices) { 12195 interesting = true; 12196 } 12197 12198 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12199 // We don't want to kill the current heavy-weight process. 12200 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12201 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12202 app.hidden = false; 12203 app.adjType = "heavy"; 12204 } 12205 12206 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12207 // This process is hosting what we currently consider to be the 12208 // home app, so we don't want to let it go into the background. 12209 adj = ProcessList.HOME_APP_ADJ; 12210 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12211 app.hidden = false; 12212 app.adjType = "home"; 12213 } 12214 12215 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12216 && app.activities.size() > 0) { 12217 // This was the previous process that showed UI to the user. 12218 // We want to try to keep it around more aggressively, to give 12219 // a good experience around switching between two apps. 12220 adj = ProcessList.PREVIOUS_APP_ADJ; 12221 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12222 app.hidden = false; 12223 app.adjType = "previous"; 12224 } 12225 12226 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12227 + " reason=" + app.adjType); 12228 12229 // By default, we use the computed adjustment. It may be changed if 12230 // there are applications dependent on our services or providers, but 12231 // this gives us a baseline and makes sure we don't get into an 12232 // infinite recursion. 12233 app.adjSeq = mAdjSeq; 12234 app.curRawAdj = app.nonStoppingAdj = adj; 12235 12236 if (mBackupTarget != null && app == mBackupTarget.app) { 12237 // If possible we want to avoid killing apps while they're being backed up 12238 if (adj > ProcessList.BACKUP_APP_ADJ) { 12239 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12240 adj = ProcessList.BACKUP_APP_ADJ; 12241 app.adjType = "backup"; 12242 app.hidden = false; 12243 } 12244 } 12245 12246 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12247 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12248 final long now = SystemClock.uptimeMillis(); 12249 // This process is more important if the top activity is 12250 // bound to the service. 12251 Iterator<ServiceRecord> jt = app.services.iterator(); 12252 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12253 ServiceRecord s = jt.next(); 12254 if (s.startRequested) { 12255 if (app.hasShownUi && app != mHomeProcess) { 12256 // If this process has shown some UI, let it immediately 12257 // go to the LRU list because it may be pretty heavy with 12258 // UI stuff. We'll tag it with a label just to help 12259 // debug and understand what is going on. 12260 if (adj > ProcessList.SERVICE_ADJ) { 12261 app.adjType = "started-bg-ui-services"; 12262 } 12263 } else { 12264 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12265 // This service has seen some activity within 12266 // recent memory, so we will keep its process ahead 12267 // of the background processes. 12268 if (adj > ProcessList.SERVICE_ADJ) { 12269 adj = ProcessList.SERVICE_ADJ; 12270 app.adjType = "started-services"; 12271 app.hidden = false; 12272 } 12273 } 12274 // If we have let the service slide into the background 12275 // state, still have some text describing what it is doing 12276 // even though the service no longer has an impact. 12277 if (adj > ProcessList.SERVICE_ADJ) { 12278 app.adjType = "started-bg-services"; 12279 } 12280 } 12281 // Don't kill this process because it is doing work; it 12282 // has said it is doing work. 12283 app.keeping = true; 12284 } 12285 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12286 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12287 Iterator<ArrayList<ConnectionRecord>> kt 12288 = s.connections.values().iterator(); 12289 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12290 ArrayList<ConnectionRecord> clist = kt.next(); 12291 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12292 // XXX should compute this based on the max of 12293 // all connected clients. 12294 ConnectionRecord cr = clist.get(i); 12295 if (cr.binding.client == app) { 12296 // Binding to ourself is not interesting. 12297 continue; 12298 } 12299 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12300 ProcessRecord client = cr.binding.client; 12301 int clientAdj = adj; 12302 int myHiddenAdj = hiddenAdj; 12303 if (myHiddenAdj > client.hiddenAdj) { 12304 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12305 myHiddenAdj = client.hiddenAdj; 12306 } else { 12307 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12308 } 12309 } 12310 int myEmptyAdj = emptyAdj; 12311 if (myEmptyAdj > client.emptyAdj) { 12312 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12313 myEmptyAdj = client.emptyAdj; 12314 } else { 12315 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12316 } 12317 } 12318 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12319 myEmptyAdj, TOP_APP, true, doingAll); 12320 String adjType = null; 12321 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12322 // Not doing bind OOM management, so treat 12323 // this guy more like a started service. 12324 if (app.hasShownUi && app != mHomeProcess) { 12325 // If this process has shown some UI, let it immediately 12326 // go to the LRU list because it may be pretty heavy with 12327 // UI stuff. We'll tag it with a label just to help 12328 // debug and understand what is going on. 12329 if (adj > clientAdj) { 12330 adjType = "bound-bg-ui-services"; 12331 } 12332 app.hidden = false; 12333 clientAdj = adj; 12334 } else { 12335 if (now >= (s.lastActivity 12336 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12337 // This service has not seen activity within 12338 // recent memory, so allow it to drop to the 12339 // LRU list if there is no other reason to keep 12340 // it around. We'll also tag it with a label just 12341 // to help debug and undertand what is going on. 12342 if (adj > clientAdj) { 12343 adjType = "bound-bg-services"; 12344 } 12345 clientAdj = adj; 12346 } 12347 } 12348 } 12349 if (adj > clientAdj) { 12350 // If this process has recently shown UI, and 12351 // the process that is binding to it is less 12352 // important than being visible, then we don't 12353 // care about the binding as much as we care 12354 // about letting this process get into the LRU 12355 // list to be killed and restarted if needed for 12356 // memory. 12357 if (app.hasShownUi && app != mHomeProcess 12358 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12359 adjType = "bound-bg-ui-services"; 12360 } else { 12361 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12362 |Context.BIND_IMPORTANT)) != 0) { 12363 adj = clientAdj; 12364 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12365 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12366 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12367 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12368 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12369 adj = clientAdj; 12370 } else { 12371 app.pendingUiClean = true; 12372 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12373 adj = ProcessList.VISIBLE_APP_ADJ; 12374 } 12375 } 12376 if (!client.hidden) { 12377 app.hidden = false; 12378 } 12379 if (client.keeping) { 12380 app.keeping = true; 12381 } 12382 adjType = "service"; 12383 } 12384 } 12385 if (adjType != null) { 12386 app.adjType = adjType; 12387 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12388 .REASON_SERVICE_IN_USE; 12389 app.adjSource = cr.binding.client; 12390 app.adjSourceOom = clientAdj; 12391 app.adjTarget = s.name; 12392 } 12393 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12394 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12395 schedGroup = Process.THREAD_GROUP_DEFAULT; 12396 } 12397 } 12398 } 12399 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12400 ActivityRecord a = cr.activity; 12401 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12402 (a.visible || a.state == ActivityState.RESUMED 12403 || a.state == ActivityState.PAUSING)) { 12404 adj = ProcessList.FOREGROUND_APP_ADJ; 12405 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12406 schedGroup = Process.THREAD_GROUP_DEFAULT; 12407 } 12408 app.hidden = false; 12409 app.adjType = "service"; 12410 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12411 .REASON_SERVICE_IN_USE; 12412 app.adjSource = a; 12413 app.adjSourceOom = adj; 12414 app.adjTarget = s.name; 12415 } 12416 } 12417 } 12418 } 12419 } 12420 } 12421 12422 // Finally, if this process has active services running in it, we 12423 // would like to avoid killing it unless it would prevent the current 12424 // application from running. By default we put the process in 12425 // with the rest of the background processes; as we scan through 12426 // its services we may bump it up from there. 12427 if (adj > hiddenAdj) { 12428 adj = hiddenAdj; 12429 app.hidden = false; 12430 app.adjType = "bg-services"; 12431 } 12432 } 12433 12434 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12435 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12436 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12437 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12438 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12439 ContentProviderRecord cpr = jt.next(); 12440 for (int i = cpr.connections.size()-1; 12441 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12442 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12443 i--) { 12444 ContentProviderConnection conn = cpr.connections.get(i); 12445 ProcessRecord client = conn.client; 12446 if (client == app) { 12447 // Being our own client is not interesting. 12448 continue; 12449 } 12450 int myHiddenAdj = hiddenAdj; 12451 if (myHiddenAdj > client.hiddenAdj) { 12452 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12453 myHiddenAdj = client.hiddenAdj; 12454 } else { 12455 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12456 } 12457 } 12458 int myEmptyAdj = emptyAdj; 12459 if (myEmptyAdj > client.emptyAdj) { 12460 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12461 myEmptyAdj = client.emptyAdj; 12462 } else { 12463 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12464 } 12465 } 12466 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12467 myEmptyAdj, TOP_APP, true, doingAll); 12468 if (adj > clientAdj) { 12469 if (app.hasShownUi && app != mHomeProcess 12470 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12471 app.adjType = "bg-ui-provider"; 12472 } else { 12473 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12474 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12475 app.adjType = "provider"; 12476 } 12477 if (!client.hidden) { 12478 app.hidden = false; 12479 } 12480 if (client.keeping) { 12481 app.keeping = true; 12482 } 12483 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12484 .REASON_PROVIDER_IN_USE; 12485 app.adjSource = client; 12486 app.adjSourceOom = clientAdj; 12487 app.adjTarget = cpr.name; 12488 } 12489 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12490 schedGroup = Process.THREAD_GROUP_DEFAULT; 12491 } 12492 } 12493 // If the provider has external (non-framework) process 12494 // dependencies, ensure that its adjustment is at least 12495 // FOREGROUND_APP_ADJ. 12496 if (cpr.hasExternalProcessHandles()) { 12497 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12498 adj = ProcessList.FOREGROUND_APP_ADJ; 12499 schedGroup = Process.THREAD_GROUP_DEFAULT; 12500 app.hidden = false; 12501 app.keeping = true; 12502 app.adjType = "provider"; 12503 app.adjTarget = cpr.name; 12504 } 12505 } 12506 } 12507 } 12508 12509 if (adj == ProcessList.SERVICE_ADJ) { 12510 if (doingAll) { 12511 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12512 mNewNumServiceProcs++; 12513 } 12514 if (app.serviceb) { 12515 adj = ProcessList.SERVICE_B_ADJ; 12516 } 12517 } else { 12518 app.serviceb = false; 12519 } 12520 12521 app.nonStoppingAdj = adj; 12522 12523 if (hasStoppingActivities) { 12524 // Only upgrade adjustment. 12525 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12526 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12527 app.adjType = "stopping"; 12528 } 12529 } 12530 12531 app.curRawAdj = adj; 12532 12533 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12534 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12535 if (adj > app.maxAdj) { 12536 adj = app.maxAdj; 12537 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12538 schedGroup = Process.THREAD_GROUP_DEFAULT; 12539 } 12540 } 12541 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12542 app.keeping = true; 12543 } 12544 12545 if (app.hasAboveClient) { 12546 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12547 // then we need to drop its adjustment to be lower than the service's 12548 // in order to honor the request. We want to drop it by one adjustment 12549 // level... but there is special meaning applied to various levels so 12550 // we will skip some of them. 12551 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12552 // System process will not get dropped, ever 12553 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12554 adj = ProcessList.VISIBLE_APP_ADJ; 12555 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12556 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12557 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12558 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12559 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12560 adj++; 12561 } 12562 } 12563 12564 int importance = app.memImportance; 12565 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12566 app.curAdj = adj; 12567 app.curSchedGroup = schedGroup; 12568 if (!interesting) { 12569 // For this reporting, if there is not something explicitly 12570 // interesting in this process then we will push it to the 12571 // background importance. 12572 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12573 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12574 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12575 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12576 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12577 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12578 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12579 } else if (adj >= ProcessList.SERVICE_ADJ) { 12580 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12581 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12582 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12583 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12584 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12585 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12586 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12587 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12588 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12589 } else { 12590 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12591 } 12592 } 12593 12594 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12595 if (foregroundActivities != app.foregroundActivities) { 12596 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12597 } 12598 if (changes != 0) { 12599 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12600 app.memImportance = importance; 12601 app.foregroundActivities = foregroundActivities; 12602 int i = mPendingProcessChanges.size()-1; 12603 ProcessChangeItem item = null; 12604 while (i >= 0) { 12605 item = mPendingProcessChanges.get(i); 12606 if (item.pid == app.pid) { 12607 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12608 break; 12609 } 12610 i--; 12611 } 12612 if (i < 0) { 12613 // No existing item in pending changes; need a new one. 12614 final int NA = mAvailProcessChanges.size(); 12615 if (NA > 0) { 12616 item = mAvailProcessChanges.remove(NA-1); 12617 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12618 } else { 12619 item = new ProcessChangeItem(); 12620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12621 } 12622 item.changes = 0; 12623 item.pid = app.pid; 12624 item.uid = app.info.uid; 12625 if (mPendingProcessChanges.size() == 0) { 12626 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12627 "*** Enqueueing dispatch processes changed!"); 12628 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12629 } 12630 mPendingProcessChanges.add(item); 12631 } 12632 item.changes |= changes; 12633 item.importance = importance; 12634 item.foregroundActivities = foregroundActivities; 12635 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12636 + Integer.toHexString(System.identityHashCode(item)) 12637 + " " + app.toShortString() + ": changes=" + item.changes 12638 + " importance=" + item.importance 12639 + " foreground=" + item.foregroundActivities 12640 + " type=" + app.adjType + " source=" + app.adjSource 12641 + " target=" + app.adjTarget); 12642 } 12643 12644 return app.curRawAdj; 12645 } 12646 12647 /** 12648 * Ask a given process to GC right now. 12649 */ 12650 final void performAppGcLocked(ProcessRecord app) { 12651 try { 12652 app.lastRequestedGc = SystemClock.uptimeMillis(); 12653 if (app.thread != null) { 12654 if (app.reportLowMemory) { 12655 app.reportLowMemory = false; 12656 app.thread.scheduleLowMemory(); 12657 } else { 12658 app.thread.processInBackground(); 12659 } 12660 } 12661 } catch (Exception e) { 12662 // whatever. 12663 } 12664 } 12665 12666 /** 12667 * Returns true if things are idle enough to perform GCs. 12668 */ 12669 private final boolean canGcNowLocked() { 12670 boolean processingBroadcasts = false; 12671 for (BroadcastQueue q : mBroadcastQueues) { 12672 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12673 processingBroadcasts = true; 12674 } 12675 } 12676 return !processingBroadcasts 12677 && (mSleeping || (mMainStack.mResumedActivity != null && 12678 mMainStack.mResumedActivity.idle)); 12679 } 12680 12681 /** 12682 * Perform GCs on all processes that are waiting for it, but only 12683 * if things are idle. 12684 */ 12685 final void performAppGcsLocked() { 12686 final int N = mProcessesToGc.size(); 12687 if (N <= 0) { 12688 return; 12689 } 12690 if (canGcNowLocked()) { 12691 while (mProcessesToGc.size() > 0) { 12692 ProcessRecord proc = mProcessesToGc.remove(0); 12693 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12694 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12695 <= SystemClock.uptimeMillis()) { 12696 // To avoid spamming the system, we will GC processes one 12697 // at a time, waiting a few seconds between each. 12698 performAppGcLocked(proc); 12699 scheduleAppGcsLocked(); 12700 return; 12701 } else { 12702 // It hasn't been long enough since we last GCed this 12703 // process... put it in the list to wait for its time. 12704 addProcessToGcListLocked(proc); 12705 break; 12706 } 12707 } 12708 } 12709 12710 scheduleAppGcsLocked(); 12711 } 12712 } 12713 12714 /** 12715 * If all looks good, perform GCs on all processes waiting for them. 12716 */ 12717 final void performAppGcsIfAppropriateLocked() { 12718 if (canGcNowLocked()) { 12719 performAppGcsLocked(); 12720 return; 12721 } 12722 // Still not idle, wait some more. 12723 scheduleAppGcsLocked(); 12724 } 12725 12726 /** 12727 * Schedule the execution of all pending app GCs. 12728 */ 12729 final void scheduleAppGcsLocked() { 12730 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12731 12732 if (mProcessesToGc.size() > 0) { 12733 // Schedule a GC for the time to the next process. 12734 ProcessRecord proc = mProcessesToGc.get(0); 12735 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12736 12737 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12738 long now = SystemClock.uptimeMillis(); 12739 if (when < (now+GC_TIMEOUT)) { 12740 when = now + GC_TIMEOUT; 12741 } 12742 mHandler.sendMessageAtTime(msg, when); 12743 } 12744 } 12745 12746 /** 12747 * Add a process to the array of processes waiting to be GCed. Keeps the 12748 * list in sorted order by the last GC time. The process can't already be 12749 * on the list. 12750 */ 12751 final void addProcessToGcListLocked(ProcessRecord proc) { 12752 boolean added = false; 12753 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12754 if (mProcessesToGc.get(i).lastRequestedGc < 12755 proc.lastRequestedGc) { 12756 added = true; 12757 mProcessesToGc.add(i+1, proc); 12758 break; 12759 } 12760 } 12761 if (!added) { 12762 mProcessesToGc.add(0, proc); 12763 } 12764 } 12765 12766 /** 12767 * Set up to ask a process to GC itself. This will either do it 12768 * immediately, or put it on the list of processes to gc the next 12769 * time things are idle. 12770 */ 12771 final void scheduleAppGcLocked(ProcessRecord app) { 12772 long now = SystemClock.uptimeMillis(); 12773 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12774 return; 12775 } 12776 if (!mProcessesToGc.contains(app)) { 12777 addProcessToGcListLocked(app); 12778 scheduleAppGcsLocked(); 12779 } 12780 } 12781 12782 final void checkExcessivePowerUsageLocked(boolean doKills) { 12783 updateCpuStatsNow(); 12784 12785 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12786 boolean doWakeKills = doKills; 12787 boolean doCpuKills = doKills; 12788 if (mLastPowerCheckRealtime == 0) { 12789 doWakeKills = false; 12790 } 12791 if (mLastPowerCheckUptime == 0) { 12792 doCpuKills = false; 12793 } 12794 if (stats.isScreenOn()) { 12795 doWakeKills = false; 12796 } 12797 final long curRealtime = SystemClock.elapsedRealtime(); 12798 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12799 final long curUptime = SystemClock.uptimeMillis(); 12800 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12801 mLastPowerCheckRealtime = curRealtime; 12802 mLastPowerCheckUptime = curUptime; 12803 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12804 doWakeKills = false; 12805 } 12806 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12807 doCpuKills = false; 12808 } 12809 int i = mLruProcesses.size(); 12810 while (i > 0) { 12811 i--; 12812 ProcessRecord app = mLruProcesses.get(i); 12813 if (!app.keeping) { 12814 long wtime; 12815 synchronized (stats) { 12816 wtime = stats.getProcessWakeTime(app.info.uid, 12817 app.pid, curRealtime); 12818 } 12819 long wtimeUsed = wtime - app.lastWakeTime; 12820 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12821 if (DEBUG_POWER) { 12822 StringBuilder sb = new StringBuilder(128); 12823 sb.append("Wake for "); 12824 app.toShortString(sb); 12825 sb.append(": over "); 12826 TimeUtils.formatDuration(realtimeSince, sb); 12827 sb.append(" used "); 12828 TimeUtils.formatDuration(wtimeUsed, sb); 12829 sb.append(" ("); 12830 sb.append((wtimeUsed*100)/realtimeSince); 12831 sb.append("%)"); 12832 Slog.i(TAG, sb.toString()); 12833 sb.setLength(0); 12834 sb.append("CPU for "); 12835 app.toShortString(sb); 12836 sb.append(": over "); 12837 TimeUtils.formatDuration(uptimeSince, sb); 12838 sb.append(" used "); 12839 TimeUtils.formatDuration(cputimeUsed, sb); 12840 sb.append(" ("); 12841 sb.append((cputimeUsed*100)/uptimeSince); 12842 sb.append("%)"); 12843 Slog.i(TAG, sb.toString()); 12844 } 12845 // If a process has held a wake lock for more 12846 // than 50% of the time during this period, 12847 // that sounds bad. Kill! 12848 if (doWakeKills && realtimeSince > 0 12849 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12850 synchronized (stats) { 12851 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12852 realtimeSince, wtimeUsed); 12853 } 12854 Slog.w(TAG, "Excessive wake lock in " + app.processName 12855 + " (pid " + app.pid + "): held " + wtimeUsed 12856 + " during " + realtimeSince); 12857 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12858 app.processName, app.setAdj, "excessive wake lock"); 12859 Process.killProcessQuiet(app.pid); 12860 } else if (doCpuKills && uptimeSince > 0 12861 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12862 synchronized (stats) { 12863 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12864 uptimeSince, cputimeUsed); 12865 } 12866 Slog.w(TAG, "Excessive CPU in " + app.processName 12867 + " (pid " + app.pid + "): used " + cputimeUsed 12868 + " during " + uptimeSince); 12869 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12870 app.processName, app.setAdj, "excessive cpu"); 12871 Process.killProcessQuiet(app.pid); 12872 } else { 12873 app.lastWakeTime = wtime; 12874 app.lastCpuTime = app.curCpuTime; 12875 } 12876 } 12877 } 12878 } 12879 12880 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12881 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12882 app.hiddenAdj = hiddenAdj; 12883 app.emptyAdj = emptyAdj; 12884 12885 if (app.thread == null) { 12886 return false; 12887 } 12888 12889 final boolean wasKeeping = app.keeping; 12890 12891 boolean success = true; 12892 12893 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12894 12895 if (app.curRawAdj != app.setRawAdj) { 12896 if (wasKeeping && !app.keeping) { 12897 // This app is no longer something we want to keep. Note 12898 // its current wake lock time to later know to kill it if 12899 // it is not behaving well. 12900 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12901 synchronized (stats) { 12902 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12903 app.pid, SystemClock.elapsedRealtime()); 12904 } 12905 app.lastCpuTime = app.curCpuTime; 12906 } 12907 12908 app.setRawAdj = app.curRawAdj; 12909 } 12910 12911 if (app.curAdj != app.setAdj) { 12912 if (Process.setOomAdj(app.pid, app.curAdj)) { 12913 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12914 TAG, "Set " + app.pid + " " + app.processName + 12915 " adj " + app.curAdj + ": " + app.adjType); 12916 app.setAdj = app.curAdj; 12917 } else { 12918 success = false; 12919 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12920 } 12921 } 12922 if (app.setSchedGroup != app.curSchedGroup) { 12923 app.setSchedGroup = app.curSchedGroup; 12924 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12925 "Setting process group of " + app.processName 12926 + " to " + app.curSchedGroup); 12927 if (app.waitingToKill != null && 12928 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12929 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12930 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12931 app.processName, app.setAdj, app.waitingToKill); 12932 app.killedBackground = true; 12933 Process.killProcessQuiet(app.pid); 12934 success = false; 12935 } else { 12936 if (true) { 12937 long oldId = Binder.clearCallingIdentity(); 12938 try { 12939 Process.setProcessGroup(app.pid, app.curSchedGroup); 12940 } catch (Exception e) { 12941 Slog.w(TAG, "Failed setting process group of " + app.pid 12942 + " to " + app.curSchedGroup); 12943 e.printStackTrace(); 12944 } finally { 12945 Binder.restoreCallingIdentity(oldId); 12946 } 12947 } else { 12948 if (app.thread != null) { 12949 try { 12950 app.thread.setSchedulingGroup(app.curSchedGroup); 12951 } catch (RemoteException e) { 12952 } 12953 } 12954 } 12955 } 12956 } 12957 return success; 12958 } 12959 12960 private final ActivityRecord resumedAppLocked() { 12961 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12962 if (resumedActivity == null || resumedActivity.app == null) { 12963 resumedActivity = mMainStack.mPausingActivity; 12964 if (resumedActivity == null || resumedActivity.app == null) { 12965 resumedActivity = mMainStack.topRunningActivityLocked(null); 12966 } 12967 } 12968 return resumedActivity; 12969 } 12970 12971 final boolean updateOomAdjLocked(ProcessRecord app) { 12972 final ActivityRecord TOP_ACT = resumedAppLocked(); 12973 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12974 int curAdj = app.curAdj; 12975 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12976 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12977 12978 mAdjSeq++; 12979 12980 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12981 TOP_APP, false); 12982 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12983 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12984 if (nowHidden != wasHidden) { 12985 // Changed to/from hidden state, so apps after it in the LRU 12986 // list may also be changed. 12987 updateOomAdjLocked(); 12988 } 12989 return success; 12990 } 12991 12992 final void updateOomAdjLocked() { 12993 final ActivityRecord TOP_ACT = resumedAppLocked(); 12994 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12995 12996 if (false) { 12997 RuntimeException e = new RuntimeException(); 12998 e.fillInStackTrace(); 12999 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13000 } 13001 13002 mAdjSeq++; 13003 mNewNumServiceProcs = 0; 13004 13005 // Let's determine how many processes we have running vs. 13006 // how many slots we have for background processes; we may want 13007 // to put multiple processes in a slot of there are enough of 13008 // them. 13009 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13010 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13011 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13012 if (emptyFactor < 1) emptyFactor = 1; 13013 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13014 if (hiddenFactor < 1) hiddenFactor = 1; 13015 int stepHidden = 0; 13016 int stepEmpty = 0; 13017 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13018 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13019 int numHidden = 0; 13020 int numEmpty = 0; 13021 int numTrimming = 0; 13022 13023 mNumNonHiddenProcs = 0; 13024 mNumHiddenProcs = 0; 13025 13026 // First update the OOM adjustment for each of the 13027 // application processes based on their current state. 13028 int i = mLruProcesses.size(); 13029 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13030 int nextHiddenAdj = curHiddenAdj+1; 13031 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13032 int nextEmptyAdj = curEmptyAdj+2; 13033 while (i > 0) { 13034 i--; 13035 ProcessRecord app = mLruProcesses.get(i); 13036 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13037 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13038 if (!app.killedBackground) { 13039 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13040 // This process was assigned as a hidden process... step the 13041 // hidden level. 13042 mNumHiddenProcs++; 13043 if (curHiddenAdj != nextHiddenAdj) { 13044 stepHidden++; 13045 if (stepHidden >= hiddenFactor) { 13046 stepHidden = 0; 13047 curHiddenAdj = nextHiddenAdj; 13048 nextHiddenAdj += 2; 13049 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13050 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13051 } 13052 } 13053 } 13054 numHidden++; 13055 if (numHidden > hiddenProcessLimit) { 13056 Slog.i(TAG, "No longer want " + app.processName 13057 + " (pid " + app.pid + "): hidden #" + numHidden); 13058 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13059 app.processName, app.setAdj, "too many background"); 13060 app.killedBackground = true; 13061 Process.killProcessQuiet(app.pid); 13062 } 13063 } else { 13064 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13065 // This process was assigned as an empty process... step the 13066 // empty level. 13067 if (curEmptyAdj != nextEmptyAdj) { 13068 stepEmpty++; 13069 if (stepEmpty >= emptyFactor) { 13070 stepEmpty = 0; 13071 curEmptyAdj = nextEmptyAdj; 13072 nextEmptyAdj += 2; 13073 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13074 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13075 } 13076 } 13077 } 13078 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13079 mNumNonHiddenProcs++; 13080 } 13081 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13082 numEmpty++; 13083 if (numEmpty > emptyProcessLimit) { 13084 Slog.i(TAG, "No longer want " + app.processName 13085 + " (pid " + app.pid + "): empty #" + numEmpty); 13086 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13087 app.processName, app.setAdj, "too many background"); 13088 app.killedBackground = true; 13089 Process.killProcessQuiet(app.pid); 13090 } 13091 } 13092 } 13093 if (app.isolated && app.services.size() <= 0) { 13094 // If this is an isolated process, and there are no 13095 // services running in it, then the process is no longer 13096 // needed. We agressively kill these because we can by 13097 // definition not re-use the same process again, and it is 13098 // good to avoid having whatever code was running in them 13099 // left sitting around after no longer needed. 13100 Slog.i(TAG, "Isolated process " + app.processName 13101 + " (pid " + app.pid + ") no longer needed"); 13102 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13103 app.processName, app.setAdj, "isolated not needed"); 13104 app.killedBackground = true; 13105 Process.killProcessQuiet(app.pid); 13106 } 13107 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13108 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13109 && !app.killedBackground) { 13110 numTrimming++; 13111 } 13112 } 13113 } 13114 13115 mNumServiceProcs = mNewNumServiceProcs; 13116 13117 // Now determine the memory trimming level of background processes. 13118 // Unfortunately we need to start at the back of the list to do this 13119 // properly. We only do this if the number of background apps we 13120 // are managing to keep around is less than half the maximum we desire; 13121 // if we are keeping a good number around, we'll let them use whatever 13122 // memory they want. 13123 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13124 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13125 final int numHiddenAndEmpty = numHidden + numEmpty; 13126 final int N = mLruProcesses.size(); 13127 int factor = numTrimming/3; 13128 int minFactor = 2; 13129 if (mHomeProcess != null) minFactor++; 13130 if (mPreviousProcess != null) minFactor++; 13131 if (factor < minFactor) factor = minFactor; 13132 int step = 0; 13133 int fgTrimLevel; 13134 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13135 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13136 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13137 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13138 } else { 13139 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13140 } 13141 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13142 for (i=0; i<N; i++) { 13143 ProcessRecord app = mLruProcesses.get(i); 13144 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13145 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13146 && !app.killedBackground) { 13147 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13148 try { 13149 app.thread.scheduleTrimMemory(curLevel); 13150 } catch (RemoteException e) { 13151 } 13152 if (false) { 13153 // For now we won't do this; our memory trimming seems 13154 // to be good enough at this point that destroying 13155 // activities causes more harm than good. 13156 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13157 && app != mHomeProcess && app != mPreviousProcess) { 13158 // Need to do this on its own message because the stack may not 13159 // be in a consistent state at this point. 13160 // For these apps we will also finish their activities 13161 // to help them free memory. 13162 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13163 } 13164 } 13165 } 13166 app.trimMemoryLevel = curLevel; 13167 step++; 13168 if (step >= factor) { 13169 step = 0; 13170 switch (curLevel) { 13171 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13172 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13173 break; 13174 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13175 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13176 break; 13177 } 13178 } 13179 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13180 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13181 && app.thread != null) { 13182 try { 13183 app.thread.scheduleTrimMemory( 13184 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13185 } catch (RemoteException e) { 13186 } 13187 } 13188 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13189 } else { 13190 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13191 && app.pendingUiClean) { 13192 // If this application is now in the background and it 13193 // had done UI, then give it the special trim level to 13194 // have it free UI resources. 13195 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13196 if (app.trimMemoryLevel < level && app.thread != null) { 13197 try { 13198 app.thread.scheduleTrimMemory(level); 13199 } catch (RemoteException e) { 13200 } 13201 } 13202 app.pendingUiClean = false; 13203 } 13204 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13205 try { 13206 app.thread.scheduleTrimMemory(fgTrimLevel); 13207 } catch (RemoteException e) { 13208 } 13209 } 13210 app.trimMemoryLevel = fgTrimLevel; 13211 } 13212 } 13213 } else { 13214 final int N = mLruProcesses.size(); 13215 for (i=0; i<N; i++) { 13216 ProcessRecord app = mLruProcesses.get(i); 13217 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13218 && app.pendingUiClean) { 13219 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13220 && app.thread != null) { 13221 try { 13222 app.thread.scheduleTrimMemory( 13223 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13224 } catch (RemoteException e) { 13225 } 13226 } 13227 app.pendingUiClean = false; 13228 } 13229 app.trimMemoryLevel = 0; 13230 } 13231 } 13232 13233 if (mAlwaysFinishActivities) { 13234 // Need to do this on its own message because the stack may not 13235 // be in a consistent state at this point. 13236 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13237 } 13238 } 13239 13240 final void trimApplications() { 13241 synchronized (this) { 13242 int i; 13243 13244 // First remove any unused application processes whose package 13245 // has been removed. 13246 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13247 final ProcessRecord app = mRemovedProcesses.get(i); 13248 if (app.activities.size() == 0 13249 && app.curReceiver == null && app.services.size() == 0) { 13250 Slog.i( 13251 TAG, "Exiting empty application process " 13252 + app.processName + " (" 13253 + (app.thread != null ? app.thread.asBinder() : null) 13254 + ")\n"); 13255 if (app.pid > 0 && app.pid != MY_PID) { 13256 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13257 app.processName, app.setAdj, "empty"); 13258 Process.killProcessQuiet(app.pid); 13259 } else { 13260 try { 13261 app.thread.scheduleExit(); 13262 } catch (Exception e) { 13263 // Ignore exceptions. 13264 } 13265 } 13266 cleanUpApplicationRecordLocked(app, false, true, -1); 13267 mRemovedProcesses.remove(i); 13268 13269 if (app.persistent) { 13270 if (app.persistent) { 13271 addAppLocked(app.info, false); 13272 } 13273 } 13274 } 13275 } 13276 13277 // Now update the oom adj for all processes. 13278 updateOomAdjLocked(); 13279 } 13280 } 13281 13282 /** This method sends the specified signal to each of the persistent apps */ 13283 public void signalPersistentProcesses(int sig) throws RemoteException { 13284 if (sig != Process.SIGNAL_USR1) { 13285 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13286 } 13287 13288 synchronized (this) { 13289 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13290 != PackageManager.PERMISSION_GRANTED) { 13291 throw new SecurityException("Requires permission " 13292 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13293 } 13294 13295 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13296 ProcessRecord r = mLruProcesses.get(i); 13297 if (r.thread != null && r.persistent) { 13298 Process.sendSignal(r.pid, sig); 13299 } 13300 } 13301 } 13302 } 13303 13304 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13305 if (proc == null || proc == mProfileProc) { 13306 proc = mProfileProc; 13307 path = mProfileFile; 13308 profileType = mProfileType; 13309 clearProfilerLocked(); 13310 } 13311 if (proc == null) { 13312 return; 13313 } 13314 try { 13315 proc.thread.profilerControl(false, path, null, profileType); 13316 } catch (RemoteException e) { 13317 throw new IllegalStateException("Process disappeared"); 13318 } 13319 } 13320 13321 private void clearProfilerLocked() { 13322 if (mProfileFd != null) { 13323 try { 13324 mProfileFd.close(); 13325 } catch (IOException e) { 13326 } 13327 } 13328 mProfileApp = null; 13329 mProfileProc = null; 13330 mProfileFile = null; 13331 mProfileType = 0; 13332 mAutoStopProfiler = false; 13333 } 13334 13335 public boolean profileControl(String process, boolean start, 13336 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13337 13338 try { 13339 synchronized (this) { 13340 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13341 // its own permission. 13342 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13343 != PackageManager.PERMISSION_GRANTED) { 13344 throw new SecurityException("Requires permission " 13345 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13346 } 13347 13348 if (start && fd == null) { 13349 throw new IllegalArgumentException("null fd"); 13350 } 13351 13352 ProcessRecord proc = null; 13353 if (process != null) { 13354 try { 13355 int pid = Integer.parseInt(process); 13356 synchronized (mPidsSelfLocked) { 13357 proc = mPidsSelfLocked.get(pid); 13358 } 13359 } catch (NumberFormatException e) { 13360 } 13361 13362 if (proc == null) { 13363 HashMap<String, SparseArray<ProcessRecord>> all 13364 = mProcessNames.getMap(); 13365 SparseArray<ProcessRecord> procs = all.get(process); 13366 if (procs != null && procs.size() > 0) { 13367 proc = procs.valueAt(0); 13368 } 13369 } 13370 } 13371 13372 if (start && (proc == null || proc.thread == null)) { 13373 throw new IllegalArgumentException("Unknown process: " + process); 13374 } 13375 13376 if (start) { 13377 stopProfilerLocked(null, null, 0); 13378 setProfileApp(proc.info, proc.processName, path, fd, false); 13379 mProfileProc = proc; 13380 mProfileType = profileType; 13381 try { 13382 fd = fd.dup(); 13383 } catch (IOException e) { 13384 fd = null; 13385 } 13386 proc.thread.profilerControl(start, path, fd, profileType); 13387 fd = null; 13388 mProfileFd = null; 13389 } else { 13390 stopProfilerLocked(proc, path, profileType); 13391 if (fd != null) { 13392 try { 13393 fd.close(); 13394 } catch (IOException e) { 13395 } 13396 } 13397 } 13398 13399 return true; 13400 } 13401 } catch (RemoteException e) { 13402 throw new IllegalStateException("Process disappeared"); 13403 } finally { 13404 if (fd != null) { 13405 try { 13406 fd.close(); 13407 } catch (IOException e) { 13408 } 13409 } 13410 } 13411 } 13412 13413 public boolean dumpHeap(String process, boolean managed, 13414 String path, ParcelFileDescriptor fd) throws RemoteException { 13415 13416 try { 13417 synchronized (this) { 13418 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13419 // its own permission (same as profileControl). 13420 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13421 != PackageManager.PERMISSION_GRANTED) { 13422 throw new SecurityException("Requires permission " 13423 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13424 } 13425 13426 if (fd == null) { 13427 throw new IllegalArgumentException("null fd"); 13428 } 13429 13430 ProcessRecord proc = null; 13431 try { 13432 int pid = Integer.parseInt(process); 13433 synchronized (mPidsSelfLocked) { 13434 proc = mPidsSelfLocked.get(pid); 13435 } 13436 } catch (NumberFormatException e) { 13437 } 13438 13439 if (proc == null) { 13440 HashMap<String, SparseArray<ProcessRecord>> all 13441 = mProcessNames.getMap(); 13442 SparseArray<ProcessRecord> procs = all.get(process); 13443 if (procs != null && procs.size() > 0) { 13444 proc = procs.valueAt(0); 13445 } 13446 } 13447 13448 if (proc == null || proc.thread == null) { 13449 throw new IllegalArgumentException("Unknown process: " + process); 13450 } 13451 13452 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13453 if (!isDebuggable) { 13454 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13455 throw new SecurityException("Process not debuggable: " + proc); 13456 } 13457 } 13458 13459 proc.thread.dumpHeap(managed, path, fd); 13460 fd = null; 13461 return true; 13462 } 13463 } catch (RemoteException e) { 13464 throw new IllegalStateException("Process disappeared"); 13465 } finally { 13466 if (fd != null) { 13467 try { 13468 fd.close(); 13469 } catch (IOException e) { 13470 } 13471 } 13472 } 13473 } 13474 13475 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13476 public void monitor() { 13477 synchronized (this) { } 13478 } 13479 13480 void onCoreSettingsChange(Bundle settings) { 13481 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13482 ProcessRecord processRecord = mLruProcesses.get(i); 13483 try { 13484 if (processRecord.thread != null) { 13485 processRecord.thread.setCoreSettings(settings); 13486 } 13487 } catch (RemoteException re) { 13488 /* ignore */ 13489 } 13490 } 13491 } 13492 13493 // Multi-user methods 13494 13495 public boolean switchUser(int userId) { 13496 final int callingUid = Binder.getCallingUid(); 13497 if (callingUid != 0 && callingUid != Process.myUid()) { 13498 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13499 return false; 13500 } 13501 if (mCurrentUserId == userId) 13502 return true; 13503 13504 synchronized (this) { 13505 // Check if user is already logged in, otherwise check if user exists first before 13506 // adding to the list of logged in users. 13507 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13508 if (!userExists(userId)) { 13509 return false; 13510 } 13511 mLoggedInUsers.append(userId, userId); 13512 } 13513 13514 mCurrentUserId = userId; 13515 boolean haveActivities = mMainStack.switchUser(userId); 13516 if (!haveActivities) { 13517 startHomeActivityLocked(userId); 13518 } 13519 13520 } 13521 13522 // Inform of user switch 13523 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13524 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13525 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13526 13527 return true; 13528 } 13529 13530 @Override 13531 public UserInfo getCurrentUser() throws RemoteException { 13532 final int callingUid = Binder.getCallingUid(); 13533 if (callingUid != 0 && callingUid != Process.myUid()) { 13534 Slog.e(TAG, "Trying to get user from unauthorized app"); 13535 return null; 13536 } 13537 return getUserManager().getUserInfo(mCurrentUserId); 13538 } 13539 13540 private void onUserRemoved(Intent intent) { 13541 int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 13542 if (extraUserId < 1) return; 13543 13544 // Kill all the processes for the user 13545 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13546 synchronized (this) { 13547 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13548 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13549 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13550 for (int i = 0; i < uids.size(); i++) { 13551 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13552 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13553 } 13554 } 13555 } 13556 13557 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13558 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13559 false, false, true, true, extraUserId); 13560 } 13561 } 13562 } 13563 13564 private boolean userExists(int userId) { 13565 UserInfo user = getUserManager().getUserInfo(userId); 13566 return user != null; 13567 } 13568 13569 UserManager getUserManager() { 13570 if (mUserManager == null) { 13571 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13572 } 13573 return mUserManager; 13574 } 13575 13576 private void checkValidCaller(int uid, int userId) { 13577 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13578 13579 throw new SecurityException("Caller uid=" + uid 13580 + " is not privileged to communicate with user=" + userId); 13581 } 13582 13583 private int applyUserId(int uid, int userId) { 13584 return UserHandle.getUid(userId, uid); 13585 } 13586 13587 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13588 if (info == null) return null; 13589 ApplicationInfo newInfo = new ApplicationInfo(info); 13590 newInfo.uid = applyUserId(info.uid, userId); 13591 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13592 + info.packageName; 13593 return newInfo; 13594 } 13595 13596 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13597 if (aInfo == null 13598 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13599 return aInfo; 13600 } 13601 13602 ActivityInfo info = new ActivityInfo(aInfo); 13603 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13604 return info; 13605 } 13606} 13607