ActivityManagerService.java revision 80a4af2bbc6af42ae605e454bf89558e564f5244
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IStopUserCallback; 50import android.app.IThumbnailReceiver; 51import android.app.Instrumentation; 52import android.app.Notification; 53import android.app.NotificationManager; 54import android.app.PendingIntent; 55import android.app.backup.IBackupManager; 56import android.content.ActivityNotFoundException; 57import android.content.BroadcastReceiver; 58import android.content.ClipData; 59import android.content.ComponentCallbacks2; 60import android.content.ComponentName; 61import android.content.ContentProvider; 62import android.content.ContentResolver; 63import android.content.Context; 64import android.content.DialogInterface; 65import android.content.IContentProvider; 66import android.content.IIntentReceiver; 67import android.content.IIntentSender; 68import android.content.Intent; 69import android.content.IntentFilter; 70import android.content.IntentSender; 71import android.content.pm.ActivityInfo; 72import android.content.pm.ApplicationInfo; 73import android.content.pm.ConfigurationInfo; 74import android.content.pm.IPackageDataObserver; 75import android.content.pm.IPackageManager; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.PackageInfo; 78import android.content.pm.PackageManager; 79import android.content.pm.UserInfo; 80import android.content.pm.PackageManager.NameNotFoundException; 81import android.content.pm.PathPermission; 82import android.content.pm.ProviderInfo; 83import android.content.pm.ResolveInfo; 84import android.content.pm.ServiceInfo; 85import android.content.res.CompatibilityInfo; 86import android.content.res.Configuration; 87import android.graphics.Bitmap; 88import android.net.Proxy; 89import android.net.ProxyProperties; 90import android.net.Uri; 91import android.os.Binder; 92import android.os.Build; 93import android.os.Bundle; 94import android.os.Debug; 95import android.os.DropBoxManager; 96import android.os.Environment; 97import android.os.FileObserver; 98import android.os.FileUtils; 99import android.os.Handler; 100import android.os.IBinder; 101import android.os.IPermissionController; 102import android.os.Looper; 103import android.os.Message; 104import android.os.Parcel; 105import android.os.ParcelFileDescriptor; 106import android.os.Process; 107import android.os.RemoteCallbackList; 108import android.os.RemoteException; 109import android.os.SELinux; 110import android.os.ServiceManager; 111import android.os.StrictMode; 112import android.os.SystemClock; 113import android.os.SystemProperties; 114import android.os.UserHandle; 115import android.os.UserManager; 116import android.provider.Settings; 117import android.text.format.Time; 118import android.util.EventLog; 119import android.util.Log; 120import android.util.Pair; 121import android.util.PrintWriterPrinter; 122import android.util.Slog; 123import android.util.SparseArray; 124import android.util.SparseIntArray; 125import android.util.TimeUtils; 126import android.view.Gravity; 127import android.view.LayoutInflater; 128import android.view.View; 129import android.view.WindowManager; 130import android.view.WindowManagerPolicy; 131 132import java.io.BufferedInputStream; 133import java.io.BufferedOutputStream; 134import java.io.BufferedReader; 135import java.io.DataInputStream; 136import java.io.DataOutputStream; 137import java.io.File; 138import java.io.FileDescriptor; 139import java.io.FileInputStream; 140import java.io.FileNotFoundException; 141import java.io.FileOutputStream; 142import java.io.IOException; 143import java.io.InputStreamReader; 144import java.io.PrintWriter; 145import java.io.StringWriter; 146import java.lang.ref.WeakReference; 147import java.util.ArrayList; 148import java.util.Collections; 149import java.util.Comparator; 150import java.util.HashMap; 151import java.util.HashSet; 152import java.util.Iterator; 153import java.util.List; 154import java.util.Locale; 155import java.util.Map; 156import java.util.Map.Entry; 157import java.util.Set; 158import java.util.concurrent.atomic.AtomicBoolean; 159import java.util.concurrent.atomic.AtomicLong; 160 161public final class ActivityManagerService extends ActivityManagerNative 162 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 163 private static final String USER_DATA_DIR = "/data/user/"; 164 static final String TAG = "ActivityManager"; 165 static final String TAG_MU = "ActivityManagerServiceMU"; 166 static final boolean DEBUG = false; 167 static final boolean localLOGV = DEBUG; 168 static final boolean DEBUG_SWITCH = localLOGV || false; 169 static final boolean DEBUG_TASKS = localLOGV || false; 170 static final boolean DEBUG_PAUSE = localLOGV || false; 171 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 172 static final boolean DEBUG_TRANSITION = localLOGV || false; 173 static final boolean DEBUG_BROADCAST = localLOGV || false; 174 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_SERVICE = localLOGV || false; 177 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 178 static final boolean DEBUG_VISBILITY = localLOGV || false; 179 static final boolean DEBUG_PROCESSES = localLOGV || false; 180 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 181 static final boolean DEBUG_PROVIDER = localLOGV || false; 182 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 183 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 184 static final boolean DEBUG_RESULTS = localLOGV || false; 185 static final boolean DEBUG_BACKUP = localLOGV || false; 186 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 187 static final boolean DEBUG_POWER = localLOGV || false; 188 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 189 static final boolean DEBUG_MU = localLOGV || false; 190 static final boolean VALIDATE_TOKENS = false; 191 static final boolean SHOW_ACTIVITY_START_TIME = true; 192 193 // Control over CPU and battery monitoring. 194 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 195 static final boolean MONITOR_CPU_USAGE = true; 196 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 197 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 198 static final boolean MONITOR_THREAD_CPU_USAGE = false; 199 200 // The flags that are set for all calls we make to the package manager. 201 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 202 203 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 204 205 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 206 207 // Maximum number of recent tasks that we can remember. 208 static final int MAX_RECENT_TASKS = 20; 209 210 // Amount of time after a call to stopAppSwitches() during which we will 211 // prevent further untrusted switches from happening. 212 static final long APP_SWITCH_DELAY_TIME = 5*1000; 213 214 // How long we wait for a launched process to attach to the activity manager 215 // before we decide it's never going to come up for real. 216 static final int PROC_START_TIMEOUT = 10*1000; 217 218 // How long we wait for a launched process to attach to the activity manager 219 // before we decide it's never going to come up for real, when the process was 220 // started with a wrapper for instrumentation (such as Valgrind) because it 221 // could take much longer than usual. 222 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 223 224 // How long to wait after going idle before forcing apps to GC. 225 static final int GC_TIMEOUT = 5*1000; 226 227 // The minimum amount of time between successive GC requests for a process. 228 static final int GC_MIN_INTERVAL = 60*1000; 229 230 // The rate at which we check for apps using excessive power -- 15 mins. 231 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 232 233 // The minimum sample duration we will allow before deciding we have 234 // enough data on wake locks to start killing things. 235 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on CPU usage to start killing things. 239 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // How long we allow a receiver to run before giving up on it. 242 static final int BROADCAST_FG_TIMEOUT = 10*1000; 243 static final int BROADCAST_BG_TIMEOUT = 60*1000; 244 245 // How long we wait until we timeout on key dispatching. 246 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 247 248 // How long we wait until we timeout on key dispatching during instrumentation. 249 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 250 251 static final int MY_PID = Process.myPid(); 252 253 static final String[] EMPTY_STRING_ARRAY = new String[0]; 254 255 public ActivityStack mMainStack; 256 257 private final boolean mHeadless; 258 259 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 260 // default actuion automatically. Important for devices without direct input 261 // devices. 262 private boolean mShowDialogs = true; 263 264 /** 265 * Description of a request to start a new activity, which has been held 266 * due to app switches being disabled. 267 */ 268 static class PendingActivityLaunch { 269 ActivityRecord r; 270 ActivityRecord sourceRecord; 271 int startFlags; 272 } 273 274 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 275 = new ArrayList<PendingActivityLaunch>(); 276 277 278 BroadcastQueue mFgBroadcastQueue; 279 BroadcastQueue mBgBroadcastQueue; 280 // Convenient for easy iteration over the queues. Foreground is first 281 // so that dispatch of foreground broadcasts gets precedence. 282 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 283 284 BroadcastQueue broadcastQueueForIntent(Intent intent) { 285 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 286 if (DEBUG_BACKGROUND_BROADCAST) { 287 Slog.i(TAG, "Broadcast intent " + intent + " on " 288 + (isFg ? "foreground" : "background") 289 + " queue"); 290 } 291 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 292 } 293 294 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 295 for (BroadcastQueue queue : mBroadcastQueues) { 296 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 297 if (r != null) { 298 return r; 299 } 300 } 301 return null; 302 } 303 304 /** 305 * Activity we have told the window manager to have key focus. 306 */ 307 ActivityRecord mFocusedActivity = null; 308 /** 309 * List of intents that were used to start the most recent tasks. 310 */ 311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 312 313 /** 314 * Process management. 315 */ 316 final ProcessList mProcessList = new ProcessList(); 317 318 /** 319 * All of the applications we currently have running organized by name. 320 * The keys are strings of the application package name (as 321 * returned by the package manager), and the keys are ApplicationRecord 322 * objects. 323 */ 324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 325 326 /** 327 * The currently running isolated processes. 328 */ 329 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 330 331 /** 332 * Counter for assigning isolated process uids, to avoid frequently reusing the 333 * same ones. 334 */ 335 int mNextIsolatedProcessUid = 0; 336 337 /** 338 * The currently running heavy-weight process, if any. 339 */ 340 ProcessRecord mHeavyWeightProcess = null; 341 342 /** 343 * The last time that various processes have crashed. 344 */ 345 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 346 347 /** 348 * Set of applications that we consider to be bad, and will reject 349 * incoming broadcasts from (which the user has no control over). 350 * Processes are added to this set when they have crashed twice within 351 * a minimum amount of time; they are removed from it when they are 352 * later restarted (hopefully due to some user action). The value is the 353 * time it was added to the list. 354 */ 355 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 356 357 /** 358 * All of the processes we currently have running organized by pid. 359 * The keys are the pid running the application. 360 * 361 * <p>NOTE: This object is protected by its own lock, NOT the global 362 * activity manager lock! 363 */ 364 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 365 366 /** 367 * All of the processes that have been forced to be foreground. The key 368 * is the pid of the caller who requested it (we hold a death 369 * link on it). 370 */ 371 abstract class ForegroundToken implements IBinder.DeathRecipient { 372 int pid; 373 IBinder token; 374 } 375 final SparseArray<ForegroundToken> mForegroundProcesses 376 = new SparseArray<ForegroundToken>(); 377 378 /** 379 * List of records for processes that someone had tried to start before the 380 * system was ready. We don't start them at that point, but ensure they 381 * are started by the time booting is complete. 382 */ 383 final ArrayList<ProcessRecord> mProcessesOnHold 384 = new ArrayList<ProcessRecord>(); 385 386 /** 387 * List of persistent applications that are in the process 388 * of being started. 389 */ 390 final ArrayList<ProcessRecord> mPersistentStartingProcesses 391 = new ArrayList<ProcessRecord>(); 392 393 /** 394 * Processes that are being forcibly torn down. 395 */ 396 final ArrayList<ProcessRecord> mRemovedProcesses 397 = new ArrayList<ProcessRecord>(); 398 399 /** 400 * List of running applications, sorted by recent usage. 401 * The first entry in the list is the least recently used. 402 * It contains ApplicationRecord objects. This list does NOT include 403 * any persistent application records (since we never want to exit them). 404 */ 405 final ArrayList<ProcessRecord> mLruProcesses 406 = new ArrayList<ProcessRecord>(); 407 408 /** 409 * List of processes that should gc as soon as things are idle. 410 */ 411 final ArrayList<ProcessRecord> mProcessesToGc 412 = new ArrayList<ProcessRecord>(); 413 414 /** 415 * This is the process holding what we currently consider to be 416 * the "home" activity. 417 */ 418 ProcessRecord mHomeProcess; 419 420 /** 421 * This is the process holding the activity the user last visited that 422 * is in a different process from the one they are currently in. 423 */ 424 ProcessRecord mPreviousProcess; 425 426 /** 427 * The time at which the previous process was last visible. 428 */ 429 long mPreviousProcessVisibleTime; 430 431 /** 432 * Which uses have been started, so are allowed to run code. 433 */ 434 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 435 436 /** 437 * Packages that the user has asked to have run in screen size 438 * compatibility mode instead of filling the screen. 439 */ 440 final CompatModePackages mCompatModePackages; 441 442 /** 443 * Set of PendingResultRecord objects that are currently active. 444 */ 445 final HashSet mPendingResultRecords = new HashSet(); 446 447 /** 448 * Set of IntentSenderRecord objects that are currently active. 449 */ 450 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 451 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 452 453 /** 454 * Fingerprints (hashCode()) of stack traces that we've 455 * already logged DropBox entries for. Guarded by itself. If 456 * something (rogue user app) forces this over 457 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 458 */ 459 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 460 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 461 462 /** 463 * Strict Mode background batched logging state. 464 * 465 * The string buffer is guarded by itself, and its lock is also 466 * used to determine if another batched write is already 467 * in-flight. 468 */ 469 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 470 471 /** 472 * Keeps track of all IIntentReceivers that have been registered for 473 * broadcasts. Hash keys are the receiver IBinder, hash value is 474 * a ReceiverList. 475 */ 476 final HashMap mRegisteredReceivers = new HashMap(); 477 478 /** 479 * Resolver for broadcast intents to registered receivers. 480 * Holds BroadcastFilter (subclass of IntentFilter). 481 */ 482 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 483 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 484 @Override 485 protected boolean allowFilterResult( 486 BroadcastFilter filter, List<BroadcastFilter> dest) { 487 IBinder target = filter.receiverList.receiver.asBinder(); 488 for (int i=dest.size()-1; i>=0; i--) { 489 if (dest.get(i).receiverList.receiver.asBinder() == target) { 490 return false; 491 } 492 } 493 return true; 494 } 495 496 @Override 497 protected BroadcastFilter[] newArray(int size) { 498 return new BroadcastFilter[size]; 499 } 500 501 @Override 502 protected String packageForFilter(BroadcastFilter filter) { 503 return filter.packageName; 504 } 505 }; 506 507 /** 508 * State of all active sticky broadcasts. Keys are the action of the 509 * sticky Intent, values are an ArrayList of all broadcasted intents with 510 * that action (which should usually be one). 511 */ 512 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 513 new HashMap<String, ArrayList<Intent>>(); 514 515 final ActiveServices mServices; 516 517 /** 518 * Backup/restore process management 519 */ 520 String mBackupAppName = null; 521 BackupRecord mBackupTarget = null; 522 523 /** 524 * List of PendingThumbnailsRecord objects of clients who are still 525 * waiting to receive all of the thumbnails for a task. 526 */ 527 final ArrayList mPendingThumbnails = new ArrayList(); 528 529 /** 530 * List of HistoryRecord objects that have been finished and must 531 * still report back to a pending thumbnail receiver. 532 */ 533 final ArrayList mCancelledThumbnails = new ArrayList(); 534 535 final ProviderMap mProviderMap = new ProviderMap(); 536 537 /** 538 * List of content providers who have clients waiting for them. The 539 * application is currently being launched and the provider will be 540 * removed from this list once it is published. 541 */ 542 final ArrayList<ContentProviderRecord> mLaunchingProviders 543 = new ArrayList<ContentProviderRecord>(); 544 545 /** 546 * Global set of specific Uri permissions that have been granted. 547 */ 548 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 549 = new SparseArray<HashMap<Uri, UriPermission>>(); 550 551 CoreSettingsObserver mCoreSettingsObserver; 552 553 /** 554 * Thread-local storage used to carry caller permissions over through 555 * indirect content-provider access. 556 * @see #ActivityManagerService.openContentUri() 557 */ 558 private class Identity { 559 public int pid; 560 public int uid; 561 562 Identity(int _pid, int _uid) { 563 pid = _pid; 564 uid = _uid; 565 } 566 } 567 568 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 569 570 /** 571 * All information we have collected about the runtime performance of 572 * any user id that can impact battery performance. 573 */ 574 final BatteryStatsService mBatteryStatsService; 575 576 /** 577 * information about component usage 578 */ 579 final UsageStatsService mUsageStatsService; 580 581 /** 582 * Current configuration information. HistoryRecord objects are given 583 * a reference to this object to indicate which configuration they are 584 * currently running in, so this object must be kept immutable. 585 */ 586 Configuration mConfiguration = new Configuration(); 587 588 /** 589 * Current sequencing integer of the configuration, for skipping old 590 * configurations. 591 */ 592 int mConfigurationSeq = 0; 593 594 /** 595 * Hardware-reported OpenGLES version. 596 */ 597 final int GL_ES_VERSION; 598 599 /** 600 * List of initialization arguments to pass to all processes when binding applications to them. 601 * For example, references to the commonly used services. 602 */ 603 HashMap<String, IBinder> mAppBindArgs; 604 605 /** 606 * Temporary to avoid allocations. Protected by main lock. 607 */ 608 final StringBuilder mStringBuilder = new StringBuilder(256); 609 610 /** 611 * Used to control how we initialize the service. 612 */ 613 boolean mStartRunning = false; 614 ComponentName mTopComponent; 615 String mTopAction; 616 String mTopData; 617 boolean mProcessesReady = false; 618 boolean mSystemReady = false; 619 boolean mBooting = false; 620 boolean mWaitingUpdate = false; 621 boolean mDidUpdate = false; 622 boolean mOnBattery = false; 623 boolean mLaunchWarningShown = false; 624 625 Context mContext; 626 627 int mFactoryTest; 628 629 boolean mCheckedForSetup; 630 631 /** 632 * The time at which we will allow normal application switches again, 633 * after a call to {@link #stopAppSwitches()}. 634 */ 635 long mAppSwitchesAllowedTime; 636 637 /** 638 * This is set to true after the first switch after mAppSwitchesAllowedTime 639 * is set; any switches after that will clear the time. 640 */ 641 boolean mDidAppSwitch; 642 643 /** 644 * Last time (in realtime) at which we checked for power usage. 645 */ 646 long mLastPowerCheckRealtime; 647 648 /** 649 * Last time (in uptime) at which we checked for power usage. 650 */ 651 long mLastPowerCheckUptime; 652 653 /** 654 * Set while we are wanting to sleep, to prevent any 655 * activities from being started/resumed. 656 */ 657 boolean mSleeping = false; 658 659 /** 660 * State of external calls telling us if the device is asleep. 661 */ 662 boolean mWentToSleep = false; 663 664 /** 665 * State of external call telling us if the lock screen is shown. 666 */ 667 boolean mLockScreenShown = false; 668 669 /** 670 * Set if we are shutting down the system, similar to sleeping. 671 */ 672 boolean mShuttingDown = false; 673 674 /** 675 * Task identifier that activities are currently being started 676 * in. Incremented each time a new task is created. 677 * todo: Replace this with a TokenSpace class that generates non-repeating 678 * integers that won't wrap. 679 */ 680 int mCurTask = 1; 681 682 /** 683 * Current sequence id for oom_adj computation traversal. 684 */ 685 int mAdjSeq = 0; 686 687 /** 688 * Current sequence id for process LRU updating. 689 */ 690 int mLruSeq = 0; 691 692 /** 693 * Keep track of the non-hidden/empty process we last found, to help 694 * determine how to distribute hidden/empty processes next time. 695 */ 696 int mNumNonHiddenProcs = 0; 697 698 /** 699 * Keep track of the number of hidden procs, to balance oom adj 700 * distribution between those and empty procs. 701 */ 702 int mNumHiddenProcs = 0; 703 704 /** 705 * Keep track of the number of service processes we last found, to 706 * determine on the next iteration which should be B services. 707 */ 708 int mNumServiceProcs = 0; 709 int mNewNumServiceProcs = 0; 710 711 /** 712 * System monitoring: number of processes that died since the last 713 * N procs were started. 714 */ 715 int[] mProcDeaths = new int[20]; 716 717 /** 718 * This is set if we had to do a delayed dexopt of an app before launching 719 * it, to increasing the ANR timeouts in that case. 720 */ 721 boolean mDidDexOpt; 722 723 String mDebugApp = null; 724 boolean mWaitForDebugger = false; 725 boolean mDebugTransient = false; 726 String mOrigDebugApp = null; 727 boolean mOrigWaitForDebugger = false; 728 boolean mAlwaysFinishActivities = false; 729 IActivityController mController = null; 730 String mProfileApp = null; 731 ProcessRecord mProfileProc = null; 732 String mProfileFile; 733 ParcelFileDescriptor mProfileFd; 734 int mProfileType = 0; 735 boolean mAutoStopProfiler = false; 736 String mOpenGlTraceApp = null; 737 738 static class ProcessChangeItem { 739 static final int CHANGE_ACTIVITIES = 1<<0; 740 static final int CHANGE_IMPORTANCE= 1<<1; 741 int changes; 742 int uid; 743 int pid; 744 int importance; 745 boolean foregroundActivities; 746 } 747 748 final RemoteCallbackList<IProcessObserver> mProcessObservers 749 = new RemoteCallbackList<IProcessObserver>(); 750 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 751 752 final ArrayList<ProcessChangeItem> mPendingProcessChanges 753 = new ArrayList<ProcessChangeItem>(); 754 final ArrayList<ProcessChangeItem> mAvailProcessChanges 755 = new ArrayList<ProcessChangeItem>(); 756 757 /** 758 * Callback of last caller to {@link #requestPss}. 759 */ 760 Runnable mRequestPssCallback; 761 762 /** 763 * Remaining processes for which we are waiting results from the last 764 * call to {@link #requestPss}. 765 */ 766 final ArrayList<ProcessRecord> mRequestPssList 767 = new ArrayList<ProcessRecord>(); 768 769 /** 770 * Runtime statistics collection thread. This object's lock is used to 771 * protect all related state. 772 */ 773 final Thread mProcessStatsThread; 774 775 /** 776 * Used to collect process stats when showing not responding dialog. 777 * Protected by mProcessStatsThread. 778 */ 779 final ProcessStats mProcessStats = new ProcessStats( 780 MONITOR_THREAD_CPU_USAGE); 781 final AtomicLong mLastCpuTime = new AtomicLong(0); 782 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 783 784 long mLastWriteTime = 0; 785 786 /** 787 * Set to true after the system has finished booting. 788 */ 789 boolean mBooted = false; 790 791 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 792 int mProcessLimitOverride = -1; 793 794 WindowManagerService mWindowManager; 795 796 static ActivityManagerService mSelf; 797 static ActivityThread mSystemThread; 798 799 private int mCurrentUserId; 800 private UserManager mUserManager; 801 802 private final class AppDeathRecipient implements IBinder.DeathRecipient { 803 final ProcessRecord mApp; 804 final int mPid; 805 final IApplicationThread mAppThread; 806 807 AppDeathRecipient(ProcessRecord app, int pid, 808 IApplicationThread thread) { 809 if (localLOGV) Slog.v( 810 TAG, "New death recipient " + this 811 + " for thread " + thread.asBinder()); 812 mApp = app; 813 mPid = pid; 814 mAppThread = thread; 815 } 816 817 public void binderDied() { 818 if (localLOGV) Slog.v( 819 TAG, "Death received in " + this 820 + " for thread " + mAppThread.asBinder()); 821 synchronized(ActivityManagerService.this) { 822 appDiedLocked(mApp, mPid, mAppThread); 823 } 824 } 825 } 826 827 static final int SHOW_ERROR_MSG = 1; 828 static final int SHOW_NOT_RESPONDING_MSG = 2; 829 static final int SHOW_FACTORY_ERROR_MSG = 3; 830 static final int UPDATE_CONFIGURATION_MSG = 4; 831 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 832 static final int WAIT_FOR_DEBUGGER_MSG = 6; 833 static final int SERVICE_TIMEOUT_MSG = 12; 834 static final int UPDATE_TIME_ZONE = 13; 835 static final int SHOW_UID_ERROR_MSG = 14; 836 static final int IM_FEELING_LUCKY_MSG = 15; 837 static final int PROC_START_TIMEOUT_MSG = 20; 838 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 839 static final int KILL_APPLICATION_MSG = 22; 840 static final int FINALIZE_PENDING_INTENT_MSG = 23; 841 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 842 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 843 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 844 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 845 static final int CLEAR_DNS_CACHE = 28; 846 static final int UPDATE_HTTP_PROXY = 29; 847 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 848 static final int DISPATCH_PROCESSES_CHANGED = 31; 849 static final int DISPATCH_PROCESS_DIED = 32; 850 static final int REPORT_MEM_USAGE = 33; 851 852 static final int FIRST_ACTIVITY_STACK_MSG = 100; 853 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 854 static final int FIRST_COMPAT_MODE_MSG = 300; 855 856 AlertDialog mUidAlert; 857 CompatModeDialog mCompatModeDialog; 858 long mLastMemUsageReportTime = 0; 859 860 final Handler mHandler = new Handler() { 861 //public Handler() { 862 // if (localLOGV) Slog.v(TAG, "Handler started!"); 863 //} 864 865 public void handleMessage(Message msg) { 866 switch (msg.what) { 867 case SHOW_ERROR_MSG: { 868 HashMap data = (HashMap) msg.obj; 869 synchronized (ActivityManagerService.this) { 870 ProcessRecord proc = (ProcessRecord)data.get("app"); 871 if (proc != null && proc.crashDialog != null) { 872 Slog.e(TAG, "App already has crash dialog: " + proc); 873 return; 874 } 875 AppErrorResult res = (AppErrorResult) data.get("result"); 876 if (mShowDialogs && !mSleeping && !mShuttingDown) { 877 Dialog d = new AppErrorDialog(mContext, res, proc); 878 d.show(); 879 proc.crashDialog = d; 880 } else { 881 // The device is asleep, so just pretend that the user 882 // saw a crash dialog and hit "force quit". 883 res.set(0); 884 } 885 } 886 887 ensureBootCompleted(); 888 } break; 889 case SHOW_NOT_RESPONDING_MSG: { 890 synchronized (ActivityManagerService.this) { 891 HashMap data = (HashMap) msg.obj; 892 ProcessRecord proc = (ProcessRecord)data.get("app"); 893 if (proc != null && proc.anrDialog != null) { 894 Slog.e(TAG, "App already has anr dialog: " + proc); 895 return; 896 } 897 898 Intent intent = new Intent("android.intent.action.ANR"); 899 if (!mProcessesReady) { 900 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 901 | Intent.FLAG_RECEIVER_FOREGROUND); 902 } 903 broadcastIntentLocked(null, null, intent, 904 null, null, 0, null, null, null, 905 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 906 907 if (mShowDialogs) { 908 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 909 mContext, proc, (ActivityRecord)data.get("activity")); 910 d.show(); 911 proc.anrDialog = d; 912 } else { 913 // Just kill the app if there is no dialog to be shown. 914 killAppAtUsersRequest(proc, null); 915 } 916 } 917 918 ensureBootCompleted(); 919 } break; 920 case SHOW_STRICT_MODE_VIOLATION_MSG: { 921 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 922 synchronized (ActivityManagerService.this) { 923 ProcessRecord proc = (ProcessRecord) data.get("app"); 924 if (proc == null) { 925 Slog.e(TAG, "App not found when showing strict mode dialog."); 926 break; 927 } 928 if (proc.crashDialog != null) { 929 Slog.e(TAG, "App already has strict mode dialog: " + proc); 930 return; 931 } 932 AppErrorResult res = (AppErrorResult) data.get("result"); 933 if (mShowDialogs && !mSleeping && !mShuttingDown) { 934 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 935 d.show(); 936 proc.crashDialog = d; 937 } else { 938 // The device is asleep, so just pretend that the user 939 // saw a crash dialog and hit "force quit". 940 res.set(0); 941 } 942 } 943 ensureBootCompleted(); 944 } break; 945 case SHOW_FACTORY_ERROR_MSG: { 946 Dialog d = new FactoryErrorDialog( 947 mContext, msg.getData().getCharSequence("msg")); 948 d.show(); 949 ensureBootCompleted(); 950 } break; 951 case UPDATE_CONFIGURATION_MSG: { 952 final ContentResolver resolver = mContext.getContentResolver(); 953 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 954 } break; 955 case GC_BACKGROUND_PROCESSES_MSG: { 956 synchronized (ActivityManagerService.this) { 957 performAppGcsIfAppropriateLocked(); 958 } 959 } break; 960 case WAIT_FOR_DEBUGGER_MSG: { 961 synchronized (ActivityManagerService.this) { 962 ProcessRecord app = (ProcessRecord)msg.obj; 963 if (msg.arg1 != 0) { 964 if (!app.waitedForDebugger) { 965 Dialog d = new AppWaitingForDebuggerDialog( 966 ActivityManagerService.this, 967 mContext, app); 968 app.waitDialog = d; 969 app.waitedForDebugger = true; 970 d.show(); 971 } 972 } else { 973 if (app.waitDialog != null) { 974 app.waitDialog.dismiss(); 975 app.waitDialog = null; 976 } 977 } 978 } 979 } break; 980 case SERVICE_TIMEOUT_MSG: { 981 if (mDidDexOpt) { 982 mDidDexOpt = false; 983 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 984 nmsg.obj = msg.obj; 985 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 986 return; 987 } 988 mServices.serviceTimeout((ProcessRecord)msg.obj); 989 } break; 990 case UPDATE_TIME_ZONE: { 991 synchronized (ActivityManagerService.this) { 992 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 993 ProcessRecord r = mLruProcesses.get(i); 994 if (r.thread != null) { 995 try { 996 r.thread.updateTimeZone(); 997 } catch (RemoteException ex) { 998 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 999 } 1000 } 1001 } 1002 } 1003 } break; 1004 case CLEAR_DNS_CACHE: { 1005 synchronized (ActivityManagerService.this) { 1006 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1007 ProcessRecord r = mLruProcesses.get(i); 1008 if (r.thread != null) { 1009 try { 1010 r.thread.clearDnsCache(); 1011 } catch (RemoteException ex) { 1012 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1013 } 1014 } 1015 } 1016 } 1017 } break; 1018 case UPDATE_HTTP_PROXY: { 1019 ProxyProperties proxy = (ProxyProperties)msg.obj; 1020 String host = ""; 1021 String port = ""; 1022 String exclList = ""; 1023 if (proxy != null) { 1024 host = proxy.getHost(); 1025 port = Integer.toString(proxy.getPort()); 1026 exclList = proxy.getExclusionList(); 1027 } 1028 synchronized (ActivityManagerService.this) { 1029 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1030 ProcessRecord r = mLruProcesses.get(i); 1031 if (r.thread != null) { 1032 try { 1033 r.thread.setHttpProxy(host, port, exclList); 1034 } catch (RemoteException ex) { 1035 Slog.w(TAG, "Failed to update http proxy for: " + 1036 r.info.processName); 1037 } 1038 } 1039 } 1040 } 1041 } break; 1042 case SHOW_UID_ERROR_MSG: { 1043 String title = "System UIDs Inconsistent"; 1044 String text = "UIDs on the system are inconsistent, you need to wipe your" 1045 + " data partition or your device will be unstable."; 1046 Log.e(TAG, title + ": " + text); 1047 if (mShowDialogs) { 1048 // XXX This is a temporary dialog, no need to localize. 1049 AlertDialog d = new BaseErrorDialog(mContext); 1050 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1051 d.setCancelable(false); 1052 d.setTitle(title); 1053 d.setMessage(text); 1054 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1055 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1056 mUidAlert = d; 1057 d.show(); 1058 } 1059 } break; 1060 case IM_FEELING_LUCKY_MSG: { 1061 if (mUidAlert != null) { 1062 mUidAlert.dismiss(); 1063 mUidAlert = null; 1064 } 1065 } break; 1066 case PROC_START_TIMEOUT_MSG: { 1067 if (mDidDexOpt) { 1068 mDidDexOpt = false; 1069 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1070 nmsg.obj = msg.obj; 1071 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1072 return; 1073 } 1074 ProcessRecord app = (ProcessRecord)msg.obj; 1075 synchronized (ActivityManagerService.this) { 1076 processStartTimedOutLocked(app); 1077 } 1078 } break; 1079 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1080 synchronized (ActivityManagerService.this) { 1081 doPendingActivityLaunchesLocked(true); 1082 } 1083 } break; 1084 case KILL_APPLICATION_MSG: { 1085 synchronized (ActivityManagerService.this) { 1086 int uid = msg.arg1; 1087 boolean restart = (msg.arg2 == 1); 1088 String pkg = (String) msg.obj; 1089 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1090 UserHandle.getUserId(uid)); 1091 } 1092 } break; 1093 case FINALIZE_PENDING_INTENT_MSG: { 1094 ((PendingIntentRecord)msg.obj).completeFinalize(); 1095 } break; 1096 case POST_HEAVY_NOTIFICATION_MSG: { 1097 INotificationManager inm = NotificationManager.getService(); 1098 if (inm == null) { 1099 return; 1100 } 1101 1102 ActivityRecord root = (ActivityRecord)msg.obj; 1103 ProcessRecord process = root.app; 1104 if (process == null) { 1105 return; 1106 } 1107 1108 try { 1109 Context context = mContext.createPackageContext(process.info.packageName, 0); 1110 String text = mContext.getString(R.string.heavy_weight_notification, 1111 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1112 Notification notification = new Notification(); 1113 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1114 notification.when = 0; 1115 notification.flags = Notification.FLAG_ONGOING_EVENT; 1116 notification.tickerText = text; 1117 notification.defaults = 0; // please be quiet 1118 notification.sound = null; 1119 notification.vibrate = null; 1120 notification.setLatestEventInfo(context, text, 1121 mContext.getText(R.string.heavy_weight_notification_detail), 1122 PendingIntent.getActivity(mContext, 0, root.intent, 1123 PendingIntent.FLAG_CANCEL_CURRENT)); 1124 1125 try { 1126 int[] outId = new int[1]; 1127 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1128 notification, outId); 1129 } catch (RuntimeException e) { 1130 Slog.w(ActivityManagerService.TAG, 1131 "Error showing notification for heavy-weight app", e); 1132 } catch (RemoteException e) { 1133 } 1134 } catch (NameNotFoundException e) { 1135 Slog.w(TAG, "Unable to create context for heavy notification", e); 1136 } 1137 } break; 1138 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1139 INotificationManager inm = NotificationManager.getService(); 1140 if (inm == null) { 1141 return; 1142 } 1143 try { 1144 inm.cancelNotification("android", 1145 R.string.heavy_weight_notification); 1146 } catch (RuntimeException e) { 1147 Slog.w(ActivityManagerService.TAG, 1148 "Error canceling notification for service", e); 1149 } catch (RemoteException e) { 1150 } 1151 } break; 1152 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1153 synchronized (ActivityManagerService.this) { 1154 checkExcessivePowerUsageLocked(true); 1155 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1156 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1157 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1158 } 1159 } break; 1160 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1161 synchronized (ActivityManagerService.this) { 1162 ActivityRecord ar = (ActivityRecord)msg.obj; 1163 if (mCompatModeDialog != null) { 1164 if (mCompatModeDialog.mAppInfo.packageName.equals( 1165 ar.info.applicationInfo.packageName)) { 1166 return; 1167 } 1168 mCompatModeDialog.dismiss(); 1169 mCompatModeDialog = null; 1170 } 1171 if (ar != null && false) { 1172 if (mCompatModePackages.getPackageAskCompatModeLocked( 1173 ar.packageName)) { 1174 int mode = mCompatModePackages.computeCompatModeLocked( 1175 ar.info.applicationInfo); 1176 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1177 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1178 mCompatModeDialog = new CompatModeDialog( 1179 ActivityManagerService.this, mContext, 1180 ar.info.applicationInfo); 1181 mCompatModeDialog.show(); 1182 } 1183 } 1184 } 1185 } 1186 break; 1187 } 1188 case DISPATCH_PROCESSES_CHANGED: { 1189 dispatchProcessesChanged(); 1190 break; 1191 } 1192 case DISPATCH_PROCESS_DIED: { 1193 final int pid = msg.arg1; 1194 final int uid = msg.arg2; 1195 dispatchProcessDied(pid, uid); 1196 break; 1197 } 1198 case REPORT_MEM_USAGE: { 1199 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1200 if (!isDebuggable) { 1201 return; 1202 } 1203 synchronized (ActivityManagerService.this) { 1204 long now = SystemClock.uptimeMillis(); 1205 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1206 // Don't report more than every 5 minutes to somewhat 1207 // avoid spamming. 1208 return; 1209 } 1210 mLastMemUsageReportTime = now; 1211 } 1212 Thread thread = new Thread() { 1213 @Override public void run() { 1214 StringBuilder dropBuilder = new StringBuilder(1024); 1215 StringBuilder logBuilder = new StringBuilder(1024); 1216 StringWriter oomSw = new StringWriter(); 1217 PrintWriter oomPw = new PrintWriter(oomSw); 1218 StringWriter catSw = new StringWriter(); 1219 PrintWriter catPw = new PrintWriter(catSw); 1220 String[] emptyArgs = new String[] { }; 1221 StringBuilder tag = new StringBuilder(128); 1222 StringBuilder stack = new StringBuilder(128); 1223 tag.append("Low on memory -- "); 1224 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1225 tag, stack); 1226 dropBuilder.append(stack); 1227 dropBuilder.append('\n'); 1228 dropBuilder.append('\n'); 1229 String oomString = oomSw.toString(); 1230 dropBuilder.append(oomString); 1231 dropBuilder.append('\n'); 1232 logBuilder.append(oomString); 1233 try { 1234 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1235 "procrank", }); 1236 final InputStreamReader converter = new InputStreamReader( 1237 proc.getInputStream()); 1238 BufferedReader in = new BufferedReader(converter); 1239 String line; 1240 while (true) { 1241 line = in.readLine(); 1242 if (line == null) { 1243 break; 1244 } 1245 if (line.length() > 0) { 1246 logBuilder.append(line); 1247 logBuilder.append('\n'); 1248 } 1249 dropBuilder.append(line); 1250 dropBuilder.append('\n'); 1251 } 1252 converter.close(); 1253 } catch (IOException e) { 1254 } 1255 synchronized (ActivityManagerService.this) { 1256 catPw.println(); 1257 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1258 catPw.println(); 1259 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1260 false, false, null); 1261 catPw.println(); 1262 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1263 } 1264 dropBuilder.append(catSw.toString()); 1265 addErrorToDropBox("lowmem", null, "system_server", null, 1266 null, tag.toString(), dropBuilder.toString(), null, null); 1267 Slog.i(TAG, logBuilder.toString()); 1268 synchronized (ActivityManagerService.this) { 1269 long now = SystemClock.uptimeMillis(); 1270 if (mLastMemUsageReportTime < now) { 1271 mLastMemUsageReportTime = now; 1272 } 1273 } 1274 } 1275 }; 1276 thread.start(); 1277 break; 1278 } 1279 } 1280 } 1281 }; 1282 1283 public static void setSystemProcess() { 1284 try { 1285 ActivityManagerService m = mSelf; 1286 1287 ServiceManager.addService("activity", m, true); 1288 ServiceManager.addService("meminfo", new MemBinder(m)); 1289 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1290 ServiceManager.addService("dbinfo", new DbBinder(m)); 1291 if (MONITOR_CPU_USAGE) { 1292 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1293 } 1294 ServiceManager.addService("permission", new PermissionController(m)); 1295 1296 ApplicationInfo info = 1297 mSelf.mContext.getPackageManager().getApplicationInfo( 1298 "android", STOCK_PM_FLAGS); 1299 mSystemThread.installSystemApplicationInfo(info); 1300 1301 synchronized (mSelf) { 1302 ProcessRecord app = mSelf.newProcessRecordLocked( 1303 mSystemThread.getApplicationThread(), info, 1304 info.processName, false); 1305 app.persistent = true; 1306 app.pid = MY_PID; 1307 app.maxAdj = ProcessList.SYSTEM_ADJ; 1308 mSelf.mProcessNames.put(app.processName, app.uid, app); 1309 synchronized (mSelf.mPidsSelfLocked) { 1310 mSelf.mPidsSelfLocked.put(app.pid, app); 1311 } 1312 mSelf.updateLruProcessLocked(app, true, true); 1313 } 1314 } catch (PackageManager.NameNotFoundException e) { 1315 throw new RuntimeException( 1316 "Unable to find android system package", e); 1317 } 1318 } 1319 1320 public void setWindowManager(WindowManagerService wm) { 1321 mWindowManager = wm; 1322 } 1323 1324 public static final Context main(int factoryTest) { 1325 AThread thr = new AThread(); 1326 thr.start(); 1327 1328 synchronized (thr) { 1329 while (thr.mService == null) { 1330 try { 1331 thr.wait(); 1332 } catch (InterruptedException e) { 1333 } 1334 } 1335 } 1336 1337 ActivityManagerService m = thr.mService; 1338 mSelf = m; 1339 ActivityThread at = ActivityThread.systemMain(); 1340 mSystemThread = at; 1341 Context context = at.getSystemContext(); 1342 context.setTheme(android.R.style.Theme_Holo); 1343 m.mContext = context; 1344 m.mFactoryTest = factoryTest; 1345 m.mMainStack = new ActivityStack(m, context, true); 1346 1347 m.mBatteryStatsService.publish(context); 1348 m.mUsageStatsService.publish(context); 1349 1350 synchronized (thr) { 1351 thr.mReady = true; 1352 thr.notifyAll(); 1353 } 1354 1355 m.startRunning(null, null, null, null); 1356 1357 return context; 1358 } 1359 1360 public static ActivityManagerService self() { 1361 return mSelf; 1362 } 1363 1364 static class AThread extends Thread { 1365 ActivityManagerService mService; 1366 boolean mReady = false; 1367 1368 public AThread() { 1369 super("ActivityManager"); 1370 } 1371 1372 public void run() { 1373 Looper.prepare(); 1374 1375 android.os.Process.setThreadPriority( 1376 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1377 android.os.Process.setCanSelfBackground(false); 1378 1379 ActivityManagerService m = new ActivityManagerService(); 1380 1381 synchronized (this) { 1382 mService = m; 1383 notifyAll(); 1384 } 1385 1386 synchronized (this) { 1387 while (!mReady) { 1388 try { 1389 wait(); 1390 } catch (InterruptedException e) { 1391 } 1392 } 1393 } 1394 1395 // For debug builds, log event loop stalls to dropbox for analysis. 1396 if (StrictMode.conditionallyEnableDebugLogging()) { 1397 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1398 } 1399 1400 Looper.loop(); 1401 } 1402 } 1403 1404 static class MemBinder extends Binder { 1405 ActivityManagerService mActivityManagerService; 1406 MemBinder(ActivityManagerService activityManagerService) { 1407 mActivityManagerService = activityManagerService; 1408 } 1409 1410 @Override 1411 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1412 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1413 != PackageManager.PERMISSION_GRANTED) { 1414 pw.println("Permission Denial: can't dump meminfo from from pid=" 1415 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1416 + " without permission " + android.Manifest.permission.DUMP); 1417 return; 1418 } 1419 1420 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1421 false, null, null, null); 1422 } 1423 } 1424 1425 static class GraphicsBinder extends Binder { 1426 ActivityManagerService mActivityManagerService; 1427 GraphicsBinder(ActivityManagerService activityManagerService) { 1428 mActivityManagerService = activityManagerService; 1429 } 1430 1431 @Override 1432 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1433 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1434 != PackageManager.PERMISSION_GRANTED) { 1435 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1436 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1437 + " without permission " + android.Manifest.permission.DUMP); 1438 return; 1439 } 1440 1441 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1442 } 1443 } 1444 1445 static class DbBinder extends Binder { 1446 ActivityManagerService mActivityManagerService; 1447 DbBinder(ActivityManagerService activityManagerService) { 1448 mActivityManagerService = activityManagerService; 1449 } 1450 1451 @Override 1452 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1453 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1454 != PackageManager.PERMISSION_GRANTED) { 1455 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1456 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1457 + " without permission " + android.Manifest.permission.DUMP); 1458 return; 1459 } 1460 1461 mActivityManagerService.dumpDbInfo(fd, pw, args); 1462 } 1463 } 1464 1465 static class CpuBinder extends Binder { 1466 ActivityManagerService mActivityManagerService; 1467 CpuBinder(ActivityManagerService activityManagerService) { 1468 mActivityManagerService = activityManagerService; 1469 } 1470 1471 @Override 1472 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1473 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1474 != PackageManager.PERMISSION_GRANTED) { 1475 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1476 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1477 + " without permission " + android.Manifest.permission.DUMP); 1478 return; 1479 } 1480 1481 synchronized (mActivityManagerService.mProcessStatsThread) { 1482 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1483 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1484 SystemClock.uptimeMillis())); 1485 } 1486 } 1487 } 1488 1489 private ActivityManagerService() { 1490 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1491 1492 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1493 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1494 mBroadcastQueues[0] = mFgBroadcastQueue; 1495 mBroadcastQueues[1] = mBgBroadcastQueue; 1496 1497 mServices = new ActiveServices(this); 1498 1499 File dataDir = Environment.getDataDirectory(); 1500 File systemDir = new File(dataDir, "system"); 1501 systemDir.mkdirs(); 1502 mBatteryStatsService = new BatteryStatsService(new File( 1503 systemDir, "batterystats.bin").toString()); 1504 mBatteryStatsService.getActiveStatistics().readLocked(); 1505 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1506 mOnBattery = DEBUG_POWER ? true 1507 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1508 mBatteryStatsService.getActiveStatistics().setCallback(this); 1509 1510 mUsageStatsService = new UsageStatsService(new File( 1511 systemDir, "usagestats").toString()); 1512 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1513 1514 // User 0 is the first and only user that runs at boot. 1515 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1516 1517 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1518 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1519 1520 mConfiguration.setToDefaults(); 1521 mConfiguration.locale = Locale.getDefault(); 1522 mConfigurationSeq = mConfiguration.seq = 1; 1523 mProcessStats.init(); 1524 1525 mCompatModePackages = new CompatModePackages(this, systemDir); 1526 1527 // Add ourself to the Watchdog monitors. 1528 Watchdog.getInstance().addMonitor(this); 1529 1530 mProcessStatsThread = new Thread("ProcessStats") { 1531 public void run() { 1532 while (true) { 1533 try { 1534 try { 1535 synchronized(this) { 1536 final long now = SystemClock.uptimeMillis(); 1537 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1538 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1539 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1540 // + ", write delay=" + nextWriteDelay); 1541 if (nextWriteDelay < nextCpuDelay) { 1542 nextCpuDelay = nextWriteDelay; 1543 } 1544 if (nextCpuDelay > 0) { 1545 mProcessStatsMutexFree.set(true); 1546 this.wait(nextCpuDelay); 1547 } 1548 } 1549 } catch (InterruptedException e) { 1550 } 1551 updateCpuStatsNow(); 1552 } catch (Exception e) { 1553 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1554 } 1555 } 1556 } 1557 }; 1558 mProcessStatsThread.start(); 1559 } 1560 1561 @Override 1562 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1563 throws RemoteException { 1564 if (code == SYSPROPS_TRANSACTION) { 1565 // We need to tell all apps about the system property change. 1566 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1567 synchronized(this) { 1568 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1569 final int NA = apps.size(); 1570 for (int ia=0; ia<NA; ia++) { 1571 ProcessRecord app = apps.valueAt(ia); 1572 if (app.thread != null) { 1573 procs.add(app.thread.asBinder()); 1574 } 1575 } 1576 } 1577 } 1578 1579 int N = procs.size(); 1580 for (int i=0; i<N; i++) { 1581 Parcel data2 = Parcel.obtain(); 1582 try { 1583 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1584 } catch (RemoteException e) { 1585 } 1586 data2.recycle(); 1587 } 1588 } 1589 try { 1590 return super.onTransact(code, data, reply, flags); 1591 } catch (RuntimeException e) { 1592 // The activity manager only throws security exceptions, so let's 1593 // log all others. 1594 if (!(e instanceof SecurityException)) { 1595 Slog.e(TAG, "Activity Manager Crash", e); 1596 } 1597 throw e; 1598 } 1599 } 1600 1601 void updateCpuStats() { 1602 final long now = SystemClock.uptimeMillis(); 1603 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1604 return; 1605 } 1606 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1607 synchronized (mProcessStatsThread) { 1608 mProcessStatsThread.notify(); 1609 } 1610 } 1611 } 1612 1613 void updateCpuStatsNow() { 1614 synchronized (mProcessStatsThread) { 1615 mProcessStatsMutexFree.set(false); 1616 final long now = SystemClock.uptimeMillis(); 1617 boolean haveNewCpuStats = false; 1618 1619 if (MONITOR_CPU_USAGE && 1620 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1621 mLastCpuTime.set(now); 1622 haveNewCpuStats = true; 1623 mProcessStats.update(); 1624 //Slog.i(TAG, mProcessStats.printCurrentState()); 1625 //Slog.i(TAG, "Total CPU usage: " 1626 // + mProcessStats.getTotalCpuPercent() + "%"); 1627 1628 // Slog the cpu usage if the property is set. 1629 if ("true".equals(SystemProperties.get("events.cpu"))) { 1630 int user = mProcessStats.getLastUserTime(); 1631 int system = mProcessStats.getLastSystemTime(); 1632 int iowait = mProcessStats.getLastIoWaitTime(); 1633 int irq = mProcessStats.getLastIrqTime(); 1634 int softIrq = mProcessStats.getLastSoftIrqTime(); 1635 int idle = mProcessStats.getLastIdleTime(); 1636 1637 int total = user + system + iowait + irq + softIrq + idle; 1638 if (total == 0) total = 1; 1639 1640 EventLog.writeEvent(EventLogTags.CPU, 1641 ((user+system+iowait+irq+softIrq) * 100) / total, 1642 (user * 100) / total, 1643 (system * 100) / total, 1644 (iowait * 100) / total, 1645 (irq * 100) / total, 1646 (softIrq * 100) / total); 1647 } 1648 } 1649 1650 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1651 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1652 synchronized(bstats) { 1653 synchronized(mPidsSelfLocked) { 1654 if (haveNewCpuStats) { 1655 if (mOnBattery) { 1656 int perc = bstats.startAddingCpuLocked(); 1657 int totalUTime = 0; 1658 int totalSTime = 0; 1659 final int N = mProcessStats.countStats(); 1660 for (int i=0; i<N; i++) { 1661 ProcessStats.Stats st = mProcessStats.getStats(i); 1662 if (!st.working) { 1663 continue; 1664 } 1665 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1666 int otherUTime = (st.rel_utime*perc)/100; 1667 int otherSTime = (st.rel_stime*perc)/100; 1668 totalUTime += otherUTime; 1669 totalSTime += otherSTime; 1670 if (pr != null) { 1671 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1672 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1673 st.rel_stime-otherSTime); 1674 ps.addSpeedStepTimes(cpuSpeedTimes); 1675 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1676 } else { 1677 BatteryStatsImpl.Uid.Proc ps = 1678 bstats.getProcessStatsLocked(st.name, st.pid); 1679 if (ps != null) { 1680 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1681 st.rel_stime-otherSTime); 1682 ps.addSpeedStepTimes(cpuSpeedTimes); 1683 } 1684 } 1685 } 1686 bstats.finishAddingCpuLocked(perc, totalUTime, 1687 totalSTime, cpuSpeedTimes); 1688 } 1689 } 1690 } 1691 1692 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1693 mLastWriteTime = now; 1694 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1695 } 1696 } 1697 } 1698 } 1699 1700 @Override 1701 public void batteryNeedsCpuUpdate() { 1702 updateCpuStatsNow(); 1703 } 1704 1705 @Override 1706 public void batteryPowerChanged(boolean onBattery) { 1707 // When plugging in, update the CPU stats first before changing 1708 // the plug state. 1709 updateCpuStatsNow(); 1710 synchronized (this) { 1711 synchronized(mPidsSelfLocked) { 1712 mOnBattery = DEBUG_POWER ? true : onBattery; 1713 } 1714 } 1715 } 1716 1717 /** 1718 * Initialize the application bind args. These are passed to each 1719 * process when the bindApplication() IPC is sent to the process. They're 1720 * lazily setup to make sure the services are running when they're asked for. 1721 */ 1722 private HashMap<String, IBinder> getCommonServicesLocked() { 1723 if (mAppBindArgs == null) { 1724 mAppBindArgs = new HashMap<String, IBinder>(); 1725 1726 // Setup the application init args 1727 mAppBindArgs.put("package", ServiceManager.getService("package")); 1728 mAppBindArgs.put("window", ServiceManager.getService("window")); 1729 mAppBindArgs.put(Context.ALARM_SERVICE, 1730 ServiceManager.getService(Context.ALARM_SERVICE)); 1731 } 1732 return mAppBindArgs; 1733 } 1734 1735 final void setFocusedActivityLocked(ActivityRecord r) { 1736 if (mFocusedActivity != r) { 1737 mFocusedActivity = r; 1738 if (r != null) { 1739 mWindowManager.setFocusedApp(r.appToken, true); 1740 } 1741 } 1742 } 1743 1744 private final void updateLruProcessInternalLocked(ProcessRecord app, 1745 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1746 // put it on the LRU to keep track of when it should be exited. 1747 int lrui = mLruProcesses.indexOf(app); 1748 if (lrui >= 0) mLruProcesses.remove(lrui); 1749 1750 int i = mLruProcesses.size()-1; 1751 int skipTop = 0; 1752 1753 app.lruSeq = mLruSeq; 1754 1755 // compute the new weight for this process. 1756 if (updateActivityTime) { 1757 app.lastActivityTime = SystemClock.uptimeMillis(); 1758 } 1759 if (app.activities.size() > 0) { 1760 // If this process has activities, we more strongly want to keep 1761 // it around. 1762 app.lruWeight = app.lastActivityTime; 1763 } else if (app.pubProviders.size() > 0) { 1764 // If this process contains content providers, we want to keep 1765 // it a little more strongly. 1766 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1767 // Also don't let it kick out the first few "real" hidden processes. 1768 skipTop = ProcessList.MIN_HIDDEN_APPS; 1769 } else { 1770 // If this process doesn't have activities, we less strongly 1771 // want to keep it around, and generally want to avoid getting 1772 // in front of any very recently used activities. 1773 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1774 // Also don't let it kick out the first few "real" hidden processes. 1775 skipTop = ProcessList.MIN_HIDDEN_APPS; 1776 } 1777 1778 while (i >= 0) { 1779 ProcessRecord p = mLruProcesses.get(i); 1780 // If this app shouldn't be in front of the first N background 1781 // apps, then skip over that many that are currently hidden. 1782 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1783 skipTop--; 1784 } 1785 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1786 mLruProcesses.add(i+1, app); 1787 break; 1788 } 1789 i--; 1790 } 1791 if (i < 0) { 1792 mLruProcesses.add(0, app); 1793 } 1794 1795 // If the app is currently using a content provider or service, 1796 // bump those processes as well. 1797 if (app.connections.size() > 0) { 1798 for (ConnectionRecord cr : app.connections) { 1799 if (cr.binding != null && cr.binding.service != null 1800 && cr.binding.service.app != null 1801 && cr.binding.service.app.lruSeq != mLruSeq) { 1802 updateLruProcessInternalLocked(cr.binding.service.app, false, 1803 updateActivityTime, i+1); 1804 } 1805 } 1806 } 1807 for (int j=app.conProviders.size()-1; j>=0; j--) { 1808 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1809 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1810 updateLruProcessInternalLocked(cpr.proc, false, 1811 updateActivityTime, i+1); 1812 } 1813 } 1814 1815 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1816 if (oomAdj) { 1817 updateOomAdjLocked(); 1818 } 1819 } 1820 1821 final void updateLruProcessLocked(ProcessRecord app, 1822 boolean oomAdj, boolean updateActivityTime) { 1823 mLruSeq++; 1824 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1825 } 1826 1827 final ProcessRecord getProcessRecordLocked( 1828 String processName, int uid) { 1829 if (uid == Process.SYSTEM_UID) { 1830 // The system gets to run in any process. If there are multiple 1831 // processes with the same uid, just pick the first (this 1832 // should never happen). 1833 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1834 processName); 1835 if (procs == null) return null; 1836 final int N = procs.size(); 1837 for (int i = 0; i < N; i++) { 1838 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1839 } 1840 } 1841 ProcessRecord proc = mProcessNames.get(processName, uid); 1842 return proc; 1843 } 1844 1845 void ensurePackageDexOpt(String packageName) { 1846 IPackageManager pm = AppGlobals.getPackageManager(); 1847 try { 1848 if (pm.performDexOpt(packageName)) { 1849 mDidDexOpt = true; 1850 } 1851 } catch (RemoteException e) { 1852 } 1853 } 1854 1855 boolean isNextTransitionForward() { 1856 int transit = mWindowManager.getPendingAppTransition(); 1857 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1858 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1859 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1860 } 1861 1862 final ProcessRecord startProcessLocked(String processName, 1863 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1864 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1865 boolean isolated) { 1866 ProcessRecord app; 1867 if (!isolated) { 1868 app = getProcessRecordLocked(processName, info.uid); 1869 } else { 1870 // If this is an isolated process, it can't re-use an existing process. 1871 app = null; 1872 } 1873 // We don't have to do anything more if: 1874 // (1) There is an existing application record; and 1875 // (2) The caller doesn't think it is dead, OR there is no thread 1876 // object attached to it so we know it couldn't have crashed; and 1877 // (3) There is a pid assigned to it, so it is either starting or 1878 // already running. 1879 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1880 + " app=" + app + " knownToBeDead=" + knownToBeDead 1881 + " thread=" + (app != null ? app.thread : null) 1882 + " pid=" + (app != null ? app.pid : -1)); 1883 if (app != null && app.pid > 0) { 1884 if (!knownToBeDead || app.thread == null) { 1885 // We already have the app running, or are waiting for it to 1886 // come up (we have a pid but not yet its thread), so keep it. 1887 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1888 // If this is a new package in the process, add the package to the list 1889 app.addPackage(info.packageName); 1890 return app; 1891 } else { 1892 // An application record is attached to a previous process, 1893 // clean it up now. 1894 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1895 handleAppDiedLocked(app, true, true); 1896 } 1897 } 1898 1899 String hostingNameStr = hostingName != null 1900 ? hostingName.flattenToShortString() : null; 1901 1902 if (!isolated) { 1903 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1904 // If we are in the background, then check to see if this process 1905 // is bad. If so, we will just silently fail. 1906 if (mBadProcesses.get(info.processName, info.uid) != null) { 1907 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1908 + "/" + info.processName); 1909 return null; 1910 } 1911 } else { 1912 // When the user is explicitly starting a process, then clear its 1913 // crash count so that we won't make it bad until they see at 1914 // least one crash dialog again, and make the process good again 1915 // if it had been bad. 1916 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1917 + "/" + info.processName); 1918 mProcessCrashTimes.remove(info.processName, info.uid); 1919 if (mBadProcesses.get(info.processName, info.uid) != null) { 1920 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1921 info.processName); 1922 mBadProcesses.remove(info.processName, info.uid); 1923 if (app != null) { 1924 app.bad = false; 1925 } 1926 } 1927 } 1928 } 1929 1930 if (app == null) { 1931 app = newProcessRecordLocked(null, info, processName, isolated); 1932 if (app == null) { 1933 Slog.w(TAG, "Failed making new process record for " 1934 + processName + "/" + info.uid + " isolated=" + isolated); 1935 return null; 1936 } 1937 mProcessNames.put(processName, app.uid, app); 1938 if (isolated) { 1939 mIsolatedProcesses.put(app.uid, app); 1940 } 1941 } else { 1942 // If this is a new package in the process, add the package to the list 1943 app.addPackage(info.packageName); 1944 } 1945 1946 // If the system is not ready yet, then hold off on starting this 1947 // process until it is. 1948 if (!mProcessesReady 1949 && !isAllowedWhileBooting(info) 1950 && !allowWhileBooting) { 1951 if (!mProcessesOnHold.contains(app)) { 1952 mProcessesOnHold.add(app); 1953 } 1954 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1955 return app; 1956 } 1957 1958 startProcessLocked(app, hostingType, hostingNameStr); 1959 return (app.pid != 0) ? app : null; 1960 } 1961 1962 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1963 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1964 } 1965 1966 private final void startProcessLocked(ProcessRecord app, 1967 String hostingType, String hostingNameStr) { 1968 if (app.pid > 0 && app.pid != MY_PID) { 1969 synchronized (mPidsSelfLocked) { 1970 mPidsSelfLocked.remove(app.pid); 1971 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1972 } 1973 app.setPid(0); 1974 } 1975 1976 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1977 "startProcessLocked removing on hold: " + app); 1978 mProcessesOnHold.remove(app); 1979 1980 updateCpuStats(); 1981 1982 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1983 mProcDeaths[0] = 0; 1984 1985 try { 1986 int uid = app.uid; 1987 1988 int[] gids = null; 1989 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1990 if (!app.isolated) { 1991 try { 1992 final PackageManager pm = mContext.getPackageManager(); 1993 gids = pm.getPackageGids(app.info.packageName); 1994 } catch (PackageManager.NameNotFoundException e) { 1995 Slog.w(TAG, "Unable to retrieve gids", e); 1996 } 1997 1998 if (Environment.isExternalStorageEmulated()) { 1999 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2000 } 2001 } 2002 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2003 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2004 && mTopComponent != null 2005 && app.processName.equals(mTopComponent.getPackageName())) { 2006 uid = 0; 2007 } 2008 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2009 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2010 uid = 0; 2011 } 2012 } 2013 int debugFlags = 0; 2014 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2015 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2016 // Also turn on CheckJNI for debuggable apps. It's quite 2017 // awkward to turn on otherwise. 2018 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2019 } 2020 // Run the app in safe mode if its manifest requests so or the 2021 // system is booted in safe mode. 2022 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2023 Zygote.systemInSafeMode == true) { 2024 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2025 } 2026 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2027 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2028 } 2029 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2030 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2031 } 2032 if ("1".equals(SystemProperties.get("debug.assert"))) { 2033 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2034 } 2035 2036 // Start the process. It will either succeed and return a result containing 2037 // the PID of the new process, or else throw a RuntimeException. 2038 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2039 app.processName, uid, uid, gids, debugFlags, mountExternal, 2040 app.info.targetSdkVersion, null, null); 2041 2042 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2043 synchronized (bs) { 2044 if (bs.isOnBattery()) { 2045 app.batteryStats.incStartsLocked(); 2046 } 2047 } 2048 2049 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2050 app.processName, hostingType, 2051 hostingNameStr != null ? hostingNameStr : ""); 2052 2053 if (app.persistent) { 2054 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2055 } 2056 2057 StringBuilder buf = mStringBuilder; 2058 buf.setLength(0); 2059 buf.append("Start proc "); 2060 buf.append(app.processName); 2061 buf.append(" for "); 2062 buf.append(hostingType); 2063 if (hostingNameStr != null) { 2064 buf.append(" "); 2065 buf.append(hostingNameStr); 2066 } 2067 buf.append(": pid="); 2068 buf.append(startResult.pid); 2069 buf.append(" uid="); 2070 buf.append(uid); 2071 buf.append(" gids={"); 2072 if (gids != null) { 2073 for (int gi=0; gi<gids.length; gi++) { 2074 if (gi != 0) buf.append(", "); 2075 buf.append(gids[gi]); 2076 2077 } 2078 } 2079 buf.append("}"); 2080 Slog.i(TAG, buf.toString()); 2081 app.setPid(startResult.pid); 2082 app.usingWrapper = startResult.usingWrapper; 2083 app.removed = false; 2084 synchronized (mPidsSelfLocked) { 2085 this.mPidsSelfLocked.put(startResult.pid, app); 2086 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2087 msg.obj = app; 2088 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2089 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2090 } 2091 } catch (RuntimeException e) { 2092 // XXX do better error recovery. 2093 app.setPid(0); 2094 Slog.e(TAG, "Failure starting process " + app.processName, e); 2095 } 2096 } 2097 2098 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2099 if (resumed) { 2100 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2101 } else { 2102 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2103 } 2104 } 2105 2106 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2107 if (mHeadless) { 2108 // Added because none of the other calls to ensureBootCompleted seem to fire 2109 // when running headless. 2110 ensureBootCompleted(); 2111 return false; 2112 } 2113 2114 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2115 && mTopAction == null) { 2116 // We are running in factory test mode, but unable to find 2117 // the factory test app, so just sit around displaying the 2118 // error message and don't try to start anything. 2119 return false; 2120 } 2121 Intent intent = new Intent( 2122 mTopAction, 2123 mTopData != null ? Uri.parse(mTopData) : null); 2124 intent.setComponent(mTopComponent); 2125 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2126 intent.addCategory(Intent.CATEGORY_HOME); 2127 } 2128 ActivityInfo aInfo = 2129 intent.resolveActivityInfo(mContext.getPackageManager(), 2130 STOCK_PM_FLAGS); 2131 if (aInfo != null) { 2132 intent.setComponent(new ComponentName( 2133 aInfo.applicationInfo.packageName, aInfo.name)); 2134 // Don't do this if the home app is currently being 2135 // instrumented. 2136 aInfo = new ActivityInfo(aInfo); 2137 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2138 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2139 aInfo.applicationInfo.uid); 2140 if (app == null || app.instrumentationClass == null) { 2141 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2142 mMainStack.startActivityLocked(null, intent, null, aInfo, 2143 null, null, 0, 0, 0, 0, null, false, null); 2144 } 2145 } 2146 if (startingUser != null) { 2147 mMainStack.addStartingUserLocked(startingUser); 2148 } 2149 2150 return true; 2151 } 2152 2153 /** 2154 * Starts the "new version setup screen" if appropriate. 2155 */ 2156 void startSetupActivityLocked() { 2157 // Only do this once per boot. 2158 if (mCheckedForSetup) { 2159 return; 2160 } 2161 2162 // We will show this screen if the current one is a different 2163 // version than the last one shown, and we are not running in 2164 // low-level factory test mode. 2165 final ContentResolver resolver = mContext.getContentResolver(); 2166 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2167 Settings.Secure.getInt(resolver, 2168 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2169 mCheckedForSetup = true; 2170 2171 // See if we should be showing the platform update setup UI. 2172 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2173 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2174 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2175 2176 // We don't allow third party apps to replace this. 2177 ResolveInfo ri = null; 2178 for (int i=0; ris != null && i<ris.size(); i++) { 2179 if ((ris.get(i).activityInfo.applicationInfo.flags 2180 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2181 ri = ris.get(i); 2182 break; 2183 } 2184 } 2185 2186 if (ri != null) { 2187 String vers = ri.activityInfo.metaData != null 2188 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2189 : null; 2190 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2191 vers = ri.activityInfo.applicationInfo.metaData.getString( 2192 Intent.METADATA_SETUP_VERSION); 2193 } 2194 String lastVers = Settings.Secure.getString( 2195 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2196 if (vers != null && !vers.equals(lastVers)) { 2197 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2198 intent.setComponent(new ComponentName( 2199 ri.activityInfo.packageName, ri.activityInfo.name)); 2200 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2201 null, null, 0, 0, 0, 0, null, false, null); 2202 } 2203 } 2204 } 2205 } 2206 2207 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2208 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2209 } 2210 2211 void enforceNotIsolatedCaller(String caller) { 2212 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2213 throw new SecurityException("Isolated process not allowed to call " + caller); 2214 } 2215 } 2216 2217 public int getFrontActivityScreenCompatMode() { 2218 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2219 synchronized (this) { 2220 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2221 } 2222 } 2223 2224 public void setFrontActivityScreenCompatMode(int mode) { 2225 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2226 "setFrontActivityScreenCompatMode"); 2227 synchronized (this) { 2228 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2229 } 2230 } 2231 2232 public int getPackageScreenCompatMode(String packageName) { 2233 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2234 synchronized (this) { 2235 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2236 } 2237 } 2238 2239 public void setPackageScreenCompatMode(String packageName, int mode) { 2240 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2241 "setPackageScreenCompatMode"); 2242 synchronized (this) { 2243 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2244 } 2245 } 2246 2247 public boolean getPackageAskScreenCompat(String packageName) { 2248 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2249 synchronized (this) { 2250 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2251 } 2252 } 2253 2254 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2255 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2256 "setPackageAskScreenCompat"); 2257 synchronized (this) { 2258 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2259 } 2260 } 2261 2262 void reportResumedActivityLocked(ActivityRecord r) { 2263 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2264 updateUsageStats(r, true); 2265 } 2266 2267 private void dispatchProcessesChanged() { 2268 int N; 2269 synchronized (this) { 2270 N = mPendingProcessChanges.size(); 2271 if (mActiveProcessChanges.length < N) { 2272 mActiveProcessChanges = new ProcessChangeItem[N]; 2273 } 2274 mPendingProcessChanges.toArray(mActiveProcessChanges); 2275 mAvailProcessChanges.addAll(mPendingProcessChanges); 2276 mPendingProcessChanges.clear(); 2277 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2278 } 2279 int i = mProcessObservers.beginBroadcast(); 2280 while (i > 0) { 2281 i--; 2282 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2283 if (observer != null) { 2284 try { 2285 for (int j=0; j<N; j++) { 2286 ProcessChangeItem item = mActiveProcessChanges[j]; 2287 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2289 + item.pid + " uid=" + item.uid + ": " 2290 + item.foregroundActivities); 2291 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2292 item.foregroundActivities); 2293 } 2294 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2295 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2296 + item.pid + " uid=" + item.uid + ": " + item.importance); 2297 observer.onImportanceChanged(item.pid, item.uid, 2298 item.importance); 2299 } 2300 } 2301 } catch (RemoteException e) { 2302 } 2303 } 2304 } 2305 mProcessObservers.finishBroadcast(); 2306 } 2307 2308 private void dispatchProcessDied(int pid, int uid) { 2309 int i = mProcessObservers.beginBroadcast(); 2310 while (i > 0) { 2311 i--; 2312 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2313 if (observer != null) { 2314 try { 2315 observer.onProcessDied(pid, uid); 2316 } catch (RemoteException e) { 2317 } 2318 } 2319 } 2320 mProcessObservers.finishBroadcast(); 2321 } 2322 2323 final void doPendingActivityLaunchesLocked(boolean doResume) { 2324 final int N = mPendingActivityLaunches.size(); 2325 if (N <= 0) { 2326 return; 2327 } 2328 for (int i=0; i<N; i++) { 2329 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2330 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2331 pal.startFlags, doResume && i == (N-1), null); 2332 } 2333 mPendingActivityLaunches.clear(); 2334 } 2335 2336 public final int startActivity(IApplicationThread caller, 2337 Intent intent, String resolvedType, IBinder resultTo, 2338 String resultWho, int requestCode, int startFlags, 2339 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2340 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2341 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2342 } 2343 2344 public final int startActivityAsUser(IApplicationThread caller, 2345 Intent intent, String resolvedType, IBinder resultTo, 2346 String resultWho, int requestCode, int startFlags, 2347 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2348 enforceNotIsolatedCaller("startActivity"); 2349 if (userId != UserHandle.getCallingUserId()) { 2350 // Requesting a different user, make sure that they have the permission 2351 if (checkComponentPermission( 2352 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2353 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2354 == PackageManager.PERMISSION_GRANTED) { 2355 // Translate to the current user id, if caller wasn't aware 2356 if (userId == UserHandle.USER_CURRENT) { 2357 userId = mCurrentUserId; 2358 } 2359 } else { 2360 String msg = "Permission Denial: " 2361 + "Request to startActivity as user " + userId 2362 + " but is calling from user " + UserHandle.getCallingUserId() 2363 + "; this requires " 2364 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2365 Slog.w(TAG, msg); 2366 throw new SecurityException(msg); 2367 } 2368 } else { 2369 if (intent.getCategories() != null 2370 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2371 // Requesting home, set the identity to the current user 2372 // HACK! 2373 userId = mCurrentUserId; 2374 } else { 2375 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2376 // the current user's userId 2377 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2378 userId = 0; 2379 } else { 2380 userId = Binder.getOrigCallingUser(); 2381 } 2382 } 2383 } 2384 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2385 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2386 null, null, options, userId); 2387 } 2388 2389 public final WaitResult startActivityAndWait(IApplicationThread caller, 2390 Intent intent, String resolvedType, IBinder resultTo, 2391 String resultWho, int requestCode, int startFlags, String profileFile, 2392 ParcelFileDescriptor profileFd, Bundle options) { 2393 enforceNotIsolatedCaller("startActivityAndWait"); 2394 WaitResult res = new WaitResult(); 2395 int userId = Binder.getOrigCallingUser(); 2396 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2397 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2398 res, null, options, userId); 2399 return res; 2400 } 2401 2402 public final int startActivityWithConfig(IApplicationThread caller, 2403 Intent intent, String resolvedType, IBinder resultTo, 2404 String resultWho, int requestCode, int startFlags, Configuration config, 2405 Bundle options) { 2406 enforceNotIsolatedCaller("startActivityWithConfig"); 2407 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2408 resultTo, resultWho, requestCode, startFlags, 2409 null, null, null, config, options, Binder.getOrigCallingUser()); 2410 return ret; 2411 } 2412 2413 public int startActivityIntentSender(IApplicationThread caller, 2414 IntentSender intent, Intent fillInIntent, String resolvedType, 2415 IBinder resultTo, String resultWho, int requestCode, 2416 int flagsMask, int flagsValues, Bundle options) { 2417 enforceNotIsolatedCaller("startActivityIntentSender"); 2418 // Refuse possible leaked file descriptors 2419 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2420 throw new IllegalArgumentException("File descriptors passed in Intent"); 2421 } 2422 2423 IIntentSender sender = intent.getTarget(); 2424 if (!(sender instanceof PendingIntentRecord)) { 2425 throw new IllegalArgumentException("Bad PendingIntent object"); 2426 } 2427 2428 PendingIntentRecord pir = (PendingIntentRecord)sender; 2429 2430 synchronized (this) { 2431 // If this is coming from the currently resumed activity, it is 2432 // effectively saying that app switches are allowed at this point. 2433 if (mMainStack.mResumedActivity != null 2434 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2435 Binder.getCallingUid()) { 2436 mAppSwitchesAllowedTime = 0; 2437 } 2438 } 2439 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2440 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2441 return ret; 2442 } 2443 2444 public boolean startNextMatchingActivity(IBinder callingActivity, 2445 Intent intent, Bundle options) { 2446 // Refuse possible leaked file descriptors 2447 if (intent != null && intent.hasFileDescriptors() == true) { 2448 throw new IllegalArgumentException("File descriptors passed in Intent"); 2449 } 2450 2451 synchronized (this) { 2452 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2453 if (r == null) { 2454 ActivityOptions.abort(options); 2455 return false; 2456 } 2457 if (r.app == null || r.app.thread == null) { 2458 // The caller is not running... d'oh! 2459 ActivityOptions.abort(options); 2460 return false; 2461 } 2462 intent = new Intent(intent); 2463 // The caller is not allowed to change the data. 2464 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2465 // And we are resetting to find the next component... 2466 intent.setComponent(null); 2467 2468 ActivityInfo aInfo = null; 2469 try { 2470 List<ResolveInfo> resolves = 2471 AppGlobals.getPackageManager().queryIntentActivities( 2472 intent, r.resolvedType, 2473 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2474 UserHandle.getCallingUserId()); 2475 2476 // Look for the original activity in the list... 2477 final int N = resolves != null ? resolves.size() : 0; 2478 for (int i=0; i<N; i++) { 2479 ResolveInfo rInfo = resolves.get(i); 2480 if (rInfo.activityInfo.packageName.equals(r.packageName) 2481 && rInfo.activityInfo.name.equals(r.info.name)) { 2482 // We found the current one... the next matching is 2483 // after it. 2484 i++; 2485 if (i<N) { 2486 aInfo = resolves.get(i).activityInfo; 2487 } 2488 break; 2489 } 2490 } 2491 } catch (RemoteException e) { 2492 } 2493 2494 if (aInfo == null) { 2495 // Nobody who is next! 2496 ActivityOptions.abort(options); 2497 return false; 2498 } 2499 2500 intent.setComponent(new ComponentName( 2501 aInfo.applicationInfo.packageName, aInfo.name)); 2502 intent.setFlags(intent.getFlags()&~( 2503 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2504 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2505 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2506 Intent.FLAG_ACTIVITY_NEW_TASK)); 2507 2508 // Okay now we need to start the new activity, replacing the 2509 // currently running activity. This is a little tricky because 2510 // we want to start the new one as if the current one is finished, 2511 // but not finish the current one first so that there is no flicker. 2512 // And thus... 2513 final boolean wasFinishing = r.finishing; 2514 r.finishing = true; 2515 2516 // Propagate reply information over to the new activity. 2517 final ActivityRecord resultTo = r.resultTo; 2518 final String resultWho = r.resultWho; 2519 final int requestCode = r.requestCode; 2520 r.resultTo = null; 2521 if (resultTo != null) { 2522 resultTo.removeResultsLocked(r, resultWho, requestCode); 2523 } 2524 2525 final long origId = Binder.clearCallingIdentity(); 2526 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2527 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2528 resultWho, requestCode, -1, r.launchedFromUid, 0, 2529 options, false, null); 2530 Binder.restoreCallingIdentity(origId); 2531 2532 r.finishing = wasFinishing; 2533 if (res != ActivityManager.START_SUCCESS) { 2534 return false; 2535 } 2536 return true; 2537 } 2538 } 2539 2540 public final int startActivityInPackage(int uid, 2541 Intent intent, String resolvedType, IBinder resultTo, 2542 String resultWho, int requestCode, int startFlags, Bundle options) { 2543 2544 // This is so super not safe, that only the system (or okay root) 2545 // can do it. 2546 final int callingUid = Binder.getCallingUid(); 2547 if (callingUid != 0 && callingUid != Process.myUid()) { 2548 throw new SecurityException( 2549 "startActivityInPackage only available to the system"); 2550 } 2551 2552 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2553 resultTo, resultWho, requestCode, startFlags, 2554 null, null, null, null, options, UserHandle.getUserId(uid)); 2555 return ret; 2556 } 2557 2558 public final int startActivities(IApplicationThread caller, 2559 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2560 enforceNotIsolatedCaller("startActivities"); 2561 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2562 options, Binder.getOrigCallingUser()); 2563 return ret; 2564 } 2565 2566 public final int startActivitiesInPackage(int uid, 2567 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2568 Bundle options) { 2569 2570 // This is so super not safe, that only the system (or okay root) 2571 // can do it. 2572 final int callingUid = Binder.getCallingUid(); 2573 if (callingUid != 0 && callingUid != Process.myUid()) { 2574 throw new SecurityException( 2575 "startActivityInPackage only available to the system"); 2576 } 2577 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2578 options, UserHandle.getUserId(uid)); 2579 return ret; 2580 } 2581 2582 final void addRecentTaskLocked(TaskRecord task) { 2583 int N = mRecentTasks.size(); 2584 // Quick case: check if the top-most recent task is the same. 2585 if (N > 0 && mRecentTasks.get(0) == task) { 2586 return; 2587 } 2588 // Remove any existing entries that are the same kind of task. 2589 for (int i=0; i<N; i++) { 2590 TaskRecord tr = mRecentTasks.get(i); 2591 if (task.userId == tr.userId 2592 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2593 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2594 mRecentTasks.remove(i); 2595 i--; 2596 N--; 2597 if (task.intent == null) { 2598 // If the new recent task we are adding is not fully 2599 // specified, then replace it with the existing recent task. 2600 task = tr; 2601 } 2602 } 2603 } 2604 if (N >= MAX_RECENT_TASKS) { 2605 mRecentTasks.remove(N-1); 2606 } 2607 mRecentTasks.add(0, task); 2608 } 2609 2610 public void setRequestedOrientation(IBinder token, 2611 int requestedOrientation) { 2612 synchronized (this) { 2613 ActivityRecord r = mMainStack.isInStackLocked(token); 2614 if (r == null) { 2615 return; 2616 } 2617 final long origId = Binder.clearCallingIdentity(); 2618 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2619 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2620 mConfiguration, 2621 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2622 if (config != null) { 2623 r.frozenBeforeDestroy = true; 2624 if (!updateConfigurationLocked(config, r, false, false)) { 2625 mMainStack.resumeTopActivityLocked(null); 2626 } 2627 } 2628 Binder.restoreCallingIdentity(origId); 2629 } 2630 } 2631 2632 public int getRequestedOrientation(IBinder token) { 2633 synchronized (this) { 2634 ActivityRecord r = mMainStack.isInStackLocked(token); 2635 if (r == null) { 2636 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2637 } 2638 return mWindowManager.getAppOrientation(r.appToken); 2639 } 2640 } 2641 2642 /** 2643 * This is the internal entry point for handling Activity.finish(). 2644 * 2645 * @param token The Binder token referencing the Activity we want to finish. 2646 * @param resultCode Result code, if any, from this Activity. 2647 * @param resultData Result data (Intent), if any, from this Activity. 2648 * 2649 * @return Returns true if the activity successfully finished, or false if it is still running. 2650 */ 2651 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2652 // Refuse possible leaked file descriptors 2653 if (resultData != null && resultData.hasFileDescriptors() == true) { 2654 throw new IllegalArgumentException("File descriptors passed in Intent"); 2655 } 2656 2657 synchronized(this) { 2658 if (mController != null) { 2659 // Find the first activity that is not finishing. 2660 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2661 if (next != null) { 2662 // ask watcher if this is allowed 2663 boolean resumeOK = true; 2664 try { 2665 resumeOK = mController.activityResuming(next.packageName); 2666 } catch (RemoteException e) { 2667 mController = null; 2668 } 2669 2670 if (!resumeOK) { 2671 return false; 2672 } 2673 } 2674 } 2675 final long origId = Binder.clearCallingIdentity(); 2676 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2677 resultData, "app-request"); 2678 Binder.restoreCallingIdentity(origId); 2679 return res; 2680 } 2681 } 2682 2683 public final void finishHeavyWeightApp() { 2684 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2685 != PackageManager.PERMISSION_GRANTED) { 2686 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2687 + Binder.getCallingPid() 2688 + ", uid=" + Binder.getCallingUid() 2689 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2690 Slog.w(TAG, msg); 2691 throw new SecurityException(msg); 2692 } 2693 2694 synchronized(this) { 2695 if (mHeavyWeightProcess == null) { 2696 return; 2697 } 2698 2699 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2700 mHeavyWeightProcess.activities); 2701 for (int i=0; i<activities.size(); i++) { 2702 ActivityRecord r = activities.get(i); 2703 if (!r.finishing) { 2704 int index = mMainStack.indexOfTokenLocked(r.appToken); 2705 if (index >= 0) { 2706 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2707 null, "finish-heavy"); 2708 } 2709 } 2710 } 2711 2712 mHeavyWeightProcess = null; 2713 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2714 } 2715 } 2716 2717 public void crashApplication(int uid, int initialPid, String packageName, 2718 String message) { 2719 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2720 != PackageManager.PERMISSION_GRANTED) { 2721 String msg = "Permission Denial: crashApplication() from pid=" 2722 + Binder.getCallingPid() 2723 + ", uid=" + Binder.getCallingUid() 2724 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2725 Slog.w(TAG, msg); 2726 throw new SecurityException(msg); 2727 } 2728 2729 synchronized(this) { 2730 ProcessRecord proc = null; 2731 2732 // Figure out which process to kill. We don't trust that initialPid 2733 // still has any relation to current pids, so must scan through the 2734 // list. 2735 synchronized (mPidsSelfLocked) { 2736 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2737 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2738 if (p.uid != uid) { 2739 continue; 2740 } 2741 if (p.pid == initialPid) { 2742 proc = p; 2743 break; 2744 } 2745 for (String str : p.pkgList) { 2746 if (str.equals(packageName)) { 2747 proc = p; 2748 } 2749 } 2750 } 2751 } 2752 2753 if (proc == null) { 2754 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2755 + " initialPid=" + initialPid 2756 + " packageName=" + packageName); 2757 return; 2758 } 2759 2760 if (proc.thread != null) { 2761 if (proc.pid == Process.myPid()) { 2762 Log.w(TAG, "crashApplication: trying to crash self!"); 2763 return; 2764 } 2765 long ident = Binder.clearCallingIdentity(); 2766 try { 2767 proc.thread.scheduleCrash(message); 2768 } catch (RemoteException e) { 2769 } 2770 Binder.restoreCallingIdentity(ident); 2771 } 2772 } 2773 } 2774 2775 public final void finishSubActivity(IBinder token, String resultWho, 2776 int requestCode) { 2777 synchronized(this) { 2778 final long origId = Binder.clearCallingIdentity(); 2779 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2780 Binder.restoreCallingIdentity(origId); 2781 } 2782 } 2783 2784 public boolean finishActivityAffinity(IBinder token) { 2785 synchronized(this) { 2786 final long origId = Binder.clearCallingIdentity(); 2787 boolean res = mMainStack.finishActivityAffinityLocked(token); 2788 Binder.restoreCallingIdentity(origId); 2789 return res; 2790 } 2791 } 2792 2793 public boolean willActivityBeVisible(IBinder token) { 2794 synchronized(this) { 2795 int i; 2796 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2797 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2798 if (r.appToken == token) { 2799 return true; 2800 } 2801 if (r.fullscreen && !r.finishing) { 2802 return false; 2803 } 2804 } 2805 return true; 2806 } 2807 } 2808 2809 public void overridePendingTransition(IBinder token, String packageName, 2810 int enterAnim, int exitAnim) { 2811 synchronized(this) { 2812 ActivityRecord self = mMainStack.isInStackLocked(token); 2813 if (self == null) { 2814 return; 2815 } 2816 2817 final long origId = Binder.clearCallingIdentity(); 2818 2819 if (self.state == ActivityState.RESUMED 2820 || self.state == ActivityState.PAUSING) { 2821 mWindowManager.overridePendingAppTransition(packageName, 2822 enterAnim, exitAnim, null); 2823 } 2824 2825 Binder.restoreCallingIdentity(origId); 2826 } 2827 } 2828 2829 /** 2830 * Main function for removing an existing process from the activity manager 2831 * as a result of that process going away. Clears out all connections 2832 * to the process. 2833 */ 2834 private final void handleAppDiedLocked(ProcessRecord app, 2835 boolean restarting, boolean allowRestart) { 2836 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2837 if (!restarting) { 2838 mLruProcesses.remove(app); 2839 } 2840 2841 if (mProfileProc == app) { 2842 clearProfilerLocked(); 2843 } 2844 2845 // Just in case... 2846 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2847 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2848 mMainStack.mPausingActivity = null; 2849 } 2850 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2851 mMainStack.mLastPausedActivity = null; 2852 } 2853 2854 // Remove this application's activities from active lists. 2855 mMainStack.removeHistoryRecordsForAppLocked(app); 2856 2857 boolean atTop = true; 2858 boolean hasVisibleActivities = false; 2859 2860 // Clean out the history list. 2861 int i = mMainStack.mHistory.size(); 2862 if (localLOGV) Slog.v( 2863 TAG, "Removing app " + app + " from history with " + i + " entries"); 2864 while (i > 0) { 2865 i--; 2866 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2867 if (localLOGV) Slog.v( 2868 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2869 if (r.app == app) { 2870 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2871 if (ActivityStack.DEBUG_ADD_REMOVE) { 2872 RuntimeException here = new RuntimeException("here"); 2873 here.fillInStackTrace(); 2874 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2875 + ": haveState=" + r.haveState 2876 + " stateNotNeeded=" + r.stateNotNeeded 2877 + " finishing=" + r.finishing 2878 + " state=" + r.state, here); 2879 } 2880 if (!r.finishing) { 2881 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2882 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2883 System.identityHashCode(r), 2884 r.task.taskId, r.shortComponentName, 2885 "proc died without state saved"); 2886 } 2887 mMainStack.removeActivityFromHistoryLocked(r); 2888 2889 } else { 2890 // We have the current state for this activity, so 2891 // it can be restarted later when needed. 2892 if (localLOGV) Slog.v( 2893 TAG, "Keeping entry, setting app to null"); 2894 if (r.visible) { 2895 hasVisibleActivities = true; 2896 } 2897 r.app = null; 2898 r.nowVisible = false; 2899 if (!r.haveState) { 2900 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2901 "App died, clearing saved state of " + r); 2902 r.icicle = null; 2903 } 2904 } 2905 2906 r.stack.cleanUpActivityLocked(r, true, true); 2907 } 2908 atTop = false; 2909 } 2910 2911 app.activities.clear(); 2912 2913 if (app.instrumentationClass != null) { 2914 Slog.w(TAG, "Crash of app " + app.processName 2915 + " running instrumentation " + app.instrumentationClass); 2916 Bundle info = new Bundle(); 2917 info.putString("shortMsg", "Process crashed."); 2918 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2919 } 2920 2921 if (!restarting) { 2922 if (!mMainStack.resumeTopActivityLocked(null)) { 2923 // If there was nothing to resume, and we are not already 2924 // restarting this process, but there is a visible activity that 2925 // is hosted by the process... then make sure all visible 2926 // activities are running, taking care of restarting this 2927 // process. 2928 if (hasVisibleActivities) { 2929 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2930 } 2931 } 2932 } 2933 } 2934 2935 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2936 IBinder threadBinder = thread.asBinder(); 2937 // Find the application record. 2938 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2939 ProcessRecord rec = mLruProcesses.get(i); 2940 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2941 return i; 2942 } 2943 } 2944 return -1; 2945 } 2946 2947 final ProcessRecord getRecordForAppLocked( 2948 IApplicationThread thread) { 2949 if (thread == null) { 2950 return null; 2951 } 2952 2953 int appIndex = getLRURecordIndexForAppLocked(thread); 2954 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2955 } 2956 2957 final void appDiedLocked(ProcessRecord app, int pid, 2958 IApplicationThread thread) { 2959 2960 mProcDeaths[0]++; 2961 2962 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2963 synchronized (stats) { 2964 stats.noteProcessDiedLocked(app.info.uid, pid); 2965 } 2966 2967 // Clean up already done if the process has been re-started. 2968 if (app.pid == pid && app.thread != null && 2969 app.thread.asBinder() == thread.asBinder()) { 2970 if (!app.killedBackground) { 2971 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2972 + ") has died."); 2973 } 2974 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2975 if (localLOGV) Slog.v( 2976 TAG, "Dying app: " + app + ", pid: " + pid 2977 + ", thread: " + thread.asBinder()); 2978 boolean doLowMem = app.instrumentationClass == null; 2979 handleAppDiedLocked(app, false, true); 2980 2981 if (doLowMem) { 2982 // If there are no longer any background processes running, 2983 // and the app that died was not running instrumentation, 2984 // then tell everyone we are now low on memory. 2985 boolean haveBg = false; 2986 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2987 ProcessRecord rec = mLruProcesses.get(i); 2988 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2989 haveBg = true; 2990 break; 2991 } 2992 } 2993 2994 if (!haveBg) { 2995 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2996 long now = SystemClock.uptimeMillis(); 2997 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2998 ProcessRecord rec = mLruProcesses.get(i); 2999 if (rec != app && rec.thread != null && 3000 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3001 // The low memory report is overriding any current 3002 // state for a GC request. Make sure to do 3003 // heavy/important/visible/foreground processes first. 3004 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3005 rec.lastRequestedGc = 0; 3006 } else { 3007 rec.lastRequestedGc = rec.lastLowMemory; 3008 } 3009 rec.reportLowMemory = true; 3010 rec.lastLowMemory = now; 3011 mProcessesToGc.remove(rec); 3012 addProcessToGcListLocked(rec); 3013 } 3014 } 3015 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3016 scheduleAppGcsLocked(); 3017 } 3018 } 3019 } else if (app.pid != pid) { 3020 // A new process has already been started. 3021 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3022 + ") has died and restarted (pid " + app.pid + ")."); 3023 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3024 } else if (DEBUG_PROCESSES) { 3025 Slog.d(TAG, "Received spurious death notification for thread " 3026 + thread.asBinder()); 3027 } 3028 } 3029 3030 /** 3031 * If a stack trace dump file is configured, dump process stack traces. 3032 * @param clearTraces causes the dump file to be erased prior to the new 3033 * traces being written, if true; when false, the new traces will be 3034 * appended to any existing file content. 3035 * @param firstPids of dalvik VM processes to dump stack traces for first 3036 * @param lastPids of dalvik VM processes to dump stack traces for last 3037 * @param nativeProcs optional list of native process names to dump stack crawls 3038 * @return file containing stack traces, or null if no dump file is configured 3039 */ 3040 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3041 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3042 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3043 if (tracesPath == null || tracesPath.length() == 0) { 3044 return null; 3045 } 3046 3047 File tracesFile = new File(tracesPath); 3048 try { 3049 File tracesDir = tracesFile.getParentFile(); 3050 if (!tracesDir.exists()) { 3051 tracesFile.mkdirs(); 3052 if (!SELinux.restorecon(tracesDir)) { 3053 return null; 3054 } 3055 } 3056 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3057 3058 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3059 tracesFile.createNewFile(); 3060 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3061 } catch (IOException e) { 3062 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3063 return null; 3064 } 3065 3066 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3067 return tracesFile; 3068 } 3069 3070 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3071 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3072 // Use a FileObserver to detect when traces finish writing. 3073 // The order of traces is considered important to maintain for legibility. 3074 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3075 public synchronized void onEvent(int event, String path) { notify(); } 3076 }; 3077 3078 try { 3079 observer.startWatching(); 3080 3081 // First collect all of the stacks of the most important pids. 3082 if (firstPids != null) { 3083 try { 3084 int num = firstPids.size(); 3085 for (int i = 0; i < num; i++) { 3086 synchronized (observer) { 3087 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3088 observer.wait(200); // Wait for write-close, give up after 200msec 3089 } 3090 } 3091 } catch (InterruptedException e) { 3092 Log.wtf(TAG, e); 3093 } 3094 } 3095 3096 // Next measure CPU usage. 3097 if (processStats != null) { 3098 processStats.init(); 3099 System.gc(); 3100 processStats.update(); 3101 try { 3102 synchronized (processStats) { 3103 processStats.wait(500); // measure over 1/2 second. 3104 } 3105 } catch (InterruptedException e) { 3106 } 3107 processStats.update(); 3108 3109 // We'll take the stack crawls of just the top apps using CPU. 3110 final int N = processStats.countWorkingStats(); 3111 int numProcs = 0; 3112 for (int i=0; i<N && numProcs<5; i++) { 3113 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3114 if (lastPids.indexOfKey(stats.pid) >= 0) { 3115 numProcs++; 3116 try { 3117 synchronized (observer) { 3118 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3119 observer.wait(200); // Wait for write-close, give up after 200msec 3120 } 3121 } catch (InterruptedException e) { 3122 Log.wtf(TAG, e); 3123 } 3124 3125 } 3126 } 3127 } 3128 3129 } finally { 3130 observer.stopWatching(); 3131 } 3132 3133 if (nativeProcs != null) { 3134 int[] pids = Process.getPidsForCommands(nativeProcs); 3135 if (pids != null) { 3136 for (int pid : pids) { 3137 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3138 } 3139 } 3140 } 3141 } 3142 3143 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3144 if (true || IS_USER_BUILD) { 3145 return; 3146 } 3147 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3148 if (tracesPath == null || tracesPath.length() == 0) { 3149 return; 3150 } 3151 3152 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3153 StrictMode.allowThreadDiskWrites(); 3154 try { 3155 final File tracesFile = new File(tracesPath); 3156 final File tracesDir = tracesFile.getParentFile(); 3157 final File tracesTmp = new File(tracesDir, "__tmp__"); 3158 try { 3159 if (!tracesDir.exists()) { 3160 tracesFile.mkdirs(); 3161 if (!SELinux.restorecon(tracesDir.getPath())) { 3162 return; 3163 } 3164 } 3165 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3166 3167 if (tracesFile.exists()) { 3168 tracesTmp.delete(); 3169 tracesFile.renameTo(tracesTmp); 3170 } 3171 StringBuilder sb = new StringBuilder(); 3172 Time tobj = new Time(); 3173 tobj.set(System.currentTimeMillis()); 3174 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3175 sb.append(": "); 3176 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3177 sb.append(" since "); 3178 sb.append(msg); 3179 FileOutputStream fos = new FileOutputStream(tracesFile); 3180 fos.write(sb.toString().getBytes()); 3181 if (app == null) { 3182 fos.write("\n*** No application process!".getBytes()); 3183 } 3184 fos.close(); 3185 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3186 } catch (IOException e) { 3187 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3188 return; 3189 } 3190 3191 if (app != null) { 3192 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3193 firstPids.add(app.pid); 3194 dumpStackTraces(tracesPath, firstPids, null, null, null); 3195 } 3196 3197 File lastTracesFile = null; 3198 File curTracesFile = null; 3199 for (int i=9; i>=0; i--) { 3200 String name = String.format("slow%02d.txt", i); 3201 curTracesFile = new File(tracesDir, name); 3202 if (curTracesFile.exists()) { 3203 if (lastTracesFile != null) { 3204 curTracesFile.renameTo(lastTracesFile); 3205 } else { 3206 curTracesFile.delete(); 3207 } 3208 } 3209 lastTracesFile = curTracesFile; 3210 } 3211 tracesFile.renameTo(curTracesFile); 3212 if (tracesTmp.exists()) { 3213 tracesTmp.renameTo(tracesFile); 3214 } 3215 } finally { 3216 StrictMode.setThreadPolicy(oldPolicy); 3217 } 3218 } 3219 3220 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3221 ActivityRecord parent, final String annotation) { 3222 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3223 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3224 3225 if (mController != null) { 3226 try { 3227 // 0 == continue, -1 = kill process immediately 3228 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3229 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3230 } catch (RemoteException e) { 3231 mController = null; 3232 } 3233 } 3234 3235 long anrTime = SystemClock.uptimeMillis(); 3236 if (MONITOR_CPU_USAGE) { 3237 updateCpuStatsNow(); 3238 } 3239 3240 synchronized (this) { 3241 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3242 if (mShuttingDown) { 3243 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3244 return; 3245 } else if (app.notResponding) { 3246 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3247 return; 3248 } else if (app.crashing) { 3249 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3250 return; 3251 } 3252 3253 // In case we come through here for the same app before completing 3254 // this one, mark as anring now so we will bail out. 3255 app.notResponding = true; 3256 3257 // Log the ANR to the event log. 3258 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3259 annotation); 3260 3261 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3262 firstPids.add(app.pid); 3263 3264 int parentPid = app.pid; 3265 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3266 if (parentPid != app.pid) firstPids.add(parentPid); 3267 3268 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3269 3270 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3271 ProcessRecord r = mLruProcesses.get(i); 3272 if (r != null && r.thread != null) { 3273 int pid = r.pid; 3274 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3275 if (r.persistent) { 3276 firstPids.add(pid); 3277 } else { 3278 lastPids.put(pid, Boolean.TRUE); 3279 } 3280 } 3281 } 3282 } 3283 } 3284 3285 // Log the ANR to the main log. 3286 StringBuilder info = new StringBuilder(); 3287 info.setLength(0); 3288 info.append("ANR in ").append(app.processName); 3289 if (activity != null && activity.shortComponentName != null) { 3290 info.append(" (").append(activity.shortComponentName).append(")"); 3291 } 3292 info.append("\n"); 3293 if (annotation != null) { 3294 info.append("Reason: ").append(annotation).append("\n"); 3295 } 3296 if (parent != null && parent != activity) { 3297 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3298 } 3299 3300 final ProcessStats processStats = new ProcessStats(true); 3301 3302 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3303 3304 String cpuInfo = null; 3305 if (MONITOR_CPU_USAGE) { 3306 updateCpuStatsNow(); 3307 synchronized (mProcessStatsThread) { 3308 cpuInfo = mProcessStats.printCurrentState(anrTime); 3309 } 3310 info.append(processStats.printCurrentLoad()); 3311 info.append(cpuInfo); 3312 } 3313 3314 info.append(processStats.printCurrentState(anrTime)); 3315 3316 Slog.e(TAG, info.toString()); 3317 if (tracesFile == null) { 3318 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3319 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3320 } 3321 3322 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3323 cpuInfo, tracesFile, null); 3324 3325 if (mController != null) { 3326 try { 3327 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3328 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3329 if (res != 0) { 3330 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3331 return; 3332 } 3333 } catch (RemoteException e) { 3334 mController = null; 3335 } 3336 } 3337 3338 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3339 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3340 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3341 3342 synchronized (this) { 3343 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3344 Slog.w(TAG, "Killing " + app + ": background ANR"); 3345 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3346 app.processName, app.setAdj, "background ANR"); 3347 Process.killProcessQuiet(app.pid); 3348 return; 3349 } 3350 3351 // Set the app's notResponding state, and look up the errorReportReceiver 3352 makeAppNotRespondingLocked(app, 3353 activity != null ? activity.shortComponentName : null, 3354 annotation != null ? "ANR " + annotation : "ANR", 3355 info.toString()); 3356 3357 // Bring up the infamous App Not Responding dialog 3358 Message msg = Message.obtain(); 3359 HashMap map = new HashMap(); 3360 msg.what = SHOW_NOT_RESPONDING_MSG; 3361 msg.obj = map; 3362 map.put("app", app); 3363 if (activity != null) { 3364 map.put("activity", activity); 3365 } 3366 3367 mHandler.sendMessage(msg); 3368 } 3369 } 3370 3371 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3372 if (!mLaunchWarningShown) { 3373 mLaunchWarningShown = true; 3374 mHandler.post(new Runnable() { 3375 @Override 3376 public void run() { 3377 synchronized (ActivityManagerService.this) { 3378 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3379 d.show(); 3380 mHandler.postDelayed(new Runnable() { 3381 @Override 3382 public void run() { 3383 synchronized (ActivityManagerService.this) { 3384 d.dismiss(); 3385 mLaunchWarningShown = false; 3386 } 3387 } 3388 }, 4000); 3389 } 3390 } 3391 }); 3392 } 3393 } 3394 3395 public boolean clearApplicationUserData(final String packageName, 3396 final IPackageDataObserver observer, final int userId) { 3397 enforceNotIsolatedCaller("clearApplicationUserData"); 3398 int uid = Binder.getCallingUid(); 3399 int pid = Binder.getCallingPid(); 3400 long callingId = Binder.clearCallingIdentity(); 3401 try { 3402 IPackageManager pm = AppGlobals.getPackageManager(); 3403 int pkgUid = -1; 3404 synchronized(this) { 3405 try { 3406 pkgUid = pm.getPackageUid(packageName, userId); 3407 } catch (RemoteException e) { 3408 } 3409 if (pkgUid == -1) { 3410 Slog.w(TAG, "Invalid packageName:" + packageName); 3411 return false; 3412 } 3413 if (uid == pkgUid || checkComponentPermission( 3414 android.Manifest.permission.CLEAR_APP_USER_DATA, 3415 pid, uid, -1, true) 3416 == PackageManager.PERMISSION_GRANTED) { 3417 forceStopPackageLocked(packageName, pkgUid); 3418 } else { 3419 throw new SecurityException(pid+" does not have permission:"+ 3420 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3421 "for process:"+packageName); 3422 } 3423 } 3424 3425 try { 3426 //clear application user data 3427 pm.clearApplicationUserData(packageName, observer, userId); 3428 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3429 Uri.fromParts("package", packageName, null)); 3430 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3431 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3432 null, null, 0, null, null, null, false, false, userId); 3433 } catch (RemoteException e) { 3434 } 3435 } finally { 3436 Binder.restoreCallingIdentity(callingId); 3437 } 3438 return true; 3439 } 3440 3441 public void killBackgroundProcesses(final String packageName) { 3442 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3443 != PackageManager.PERMISSION_GRANTED && 3444 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3445 != PackageManager.PERMISSION_GRANTED) { 3446 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3447 + Binder.getCallingPid() 3448 + ", uid=" + Binder.getCallingUid() 3449 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3450 Slog.w(TAG, msg); 3451 throw new SecurityException(msg); 3452 } 3453 3454 int userId = UserHandle.getCallingUserId(); 3455 long callingId = Binder.clearCallingIdentity(); 3456 try { 3457 IPackageManager pm = AppGlobals.getPackageManager(); 3458 int pkgUid = -1; 3459 synchronized(this) { 3460 try { 3461 pkgUid = pm.getPackageUid(packageName, userId); 3462 } catch (RemoteException e) { 3463 } 3464 if (pkgUid == -1) { 3465 Slog.w(TAG, "Invalid packageName: " + packageName); 3466 return; 3467 } 3468 killPackageProcessesLocked(packageName, pkgUid, -1, 3469 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3470 } 3471 } finally { 3472 Binder.restoreCallingIdentity(callingId); 3473 } 3474 } 3475 3476 public void killAllBackgroundProcesses() { 3477 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3478 != PackageManager.PERMISSION_GRANTED) { 3479 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3480 + Binder.getCallingPid() 3481 + ", uid=" + Binder.getCallingUid() 3482 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3483 Slog.w(TAG, msg); 3484 throw new SecurityException(msg); 3485 } 3486 3487 long callingId = Binder.clearCallingIdentity(); 3488 try { 3489 synchronized(this) { 3490 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3491 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3492 final int NA = apps.size(); 3493 for (int ia=0; ia<NA; ia++) { 3494 ProcessRecord app = apps.valueAt(ia); 3495 if (app.persistent) { 3496 // we don't kill persistent processes 3497 continue; 3498 } 3499 if (app.removed) { 3500 procs.add(app); 3501 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3502 app.removed = true; 3503 procs.add(app); 3504 } 3505 } 3506 } 3507 3508 int N = procs.size(); 3509 for (int i=0; i<N; i++) { 3510 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3511 } 3512 } 3513 } finally { 3514 Binder.restoreCallingIdentity(callingId); 3515 } 3516 } 3517 3518 public void forceStopPackage(final String packageName) { 3519 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3520 != PackageManager.PERMISSION_GRANTED) { 3521 String msg = "Permission Denial: forceStopPackage() from pid=" 3522 + Binder.getCallingPid() 3523 + ", uid=" + Binder.getCallingUid() 3524 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3525 Slog.w(TAG, msg); 3526 throw new SecurityException(msg); 3527 } 3528 final int userId = UserHandle.getCallingUserId(); 3529 long callingId = Binder.clearCallingIdentity(); 3530 try { 3531 IPackageManager pm = AppGlobals.getPackageManager(); 3532 int pkgUid = -1; 3533 synchronized(this) { 3534 try { 3535 pkgUid = pm.getPackageUid(packageName, userId); 3536 } catch (RemoteException e) { 3537 } 3538 if (pkgUid == -1) { 3539 Slog.w(TAG, "Invalid packageName: " + packageName); 3540 return; 3541 } 3542 forceStopPackageLocked(packageName, pkgUid); 3543 try { 3544 pm.setPackageStoppedState(packageName, true, userId); 3545 } catch (RemoteException e) { 3546 } catch (IllegalArgumentException e) { 3547 Slog.w(TAG, "Failed trying to unstop package " 3548 + packageName + ": " + e); 3549 } 3550 } 3551 } finally { 3552 Binder.restoreCallingIdentity(callingId); 3553 } 3554 } 3555 3556 /* 3557 * The pkg name and uid have to be specified. 3558 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3559 */ 3560 public void killApplicationWithUid(String pkg, int uid) { 3561 if (pkg == null) { 3562 return; 3563 } 3564 // Make sure the uid is valid. 3565 if (uid < 0) { 3566 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3567 return; 3568 } 3569 int callerUid = Binder.getCallingUid(); 3570 // Only the system server can kill an application 3571 if (callerUid == Process.SYSTEM_UID) { 3572 // Post an aysnc message to kill the application 3573 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3574 msg.arg1 = uid; 3575 msg.arg2 = 0; 3576 msg.obj = pkg; 3577 mHandler.sendMessage(msg); 3578 } else { 3579 throw new SecurityException(callerUid + " cannot kill pkg: " + 3580 pkg); 3581 } 3582 } 3583 3584 public void closeSystemDialogs(String reason) { 3585 enforceNotIsolatedCaller("closeSystemDialogs"); 3586 3587 final int uid = Binder.getCallingUid(); 3588 final long origId = Binder.clearCallingIdentity(); 3589 synchronized (this) { 3590 closeSystemDialogsLocked(uid, reason); 3591 } 3592 Binder.restoreCallingIdentity(origId); 3593 } 3594 3595 void closeSystemDialogsLocked(int callingUid, String reason) { 3596 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3597 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3598 if (reason != null) { 3599 intent.putExtra("reason", reason); 3600 } 3601 mWindowManager.closeSystemDialogs(reason); 3602 3603 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3604 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3605 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3606 r.stack.finishActivityLocked(r, i, 3607 Activity.RESULT_CANCELED, null, "close-sys"); 3608 } 3609 } 3610 3611 broadcastIntentLocked(null, null, intent, null, 3612 null, 0, null, null, null, false, false, -1, 3613 callingUid, 0 /* TODO: Verify */); 3614 } 3615 3616 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3617 throws RemoteException { 3618 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3619 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3620 for (int i=pids.length-1; i>=0; i--) { 3621 infos[i] = new Debug.MemoryInfo(); 3622 Debug.getMemoryInfo(pids[i], infos[i]); 3623 } 3624 return infos; 3625 } 3626 3627 public long[] getProcessPss(int[] pids) throws RemoteException { 3628 enforceNotIsolatedCaller("getProcessPss"); 3629 long[] pss = new long[pids.length]; 3630 for (int i=pids.length-1; i>=0; i--) { 3631 pss[i] = Debug.getPss(pids[i]); 3632 } 3633 return pss; 3634 } 3635 3636 public void killApplicationProcess(String processName, int uid) { 3637 if (processName == null) { 3638 return; 3639 } 3640 3641 int callerUid = Binder.getCallingUid(); 3642 // Only the system server can kill an application 3643 if (callerUid == Process.SYSTEM_UID) { 3644 synchronized (this) { 3645 ProcessRecord app = getProcessRecordLocked(processName, uid); 3646 if (app != null && app.thread != null) { 3647 try { 3648 app.thread.scheduleSuicide(); 3649 } catch (RemoteException e) { 3650 // If the other end already died, then our work here is done. 3651 } 3652 } else { 3653 Slog.w(TAG, "Process/uid not found attempting kill of " 3654 + processName + " / " + uid); 3655 } 3656 } 3657 } else { 3658 throw new SecurityException(callerUid + " cannot kill app process: " + 3659 processName); 3660 } 3661 } 3662 3663 private void forceStopPackageLocked(final String packageName, int uid) { 3664 forceStopPackageLocked(packageName, uid, false, false, true, false, 3665 UserHandle.getUserId(uid)); 3666 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3667 Uri.fromParts("package", packageName, null)); 3668 if (!mProcessesReady) { 3669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3670 } 3671 intent.putExtra(Intent.EXTRA_UID, uid); 3672 broadcastIntentLocked(null, null, intent, 3673 null, null, 0, null, null, null, 3674 false, false, 3675 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3676 } 3677 3678 private void forceStopUserLocked(int userId) { 3679 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3680 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3681 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3682 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3683 broadcastIntentLocked(null, null, intent, 3684 null, null, 0, null, null, null, 3685 false, false, 3686 MY_PID, Process.SYSTEM_UID, userId); 3687 } 3688 3689 private final boolean killPackageProcessesLocked(String packageName, int uid, 3690 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3691 boolean doit, boolean evenPersistent, String reason) { 3692 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3693 3694 // Remove all processes this package may have touched: all with the 3695 // same UID (except for the system or root user), and all whose name 3696 // matches the package name. 3697 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3698 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3699 final int NA = apps.size(); 3700 for (int ia=0; ia<NA; ia++) { 3701 ProcessRecord app = apps.valueAt(ia); 3702 if (app.persistent && !evenPersistent) { 3703 // we don't kill persistent processes 3704 continue; 3705 } 3706 if (app.removed) { 3707 if (doit) { 3708 procs.add(app); 3709 } 3710 // If no package is specified, we call all processes under the 3711 // give user id. 3712 } else if (packageName == null) { 3713 if (app.userId == userId) { 3714 if (app.setAdj >= minOomAdj) { 3715 if (!doit) { 3716 return true; 3717 } 3718 app.removed = true; 3719 procs.add(app); 3720 } 3721 } 3722 // If uid is specified and the uid and process name match 3723 // Or, the uid is not specified and the process name matches 3724 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3725 || ((app.processName.equals(packageName) 3726 || app.processName.startsWith(procNamePrefix)) 3727 && uid < 0))) { 3728 if (app.setAdj >= minOomAdj) { 3729 if (!doit) { 3730 return true; 3731 } 3732 app.removed = true; 3733 procs.add(app); 3734 } 3735 } 3736 } 3737 } 3738 3739 int N = procs.size(); 3740 for (int i=0; i<N; i++) { 3741 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3742 } 3743 return N > 0; 3744 } 3745 3746 private final boolean forceStopPackageLocked(String name, int uid, 3747 boolean callerWillRestart, boolean purgeCache, boolean doit, 3748 boolean evenPersistent, int userId) { 3749 int i; 3750 int N; 3751 3752 if (uid < 0 && name != null) { 3753 try { 3754 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3755 } catch (RemoteException e) { 3756 } 3757 } 3758 3759 if (doit) { 3760 if (name != null) { 3761 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3762 } else { 3763 Slog.i(TAG, "Force stopping user " + userId); 3764 } 3765 3766 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3767 while (badApps.hasNext()) { 3768 SparseArray<Long> ba = badApps.next(); 3769 for (i=ba.size()-1; i>=0; i--) { 3770 boolean remove = false; 3771 final int entUid = ba.keyAt(i); 3772 if (name != null) { 3773 if (entUid == uid) { 3774 remove = true; 3775 } 3776 } else if (UserHandle.getUserId(entUid) == userId) { 3777 remove = true; 3778 } 3779 if (remove) { 3780 ba.removeAt(i); 3781 } 3782 } 3783 if (ba.size() == 0) { 3784 badApps.remove(); 3785 } 3786 } 3787 } 3788 3789 boolean didSomething = killPackageProcessesLocked(name, uid, 3790 name == null ? userId : -1 , -100, callerWillRestart, false, 3791 doit, evenPersistent, 3792 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3793 3794 TaskRecord lastTask = null; 3795 for (i=0; i<mMainStack.mHistory.size(); i++) { 3796 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3797 final boolean samePackage = r.packageName.equals(name) 3798 || (name == null && r.userId == userId); 3799 if (r.userId == userId 3800 && (samePackage || r.task == lastTask) 3801 && (r.app == null || evenPersistent || !r.app.persistent)) { 3802 if (!doit) { 3803 if (r.finishing) { 3804 // If this activity is just finishing, then it is not 3805 // interesting as far as something to stop. 3806 continue; 3807 } 3808 return true; 3809 } 3810 didSomething = true; 3811 Slog.i(TAG, " Force finishing activity " + r); 3812 if (samePackage) { 3813 if (r.app != null) { 3814 r.app.removed = true; 3815 } 3816 r.app = null; 3817 } 3818 lastTask = r.task; 3819 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3820 null, "force-stop", true)) { 3821 i--; 3822 } 3823 } 3824 } 3825 3826 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3827 if (!doit) { 3828 return true; 3829 } 3830 didSomething = true; 3831 } 3832 3833 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3834 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3835 if ((name == null || provider.info.packageName.equals(name)) 3836 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3837 if (!doit) { 3838 return true; 3839 } 3840 didSomething = true; 3841 providers.add(provider); 3842 } 3843 } 3844 3845 N = providers.size(); 3846 for (i=0; i<N; i++) { 3847 removeDyingProviderLocked(null, providers.get(i), true); 3848 } 3849 3850 if (doit) { 3851 if (purgeCache && name != null) { 3852 AttributeCache ac = AttributeCache.instance(); 3853 if (ac != null) { 3854 ac.removePackage(name); 3855 } 3856 } 3857 if (mBooted) { 3858 mMainStack.resumeTopActivityLocked(null); 3859 mMainStack.scheduleIdleLocked(); 3860 } 3861 } 3862 3863 return didSomething; 3864 } 3865 3866 private final boolean removeProcessLocked(ProcessRecord app, 3867 boolean callerWillRestart, boolean allowRestart, String reason) { 3868 final String name = app.processName; 3869 final int uid = app.uid; 3870 if (DEBUG_PROCESSES) Slog.d( 3871 TAG, "Force removing proc " + app.toShortString() + " (" + name 3872 + "/" + uid + ")"); 3873 3874 mProcessNames.remove(name, uid); 3875 mIsolatedProcesses.remove(app.uid); 3876 if (mHeavyWeightProcess == app) { 3877 mHeavyWeightProcess = null; 3878 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3879 } 3880 boolean needRestart = false; 3881 if (app.pid > 0 && app.pid != MY_PID) { 3882 int pid = app.pid; 3883 synchronized (mPidsSelfLocked) { 3884 mPidsSelfLocked.remove(pid); 3885 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3886 } 3887 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3888 handleAppDiedLocked(app, true, allowRestart); 3889 mLruProcesses.remove(app); 3890 Process.killProcessQuiet(pid); 3891 3892 if (app.persistent && !app.isolated) { 3893 if (!callerWillRestart) { 3894 addAppLocked(app.info, false); 3895 } else { 3896 needRestart = true; 3897 } 3898 } 3899 } else { 3900 mRemovedProcesses.add(app); 3901 } 3902 3903 return needRestart; 3904 } 3905 3906 private final void processStartTimedOutLocked(ProcessRecord app) { 3907 final int pid = app.pid; 3908 boolean gone = false; 3909 synchronized (mPidsSelfLocked) { 3910 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3911 if (knownApp != null && knownApp.thread == null) { 3912 mPidsSelfLocked.remove(pid); 3913 gone = true; 3914 } 3915 } 3916 3917 if (gone) { 3918 Slog.w(TAG, "Process " + app + " failed to attach"); 3919 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3920 app.processName); 3921 mProcessNames.remove(app.processName, app.uid); 3922 mIsolatedProcesses.remove(app.uid); 3923 if (mHeavyWeightProcess == app) { 3924 mHeavyWeightProcess = null; 3925 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3926 } 3927 // Take care of any launching providers waiting for this process. 3928 checkAppInLaunchingProvidersLocked(app, true); 3929 // Take care of any services that are waiting for the process. 3930 mServices.processStartTimedOutLocked(app); 3931 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3932 app.processName, app.setAdj, "start timeout"); 3933 Process.killProcessQuiet(pid); 3934 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3935 Slog.w(TAG, "Unattached app died before backup, skipping"); 3936 try { 3937 IBackupManager bm = IBackupManager.Stub.asInterface( 3938 ServiceManager.getService(Context.BACKUP_SERVICE)); 3939 bm.agentDisconnected(app.info.packageName); 3940 } catch (RemoteException e) { 3941 // Can't happen; the backup manager is local 3942 } 3943 } 3944 if (isPendingBroadcastProcessLocked(pid)) { 3945 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3946 skipPendingBroadcastLocked(pid); 3947 } 3948 } else { 3949 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3950 } 3951 } 3952 3953 private final boolean attachApplicationLocked(IApplicationThread thread, 3954 int pid) { 3955 3956 // Find the application record that is being attached... either via 3957 // the pid if we are running in multiple processes, or just pull the 3958 // next app record if we are emulating process with anonymous threads. 3959 ProcessRecord app; 3960 if (pid != MY_PID && pid >= 0) { 3961 synchronized (mPidsSelfLocked) { 3962 app = mPidsSelfLocked.get(pid); 3963 } 3964 } else { 3965 app = null; 3966 } 3967 3968 if (app == null) { 3969 Slog.w(TAG, "No pending application record for pid " + pid 3970 + " (IApplicationThread " + thread + "); dropping process"); 3971 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3972 if (pid > 0 && pid != MY_PID) { 3973 Process.killProcessQuiet(pid); 3974 } else { 3975 try { 3976 thread.scheduleExit(); 3977 } catch (Exception e) { 3978 // Ignore exceptions. 3979 } 3980 } 3981 return false; 3982 } 3983 3984 // If this application record is still attached to a previous 3985 // process, clean it up now. 3986 if (app.thread != null) { 3987 handleAppDiedLocked(app, true, true); 3988 } 3989 3990 // Tell the process all about itself. 3991 3992 if (localLOGV) Slog.v( 3993 TAG, "Binding process pid " + pid + " to record " + app); 3994 3995 String processName = app.processName; 3996 try { 3997 AppDeathRecipient adr = new AppDeathRecipient( 3998 app, pid, thread); 3999 thread.asBinder().linkToDeath(adr, 0); 4000 app.deathRecipient = adr; 4001 } catch (RemoteException e) { 4002 app.resetPackageList(); 4003 startProcessLocked(app, "link fail", processName); 4004 return false; 4005 } 4006 4007 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4008 4009 app.thread = thread; 4010 app.curAdj = app.setAdj = -100; 4011 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4012 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4013 app.forcingToForeground = null; 4014 app.foregroundServices = false; 4015 app.hasShownUi = false; 4016 app.debugging = false; 4017 4018 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4019 4020 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4021 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4022 4023 if (!normalMode) { 4024 Slog.i(TAG, "Launching preboot mode app: " + app); 4025 } 4026 4027 if (localLOGV) Slog.v( 4028 TAG, "New app record " + app 4029 + " thread=" + thread.asBinder() + " pid=" + pid); 4030 try { 4031 int testMode = IApplicationThread.DEBUG_OFF; 4032 if (mDebugApp != null && mDebugApp.equals(processName)) { 4033 testMode = mWaitForDebugger 4034 ? IApplicationThread.DEBUG_WAIT 4035 : IApplicationThread.DEBUG_ON; 4036 app.debugging = true; 4037 if (mDebugTransient) { 4038 mDebugApp = mOrigDebugApp; 4039 mWaitForDebugger = mOrigWaitForDebugger; 4040 } 4041 } 4042 String profileFile = app.instrumentationProfileFile; 4043 ParcelFileDescriptor profileFd = null; 4044 boolean profileAutoStop = false; 4045 if (mProfileApp != null && mProfileApp.equals(processName)) { 4046 mProfileProc = app; 4047 profileFile = mProfileFile; 4048 profileFd = mProfileFd; 4049 profileAutoStop = mAutoStopProfiler; 4050 } 4051 boolean enableOpenGlTrace = false; 4052 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4053 enableOpenGlTrace = true; 4054 mOpenGlTraceApp = null; 4055 } 4056 4057 // If the app is being launched for restore or full backup, set it up specially 4058 boolean isRestrictedBackupMode = false; 4059 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4060 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4061 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4062 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4063 } 4064 4065 ensurePackageDexOpt(app.instrumentationInfo != null 4066 ? app.instrumentationInfo.packageName 4067 : app.info.packageName); 4068 if (app.instrumentationClass != null) { 4069 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4070 } 4071 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4072 + processName + " with config " + mConfiguration); 4073 ApplicationInfo appInfo = app.instrumentationInfo != null 4074 ? app.instrumentationInfo : app.info; 4075 app.compat = compatibilityInfoForPackageLocked(appInfo); 4076 if (profileFd != null) { 4077 profileFd = profileFd.dup(); 4078 } 4079 thread.bindApplication(processName, appInfo, providers, 4080 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4081 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4082 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4083 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4084 mCoreSettingsObserver.getCoreSettingsLocked()); 4085 updateLruProcessLocked(app, false, true); 4086 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4087 } catch (Exception e) { 4088 // todo: Yikes! What should we do? For now we will try to 4089 // start another process, but that could easily get us in 4090 // an infinite loop of restarting processes... 4091 Slog.w(TAG, "Exception thrown during bind!", e); 4092 4093 app.resetPackageList(); 4094 app.unlinkDeathRecipient(); 4095 startProcessLocked(app, "bind fail", processName); 4096 return false; 4097 } 4098 4099 // Remove this record from the list of starting applications. 4100 mPersistentStartingProcesses.remove(app); 4101 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4102 "Attach application locked removing on hold: " + app); 4103 mProcessesOnHold.remove(app); 4104 4105 boolean badApp = false; 4106 boolean didSomething = false; 4107 4108 // See if the top visible activity is waiting to run in this process... 4109 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4110 if (hr != null && normalMode) { 4111 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4112 && processName.equals(hr.processName)) { 4113 try { 4114 if (mHeadless) { 4115 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4116 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4117 didSomething = true; 4118 } 4119 } catch (Exception e) { 4120 Slog.w(TAG, "Exception in new application when starting activity " 4121 + hr.intent.getComponent().flattenToShortString(), e); 4122 badApp = true; 4123 } 4124 } else { 4125 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4126 } 4127 } 4128 4129 // Find any services that should be running in this process... 4130 if (!badApp) { 4131 try { 4132 didSomething |= mServices.attachApplicationLocked(app, processName); 4133 } catch (Exception e) { 4134 badApp = true; 4135 } 4136 } 4137 4138 // Check if a next-broadcast receiver is in this process... 4139 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4140 try { 4141 didSomething = sendPendingBroadcastsLocked(app); 4142 } catch (Exception e) { 4143 // If the app died trying to launch the receiver we declare it 'bad' 4144 badApp = true; 4145 } 4146 } 4147 4148 // Check whether the next backup agent is in this process... 4149 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4150 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4151 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4152 try { 4153 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4154 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4155 mBackupTarget.backupMode); 4156 } catch (Exception e) { 4157 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4158 e.printStackTrace(); 4159 } 4160 } 4161 4162 if (badApp) { 4163 // todo: Also need to kill application to deal with all 4164 // kinds of exceptions. 4165 handleAppDiedLocked(app, false, true); 4166 return false; 4167 } 4168 4169 if (!didSomething) { 4170 updateOomAdjLocked(); 4171 } 4172 4173 return true; 4174 } 4175 4176 public final void attachApplication(IApplicationThread thread) { 4177 synchronized (this) { 4178 int callingPid = Binder.getCallingPid(); 4179 final long origId = Binder.clearCallingIdentity(); 4180 attachApplicationLocked(thread, callingPid); 4181 Binder.restoreCallingIdentity(origId); 4182 } 4183 } 4184 4185 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4186 final long origId = Binder.clearCallingIdentity(); 4187 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4188 if (stopProfiling) { 4189 synchronized (this) { 4190 if (mProfileProc == r.app) { 4191 if (mProfileFd != null) { 4192 try { 4193 mProfileFd.close(); 4194 } catch (IOException e) { 4195 } 4196 clearProfilerLocked(); 4197 } 4198 } 4199 } 4200 } 4201 Binder.restoreCallingIdentity(origId); 4202 } 4203 4204 void enableScreenAfterBoot() { 4205 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4206 SystemClock.uptimeMillis()); 4207 mWindowManager.enableScreenAfterBoot(); 4208 4209 synchronized (this) { 4210 updateEventDispatchingLocked(); 4211 } 4212 } 4213 4214 public void showBootMessage(final CharSequence msg, final boolean always) { 4215 enforceNotIsolatedCaller("showBootMessage"); 4216 mWindowManager.showBootMessage(msg, always); 4217 } 4218 4219 public void dismissKeyguardOnNextActivity() { 4220 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4221 final long token = Binder.clearCallingIdentity(); 4222 try { 4223 synchronized (this) { 4224 if (mLockScreenShown) { 4225 mLockScreenShown = false; 4226 comeOutOfSleepIfNeededLocked(); 4227 } 4228 mMainStack.dismissKeyguardOnNextActivityLocked(); 4229 } 4230 } finally { 4231 Binder.restoreCallingIdentity(token); 4232 } 4233 } 4234 4235 final void finishBooting() { 4236 IntentFilter pkgFilter = new IntentFilter(); 4237 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4238 pkgFilter.addDataScheme("package"); 4239 mContext.registerReceiver(new BroadcastReceiver() { 4240 @Override 4241 public void onReceive(Context context, Intent intent) { 4242 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4243 if (pkgs != null) { 4244 for (String pkg : pkgs) { 4245 synchronized (ActivityManagerService.this) { 4246 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4247 setResultCode(Activity.RESULT_OK); 4248 return; 4249 } 4250 } 4251 } 4252 } 4253 } 4254 }, pkgFilter); 4255 4256 synchronized (this) { 4257 // Ensure that any processes we had put on hold are now started 4258 // up. 4259 final int NP = mProcessesOnHold.size(); 4260 if (NP > 0) { 4261 ArrayList<ProcessRecord> procs = 4262 new ArrayList<ProcessRecord>(mProcessesOnHold); 4263 for (int ip=0; ip<NP; ip++) { 4264 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4265 + procs.get(ip)); 4266 startProcessLocked(procs.get(ip), "on-hold", null); 4267 } 4268 } 4269 4270 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4271 // Start looking for apps that are abusing wake locks. 4272 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4273 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4274 // Tell anyone interested that we are done booting! 4275 SystemProperties.set("sys.boot_completed", "1"); 4276 SystemProperties.set("dev.bootcomplete", "1"); 4277 for (int i=0; i<mStartedUsers.size(); i++) { 4278 UserStartedState uss = mStartedUsers.valueAt(i); 4279 if (uss.mState == UserStartedState.STATE_BOOTING) { 4280 uss.mState = UserStartedState.STATE_RUNNING; 4281 broadcastIntentLocked(null, null, 4282 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4283 null, null, 0, null, null, 4284 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4285 false, false, MY_PID, Process.SYSTEM_UID, 4286 mStartedUsers.keyAt(i)); 4287 } 4288 } 4289 } 4290 } 4291 } 4292 4293 final void ensureBootCompleted() { 4294 boolean booting; 4295 boolean enableScreen; 4296 synchronized (this) { 4297 booting = mBooting; 4298 mBooting = false; 4299 enableScreen = !mBooted; 4300 mBooted = true; 4301 } 4302 4303 if (booting) { 4304 finishBooting(); 4305 } 4306 4307 if (enableScreen) { 4308 enableScreenAfterBoot(); 4309 } 4310 } 4311 4312 public final void activityPaused(IBinder token) { 4313 final long origId = Binder.clearCallingIdentity(); 4314 mMainStack.activityPaused(token, false); 4315 Binder.restoreCallingIdentity(origId); 4316 } 4317 4318 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4319 CharSequence description) { 4320 if (localLOGV) Slog.v( 4321 TAG, "Activity stopped: token=" + token); 4322 4323 // Refuse possible leaked file descriptors 4324 if (icicle != null && icicle.hasFileDescriptors()) { 4325 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4326 } 4327 4328 ActivityRecord r = null; 4329 4330 final long origId = Binder.clearCallingIdentity(); 4331 4332 synchronized (this) { 4333 r = mMainStack.isInStackLocked(token); 4334 if (r != null) { 4335 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4336 } 4337 } 4338 4339 if (r != null) { 4340 sendPendingThumbnail(r, null, null, null, false); 4341 } 4342 4343 trimApplications(); 4344 4345 Binder.restoreCallingIdentity(origId); 4346 } 4347 4348 public final void activityDestroyed(IBinder token) { 4349 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4350 mMainStack.activityDestroyed(token); 4351 } 4352 4353 public String getCallingPackage(IBinder token) { 4354 synchronized (this) { 4355 ActivityRecord r = getCallingRecordLocked(token); 4356 return r != null && r.app != null ? r.info.packageName : null; 4357 } 4358 } 4359 4360 public ComponentName getCallingActivity(IBinder token) { 4361 synchronized (this) { 4362 ActivityRecord r = getCallingRecordLocked(token); 4363 return r != null ? r.intent.getComponent() : null; 4364 } 4365 } 4366 4367 private ActivityRecord getCallingRecordLocked(IBinder token) { 4368 ActivityRecord r = mMainStack.isInStackLocked(token); 4369 if (r == null) { 4370 return null; 4371 } 4372 return r.resultTo; 4373 } 4374 4375 public ComponentName getActivityClassForToken(IBinder token) { 4376 synchronized(this) { 4377 ActivityRecord r = mMainStack.isInStackLocked(token); 4378 if (r == null) { 4379 return null; 4380 } 4381 return r.intent.getComponent(); 4382 } 4383 } 4384 4385 public String getPackageForToken(IBinder token) { 4386 synchronized(this) { 4387 ActivityRecord r = mMainStack.isInStackLocked(token); 4388 if (r == null) { 4389 return null; 4390 } 4391 return r.packageName; 4392 } 4393 } 4394 4395 public IIntentSender getIntentSender(int type, 4396 String packageName, IBinder token, String resultWho, 4397 int requestCode, Intent[] intents, String[] resolvedTypes, 4398 int flags, Bundle options) { 4399 enforceNotIsolatedCaller("getIntentSender"); 4400 // Refuse possible leaked file descriptors 4401 if (intents != null) { 4402 if (intents.length < 1) { 4403 throw new IllegalArgumentException("Intents array length must be >= 1"); 4404 } 4405 for (int i=0; i<intents.length; i++) { 4406 Intent intent = intents[i]; 4407 if (intent != null) { 4408 if (intent.hasFileDescriptors()) { 4409 throw new IllegalArgumentException("File descriptors passed in Intent"); 4410 } 4411 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4412 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4413 throw new IllegalArgumentException( 4414 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4415 } 4416 intents[i] = new Intent(intent); 4417 } 4418 } 4419 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4420 throw new IllegalArgumentException( 4421 "Intent array length does not match resolvedTypes length"); 4422 } 4423 } 4424 if (options != null) { 4425 if (options.hasFileDescriptors()) { 4426 throw new IllegalArgumentException("File descriptors passed in options"); 4427 } 4428 } 4429 4430 synchronized(this) { 4431 int callingUid = Binder.getCallingUid(); 4432 try { 4433 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4434 int uid = AppGlobals.getPackageManager() 4435 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4436 if (!UserHandle.isSameApp(callingUid, uid)) { 4437 String msg = "Permission Denial: getIntentSender() from pid=" 4438 + Binder.getCallingPid() 4439 + ", uid=" + Binder.getCallingUid() 4440 + ", (need uid=" + uid + ")" 4441 + " is not allowed to send as package " + packageName; 4442 Slog.w(TAG, msg); 4443 throw new SecurityException(msg); 4444 } 4445 } 4446 4447 if (DEBUG_MU) 4448 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4449 + Binder.getOrigCallingUid()); 4450 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4451 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4452 4453 } catch (RemoteException e) { 4454 throw new SecurityException(e); 4455 } 4456 } 4457 } 4458 4459 IIntentSender getIntentSenderLocked(int type, 4460 String packageName, int callingUid, IBinder token, String resultWho, 4461 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4462 Bundle options) { 4463 if (DEBUG_MU) 4464 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4465 ActivityRecord activity = null; 4466 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4467 activity = mMainStack.isInStackLocked(token); 4468 if (activity == null) { 4469 return null; 4470 } 4471 if (activity.finishing) { 4472 return null; 4473 } 4474 } 4475 4476 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4477 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4478 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4479 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4480 |PendingIntent.FLAG_UPDATE_CURRENT); 4481 4482 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4483 type, packageName, activity, resultWho, 4484 requestCode, intents, resolvedTypes, flags, options); 4485 WeakReference<PendingIntentRecord> ref; 4486 ref = mIntentSenderRecords.get(key); 4487 PendingIntentRecord rec = ref != null ? ref.get() : null; 4488 if (rec != null) { 4489 if (!cancelCurrent) { 4490 if (updateCurrent) { 4491 if (rec.key.requestIntent != null) { 4492 rec.key.requestIntent.replaceExtras(intents != null ? 4493 intents[intents.length - 1] : null); 4494 } 4495 if (intents != null) { 4496 intents[intents.length-1] = rec.key.requestIntent; 4497 rec.key.allIntents = intents; 4498 rec.key.allResolvedTypes = resolvedTypes; 4499 } else { 4500 rec.key.allIntents = null; 4501 rec.key.allResolvedTypes = null; 4502 } 4503 } 4504 return rec; 4505 } 4506 rec.canceled = true; 4507 mIntentSenderRecords.remove(key); 4508 } 4509 if (noCreate) { 4510 return rec; 4511 } 4512 rec = new PendingIntentRecord(this, key, callingUid); 4513 mIntentSenderRecords.put(key, rec.ref); 4514 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4515 if (activity.pendingResults == null) { 4516 activity.pendingResults 4517 = new HashSet<WeakReference<PendingIntentRecord>>(); 4518 } 4519 activity.pendingResults.add(rec.ref); 4520 } 4521 return rec; 4522 } 4523 4524 public void cancelIntentSender(IIntentSender sender) { 4525 if (!(sender instanceof PendingIntentRecord)) { 4526 return; 4527 } 4528 synchronized(this) { 4529 PendingIntentRecord rec = (PendingIntentRecord)sender; 4530 try { 4531 int uid = AppGlobals.getPackageManager() 4532 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4533 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4534 String msg = "Permission Denial: cancelIntentSender() from pid=" 4535 + Binder.getCallingPid() 4536 + ", uid=" + Binder.getCallingUid() 4537 + " is not allowed to cancel packges " 4538 + rec.key.packageName; 4539 Slog.w(TAG, msg); 4540 throw new SecurityException(msg); 4541 } 4542 } catch (RemoteException e) { 4543 throw new SecurityException(e); 4544 } 4545 cancelIntentSenderLocked(rec, true); 4546 } 4547 } 4548 4549 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4550 rec.canceled = true; 4551 mIntentSenderRecords.remove(rec.key); 4552 if (cleanActivity && rec.key.activity != null) { 4553 rec.key.activity.pendingResults.remove(rec.ref); 4554 } 4555 } 4556 4557 public String getPackageForIntentSender(IIntentSender pendingResult) { 4558 if (!(pendingResult instanceof PendingIntentRecord)) { 4559 return null; 4560 } 4561 try { 4562 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4563 return res.key.packageName; 4564 } catch (ClassCastException e) { 4565 } 4566 return null; 4567 } 4568 4569 public int getUidForIntentSender(IIntentSender sender) { 4570 if (sender instanceof PendingIntentRecord) { 4571 try { 4572 PendingIntentRecord res = (PendingIntentRecord)sender; 4573 return res.uid; 4574 } catch (ClassCastException e) { 4575 } 4576 } 4577 return -1; 4578 } 4579 4580 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4581 if (!(pendingResult instanceof PendingIntentRecord)) { 4582 return false; 4583 } 4584 try { 4585 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4586 if (res.key.allIntents == null) { 4587 return false; 4588 } 4589 for (int i=0; i<res.key.allIntents.length; i++) { 4590 Intent intent = res.key.allIntents[i]; 4591 if (intent.getPackage() != null && intent.getComponent() != null) { 4592 return false; 4593 } 4594 } 4595 return true; 4596 } catch (ClassCastException e) { 4597 } 4598 return false; 4599 } 4600 4601 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4602 if (!(pendingResult instanceof PendingIntentRecord)) { 4603 return false; 4604 } 4605 try { 4606 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4607 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4608 return true; 4609 } 4610 return false; 4611 } catch (ClassCastException e) { 4612 } 4613 return false; 4614 } 4615 4616 public void setProcessLimit(int max) { 4617 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4618 "setProcessLimit()"); 4619 synchronized (this) { 4620 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4621 mProcessLimitOverride = max; 4622 } 4623 trimApplications(); 4624 } 4625 4626 public int getProcessLimit() { 4627 synchronized (this) { 4628 return mProcessLimitOverride; 4629 } 4630 } 4631 4632 void foregroundTokenDied(ForegroundToken token) { 4633 synchronized (ActivityManagerService.this) { 4634 synchronized (mPidsSelfLocked) { 4635 ForegroundToken cur 4636 = mForegroundProcesses.get(token.pid); 4637 if (cur != token) { 4638 return; 4639 } 4640 mForegroundProcesses.remove(token.pid); 4641 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4642 if (pr == null) { 4643 return; 4644 } 4645 pr.forcingToForeground = null; 4646 pr.foregroundServices = false; 4647 } 4648 updateOomAdjLocked(); 4649 } 4650 } 4651 4652 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4653 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4654 "setProcessForeground()"); 4655 synchronized(this) { 4656 boolean changed = false; 4657 4658 synchronized (mPidsSelfLocked) { 4659 ProcessRecord pr = mPidsSelfLocked.get(pid); 4660 if (pr == null && isForeground) { 4661 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4662 return; 4663 } 4664 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4665 if (oldToken != null) { 4666 oldToken.token.unlinkToDeath(oldToken, 0); 4667 mForegroundProcesses.remove(pid); 4668 if (pr != null) { 4669 pr.forcingToForeground = null; 4670 } 4671 changed = true; 4672 } 4673 if (isForeground && token != null) { 4674 ForegroundToken newToken = new ForegroundToken() { 4675 public void binderDied() { 4676 foregroundTokenDied(this); 4677 } 4678 }; 4679 newToken.pid = pid; 4680 newToken.token = token; 4681 try { 4682 token.linkToDeath(newToken, 0); 4683 mForegroundProcesses.put(pid, newToken); 4684 pr.forcingToForeground = token; 4685 changed = true; 4686 } catch (RemoteException e) { 4687 // If the process died while doing this, we will later 4688 // do the cleanup with the process death link. 4689 } 4690 } 4691 } 4692 4693 if (changed) { 4694 updateOomAdjLocked(); 4695 } 4696 } 4697 } 4698 4699 // ========================================================= 4700 // PERMISSIONS 4701 // ========================================================= 4702 4703 static class PermissionController extends IPermissionController.Stub { 4704 ActivityManagerService mActivityManagerService; 4705 PermissionController(ActivityManagerService activityManagerService) { 4706 mActivityManagerService = activityManagerService; 4707 } 4708 4709 public boolean checkPermission(String permission, int pid, int uid) { 4710 return mActivityManagerService.checkPermission(permission, pid, 4711 uid) == PackageManager.PERMISSION_GRANTED; 4712 } 4713 } 4714 4715 /** 4716 * This can be called with or without the global lock held. 4717 */ 4718 int checkComponentPermission(String permission, int pid, int uid, 4719 int owningUid, boolean exported) { 4720 // We might be performing an operation on behalf of an indirect binder 4721 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4722 // client identity accordingly before proceeding. 4723 Identity tlsIdentity = sCallerIdentity.get(); 4724 if (tlsIdentity != null) { 4725 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4726 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4727 uid = tlsIdentity.uid; 4728 pid = tlsIdentity.pid; 4729 } 4730 4731 if (pid == MY_PID) { 4732 return PackageManager.PERMISSION_GRANTED; 4733 } 4734 4735 return ActivityManager.checkComponentPermission(permission, uid, 4736 owningUid, exported); 4737 } 4738 4739 /** 4740 * As the only public entry point for permissions checking, this method 4741 * can enforce the semantic that requesting a check on a null global 4742 * permission is automatically denied. (Internally a null permission 4743 * string is used when calling {@link #checkComponentPermission} in cases 4744 * when only uid-based security is needed.) 4745 * 4746 * This can be called with or without the global lock held. 4747 */ 4748 public int checkPermission(String permission, int pid, int uid) { 4749 if (permission == null) { 4750 return PackageManager.PERMISSION_DENIED; 4751 } 4752 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4753 } 4754 4755 /** 4756 * Binder IPC calls go through the public entry point. 4757 * This can be called with or without the global lock held. 4758 */ 4759 int checkCallingPermission(String permission) { 4760 return checkPermission(permission, 4761 Binder.getCallingPid(), 4762 UserHandle.getAppId(Binder.getCallingUid())); 4763 } 4764 4765 /** 4766 * This can be called with or without the global lock held. 4767 */ 4768 void enforceCallingPermission(String permission, String func) { 4769 if (checkCallingPermission(permission) 4770 == PackageManager.PERMISSION_GRANTED) { 4771 return; 4772 } 4773 4774 String msg = "Permission Denial: " + func + " from pid=" 4775 + Binder.getCallingPid() 4776 + ", uid=" + Binder.getCallingUid() 4777 + " requires " + permission; 4778 Slog.w(TAG, msg); 4779 throw new SecurityException(msg); 4780 } 4781 4782 /** 4783 * Determine if UID is holding permissions required to access {@link Uri} in 4784 * the given {@link ProviderInfo}. Final permission checking is always done 4785 * in {@link ContentProvider}. 4786 */ 4787 private final boolean checkHoldingPermissionsLocked( 4788 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4789 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4790 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4791 4792 if (pi.applicationInfo.uid == uid) { 4793 return true; 4794 } else if (!pi.exported) { 4795 return false; 4796 } 4797 4798 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4799 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4800 try { 4801 // check if target holds top-level <provider> permissions 4802 if (!readMet && pi.readPermission != null 4803 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4804 readMet = true; 4805 } 4806 if (!writeMet && pi.writePermission != null 4807 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4808 writeMet = true; 4809 } 4810 4811 // track if unprotected read/write is allowed; any denied 4812 // <path-permission> below removes this ability 4813 boolean allowDefaultRead = pi.readPermission == null; 4814 boolean allowDefaultWrite = pi.writePermission == null; 4815 4816 // check if target holds any <path-permission> that match uri 4817 final PathPermission[] pps = pi.pathPermissions; 4818 if (pps != null) { 4819 final String path = uri.getPath(); 4820 int i = pps.length; 4821 while (i > 0 && (!readMet || !writeMet)) { 4822 i--; 4823 PathPermission pp = pps[i]; 4824 if (pp.match(path)) { 4825 if (!readMet) { 4826 final String pprperm = pp.getReadPermission(); 4827 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4828 + pprperm + " for " + pp.getPath() 4829 + ": match=" + pp.match(path) 4830 + " check=" + pm.checkUidPermission(pprperm, uid)); 4831 if (pprperm != null) { 4832 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4833 readMet = true; 4834 } else { 4835 allowDefaultRead = false; 4836 } 4837 } 4838 } 4839 if (!writeMet) { 4840 final String ppwperm = pp.getWritePermission(); 4841 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4842 + ppwperm + " for " + pp.getPath() 4843 + ": match=" + pp.match(path) 4844 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4845 if (ppwperm != null) { 4846 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4847 writeMet = true; 4848 } else { 4849 allowDefaultWrite = false; 4850 } 4851 } 4852 } 4853 } 4854 } 4855 } 4856 4857 // grant unprotected <provider> read/write, if not blocked by 4858 // <path-permission> above 4859 if (allowDefaultRead) readMet = true; 4860 if (allowDefaultWrite) writeMet = true; 4861 4862 } catch (RemoteException e) { 4863 return false; 4864 } 4865 4866 return readMet && writeMet; 4867 } 4868 4869 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4870 int modeFlags) { 4871 // Root gets to do everything. 4872 if (uid == 0) { 4873 return true; 4874 } 4875 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4876 if (perms == null) return false; 4877 UriPermission perm = perms.get(uri); 4878 if (perm == null) return false; 4879 return (modeFlags&perm.modeFlags) == modeFlags; 4880 } 4881 4882 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4883 enforceNotIsolatedCaller("checkUriPermission"); 4884 4885 // Another redirected-binder-call permissions check as in 4886 // {@link checkComponentPermission}. 4887 Identity tlsIdentity = sCallerIdentity.get(); 4888 if (tlsIdentity != null) { 4889 uid = tlsIdentity.uid; 4890 pid = tlsIdentity.pid; 4891 } 4892 4893 uid = UserHandle.getAppId(uid); 4894 // Our own process gets to do everything. 4895 if (pid == MY_PID) { 4896 return PackageManager.PERMISSION_GRANTED; 4897 } 4898 synchronized(this) { 4899 return checkUriPermissionLocked(uri, uid, modeFlags) 4900 ? PackageManager.PERMISSION_GRANTED 4901 : PackageManager.PERMISSION_DENIED; 4902 } 4903 } 4904 4905 /** 4906 * Check if the targetPkg can be granted permission to access uri by 4907 * the callingUid using the given modeFlags. Throws a security exception 4908 * if callingUid is not allowed to do this. Returns the uid of the target 4909 * if the URI permission grant should be performed; returns -1 if it is not 4910 * needed (for example targetPkg already has permission to access the URI). 4911 * If you already know the uid of the target, you can supply it in 4912 * lastTargetUid else set that to -1. 4913 */ 4914 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4915 Uri uri, int modeFlags, int lastTargetUid) { 4916 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4917 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4918 if (modeFlags == 0) { 4919 return -1; 4920 } 4921 4922 if (targetPkg != null) { 4923 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4924 "Checking grant " + targetPkg + " permission to " + uri); 4925 } 4926 4927 final IPackageManager pm = AppGlobals.getPackageManager(); 4928 4929 // If this is not a content: uri, we can't do anything with it. 4930 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4931 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4932 "Can't grant URI permission for non-content URI: " + uri); 4933 return -1; 4934 } 4935 4936 String name = uri.getAuthority(); 4937 ProviderInfo pi = null; 4938 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4939 UserHandle.getUserId(callingUid)); 4940 if (cpr != null) { 4941 pi = cpr.info; 4942 } else { 4943 try { 4944 pi = pm.resolveContentProvider(name, 4945 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4946 } catch (RemoteException ex) { 4947 } 4948 } 4949 if (pi == null) { 4950 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4951 return -1; 4952 } 4953 4954 int targetUid = lastTargetUid; 4955 if (targetUid < 0 && targetPkg != null) { 4956 try { 4957 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4958 if (targetUid < 0) { 4959 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4960 "Can't grant URI permission no uid for: " + targetPkg); 4961 return -1; 4962 } 4963 } catch (RemoteException ex) { 4964 return -1; 4965 } 4966 } 4967 4968 if (targetUid >= 0) { 4969 // First... does the target actually need this permission? 4970 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4971 // No need to grant the target this permission. 4972 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4973 "Target " + targetPkg + " already has full permission to " + uri); 4974 return -1; 4975 } 4976 } else { 4977 // First... there is no target package, so can anyone access it? 4978 boolean allowed = pi.exported; 4979 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4980 if (pi.readPermission != null) { 4981 allowed = false; 4982 } 4983 } 4984 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4985 if (pi.writePermission != null) { 4986 allowed = false; 4987 } 4988 } 4989 if (allowed) { 4990 return -1; 4991 } 4992 } 4993 4994 // Second... is the provider allowing granting of URI permissions? 4995 if (!pi.grantUriPermissions) { 4996 throw new SecurityException("Provider " + pi.packageName 4997 + "/" + pi.name 4998 + " does not allow granting of Uri permissions (uri " 4999 + uri + ")"); 5000 } 5001 if (pi.uriPermissionPatterns != null) { 5002 final int N = pi.uriPermissionPatterns.length; 5003 boolean allowed = false; 5004 for (int i=0; i<N; i++) { 5005 if (pi.uriPermissionPatterns[i] != null 5006 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5007 allowed = true; 5008 break; 5009 } 5010 } 5011 if (!allowed) { 5012 throw new SecurityException("Provider " + pi.packageName 5013 + "/" + pi.name 5014 + " does not allow granting of permission to path of Uri " 5015 + uri); 5016 } 5017 } 5018 5019 // Third... does the caller itself have permission to access 5020 // this uri? 5021 if (callingUid != Process.myUid()) { 5022 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5023 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5024 throw new SecurityException("Uid " + callingUid 5025 + " does not have permission to uri " + uri); 5026 } 5027 } 5028 } 5029 5030 return targetUid; 5031 } 5032 5033 public int checkGrantUriPermission(int callingUid, String targetPkg, 5034 Uri uri, int modeFlags) { 5035 enforceNotIsolatedCaller("checkGrantUriPermission"); 5036 synchronized(this) { 5037 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5038 } 5039 } 5040 5041 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5042 Uri uri, int modeFlags, UriPermissionOwner owner) { 5043 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5044 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5045 if (modeFlags == 0) { 5046 return; 5047 } 5048 5049 // So here we are: the caller has the assumed permission 5050 // to the uri, and the target doesn't. Let's now give this to 5051 // the target. 5052 5053 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5054 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5055 5056 HashMap<Uri, UriPermission> targetUris 5057 = mGrantedUriPermissions.get(targetUid); 5058 if (targetUris == null) { 5059 targetUris = new HashMap<Uri, UriPermission>(); 5060 mGrantedUriPermissions.put(targetUid, targetUris); 5061 } 5062 5063 UriPermission perm = targetUris.get(uri); 5064 if (perm == null) { 5065 perm = new UriPermission(targetUid, uri); 5066 targetUris.put(uri, perm); 5067 } 5068 5069 perm.modeFlags |= modeFlags; 5070 if (owner == null) { 5071 perm.globalModeFlags |= modeFlags; 5072 } else { 5073 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5074 perm.readOwners.add(owner); 5075 owner.addReadPermission(perm); 5076 } 5077 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5078 perm.writeOwners.add(owner); 5079 owner.addWritePermission(perm); 5080 } 5081 } 5082 } 5083 5084 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5085 int modeFlags, UriPermissionOwner owner) { 5086 if (targetPkg == null) { 5087 throw new NullPointerException("targetPkg"); 5088 } 5089 5090 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5091 if (targetUid < 0) { 5092 return; 5093 } 5094 5095 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5096 } 5097 5098 static class NeededUriGrants extends ArrayList<Uri> { 5099 final String targetPkg; 5100 final int targetUid; 5101 final int flags; 5102 5103 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5104 targetPkg = _targetPkg; 5105 targetUid = _targetUid; 5106 flags = _flags; 5107 } 5108 } 5109 5110 /** 5111 * Like checkGrantUriPermissionLocked, but takes an Intent. 5112 */ 5113 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5114 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5115 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5116 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5117 + " clip=" + (intent != null ? intent.getClipData() : null) 5118 + " from " + intent + "; flags=0x" 5119 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5120 5121 if (targetPkg == null) { 5122 throw new NullPointerException("targetPkg"); 5123 } 5124 5125 if (intent == null) { 5126 return null; 5127 } 5128 Uri data = intent.getData(); 5129 ClipData clip = intent.getClipData(); 5130 if (data == null && clip == null) { 5131 return null; 5132 } 5133 if (data != null) { 5134 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5135 mode, needed != null ? needed.targetUid : -1); 5136 if (target > 0) { 5137 if (needed == null) { 5138 needed = new NeededUriGrants(targetPkg, target, mode); 5139 } 5140 needed.add(data); 5141 } 5142 } 5143 if (clip != null) { 5144 for (int i=0; i<clip.getItemCount(); i++) { 5145 Uri uri = clip.getItemAt(i).getUri(); 5146 if (uri != null) { 5147 int target = -1; 5148 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5149 mode, needed != null ? needed.targetUid : -1); 5150 if (target > 0) { 5151 if (needed == null) { 5152 needed = new NeededUriGrants(targetPkg, target, mode); 5153 } 5154 needed.add(uri); 5155 } 5156 } else { 5157 Intent clipIntent = clip.getItemAt(i).getIntent(); 5158 if (clipIntent != null) { 5159 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5160 callingUid, targetPkg, clipIntent, mode, needed); 5161 if (newNeeded != null) { 5162 needed = newNeeded; 5163 } 5164 } 5165 } 5166 } 5167 } 5168 5169 return needed; 5170 } 5171 5172 /** 5173 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5174 */ 5175 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5176 UriPermissionOwner owner) { 5177 if (needed != null) { 5178 for (int i=0; i<needed.size(); i++) { 5179 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5180 needed.get(i), needed.flags, owner); 5181 } 5182 } 5183 } 5184 5185 void grantUriPermissionFromIntentLocked(int callingUid, 5186 String targetPkg, Intent intent, UriPermissionOwner owner) { 5187 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5188 intent, intent != null ? intent.getFlags() : 0, null); 5189 if (needed == null) { 5190 return; 5191 } 5192 5193 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5194 } 5195 5196 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5197 Uri uri, int modeFlags) { 5198 enforceNotIsolatedCaller("grantUriPermission"); 5199 synchronized(this) { 5200 final ProcessRecord r = getRecordForAppLocked(caller); 5201 if (r == null) { 5202 throw new SecurityException("Unable to find app for caller " 5203 + caller 5204 + " when granting permission to uri " + uri); 5205 } 5206 if (targetPkg == null) { 5207 throw new IllegalArgumentException("null target"); 5208 } 5209 if (uri == null) { 5210 throw new IllegalArgumentException("null uri"); 5211 } 5212 5213 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5214 null); 5215 } 5216 } 5217 5218 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5219 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5220 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5221 HashMap<Uri, UriPermission> perms 5222 = mGrantedUriPermissions.get(perm.uid); 5223 if (perms != null) { 5224 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5225 "Removing " + perm.uid + " permission to " + perm.uri); 5226 perms.remove(perm.uri); 5227 if (perms.size() == 0) { 5228 mGrantedUriPermissions.remove(perm.uid); 5229 } 5230 } 5231 } 5232 } 5233 5234 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5235 int modeFlags) { 5236 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5237 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5238 if (modeFlags == 0) { 5239 return; 5240 } 5241 5242 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5243 "Revoking all granted permissions to " + uri); 5244 5245 final IPackageManager pm = AppGlobals.getPackageManager(); 5246 5247 final String authority = uri.getAuthority(); 5248 ProviderInfo pi = null; 5249 int userId = UserHandle.getUserId(callingUid); 5250 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5251 if (cpr != null) { 5252 pi = cpr.info; 5253 } else { 5254 try { 5255 pi = pm.resolveContentProvider(authority, 5256 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5257 } catch (RemoteException ex) { 5258 } 5259 } 5260 if (pi == null) { 5261 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5262 return; 5263 } 5264 5265 // Does the caller have this permission on the URI? 5266 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5267 // Right now, if you are not the original owner of the permission, 5268 // you are not allowed to revoke it. 5269 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5270 throw new SecurityException("Uid " + callingUid 5271 + " does not have permission to uri " + uri); 5272 //} 5273 } 5274 5275 // Go through all of the permissions and remove any that match. 5276 final List<String> SEGMENTS = uri.getPathSegments(); 5277 if (SEGMENTS != null) { 5278 final int NS = SEGMENTS.size(); 5279 int N = mGrantedUriPermissions.size(); 5280 for (int i=0; i<N; i++) { 5281 HashMap<Uri, UriPermission> perms 5282 = mGrantedUriPermissions.valueAt(i); 5283 Iterator<UriPermission> it = perms.values().iterator(); 5284 toploop: 5285 while (it.hasNext()) { 5286 UriPermission perm = it.next(); 5287 Uri targetUri = perm.uri; 5288 if (!authority.equals(targetUri.getAuthority())) { 5289 continue; 5290 } 5291 List<String> targetSegments = targetUri.getPathSegments(); 5292 if (targetSegments == null) { 5293 continue; 5294 } 5295 if (targetSegments.size() < NS) { 5296 continue; 5297 } 5298 for (int j=0; j<NS; j++) { 5299 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5300 continue toploop; 5301 } 5302 } 5303 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5304 "Revoking " + perm.uid + " permission to " + perm.uri); 5305 perm.clearModes(modeFlags); 5306 if (perm.modeFlags == 0) { 5307 it.remove(); 5308 } 5309 } 5310 if (perms.size() == 0) { 5311 mGrantedUriPermissions.remove( 5312 mGrantedUriPermissions.keyAt(i)); 5313 N--; 5314 i--; 5315 } 5316 } 5317 } 5318 } 5319 5320 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5321 int modeFlags) { 5322 enforceNotIsolatedCaller("revokeUriPermission"); 5323 synchronized(this) { 5324 final ProcessRecord r = getRecordForAppLocked(caller); 5325 if (r == null) { 5326 throw new SecurityException("Unable to find app for caller " 5327 + caller 5328 + " when revoking permission to uri " + uri); 5329 } 5330 if (uri == null) { 5331 Slog.w(TAG, "revokeUriPermission: null uri"); 5332 return; 5333 } 5334 5335 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5336 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5337 if (modeFlags == 0) { 5338 return; 5339 } 5340 5341 final IPackageManager pm = AppGlobals.getPackageManager(); 5342 5343 final String authority = uri.getAuthority(); 5344 ProviderInfo pi = null; 5345 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5346 if (cpr != null) { 5347 pi = cpr.info; 5348 } else { 5349 try { 5350 pi = pm.resolveContentProvider(authority, 5351 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5352 } catch (RemoteException ex) { 5353 } 5354 } 5355 if (pi == null) { 5356 Slog.w(TAG, "No content provider found for permission revoke: " 5357 + uri.toSafeString()); 5358 return; 5359 } 5360 5361 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5362 } 5363 } 5364 5365 @Override 5366 public IBinder newUriPermissionOwner(String name) { 5367 enforceNotIsolatedCaller("newUriPermissionOwner"); 5368 synchronized(this) { 5369 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5370 return owner.getExternalTokenLocked(); 5371 } 5372 } 5373 5374 @Override 5375 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5376 Uri uri, int modeFlags) { 5377 synchronized(this) { 5378 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5379 if (owner == null) { 5380 throw new IllegalArgumentException("Unknown owner: " + token); 5381 } 5382 if (fromUid != Binder.getCallingUid()) { 5383 if (Binder.getCallingUid() != Process.myUid()) { 5384 // Only system code can grant URI permissions on behalf 5385 // of other users. 5386 throw new SecurityException("nice try"); 5387 } 5388 } 5389 if (targetPkg == null) { 5390 throw new IllegalArgumentException("null target"); 5391 } 5392 if (uri == null) { 5393 throw new IllegalArgumentException("null uri"); 5394 } 5395 5396 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5397 } 5398 } 5399 5400 @Override 5401 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5402 synchronized(this) { 5403 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5404 if (owner == null) { 5405 throw new IllegalArgumentException("Unknown owner: " + token); 5406 } 5407 5408 if (uri == null) { 5409 owner.removeUriPermissionsLocked(mode); 5410 } else { 5411 owner.removeUriPermissionLocked(uri, mode); 5412 } 5413 } 5414 } 5415 5416 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5417 synchronized (this) { 5418 ProcessRecord app = 5419 who != null ? getRecordForAppLocked(who) : null; 5420 if (app == null) return; 5421 5422 Message msg = Message.obtain(); 5423 msg.what = WAIT_FOR_DEBUGGER_MSG; 5424 msg.obj = app; 5425 msg.arg1 = waiting ? 1 : 0; 5426 mHandler.sendMessage(msg); 5427 } 5428 } 5429 5430 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5431 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5432 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5433 outInfo.availMem = Process.getFreeMemory(); 5434 outInfo.totalMem = Process.getTotalMemory(); 5435 outInfo.threshold = homeAppMem; 5436 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5437 outInfo.hiddenAppThreshold = hiddenAppMem; 5438 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5439 ProcessList.SERVICE_ADJ); 5440 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5441 ProcessList.VISIBLE_APP_ADJ); 5442 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5443 ProcessList.FOREGROUND_APP_ADJ); 5444 } 5445 5446 // ========================================================= 5447 // TASK MANAGEMENT 5448 // ========================================================= 5449 5450 public List getTasks(int maxNum, int flags, 5451 IThumbnailReceiver receiver) { 5452 ArrayList list = new ArrayList(); 5453 5454 PendingThumbnailsRecord pending = null; 5455 IApplicationThread topThumbnail = null; 5456 ActivityRecord topRecord = null; 5457 5458 synchronized(this) { 5459 if (localLOGV) Slog.v( 5460 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5461 + ", receiver=" + receiver); 5462 5463 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5464 != PackageManager.PERMISSION_GRANTED) { 5465 if (receiver != null) { 5466 // If the caller wants to wait for pending thumbnails, 5467 // it ain't gonna get them. 5468 try { 5469 receiver.finished(); 5470 } catch (RemoteException ex) { 5471 } 5472 } 5473 String msg = "Permission Denial: getTasks() from pid=" 5474 + Binder.getCallingPid() 5475 + ", uid=" + Binder.getCallingUid() 5476 + " requires " + android.Manifest.permission.GET_TASKS; 5477 Slog.w(TAG, msg); 5478 throw new SecurityException(msg); 5479 } 5480 5481 int pos = mMainStack.mHistory.size()-1; 5482 ActivityRecord next = 5483 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5484 ActivityRecord top = null; 5485 TaskRecord curTask = null; 5486 int numActivities = 0; 5487 int numRunning = 0; 5488 while (pos >= 0 && maxNum > 0) { 5489 final ActivityRecord r = next; 5490 pos--; 5491 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5492 5493 // Initialize state for next task if needed. 5494 if (top == null || 5495 (top.state == ActivityState.INITIALIZING 5496 && top.task == r.task)) { 5497 top = r; 5498 curTask = r.task; 5499 numActivities = numRunning = 0; 5500 } 5501 5502 // Add 'r' into the current task. 5503 numActivities++; 5504 if (r.app != null && r.app.thread != null) { 5505 numRunning++; 5506 } 5507 5508 if (localLOGV) Slog.v( 5509 TAG, r.intent.getComponent().flattenToShortString() 5510 + ": task=" + r.task); 5511 5512 // If the next one is a different task, generate a new 5513 // TaskInfo entry for what we have. 5514 if (next == null || next.task != curTask) { 5515 ActivityManager.RunningTaskInfo ci 5516 = new ActivityManager.RunningTaskInfo(); 5517 ci.id = curTask.taskId; 5518 ci.baseActivity = r.intent.getComponent(); 5519 ci.topActivity = top.intent.getComponent(); 5520 if (top.thumbHolder != null) { 5521 ci.description = top.thumbHolder.lastDescription; 5522 } 5523 ci.numActivities = numActivities; 5524 ci.numRunning = numRunning; 5525 //System.out.println( 5526 // "#" + maxNum + ": " + " descr=" + ci.description); 5527 if (ci.thumbnail == null && receiver != null) { 5528 if (localLOGV) Slog.v( 5529 TAG, "State=" + top.state + "Idle=" + top.idle 5530 + " app=" + top.app 5531 + " thr=" + (top.app != null ? top.app.thread : null)); 5532 if (top.state == ActivityState.RESUMED 5533 || top.state == ActivityState.PAUSING) { 5534 if (top.idle && top.app != null 5535 && top.app.thread != null) { 5536 topRecord = top; 5537 topThumbnail = top.app.thread; 5538 } else { 5539 top.thumbnailNeeded = true; 5540 } 5541 } 5542 if (pending == null) { 5543 pending = new PendingThumbnailsRecord(receiver); 5544 } 5545 pending.pendingRecords.add(top); 5546 } 5547 list.add(ci); 5548 maxNum--; 5549 top = null; 5550 } 5551 } 5552 5553 if (pending != null) { 5554 mPendingThumbnails.add(pending); 5555 } 5556 } 5557 5558 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5559 5560 if (topThumbnail != null) { 5561 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5562 try { 5563 topThumbnail.requestThumbnail(topRecord.appToken); 5564 } catch (Exception e) { 5565 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5566 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5567 } 5568 } 5569 5570 if (pending == null && receiver != null) { 5571 // In this case all thumbnails were available and the client 5572 // is being asked to be told when the remaining ones come in... 5573 // which is unusually, since the top-most currently running 5574 // activity should never have a canned thumbnail! Oh well. 5575 try { 5576 receiver.finished(); 5577 } catch (RemoteException ex) { 5578 } 5579 } 5580 5581 return list; 5582 } 5583 5584 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5585 int flags, int userId) { 5586 final int callingUid = Binder.getCallingUid(); 5587 if (userId != UserHandle.getCallingUserId()) { 5588 // Check if the caller is holding permissions for cross-user requests. 5589 if (checkComponentPermission( 5590 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5591 Binder.getCallingPid(), callingUid, -1, true) 5592 != PackageManager.PERMISSION_GRANTED) { 5593 String msg = "Permission Denial: " 5594 + "Request to get recent tasks for user " + userId 5595 + " but is calling from user " + UserHandle.getUserId(callingUid) 5596 + "; this requires " 5597 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5598 Slog.w(TAG, msg); 5599 throw new SecurityException(msg); 5600 } else { 5601 if (userId == UserHandle.USER_CURRENT) { 5602 userId = mCurrentUserId; 5603 } 5604 } 5605 } 5606 5607 synchronized (this) { 5608 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5609 "getRecentTasks()"); 5610 final boolean detailed = checkCallingPermission( 5611 android.Manifest.permission.GET_DETAILED_TASKS) 5612 == PackageManager.PERMISSION_GRANTED; 5613 5614 IPackageManager pm = AppGlobals.getPackageManager(); 5615 5616 final int N = mRecentTasks.size(); 5617 ArrayList<ActivityManager.RecentTaskInfo> res 5618 = new ArrayList<ActivityManager.RecentTaskInfo>( 5619 maxNum < N ? maxNum : N); 5620 for (int i=0; i<N && maxNum > 0; i++) { 5621 TaskRecord tr = mRecentTasks.get(i); 5622 // Only add calling user's recent tasks 5623 if (tr.userId != userId) continue; 5624 // Return the entry if desired by the caller. We always return 5625 // the first entry, because callers always expect this to be the 5626 // foreground app. We may filter others if the caller has 5627 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5628 // we should exclude the entry. 5629 5630 if (i == 0 5631 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5632 || (tr.intent == null) 5633 || ((tr.intent.getFlags() 5634 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5635 ActivityManager.RecentTaskInfo rti 5636 = new ActivityManager.RecentTaskInfo(); 5637 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5638 rti.persistentId = tr.taskId; 5639 rti.baseIntent = new Intent( 5640 tr.intent != null ? tr.intent : tr.affinityIntent); 5641 if (!detailed) { 5642 rti.baseIntent.replaceExtras((Bundle)null); 5643 } 5644 rti.origActivity = tr.origActivity; 5645 rti.description = tr.lastDescription; 5646 5647 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5648 // Check whether this activity is currently available. 5649 try { 5650 if (rti.origActivity != null) { 5651 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5652 == null) { 5653 continue; 5654 } 5655 } else if (rti.baseIntent != null) { 5656 if (pm.queryIntentActivities(rti.baseIntent, 5657 null, 0, userId) == null) { 5658 continue; 5659 } 5660 } 5661 } catch (RemoteException e) { 5662 // Will never happen. 5663 } 5664 } 5665 5666 res.add(rti); 5667 maxNum--; 5668 } 5669 } 5670 return res; 5671 } 5672 } 5673 5674 private TaskRecord taskForIdLocked(int id) { 5675 final int N = mRecentTasks.size(); 5676 for (int i=0; i<N; i++) { 5677 TaskRecord tr = mRecentTasks.get(i); 5678 if (tr.taskId == id) { 5679 return tr; 5680 } 5681 } 5682 return null; 5683 } 5684 5685 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5686 synchronized (this) { 5687 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5688 "getTaskThumbnails()"); 5689 TaskRecord tr = taskForIdLocked(id); 5690 if (tr != null) { 5691 return mMainStack.getTaskThumbnailsLocked(tr); 5692 } 5693 } 5694 return null; 5695 } 5696 5697 public boolean removeSubTask(int taskId, int subTaskIndex) { 5698 synchronized (this) { 5699 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5700 "removeSubTask()"); 5701 long ident = Binder.clearCallingIdentity(); 5702 try { 5703 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5704 true) != null; 5705 } finally { 5706 Binder.restoreCallingIdentity(ident); 5707 } 5708 } 5709 } 5710 5711 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5712 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5713 Intent baseIntent = new Intent( 5714 tr.intent != null ? tr.intent : tr.affinityIntent); 5715 ComponentName component = baseIntent.getComponent(); 5716 if (component == null) { 5717 Slog.w(TAG, "Now component for base intent of task: " + tr); 5718 return; 5719 } 5720 5721 // Find any running services associated with this app. 5722 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5723 5724 if (killProcesses) { 5725 // Find any running processes associated with this app. 5726 final String pkg = component.getPackageName(); 5727 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5728 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5729 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5730 for (int i=0; i<uids.size(); i++) { 5731 ProcessRecord proc = uids.valueAt(i); 5732 if (proc.userId != tr.userId) { 5733 continue; 5734 } 5735 if (!proc.pkgList.contains(pkg)) { 5736 continue; 5737 } 5738 procs.add(proc); 5739 } 5740 } 5741 5742 // Kill the running processes. 5743 for (int i=0; i<procs.size(); i++) { 5744 ProcessRecord pr = procs.get(i); 5745 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5746 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5747 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5748 pr.processName, pr.setAdj, "remove task"); 5749 pr.killedBackground = true; 5750 Process.killProcessQuiet(pr.pid); 5751 } else { 5752 pr.waitingToKill = "remove task"; 5753 } 5754 } 5755 } 5756 } 5757 5758 public boolean removeTask(int taskId, int flags) { 5759 synchronized (this) { 5760 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5761 "removeTask()"); 5762 long ident = Binder.clearCallingIdentity(); 5763 try { 5764 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5765 false); 5766 if (r != null) { 5767 mRecentTasks.remove(r.task); 5768 cleanUpRemovedTaskLocked(r.task, flags); 5769 return true; 5770 } else { 5771 TaskRecord tr = null; 5772 int i=0; 5773 while (i < mRecentTasks.size()) { 5774 TaskRecord t = mRecentTasks.get(i); 5775 if (t.taskId == taskId) { 5776 tr = t; 5777 break; 5778 } 5779 i++; 5780 } 5781 if (tr != null) { 5782 if (tr.numActivities <= 0) { 5783 // Caller is just removing a recent task that is 5784 // not actively running. That is easy! 5785 mRecentTasks.remove(i); 5786 cleanUpRemovedTaskLocked(tr, flags); 5787 return true; 5788 } else { 5789 Slog.w(TAG, "removeTask: task " + taskId 5790 + " does not have activities to remove, " 5791 + " but numActivities=" + tr.numActivities 5792 + ": " + tr); 5793 } 5794 } 5795 } 5796 } finally { 5797 Binder.restoreCallingIdentity(ident); 5798 } 5799 } 5800 return false; 5801 } 5802 5803 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5804 int j; 5805 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5806 TaskRecord jt = startTask; 5807 5808 // First look backwards 5809 for (j=startIndex-1; j>=0; j--) { 5810 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5811 if (r.task != jt) { 5812 jt = r.task; 5813 if (affinity.equals(jt.affinity)) { 5814 return j; 5815 } 5816 } 5817 } 5818 5819 // Now look forwards 5820 final int N = mMainStack.mHistory.size(); 5821 jt = startTask; 5822 for (j=startIndex+1; j<N; j++) { 5823 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5824 if (r.task != jt) { 5825 if (affinity.equals(jt.affinity)) { 5826 return j; 5827 } 5828 jt = r.task; 5829 } 5830 } 5831 5832 // Might it be at the top? 5833 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5834 return N-1; 5835 } 5836 5837 return -1; 5838 } 5839 5840 /** 5841 * TODO: Add mController hook 5842 */ 5843 public void moveTaskToFront(int task, int flags, Bundle options) { 5844 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5845 "moveTaskToFront()"); 5846 5847 synchronized(this) { 5848 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5849 Binder.getCallingUid(), "Task to front")) { 5850 ActivityOptions.abort(options); 5851 return; 5852 } 5853 final long origId = Binder.clearCallingIdentity(); 5854 try { 5855 TaskRecord tr = taskForIdLocked(task); 5856 if (tr != null) { 5857 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5858 mMainStack.mUserLeaving = true; 5859 } 5860 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5861 // Caller wants the home activity moved with it. To accomplish this, 5862 // we'll just move the home task to the top first. 5863 mMainStack.moveHomeToFrontLocked(); 5864 } 5865 mMainStack.moveTaskToFrontLocked(tr, null, options); 5866 return; 5867 } 5868 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5869 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5870 if (hr.task.taskId == task) { 5871 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5872 mMainStack.mUserLeaving = true; 5873 } 5874 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5875 // Caller wants the home activity moved with it. To accomplish this, 5876 // we'll just move the home task to the top first. 5877 mMainStack.moveHomeToFrontLocked(); 5878 } 5879 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5880 return; 5881 } 5882 } 5883 } finally { 5884 Binder.restoreCallingIdentity(origId); 5885 } 5886 ActivityOptions.abort(options); 5887 } 5888 } 5889 5890 public void moveTaskToBack(int task) { 5891 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5892 "moveTaskToBack()"); 5893 5894 synchronized(this) { 5895 if (mMainStack.mResumedActivity != null 5896 && mMainStack.mResumedActivity.task.taskId == task) { 5897 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5898 Binder.getCallingUid(), "Task to back")) { 5899 return; 5900 } 5901 } 5902 final long origId = Binder.clearCallingIdentity(); 5903 mMainStack.moveTaskToBackLocked(task, null); 5904 Binder.restoreCallingIdentity(origId); 5905 } 5906 } 5907 5908 /** 5909 * Moves an activity, and all of the other activities within the same task, to the bottom 5910 * of the history stack. The activity's order within the task is unchanged. 5911 * 5912 * @param token A reference to the activity we wish to move 5913 * @param nonRoot If false then this only works if the activity is the root 5914 * of a task; if true it will work for any activity in a task. 5915 * @return Returns true if the move completed, false if not. 5916 */ 5917 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5918 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5919 synchronized(this) { 5920 final long origId = Binder.clearCallingIdentity(); 5921 int taskId = getTaskForActivityLocked(token, !nonRoot); 5922 if (taskId >= 0) { 5923 return mMainStack.moveTaskToBackLocked(taskId, null); 5924 } 5925 Binder.restoreCallingIdentity(origId); 5926 } 5927 return false; 5928 } 5929 5930 public void moveTaskBackwards(int task) { 5931 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5932 "moveTaskBackwards()"); 5933 5934 synchronized(this) { 5935 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5936 Binder.getCallingUid(), "Task backwards")) { 5937 return; 5938 } 5939 final long origId = Binder.clearCallingIdentity(); 5940 moveTaskBackwardsLocked(task); 5941 Binder.restoreCallingIdentity(origId); 5942 } 5943 } 5944 5945 private final void moveTaskBackwardsLocked(int task) { 5946 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5947 } 5948 5949 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5950 synchronized(this) { 5951 return getTaskForActivityLocked(token, onlyRoot); 5952 } 5953 } 5954 5955 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5956 final int N = mMainStack.mHistory.size(); 5957 TaskRecord lastTask = null; 5958 for (int i=0; i<N; i++) { 5959 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5960 if (r.appToken == token) { 5961 if (!onlyRoot || lastTask != r.task) { 5962 return r.task.taskId; 5963 } 5964 return -1; 5965 } 5966 lastTask = r.task; 5967 } 5968 5969 return -1; 5970 } 5971 5972 // ========================================================= 5973 // THUMBNAILS 5974 // ========================================================= 5975 5976 public void reportThumbnail(IBinder token, 5977 Bitmap thumbnail, CharSequence description) { 5978 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5979 final long origId = Binder.clearCallingIdentity(); 5980 sendPendingThumbnail(null, token, thumbnail, description, true); 5981 Binder.restoreCallingIdentity(origId); 5982 } 5983 5984 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5985 Bitmap thumbnail, CharSequence description, boolean always) { 5986 TaskRecord task = null; 5987 ArrayList receivers = null; 5988 5989 //System.out.println("Send pending thumbnail: " + r); 5990 5991 synchronized(this) { 5992 if (r == null) { 5993 r = mMainStack.isInStackLocked(token); 5994 if (r == null) { 5995 return; 5996 } 5997 } 5998 if (thumbnail == null && r.thumbHolder != null) { 5999 thumbnail = r.thumbHolder.lastThumbnail; 6000 description = r.thumbHolder.lastDescription; 6001 } 6002 if (thumbnail == null && !always) { 6003 // If there is no thumbnail, and this entry is not actually 6004 // going away, then abort for now and pick up the next 6005 // thumbnail we get. 6006 return; 6007 } 6008 task = r.task; 6009 6010 int N = mPendingThumbnails.size(); 6011 int i=0; 6012 while (i<N) { 6013 PendingThumbnailsRecord pr = 6014 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6015 //System.out.println("Looking in " + pr.pendingRecords); 6016 if (pr.pendingRecords.remove(r)) { 6017 if (receivers == null) { 6018 receivers = new ArrayList(); 6019 } 6020 receivers.add(pr); 6021 if (pr.pendingRecords.size() == 0) { 6022 pr.finished = true; 6023 mPendingThumbnails.remove(i); 6024 N--; 6025 continue; 6026 } 6027 } 6028 i++; 6029 } 6030 } 6031 6032 if (receivers != null) { 6033 final int N = receivers.size(); 6034 for (int i=0; i<N; i++) { 6035 try { 6036 PendingThumbnailsRecord pr = 6037 (PendingThumbnailsRecord)receivers.get(i); 6038 pr.receiver.newThumbnail( 6039 task != null ? task.taskId : -1, thumbnail, description); 6040 if (pr.finished) { 6041 pr.receiver.finished(); 6042 } 6043 } catch (Exception e) { 6044 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6045 } 6046 } 6047 } 6048 } 6049 6050 // ========================================================= 6051 // CONTENT PROVIDERS 6052 // ========================================================= 6053 6054 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6055 List<ProviderInfo> providers = null; 6056 try { 6057 providers = AppGlobals.getPackageManager(). 6058 queryContentProviders(app.processName, app.uid, 6059 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6060 } catch (RemoteException ex) { 6061 } 6062 if (DEBUG_MU) 6063 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6064 int userId = app.userId; 6065 if (providers != null) { 6066 int N = providers.size(); 6067 for (int i=0; i<N; i++) { 6068 ProviderInfo cpi = 6069 (ProviderInfo)providers.get(i); 6070 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6071 cpi.name, cpi.flags); 6072 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6073 // This is a singleton provider, but a user besides the 6074 // default user is asking to initialize a process it runs 6075 // in... well, no, it doesn't actually run in this process, 6076 // it runs in the process of the default user. Get rid of it. 6077 providers.remove(i); 6078 N--; 6079 continue; 6080 } 6081 6082 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6083 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6084 if (cpr == null) { 6085 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6086 mProviderMap.putProviderByClass(comp, cpr); 6087 } 6088 if (DEBUG_MU) 6089 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6090 app.pubProviders.put(cpi.name, cpr); 6091 app.addPackage(cpi.applicationInfo.packageName); 6092 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6093 } 6094 } 6095 return providers; 6096 } 6097 6098 /** 6099 * Check if {@link ProcessRecord} has a possible chance at accessing the 6100 * given {@link ProviderInfo}. Final permission checking is always done 6101 * in {@link ContentProvider}. 6102 */ 6103 private final String checkContentProviderPermissionLocked( 6104 ProviderInfo cpi, ProcessRecord r) { 6105 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6106 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6107 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6108 cpi.applicationInfo.uid, cpi.exported) 6109 == PackageManager.PERMISSION_GRANTED) { 6110 return null; 6111 } 6112 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6113 cpi.applicationInfo.uid, cpi.exported) 6114 == PackageManager.PERMISSION_GRANTED) { 6115 return null; 6116 } 6117 6118 PathPermission[] pps = cpi.pathPermissions; 6119 if (pps != null) { 6120 int i = pps.length; 6121 while (i > 0) { 6122 i--; 6123 PathPermission pp = pps[i]; 6124 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6125 cpi.applicationInfo.uid, cpi.exported) 6126 == PackageManager.PERMISSION_GRANTED) { 6127 return null; 6128 } 6129 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6130 cpi.applicationInfo.uid, cpi.exported) 6131 == PackageManager.PERMISSION_GRANTED) { 6132 return null; 6133 } 6134 } 6135 } 6136 6137 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6138 if (perms != null) { 6139 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6140 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6141 return null; 6142 } 6143 } 6144 } 6145 6146 String msg; 6147 if (!cpi.exported) { 6148 msg = "Permission Denial: opening provider " + cpi.name 6149 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6150 + ", uid=" + callingUid + ") that is not exported from uid " 6151 + cpi.applicationInfo.uid; 6152 } else { 6153 msg = "Permission Denial: opening provider " + cpi.name 6154 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6155 + ", uid=" + callingUid + ") requires " 6156 + cpi.readPermission + " or " + cpi.writePermission; 6157 } 6158 Slog.w(TAG, msg); 6159 return msg; 6160 } 6161 6162 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6163 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6164 if (r != null) { 6165 for (int i=0; i<r.conProviders.size(); i++) { 6166 ContentProviderConnection conn = r.conProviders.get(i); 6167 if (conn.provider == cpr) { 6168 if (DEBUG_PROVIDER) Slog.v(TAG, 6169 "Adding provider requested by " 6170 + r.processName + " from process " 6171 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6172 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6173 if (stable) { 6174 conn.stableCount++; 6175 conn.numStableIncs++; 6176 } else { 6177 conn.unstableCount++; 6178 conn.numUnstableIncs++; 6179 } 6180 return conn; 6181 } 6182 } 6183 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6184 if (stable) { 6185 conn.stableCount = 1; 6186 conn.numStableIncs = 1; 6187 } else { 6188 conn.unstableCount = 1; 6189 conn.numUnstableIncs = 1; 6190 } 6191 cpr.connections.add(conn); 6192 r.conProviders.add(conn); 6193 return conn; 6194 } 6195 cpr.addExternalProcessHandleLocked(externalProcessToken); 6196 return null; 6197 } 6198 6199 boolean decProviderCountLocked(ContentProviderConnection conn, 6200 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6201 if (conn != null) { 6202 cpr = conn.provider; 6203 if (DEBUG_PROVIDER) Slog.v(TAG, 6204 "Removing provider requested by " 6205 + conn.client.processName + " from process " 6206 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6207 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6208 if (stable) { 6209 conn.stableCount--; 6210 } else { 6211 conn.unstableCount--; 6212 } 6213 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6214 cpr.connections.remove(conn); 6215 conn.client.conProviders.remove(conn); 6216 return true; 6217 } 6218 return false; 6219 } 6220 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6221 return false; 6222 } 6223 6224 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6225 String name, IBinder token, boolean stable) { 6226 ContentProviderRecord cpr; 6227 ContentProviderConnection conn = null; 6228 ProviderInfo cpi = null; 6229 6230 synchronized(this) { 6231 ProcessRecord r = null; 6232 if (caller != null) { 6233 r = getRecordForAppLocked(caller); 6234 if (r == null) { 6235 throw new SecurityException( 6236 "Unable to find app for caller " + caller 6237 + " (pid=" + Binder.getCallingPid() 6238 + ") when getting content provider " + name); 6239 } 6240 } 6241 6242 // First check if this content provider has been published... 6243 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6244 cpr = mProviderMap.getProviderByName(name, userId); 6245 boolean providerRunning = cpr != null; 6246 if (providerRunning) { 6247 cpi = cpr.info; 6248 String msg; 6249 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6250 throw new SecurityException(msg); 6251 } 6252 6253 if (r != null && cpr.canRunHere(r)) { 6254 // This provider has been published or is in the process 6255 // of being published... but it is also allowed to run 6256 // in the caller's process, so don't make a connection 6257 // and just let the caller instantiate its own instance. 6258 ContentProviderHolder holder = cpr.newHolder(null); 6259 // don't give caller the provider object, it needs 6260 // to make its own. 6261 holder.provider = null; 6262 return holder; 6263 } 6264 6265 final long origId = Binder.clearCallingIdentity(); 6266 6267 // In this case the provider instance already exists, so we can 6268 // return it right away. 6269 conn = incProviderCountLocked(r, cpr, token, stable); 6270 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6271 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6272 // If this is a perceptible app accessing the provider, 6273 // make sure to count it as being accessed and thus 6274 // back up on the LRU list. This is good because 6275 // content providers are often expensive to start. 6276 updateLruProcessLocked(cpr.proc, false, true); 6277 } 6278 } 6279 6280 if (cpr.proc != null) { 6281 if (false) { 6282 if (cpr.name.flattenToShortString().equals( 6283 "com.android.providers.calendar/.CalendarProvider2")) { 6284 Slog.v(TAG, "****************** KILLING " 6285 + cpr.name.flattenToShortString()); 6286 Process.killProcess(cpr.proc.pid); 6287 } 6288 } 6289 boolean success = updateOomAdjLocked(cpr.proc); 6290 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6291 // NOTE: there is still a race here where a signal could be 6292 // pending on the process even though we managed to update its 6293 // adj level. Not sure what to do about this, but at least 6294 // the race is now smaller. 6295 if (!success) { 6296 // Uh oh... it looks like the provider's process 6297 // has been killed on us. We need to wait for a new 6298 // process to be started, and make sure its death 6299 // doesn't kill our process. 6300 Slog.i(TAG, 6301 "Existing provider " + cpr.name.flattenToShortString() 6302 + " is crashing; detaching " + r); 6303 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6304 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6305 if (!lastRef) { 6306 // This wasn't the last ref our process had on 6307 // the provider... we have now been killed, bail. 6308 return null; 6309 } 6310 providerRunning = false; 6311 conn = null; 6312 } 6313 } 6314 6315 Binder.restoreCallingIdentity(origId); 6316 } 6317 6318 boolean singleton; 6319 if (!providerRunning) { 6320 try { 6321 cpi = AppGlobals.getPackageManager(). 6322 resolveContentProvider(name, 6323 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6324 } catch (RemoteException ex) { 6325 } 6326 if (cpi == null) { 6327 return null; 6328 } 6329 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6330 cpi.name, cpi.flags); 6331 if (singleton) { 6332 userId = 0; 6333 } 6334 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6335 6336 String msg; 6337 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6338 throw new SecurityException(msg); 6339 } 6340 6341 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6342 && !cpi.processName.equals("system")) { 6343 // If this content provider does not run in the system 6344 // process, and the system is not yet ready to run other 6345 // processes, then fail fast instead of hanging. 6346 throw new IllegalArgumentException( 6347 "Attempt to launch content provider before system ready"); 6348 } 6349 6350 // Make sure that the user who owns this provider is started. If not, 6351 // we don't want to allow it to run. 6352 if (mStartedUsers.get(userId) == null) { 6353 Slog.w(TAG, "Unable to launch app " 6354 + cpi.applicationInfo.packageName + "/" 6355 + cpi.applicationInfo.uid + " for provider " 6356 + name + ": user " + userId + " is stopped"); 6357 return null; 6358 } 6359 6360 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6361 cpr = mProviderMap.getProviderByClass(comp, userId); 6362 final boolean firstClass = cpr == null; 6363 if (firstClass) { 6364 try { 6365 ApplicationInfo ai = 6366 AppGlobals.getPackageManager(). 6367 getApplicationInfo( 6368 cpi.applicationInfo.packageName, 6369 STOCK_PM_FLAGS, userId); 6370 if (ai == null) { 6371 Slog.w(TAG, "No package info for content provider " 6372 + cpi.name); 6373 return null; 6374 } 6375 ai = getAppInfoForUser(ai, userId); 6376 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6377 } catch (RemoteException ex) { 6378 // pm is in same process, this will never happen. 6379 } 6380 } 6381 6382 if (r != null && cpr.canRunHere(r)) { 6383 // If this is a multiprocess provider, then just return its 6384 // info and allow the caller to instantiate it. Only do 6385 // this if the provider is the same user as the caller's 6386 // process, or can run as root (so can be in any process). 6387 return cpr.newHolder(null); 6388 } 6389 6390 if (DEBUG_PROVIDER) { 6391 RuntimeException e = new RuntimeException("here"); 6392 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6393 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6394 } 6395 6396 // This is single process, and our app is now connecting to it. 6397 // See if we are already in the process of launching this 6398 // provider. 6399 final int N = mLaunchingProviders.size(); 6400 int i; 6401 for (i=0; i<N; i++) { 6402 if (mLaunchingProviders.get(i) == cpr) { 6403 break; 6404 } 6405 } 6406 6407 // If the provider is not already being launched, then get it 6408 // started. 6409 if (i >= N) { 6410 final long origId = Binder.clearCallingIdentity(); 6411 6412 try { 6413 // Content provider is now in use, its package can't be stopped. 6414 try { 6415 AppGlobals.getPackageManager().setPackageStoppedState( 6416 cpr.appInfo.packageName, false, userId); 6417 } catch (RemoteException e) { 6418 } catch (IllegalArgumentException e) { 6419 Slog.w(TAG, "Failed trying to unstop package " 6420 + cpr.appInfo.packageName + ": " + e); 6421 } 6422 6423 ProcessRecord proc = startProcessLocked(cpi.processName, 6424 cpr.appInfo, false, 0, "content provider", 6425 new ComponentName(cpi.applicationInfo.packageName, 6426 cpi.name), false, false); 6427 if (proc == null) { 6428 Slog.w(TAG, "Unable to launch app " 6429 + cpi.applicationInfo.packageName + "/" 6430 + cpi.applicationInfo.uid + " for provider " 6431 + name + ": process is bad"); 6432 return null; 6433 } 6434 cpr.launchingApp = proc; 6435 mLaunchingProviders.add(cpr); 6436 } finally { 6437 Binder.restoreCallingIdentity(origId); 6438 } 6439 } 6440 6441 // Make sure the provider is published (the same provider class 6442 // may be published under multiple names). 6443 if (firstClass) { 6444 mProviderMap.putProviderByClass(comp, cpr); 6445 } 6446 6447 mProviderMap.putProviderByName(name, cpr); 6448 conn = incProviderCountLocked(r, cpr, token, stable); 6449 if (conn != null) { 6450 conn.waiting = true; 6451 } 6452 } 6453 } 6454 6455 // Wait for the provider to be published... 6456 synchronized (cpr) { 6457 while (cpr.provider == null) { 6458 if (cpr.launchingApp == null) { 6459 Slog.w(TAG, "Unable to launch app " 6460 + cpi.applicationInfo.packageName + "/" 6461 + cpi.applicationInfo.uid + " for provider " 6462 + name + ": launching app became null"); 6463 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6464 cpi.applicationInfo.packageName, 6465 cpi.applicationInfo.uid, name); 6466 return null; 6467 } 6468 try { 6469 if (DEBUG_MU) { 6470 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6471 + cpr.launchingApp); 6472 } 6473 if (conn != null) { 6474 conn.waiting = true; 6475 } 6476 cpr.wait(); 6477 } catch (InterruptedException ex) { 6478 } finally { 6479 if (conn != null) { 6480 conn.waiting = false; 6481 } 6482 } 6483 } 6484 } 6485 return cpr != null ? cpr.newHolder(conn) : null; 6486 } 6487 6488 public final ContentProviderHolder getContentProvider( 6489 IApplicationThread caller, String name, boolean stable) { 6490 enforceNotIsolatedCaller("getContentProvider"); 6491 if (caller == null) { 6492 String msg = "null IApplicationThread when getting content provider " 6493 + name; 6494 Slog.w(TAG, msg); 6495 throw new SecurityException(msg); 6496 } 6497 6498 return getContentProviderImpl(caller, name, null, stable); 6499 } 6500 6501 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6502 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6503 "Do not have permission in call getContentProviderExternal()"); 6504 return getContentProviderExternalUnchecked(name, token); 6505 } 6506 6507 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6508 return getContentProviderImpl(null, name, token, true); 6509 } 6510 6511 /** 6512 * Drop a content provider from a ProcessRecord's bookkeeping 6513 * @param cpr 6514 */ 6515 public void removeContentProvider(IBinder connection, boolean stable) { 6516 enforceNotIsolatedCaller("removeContentProvider"); 6517 synchronized (this) { 6518 ContentProviderConnection conn; 6519 try { 6520 conn = (ContentProviderConnection)connection; 6521 } catch (ClassCastException e) { 6522 String msg ="removeContentProvider: " + connection 6523 + " not a ContentProviderConnection"; 6524 Slog.w(TAG, msg); 6525 throw new IllegalArgumentException(msg); 6526 } 6527 if (conn == null) { 6528 throw new NullPointerException("connection is null"); 6529 } 6530 if (decProviderCountLocked(conn, null, null, stable)) { 6531 updateOomAdjLocked(); 6532 } 6533 } 6534 } 6535 6536 public void removeContentProviderExternal(String name, IBinder token) { 6537 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6538 "Do not have permission in call removeContentProviderExternal()"); 6539 removeContentProviderExternalUnchecked(name, token); 6540 } 6541 6542 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6543 synchronized (this) { 6544 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6545 Binder.getOrigCallingUser()); 6546 if(cpr == null) { 6547 //remove from mProvidersByClass 6548 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6549 return; 6550 } 6551 6552 //update content provider record entry info 6553 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6554 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6555 Binder.getOrigCallingUser()); 6556 if (localCpr.hasExternalProcessHandles()) { 6557 if (localCpr.removeExternalProcessHandleLocked(token)) { 6558 updateOomAdjLocked(); 6559 } else { 6560 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6561 + " with no external reference for token: " 6562 + token + "."); 6563 } 6564 } else { 6565 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6566 + " with no external references."); 6567 } 6568 } 6569 } 6570 6571 public final void publishContentProviders(IApplicationThread caller, 6572 List<ContentProviderHolder> providers) { 6573 if (providers == null) { 6574 return; 6575 } 6576 6577 enforceNotIsolatedCaller("publishContentProviders"); 6578 synchronized (this) { 6579 final ProcessRecord r = getRecordForAppLocked(caller); 6580 if (DEBUG_MU) 6581 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6582 if (r == null) { 6583 throw new SecurityException( 6584 "Unable to find app for caller " + caller 6585 + " (pid=" + Binder.getCallingPid() 6586 + ") when publishing content providers"); 6587 } 6588 6589 final long origId = Binder.clearCallingIdentity(); 6590 6591 final int N = providers.size(); 6592 for (int i=0; i<N; i++) { 6593 ContentProviderHolder src = providers.get(i); 6594 if (src == null || src.info == null || src.provider == null) { 6595 continue; 6596 } 6597 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6598 if (DEBUG_MU) 6599 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6600 if (dst != null) { 6601 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6602 mProviderMap.putProviderByClass(comp, dst); 6603 String names[] = dst.info.authority.split(";"); 6604 for (int j = 0; j < names.length; j++) { 6605 mProviderMap.putProviderByName(names[j], dst); 6606 } 6607 6608 int NL = mLaunchingProviders.size(); 6609 int j; 6610 for (j=0; j<NL; j++) { 6611 if (mLaunchingProviders.get(j) == dst) { 6612 mLaunchingProviders.remove(j); 6613 j--; 6614 NL--; 6615 } 6616 } 6617 synchronized (dst) { 6618 dst.provider = src.provider; 6619 dst.proc = r; 6620 dst.notifyAll(); 6621 } 6622 updateOomAdjLocked(r); 6623 } 6624 } 6625 6626 Binder.restoreCallingIdentity(origId); 6627 } 6628 } 6629 6630 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6631 ContentProviderConnection conn; 6632 try { 6633 conn = (ContentProviderConnection)connection; 6634 } catch (ClassCastException e) { 6635 String msg ="refContentProvider: " + connection 6636 + " not a ContentProviderConnection"; 6637 Slog.w(TAG, msg); 6638 throw new IllegalArgumentException(msg); 6639 } 6640 if (conn == null) { 6641 throw new NullPointerException("connection is null"); 6642 } 6643 6644 synchronized (this) { 6645 if (stable > 0) { 6646 conn.numStableIncs += stable; 6647 } 6648 stable = conn.stableCount + stable; 6649 if (stable < 0) { 6650 throw new IllegalStateException("stableCount < 0: " + stable); 6651 } 6652 6653 if (unstable > 0) { 6654 conn.numUnstableIncs += unstable; 6655 } 6656 unstable = conn.unstableCount + unstable; 6657 if (unstable < 0) { 6658 throw new IllegalStateException("unstableCount < 0: " + unstable); 6659 } 6660 6661 if ((stable+unstable) <= 0) { 6662 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6663 + stable + " unstable=" + unstable); 6664 } 6665 conn.stableCount = stable; 6666 conn.unstableCount = unstable; 6667 return !conn.dead; 6668 } 6669 } 6670 6671 public void unstableProviderDied(IBinder connection) { 6672 ContentProviderConnection conn; 6673 try { 6674 conn = (ContentProviderConnection)connection; 6675 } catch (ClassCastException e) { 6676 String msg ="refContentProvider: " + connection 6677 + " not a ContentProviderConnection"; 6678 Slog.w(TAG, msg); 6679 throw new IllegalArgumentException(msg); 6680 } 6681 if (conn == null) { 6682 throw new NullPointerException("connection is null"); 6683 } 6684 6685 // Safely retrieve the content provider associated with the connection. 6686 IContentProvider provider; 6687 synchronized (this) { 6688 provider = conn.provider.provider; 6689 } 6690 6691 if (provider == null) { 6692 // Um, yeah, we're way ahead of you. 6693 return; 6694 } 6695 6696 // Make sure the caller is being honest with us. 6697 if (provider.asBinder().pingBinder()) { 6698 // Er, no, still looks good to us. 6699 synchronized (this) { 6700 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6701 + " says " + conn + " died, but we don't agree"); 6702 return; 6703 } 6704 } 6705 6706 // Well look at that! It's dead! 6707 synchronized (this) { 6708 if (conn.provider.provider != provider) { 6709 // But something changed... good enough. 6710 return; 6711 } 6712 6713 ProcessRecord proc = conn.provider.proc; 6714 if (proc == null || proc.thread == null) { 6715 // Seems like the process is already cleaned up. 6716 return; 6717 } 6718 6719 // As far as we're concerned, this is just like receiving a 6720 // death notification... just a bit prematurely. 6721 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6722 + ") early provider death"); 6723 final long ident = Binder.clearCallingIdentity(); 6724 try { 6725 appDiedLocked(proc, proc.pid, proc.thread); 6726 } finally { 6727 Binder.restoreCallingIdentity(ident); 6728 } 6729 } 6730 } 6731 6732 public static final void installSystemProviders() { 6733 List<ProviderInfo> providers; 6734 synchronized (mSelf) { 6735 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6736 providers = mSelf.generateApplicationProvidersLocked(app); 6737 if (providers != null) { 6738 for (int i=providers.size()-1; i>=0; i--) { 6739 ProviderInfo pi = (ProviderInfo)providers.get(i); 6740 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6741 Slog.w(TAG, "Not installing system proc provider " + pi.name 6742 + ": not system .apk"); 6743 providers.remove(i); 6744 } 6745 } 6746 } 6747 } 6748 if (providers != null) { 6749 mSystemThread.installSystemProviders(providers); 6750 } 6751 6752 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6753 6754 mSelf.mUsageStatsService.monitorPackages(); 6755 } 6756 6757 /** 6758 * Allows app to retrieve the MIME type of a URI without having permission 6759 * to access its content provider. 6760 * 6761 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6762 * 6763 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6764 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6765 */ 6766 public String getProviderMimeType(Uri uri) { 6767 enforceNotIsolatedCaller("getProviderMimeType"); 6768 final String name = uri.getAuthority(); 6769 final long ident = Binder.clearCallingIdentity(); 6770 ContentProviderHolder holder = null; 6771 6772 try { 6773 holder = getContentProviderExternalUnchecked(name, null); 6774 if (holder != null) { 6775 return holder.provider.getType(uri); 6776 } 6777 } catch (RemoteException e) { 6778 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6779 return null; 6780 } finally { 6781 if (holder != null) { 6782 removeContentProviderExternalUnchecked(name, null); 6783 } 6784 Binder.restoreCallingIdentity(ident); 6785 } 6786 6787 return null; 6788 } 6789 6790 // ========================================================= 6791 // GLOBAL MANAGEMENT 6792 // ========================================================= 6793 6794 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6795 ApplicationInfo info, String customProcess, boolean isolated) { 6796 String proc = customProcess != null ? customProcess : info.processName; 6797 BatteryStatsImpl.Uid.Proc ps = null; 6798 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6799 int uid = info.uid; 6800 if (isolated) { 6801 int userId = UserHandle.getUserId(uid); 6802 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6803 uid = 0; 6804 while (true) { 6805 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6806 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6807 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6808 } 6809 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6810 mNextIsolatedProcessUid++; 6811 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6812 // No process for this uid, use it. 6813 break; 6814 } 6815 stepsLeft--; 6816 if (stepsLeft <= 0) { 6817 return null; 6818 } 6819 } 6820 } 6821 synchronized (stats) { 6822 ps = stats.getProcessStatsLocked(info.uid, proc); 6823 } 6824 return new ProcessRecord(ps, thread, info, proc, uid); 6825 } 6826 6827 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6828 ProcessRecord app; 6829 if (!isolated) { 6830 app = getProcessRecordLocked(info.processName, info.uid); 6831 } else { 6832 app = null; 6833 } 6834 6835 if (app == null) { 6836 app = newProcessRecordLocked(null, info, null, isolated); 6837 mProcessNames.put(info.processName, app.uid, app); 6838 if (isolated) { 6839 mIsolatedProcesses.put(app.uid, app); 6840 } 6841 updateLruProcessLocked(app, true, true); 6842 } 6843 6844 // This package really, really can not be stopped. 6845 try { 6846 AppGlobals.getPackageManager().setPackageStoppedState( 6847 info.packageName, false, UserHandle.getUserId(app.uid)); 6848 } catch (RemoteException e) { 6849 } catch (IllegalArgumentException e) { 6850 Slog.w(TAG, "Failed trying to unstop package " 6851 + info.packageName + ": " + e); 6852 } 6853 6854 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6855 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6856 app.persistent = true; 6857 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6858 } 6859 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6860 mPersistentStartingProcesses.add(app); 6861 startProcessLocked(app, "added application", app.processName); 6862 } 6863 6864 return app; 6865 } 6866 6867 public void unhandledBack() { 6868 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6869 "unhandledBack()"); 6870 6871 synchronized(this) { 6872 int count = mMainStack.mHistory.size(); 6873 if (DEBUG_SWITCH) Slog.d( 6874 TAG, "Performing unhandledBack(): stack size = " + count); 6875 if (count > 1) { 6876 final long origId = Binder.clearCallingIdentity(); 6877 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6878 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6879 Binder.restoreCallingIdentity(origId); 6880 } 6881 } 6882 } 6883 6884 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6885 enforceNotIsolatedCaller("openContentUri"); 6886 String name = uri.getAuthority(); 6887 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6888 ParcelFileDescriptor pfd = null; 6889 if (cph != null) { 6890 // We record the binder invoker's uid in thread-local storage before 6891 // going to the content provider to open the file. Later, in the code 6892 // that handles all permissions checks, we look for this uid and use 6893 // that rather than the Activity Manager's own uid. The effect is that 6894 // we do the check against the caller's permissions even though it looks 6895 // to the content provider like the Activity Manager itself is making 6896 // the request. 6897 sCallerIdentity.set(new Identity( 6898 Binder.getCallingPid(), Binder.getCallingUid())); 6899 try { 6900 pfd = cph.provider.openFile(uri, "r"); 6901 } catch (FileNotFoundException e) { 6902 // do nothing; pfd will be returned null 6903 } finally { 6904 // Ensure that whatever happens, we clean up the identity state 6905 sCallerIdentity.remove(); 6906 } 6907 6908 // We've got the fd now, so we're done with the provider. 6909 removeContentProviderExternalUnchecked(name, null); 6910 } else { 6911 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6912 } 6913 return pfd; 6914 } 6915 6916 // Actually is sleeping or shutting down or whatever else in the future 6917 // is an inactive state. 6918 public boolean isSleeping() { 6919 return mSleeping || mShuttingDown; 6920 } 6921 6922 public void goingToSleep() { 6923 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6924 != PackageManager.PERMISSION_GRANTED) { 6925 throw new SecurityException("Requires permission " 6926 + android.Manifest.permission.DEVICE_POWER); 6927 } 6928 6929 synchronized(this) { 6930 mWentToSleep = true; 6931 updateEventDispatchingLocked(); 6932 6933 if (!mSleeping) { 6934 mSleeping = true; 6935 mMainStack.stopIfSleepingLocked(); 6936 6937 // Initialize the wake times of all processes. 6938 checkExcessivePowerUsageLocked(false); 6939 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6940 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6941 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6942 } 6943 } 6944 } 6945 6946 public boolean shutdown(int timeout) { 6947 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6948 != PackageManager.PERMISSION_GRANTED) { 6949 throw new SecurityException("Requires permission " 6950 + android.Manifest.permission.SHUTDOWN); 6951 } 6952 6953 boolean timedout = false; 6954 6955 synchronized(this) { 6956 mShuttingDown = true; 6957 updateEventDispatchingLocked(); 6958 6959 if (mMainStack.mResumedActivity != null) { 6960 mMainStack.stopIfSleepingLocked(); 6961 final long endTime = System.currentTimeMillis() + timeout; 6962 while (mMainStack.mResumedActivity != null 6963 || mMainStack.mPausingActivity != null) { 6964 long delay = endTime - System.currentTimeMillis(); 6965 if (delay <= 0) { 6966 Slog.w(TAG, "Activity manager shutdown timed out"); 6967 timedout = true; 6968 break; 6969 } 6970 try { 6971 this.wait(); 6972 } catch (InterruptedException e) { 6973 } 6974 } 6975 } 6976 } 6977 6978 mUsageStatsService.shutdown(); 6979 mBatteryStatsService.shutdown(); 6980 6981 return timedout; 6982 } 6983 6984 public final void activitySlept(IBinder token) { 6985 if (localLOGV) Slog.v( 6986 TAG, "Activity slept: token=" + token); 6987 6988 ActivityRecord r = null; 6989 6990 final long origId = Binder.clearCallingIdentity(); 6991 6992 synchronized (this) { 6993 r = mMainStack.isInStackLocked(token); 6994 if (r != null) { 6995 mMainStack.activitySleptLocked(r); 6996 } 6997 } 6998 6999 Binder.restoreCallingIdentity(origId); 7000 } 7001 7002 private void comeOutOfSleepIfNeededLocked() { 7003 if (!mWentToSleep && !mLockScreenShown) { 7004 if (mSleeping) { 7005 mSleeping = false; 7006 mMainStack.awakeFromSleepingLocked(); 7007 mMainStack.resumeTopActivityLocked(null); 7008 } 7009 } 7010 } 7011 7012 public void wakingUp() { 7013 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7014 != PackageManager.PERMISSION_GRANTED) { 7015 throw new SecurityException("Requires permission " 7016 + android.Manifest.permission.DEVICE_POWER); 7017 } 7018 7019 synchronized(this) { 7020 mWentToSleep = false; 7021 updateEventDispatchingLocked(); 7022 comeOutOfSleepIfNeededLocked(); 7023 } 7024 } 7025 7026 private void updateEventDispatchingLocked() { 7027 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7028 } 7029 7030 public void setLockScreenShown(boolean shown) { 7031 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7032 != PackageManager.PERMISSION_GRANTED) { 7033 throw new SecurityException("Requires permission " 7034 + android.Manifest.permission.DEVICE_POWER); 7035 } 7036 7037 synchronized(this) { 7038 mLockScreenShown = shown; 7039 comeOutOfSleepIfNeededLocked(); 7040 } 7041 } 7042 7043 public void stopAppSwitches() { 7044 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7045 != PackageManager.PERMISSION_GRANTED) { 7046 throw new SecurityException("Requires permission " 7047 + android.Manifest.permission.STOP_APP_SWITCHES); 7048 } 7049 7050 synchronized(this) { 7051 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7052 + APP_SWITCH_DELAY_TIME; 7053 mDidAppSwitch = false; 7054 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7055 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7056 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7057 } 7058 } 7059 7060 public void resumeAppSwitches() { 7061 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7062 != PackageManager.PERMISSION_GRANTED) { 7063 throw new SecurityException("Requires permission " 7064 + android.Manifest.permission.STOP_APP_SWITCHES); 7065 } 7066 7067 synchronized(this) { 7068 // Note that we don't execute any pending app switches... we will 7069 // let those wait until either the timeout, or the next start 7070 // activity request. 7071 mAppSwitchesAllowedTime = 0; 7072 } 7073 } 7074 7075 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7076 String name) { 7077 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7078 return true; 7079 } 7080 7081 final int perm = checkComponentPermission( 7082 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7083 callingUid, -1, true); 7084 if (perm == PackageManager.PERMISSION_GRANTED) { 7085 return true; 7086 } 7087 7088 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7089 return false; 7090 } 7091 7092 public void setDebugApp(String packageName, boolean waitForDebugger, 7093 boolean persistent) { 7094 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7095 "setDebugApp()"); 7096 7097 // Note that this is not really thread safe if there are multiple 7098 // callers into it at the same time, but that's not a situation we 7099 // care about. 7100 if (persistent) { 7101 final ContentResolver resolver = mContext.getContentResolver(); 7102 Settings.System.putString( 7103 resolver, Settings.System.DEBUG_APP, 7104 packageName); 7105 Settings.System.putInt( 7106 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7107 waitForDebugger ? 1 : 0); 7108 } 7109 7110 synchronized (this) { 7111 if (!persistent) { 7112 mOrigDebugApp = mDebugApp; 7113 mOrigWaitForDebugger = mWaitForDebugger; 7114 } 7115 mDebugApp = packageName; 7116 mWaitForDebugger = waitForDebugger; 7117 mDebugTransient = !persistent; 7118 if (packageName != null) { 7119 final long origId = Binder.clearCallingIdentity(); 7120 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7121 Binder.restoreCallingIdentity(origId); 7122 } 7123 } 7124 } 7125 7126 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7127 synchronized (this) { 7128 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7129 if (!isDebuggable) { 7130 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7131 throw new SecurityException("Process not debuggable: " + app.packageName); 7132 } 7133 } 7134 7135 mOpenGlTraceApp = processName; 7136 } 7137 } 7138 7139 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7140 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7141 synchronized (this) { 7142 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7143 if (!isDebuggable) { 7144 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7145 throw new SecurityException("Process not debuggable: " + app.packageName); 7146 } 7147 } 7148 mProfileApp = processName; 7149 mProfileFile = profileFile; 7150 if (mProfileFd != null) { 7151 try { 7152 mProfileFd.close(); 7153 } catch (IOException e) { 7154 } 7155 mProfileFd = null; 7156 } 7157 mProfileFd = profileFd; 7158 mProfileType = 0; 7159 mAutoStopProfiler = autoStopProfiler; 7160 } 7161 } 7162 7163 public void setAlwaysFinish(boolean enabled) { 7164 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7165 "setAlwaysFinish()"); 7166 7167 Settings.System.putInt( 7168 mContext.getContentResolver(), 7169 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7170 7171 synchronized (this) { 7172 mAlwaysFinishActivities = enabled; 7173 } 7174 } 7175 7176 public void setActivityController(IActivityController controller) { 7177 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7178 "setActivityController()"); 7179 synchronized (this) { 7180 mController = controller; 7181 } 7182 } 7183 7184 public boolean isUserAMonkey() { 7185 // For now the fact that there is a controller implies 7186 // we have a monkey. 7187 synchronized (this) { 7188 return mController != null; 7189 } 7190 } 7191 7192 public void registerProcessObserver(IProcessObserver observer) { 7193 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7194 "registerProcessObserver()"); 7195 synchronized (this) { 7196 mProcessObservers.register(observer); 7197 } 7198 } 7199 7200 public void unregisterProcessObserver(IProcessObserver observer) { 7201 synchronized (this) { 7202 mProcessObservers.unregister(observer); 7203 } 7204 } 7205 7206 public void setImmersive(IBinder token, boolean immersive) { 7207 synchronized(this) { 7208 ActivityRecord r = mMainStack.isInStackLocked(token); 7209 if (r == null) { 7210 throw new IllegalArgumentException(); 7211 } 7212 r.immersive = immersive; 7213 } 7214 } 7215 7216 public boolean isImmersive(IBinder token) { 7217 synchronized (this) { 7218 ActivityRecord r = mMainStack.isInStackLocked(token); 7219 if (r == null) { 7220 throw new IllegalArgumentException(); 7221 } 7222 return r.immersive; 7223 } 7224 } 7225 7226 public boolean isTopActivityImmersive() { 7227 enforceNotIsolatedCaller("startActivity"); 7228 synchronized (this) { 7229 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7230 return (r != null) ? r.immersive : false; 7231 } 7232 } 7233 7234 public final void enterSafeMode() { 7235 synchronized(this) { 7236 // It only makes sense to do this before the system is ready 7237 // and started launching other packages. 7238 if (!mSystemReady) { 7239 try { 7240 AppGlobals.getPackageManager().enterSafeMode(); 7241 } catch (RemoteException e) { 7242 } 7243 } 7244 } 7245 } 7246 7247 public final void showSafeModeOverlay() { 7248 View v = LayoutInflater.from(mContext).inflate( 7249 com.android.internal.R.layout.safe_mode, null); 7250 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7251 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7252 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7253 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7254 lp.gravity = Gravity.BOTTOM | Gravity.START; 7255 lp.format = v.getBackground().getOpacity(); 7256 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7257 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7258 ((WindowManager)mContext.getSystemService( 7259 Context.WINDOW_SERVICE)).addView(v, lp); 7260 } 7261 7262 public void noteWakeupAlarm(IIntentSender sender) { 7263 if (!(sender instanceof PendingIntentRecord)) { 7264 return; 7265 } 7266 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7267 synchronized (stats) { 7268 if (mBatteryStatsService.isOnBattery()) { 7269 mBatteryStatsService.enforceCallingPermission(); 7270 PendingIntentRecord rec = (PendingIntentRecord)sender; 7271 int MY_UID = Binder.getCallingUid(); 7272 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7273 BatteryStatsImpl.Uid.Pkg pkg = 7274 stats.getPackageStatsLocked(uid, rec.key.packageName); 7275 pkg.incWakeupsLocked(); 7276 } 7277 } 7278 } 7279 7280 public boolean killPids(int[] pids, String pReason, boolean secure) { 7281 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7282 throw new SecurityException("killPids only available to the system"); 7283 } 7284 String reason = (pReason == null) ? "Unknown" : pReason; 7285 // XXX Note: don't acquire main activity lock here, because the window 7286 // manager calls in with its locks held. 7287 7288 boolean killed = false; 7289 synchronized (mPidsSelfLocked) { 7290 int[] types = new int[pids.length]; 7291 int worstType = 0; 7292 for (int i=0; i<pids.length; i++) { 7293 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7294 if (proc != null) { 7295 int type = proc.setAdj; 7296 types[i] = type; 7297 if (type > worstType) { 7298 worstType = type; 7299 } 7300 } 7301 } 7302 7303 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7304 // then constrain it so we will kill all hidden procs. 7305 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7306 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7307 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7308 } 7309 7310 // If this is not a secure call, don't let it kill processes that 7311 // are important. 7312 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7313 worstType = ProcessList.SERVICE_ADJ; 7314 } 7315 7316 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7317 for (int i=0; i<pids.length; i++) { 7318 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7319 if (proc == null) { 7320 continue; 7321 } 7322 int adj = proc.setAdj; 7323 if (adj >= worstType && !proc.killedBackground) { 7324 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7325 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7326 proc.processName, adj, reason); 7327 killed = true; 7328 proc.killedBackground = true; 7329 Process.killProcessQuiet(pids[i]); 7330 } 7331 } 7332 } 7333 return killed; 7334 } 7335 7336 @Override 7337 public boolean killProcessesBelowForeground(String reason) { 7338 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7339 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7340 } 7341 7342 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7343 } 7344 7345 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7346 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7347 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7348 } 7349 7350 boolean killed = false; 7351 synchronized (mPidsSelfLocked) { 7352 final int size = mPidsSelfLocked.size(); 7353 for (int i = 0; i < size; i++) { 7354 final int pid = mPidsSelfLocked.keyAt(i); 7355 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7356 if (proc == null) continue; 7357 7358 final int adj = proc.setAdj; 7359 if (adj > belowAdj && !proc.killedBackground) { 7360 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7361 EventLog.writeEvent( 7362 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7363 killed = true; 7364 proc.killedBackground = true; 7365 Process.killProcessQuiet(pid); 7366 } 7367 } 7368 } 7369 return killed; 7370 } 7371 7372 public final void startRunning(String pkg, String cls, String action, 7373 String data) { 7374 synchronized(this) { 7375 if (mStartRunning) { 7376 return; 7377 } 7378 mStartRunning = true; 7379 mTopComponent = pkg != null && cls != null 7380 ? new ComponentName(pkg, cls) : null; 7381 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7382 mTopData = data; 7383 if (!mSystemReady) { 7384 return; 7385 } 7386 } 7387 7388 systemReady(null); 7389 } 7390 7391 private void retrieveSettings() { 7392 final ContentResolver resolver = mContext.getContentResolver(); 7393 String debugApp = Settings.System.getString( 7394 resolver, Settings.System.DEBUG_APP); 7395 boolean waitForDebugger = Settings.System.getInt( 7396 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7397 boolean alwaysFinishActivities = Settings.System.getInt( 7398 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7399 7400 Configuration configuration = new Configuration(); 7401 Settings.System.getConfiguration(resolver, configuration); 7402 7403 synchronized (this) { 7404 mDebugApp = mOrigDebugApp = debugApp; 7405 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7406 mAlwaysFinishActivities = alwaysFinishActivities; 7407 // This happens before any activities are started, so we can 7408 // change mConfiguration in-place. 7409 updateConfigurationLocked(configuration, null, false, true); 7410 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7411 } 7412 } 7413 7414 public boolean testIsSystemReady() { 7415 // no need to synchronize(this) just to read & return the value 7416 return mSystemReady; 7417 } 7418 7419 private static File getCalledPreBootReceiversFile() { 7420 File dataDir = Environment.getDataDirectory(); 7421 File systemDir = new File(dataDir, "system"); 7422 File fname = new File(systemDir, "called_pre_boots.dat"); 7423 return fname; 7424 } 7425 7426 static final int LAST_DONE_VERSION = 10000; 7427 7428 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7429 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7430 File file = getCalledPreBootReceiversFile(); 7431 FileInputStream fis = null; 7432 try { 7433 fis = new FileInputStream(file); 7434 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7435 int fvers = dis.readInt(); 7436 if (fvers == LAST_DONE_VERSION) { 7437 String vers = dis.readUTF(); 7438 String codename = dis.readUTF(); 7439 String build = dis.readUTF(); 7440 if (android.os.Build.VERSION.RELEASE.equals(vers) 7441 && android.os.Build.VERSION.CODENAME.equals(codename) 7442 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7443 int num = dis.readInt(); 7444 while (num > 0) { 7445 num--; 7446 String pkg = dis.readUTF(); 7447 String cls = dis.readUTF(); 7448 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7449 } 7450 } 7451 } 7452 } catch (FileNotFoundException e) { 7453 } catch (IOException e) { 7454 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7455 } finally { 7456 if (fis != null) { 7457 try { 7458 fis.close(); 7459 } catch (IOException e) { 7460 } 7461 } 7462 } 7463 return lastDoneReceivers; 7464 } 7465 7466 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7467 File file = getCalledPreBootReceiversFile(); 7468 FileOutputStream fos = null; 7469 DataOutputStream dos = null; 7470 try { 7471 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7472 fos = new FileOutputStream(file); 7473 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7474 dos.writeInt(LAST_DONE_VERSION); 7475 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7476 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7477 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7478 dos.writeInt(list.size()); 7479 for (int i=0; i<list.size(); i++) { 7480 dos.writeUTF(list.get(i).getPackageName()); 7481 dos.writeUTF(list.get(i).getClassName()); 7482 } 7483 } catch (IOException e) { 7484 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7485 file.delete(); 7486 } finally { 7487 FileUtils.sync(fos); 7488 if (dos != null) { 7489 try { 7490 dos.close(); 7491 } catch (IOException e) { 7492 // TODO Auto-generated catch block 7493 e.printStackTrace(); 7494 } 7495 } 7496 } 7497 } 7498 7499 public void systemReady(final Runnable goingCallback) { 7500 synchronized(this) { 7501 if (mSystemReady) { 7502 if (goingCallback != null) goingCallback.run(); 7503 return; 7504 } 7505 7506 // Check to see if there are any update receivers to run. 7507 if (!mDidUpdate) { 7508 if (mWaitingUpdate) { 7509 return; 7510 } 7511 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7512 List<ResolveInfo> ris = null; 7513 try { 7514 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7515 intent, null, 0, 0); 7516 } catch (RemoteException e) { 7517 } 7518 if (ris != null) { 7519 for (int i=ris.size()-1; i>=0; i--) { 7520 if ((ris.get(i).activityInfo.applicationInfo.flags 7521 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7522 ris.remove(i); 7523 } 7524 } 7525 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7526 7527 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7528 7529 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7530 for (int i=0; i<ris.size(); i++) { 7531 ActivityInfo ai = ris.get(i).activityInfo; 7532 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7533 if (lastDoneReceivers.contains(comp)) { 7534 ris.remove(i); 7535 i--; 7536 } 7537 } 7538 7539 for (int i=0; i<ris.size(); i++) { 7540 ActivityInfo ai = ris.get(i).activityInfo; 7541 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7542 doneReceivers.add(comp); 7543 intent.setComponent(comp); 7544 IIntentReceiver finisher = null; 7545 if (i == ris.size()-1) { 7546 finisher = new IIntentReceiver.Stub() { 7547 public void performReceive(Intent intent, int resultCode, 7548 String data, Bundle extras, boolean ordered, 7549 boolean sticky) { 7550 // The raw IIntentReceiver interface is called 7551 // with the AM lock held, so redispatch to 7552 // execute our code without the lock. 7553 mHandler.post(new Runnable() { 7554 public void run() { 7555 synchronized (ActivityManagerService.this) { 7556 mDidUpdate = true; 7557 } 7558 writeLastDonePreBootReceivers(doneReceivers); 7559 showBootMessage(mContext.getText( 7560 R.string.android_upgrading_complete), 7561 false); 7562 systemReady(goingCallback); 7563 } 7564 }); 7565 } 7566 }; 7567 } 7568 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7569 /* TODO: Send this to all users */ 7570 broadcastIntentLocked(null, null, intent, null, finisher, 7571 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7572 0 /* UserId zero */); 7573 if (finisher != null) { 7574 mWaitingUpdate = true; 7575 } 7576 } 7577 } 7578 if (mWaitingUpdate) { 7579 return; 7580 } 7581 mDidUpdate = true; 7582 } 7583 7584 mSystemReady = true; 7585 if (!mStartRunning) { 7586 return; 7587 } 7588 } 7589 7590 ArrayList<ProcessRecord> procsToKill = null; 7591 synchronized(mPidsSelfLocked) { 7592 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7593 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7594 if (!isAllowedWhileBooting(proc.info)){ 7595 if (procsToKill == null) { 7596 procsToKill = new ArrayList<ProcessRecord>(); 7597 } 7598 procsToKill.add(proc); 7599 } 7600 } 7601 } 7602 7603 synchronized(this) { 7604 if (procsToKill != null) { 7605 for (int i=procsToKill.size()-1; i>=0; i--) { 7606 ProcessRecord proc = procsToKill.get(i); 7607 Slog.i(TAG, "Removing system update proc: " + proc); 7608 removeProcessLocked(proc, true, false, "system update done"); 7609 } 7610 } 7611 7612 // Now that we have cleaned up any update processes, we 7613 // are ready to start launching real processes and know that 7614 // we won't trample on them any more. 7615 mProcessesReady = true; 7616 } 7617 7618 Slog.i(TAG, "System now ready"); 7619 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7620 SystemClock.uptimeMillis()); 7621 7622 synchronized(this) { 7623 // Make sure we have no pre-ready processes sitting around. 7624 7625 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7626 ResolveInfo ri = mContext.getPackageManager() 7627 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7628 STOCK_PM_FLAGS); 7629 CharSequence errorMsg = null; 7630 if (ri != null) { 7631 ActivityInfo ai = ri.activityInfo; 7632 ApplicationInfo app = ai.applicationInfo; 7633 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7634 mTopAction = Intent.ACTION_FACTORY_TEST; 7635 mTopData = null; 7636 mTopComponent = new ComponentName(app.packageName, 7637 ai.name); 7638 } else { 7639 errorMsg = mContext.getResources().getText( 7640 com.android.internal.R.string.factorytest_not_system); 7641 } 7642 } else { 7643 errorMsg = mContext.getResources().getText( 7644 com.android.internal.R.string.factorytest_no_action); 7645 } 7646 if (errorMsg != null) { 7647 mTopAction = null; 7648 mTopData = null; 7649 mTopComponent = null; 7650 Message msg = Message.obtain(); 7651 msg.what = SHOW_FACTORY_ERROR_MSG; 7652 msg.getData().putCharSequence("msg", errorMsg); 7653 mHandler.sendMessage(msg); 7654 } 7655 } 7656 } 7657 7658 retrieveSettings(); 7659 7660 if (goingCallback != null) goingCallback.run(); 7661 7662 synchronized (this) { 7663 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7664 try { 7665 List apps = AppGlobals.getPackageManager(). 7666 getPersistentApplications(STOCK_PM_FLAGS); 7667 if (apps != null) { 7668 int N = apps.size(); 7669 int i; 7670 for (i=0; i<N; i++) { 7671 ApplicationInfo info 7672 = (ApplicationInfo)apps.get(i); 7673 if (info != null && 7674 !info.packageName.equals("android")) { 7675 addAppLocked(info, false); 7676 } 7677 } 7678 } 7679 } catch (RemoteException ex) { 7680 // pm is in same process, this will never happen. 7681 } 7682 } 7683 7684 // Start up initial activity. 7685 mBooting = true; 7686 7687 try { 7688 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7689 Message msg = Message.obtain(); 7690 msg.what = SHOW_UID_ERROR_MSG; 7691 mHandler.sendMessage(msg); 7692 } 7693 } catch (RemoteException e) { 7694 } 7695 7696 mMainStack.resumeTopActivityLocked(null); 7697 } 7698 } 7699 7700 private boolean makeAppCrashingLocked(ProcessRecord app, 7701 String shortMsg, String longMsg, String stackTrace) { 7702 app.crashing = true; 7703 app.crashingReport = generateProcessError(app, 7704 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7705 startAppProblemLocked(app); 7706 app.stopFreezingAllLocked(); 7707 return handleAppCrashLocked(app); 7708 } 7709 7710 private void makeAppNotRespondingLocked(ProcessRecord app, 7711 String activity, String shortMsg, String longMsg) { 7712 app.notResponding = true; 7713 app.notRespondingReport = generateProcessError(app, 7714 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7715 activity, shortMsg, longMsg, null); 7716 startAppProblemLocked(app); 7717 app.stopFreezingAllLocked(); 7718 } 7719 7720 /** 7721 * Generate a process error record, suitable for attachment to a ProcessRecord. 7722 * 7723 * @param app The ProcessRecord in which the error occurred. 7724 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7725 * ActivityManager.AppErrorStateInfo 7726 * @param activity The activity associated with the crash, if known. 7727 * @param shortMsg Short message describing the crash. 7728 * @param longMsg Long message describing the crash. 7729 * @param stackTrace Full crash stack trace, may be null. 7730 * 7731 * @return Returns a fully-formed AppErrorStateInfo record. 7732 */ 7733 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7734 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7735 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7736 7737 report.condition = condition; 7738 report.processName = app.processName; 7739 report.pid = app.pid; 7740 report.uid = app.info.uid; 7741 report.tag = activity; 7742 report.shortMsg = shortMsg; 7743 report.longMsg = longMsg; 7744 report.stackTrace = stackTrace; 7745 7746 return report; 7747 } 7748 7749 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7750 synchronized (this) { 7751 app.crashing = false; 7752 app.crashingReport = null; 7753 app.notResponding = false; 7754 app.notRespondingReport = null; 7755 if (app.anrDialog == fromDialog) { 7756 app.anrDialog = null; 7757 } 7758 if (app.waitDialog == fromDialog) { 7759 app.waitDialog = null; 7760 } 7761 if (app.pid > 0 && app.pid != MY_PID) { 7762 handleAppCrashLocked(app); 7763 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7764 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7765 app.processName, app.setAdj, "user's request after error"); 7766 Process.killProcessQuiet(app.pid); 7767 } 7768 } 7769 } 7770 7771 private boolean handleAppCrashLocked(ProcessRecord app) { 7772 if (mHeadless) { 7773 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7774 return false; 7775 } 7776 long now = SystemClock.uptimeMillis(); 7777 7778 Long crashTime; 7779 if (!app.isolated) { 7780 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7781 } else { 7782 crashTime = null; 7783 } 7784 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7785 // This process loses! 7786 Slog.w(TAG, "Process " + app.info.processName 7787 + " has crashed too many times: killing!"); 7788 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7789 app.info.processName, app.uid); 7790 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7791 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7792 if (r.app == app) { 7793 Slog.w(TAG, " Force finishing activity " 7794 + r.intent.getComponent().flattenToShortString()); 7795 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7796 } 7797 } 7798 if (!app.persistent) { 7799 // We don't want to start this process again until the user 7800 // explicitly does so... but for persistent process, we really 7801 // need to keep it running. If a persistent process is actually 7802 // repeatedly crashing, then badness for everyone. 7803 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7804 app.info.processName); 7805 if (!app.isolated) { 7806 // XXX We don't have a way to mark isolated processes 7807 // as bad, since they don't have a peristent identity. 7808 mBadProcesses.put(app.info.processName, app.uid, now); 7809 mProcessCrashTimes.remove(app.info.processName, app.uid); 7810 } 7811 app.bad = true; 7812 app.removed = true; 7813 // Don't let services in this process be restarted and potentially 7814 // annoy the user repeatedly. Unless it is persistent, since those 7815 // processes run critical code. 7816 removeProcessLocked(app, false, false, "crash"); 7817 mMainStack.resumeTopActivityLocked(null); 7818 return false; 7819 } 7820 mMainStack.resumeTopActivityLocked(null); 7821 } else { 7822 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7823 if (r != null && r.app == app) { 7824 // If the top running activity is from this crashing 7825 // process, then terminate it to avoid getting in a loop. 7826 Slog.w(TAG, " Force finishing activity " 7827 + r.intent.getComponent().flattenToShortString()); 7828 int index = mMainStack.indexOfActivityLocked(r); 7829 r.stack.finishActivityLocked(r, index, 7830 Activity.RESULT_CANCELED, null, "crashed"); 7831 // Also terminate any activities below it that aren't yet 7832 // stopped, to avoid a situation where one will get 7833 // re-start our crashing activity once it gets resumed again. 7834 index--; 7835 if (index >= 0) { 7836 r = (ActivityRecord)mMainStack.mHistory.get(index); 7837 if (r.state == ActivityState.RESUMED 7838 || r.state == ActivityState.PAUSING 7839 || r.state == ActivityState.PAUSED) { 7840 if (!r.isHomeActivity || mHomeProcess != r.app) { 7841 Slog.w(TAG, " Force finishing activity " 7842 + r.intent.getComponent().flattenToShortString()); 7843 r.stack.finishActivityLocked(r, index, 7844 Activity.RESULT_CANCELED, null, "crashed"); 7845 } 7846 } 7847 } 7848 } 7849 } 7850 7851 // Bump up the crash count of any services currently running in the proc. 7852 if (app.services.size() != 0) { 7853 // Any services running in the application need to be placed 7854 // back in the pending list. 7855 Iterator<ServiceRecord> it = app.services.iterator(); 7856 while (it.hasNext()) { 7857 ServiceRecord sr = it.next(); 7858 sr.crashCount++; 7859 } 7860 } 7861 7862 // If the crashing process is what we consider to be the "home process" and it has been 7863 // replaced by a third-party app, clear the package preferred activities from packages 7864 // with a home activity running in the process to prevent a repeatedly crashing app 7865 // from blocking the user to manually clear the list. 7866 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7867 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7868 Iterator it = mHomeProcess.activities.iterator(); 7869 while (it.hasNext()) { 7870 ActivityRecord r = (ActivityRecord)it.next(); 7871 if (r.isHomeActivity) { 7872 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7873 try { 7874 ActivityThread.getPackageManager() 7875 .clearPackagePreferredActivities(r.packageName); 7876 } catch (RemoteException c) { 7877 // pm is in same process, this will never happen. 7878 } 7879 } 7880 } 7881 } 7882 7883 if (!app.isolated) { 7884 // XXX Can't keep track of crash times for isolated processes, 7885 // because they don't have a perisistent identity. 7886 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7887 } 7888 7889 return true; 7890 } 7891 7892 void startAppProblemLocked(ProcessRecord app) { 7893 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7894 mContext, app.info.packageName, app.info.flags); 7895 skipCurrentReceiverLocked(app); 7896 } 7897 7898 void skipCurrentReceiverLocked(ProcessRecord app) { 7899 for (BroadcastQueue queue : mBroadcastQueues) { 7900 queue.skipCurrentReceiverLocked(app); 7901 } 7902 } 7903 7904 /** 7905 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7906 * The application process will exit immediately after this call returns. 7907 * @param app object of the crashing app, null for the system server 7908 * @param crashInfo describing the exception 7909 */ 7910 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7911 ProcessRecord r = findAppProcess(app, "Crash"); 7912 final String processName = app == null ? "system_server" 7913 : (r == null ? "unknown" : r.processName); 7914 7915 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7916 processName, 7917 r == null ? -1 : r.info.flags, 7918 crashInfo.exceptionClassName, 7919 crashInfo.exceptionMessage, 7920 crashInfo.throwFileName, 7921 crashInfo.throwLineNumber); 7922 7923 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7924 7925 crashApplication(r, crashInfo); 7926 } 7927 7928 public void handleApplicationStrictModeViolation( 7929 IBinder app, 7930 int violationMask, 7931 StrictMode.ViolationInfo info) { 7932 ProcessRecord r = findAppProcess(app, "StrictMode"); 7933 if (r == null) { 7934 return; 7935 } 7936 7937 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7938 Integer stackFingerprint = info.hashCode(); 7939 boolean logIt = true; 7940 synchronized (mAlreadyLoggedViolatedStacks) { 7941 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7942 logIt = false; 7943 // TODO: sub-sample into EventLog for these, with 7944 // the info.durationMillis? Then we'd get 7945 // the relative pain numbers, without logging all 7946 // the stack traces repeatedly. We'd want to do 7947 // likewise in the client code, which also does 7948 // dup suppression, before the Binder call. 7949 } else { 7950 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7951 mAlreadyLoggedViolatedStacks.clear(); 7952 } 7953 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7954 } 7955 } 7956 if (logIt) { 7957 logStrictModeViolationToDropBox(r, info); 7958 } 7959 } 7960 7961 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7962 AppErrorResult result = new AppErrorResult(); 7963 synchronized (this) { 7964 final long origId = Binder.clearCallingIdentity(); 7965 7966 Message msg = Message.obtain(); 7967 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7968 HashMap<String, Object> data = new HashMap<String, Object>(); 7969 data.put("result", result); 7970 data.put("app", r); 7971 data.put("violationMask", violationMask); 7972 data.put("info", info); 7973 msg.obj = data; 7974 mHandler.sendMessage(msg); 7975 7976 Binder.restoreCallingIdentity(origId); 7977 } 7978 int res = result.get(); 7979 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7980 } 7981 } 7982 7983 // Depending on the policy in effect, there could be a bunch of 7984 // these in quick succession so we try to batch these together to 7985 // minimize disk writes, number of dropbox entries, and maximize 7986 // compression, by having more fewer, larger records. 7987 private void logStrictModeViolationToDropBox( 7988 ProcessRecord process, 7989 StrictMode.ViolationInfo info) { 7990 if (info == null) { 7991 return; 7992 } 7993 final boolean isSystemApp = process == null || 7994 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7995 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7996 final String processName = process == null ? "unknown" : process.processName; 7997 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7998 final DropBoxManager dbox = (DropBoxManager) 7999 mContext.getSystemService(Context.DROPBOX_SERVICE); 8000 8001 // Exit early if the dropbox isn't configured to accept this report type. 8002 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8003 8004 boolean bufferWasEmpty; 8005 boolean needsFlush; 8006 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8007 synchronized (sb) { 8008 bufferWasEmpty = sb.length() == 0; 8009 appendDropBoxProcessHeaders(process, processName, sb); 8010 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8011 sb.append("System-App: ").append(isSystemApp).append("\n"); 8012 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8013 if (info.violationNumThisLoop != 0) { 8014 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8015 } 8016 if (info.numAnimationsRunning != 0) { 8017 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8018 } 8019 if (info.broadcastIntentAction != null) { 8020 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8021 } 8022 if (info.durationMillis != -1) { 8023 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8024 } 8025 if (info.numInstances != -1) { 8026 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8027 } 8028 if (info.tags != null) { 8029 for (String tag : info.tags) { 8030 sb.append("Span-Tag: ").append(tag).append("\n"); 8031 } 8032 } 8033 sb.append("\n"); 8034 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8035 sb.append(info.crashInfo.stackTrace); 8036 } 8037 sb.append("\n"); 8038 8039 // Only buffer up to ~64k. Various logging bits truncate 8040 // things at 128k. 8041 needsFlush = (sb.length() > 64 * 1024); 8042 } 8043 8044 // Flush immediately if the buffer's grown too large, or this 8045 // is a non-system app. Non-system apps are isolated with a 8046 // different tag & policy and not batched. 8047 // 8048 // Batching is useful during internal testing with 8049 // StrictMode settings turned up high. Without batching, 8050 // thousands of separate files could be created on boot. 8051 if (!isSystemApp || needsFlush) { 8052 new Thread("Error dump: " + dropboxTag) { 8053 @Override 8054 public void run() { 8055 String report; 8056 synchronized (sb) { 8057 report = sb.toString(); 8058 sb.delete(0, sb.length()); 8059 sb.trimToSize(); 8060 } 8061 if (report.length() != 0) { 8062 dbox.addText(dropboxTag, report); 8063 } 8064 } 8065 }.start(); 8066 return; 8067 } 8068 8069 // System app batching: 8070 if (!bufferWasEmpty) { 8071 // An existing dropbox-writing thread is outstanding, so 8072 // we don't need to start it up. The existing thread will 8073 // catch the buffer appends we just did. 8074 return; 8075 } 8076 8077 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8078 // (After this point, we shouldn't access AMS internal data structures.) 8079 new Thread("Error dump: " + dropboxTag) { 8080 @Override 8081 public void run() { 8082 // 5 second sleep to let stacks arrive and be batched together 8083 try { 8084 Thread.sleep(5000); // 5 seconds 8085 } catch (InterruptedException e) {} 8086 8087 String errorReport; 8088 synchronized (mStrictModeBuffer) { 8089 errorReport = mStrictModeBuffer.toString(); 8090 if (errorReport.length() == 0) { 8091 return; 8092 } 8093 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8094 mStrictModeBuffer.trimToSize(); 8095 } 8096 dbox.addText(dropboxTag, errorReport); 8097 } 8098 }.start(); 8099 } 8100 8101 /** 8102 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8103 * @param app object of the crashing app, null for the system server 8104 * @param tag reported by the caller 8105 * @param crashInfo describing the context of the error 8106 * @return true if the process should exit immediately (WTF is fatal) 8107 */ 8108 public boolean handleApplicationWtf(IBinder app, String tag, 8109 ApplicationErrorReport.CrashInfo crashInfo) { 8110 ProcessRecord r = findAppProcess(app, "WTF"); 8111 final String processName = app == null ? "system_server" 8112 : (r == null ? "unknown" : r.processName); 8113 8114 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8115 processName, 8116 r == null ? -1 : r.info.flags, 8117 tag, crashInfo.exceptionMessage); 8118 8119 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8120 8121 if (r != null && r.pid != Process.myPid() && 8122 Settings.Secure.getInt(mContext.getContentResolver(), 8123 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8124 crashApplication(r, crashInfo); 8125 return true; 8126 } else { 8127 return false; 8128 } 8129 } 8130 8131 /** 8132 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8133 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8134 */ 8135 private ProcessRecord findAppProcess(IBinder app, String reason) { 8136 if (app == null) { 8137 return null; 8138 } 8139 8140 synchronized (this) { 8141 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8142 final int NA = apps.size(); 8143 for (int ia=0; ia<NA; ia++) { 8144 ProcessRecord p = apps.valueAt(ia); 8145 if (p.thread != null && p.thread.asBinder() == app) { 8146 return p; 8147 } 8148 } 8149 } 8150 8151 Slog.w(TAG, "Can't find mystery application for " + reason 8152 + " from pid=" + Binder.getCallingPid() 8153 + " uid=" + Binder.getCallingUid() + ": " + app); 8154 return null; 8155 } 8156 } 8157 8158 /** 8159 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8160 * to append various headers to the dropbox log text. 8161 */ 8162 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8163 StringBuilder sb) { 8164 // Watchdog thread ends up invoking this function (with 8165 // a null ProcessRecord) to add the stack file to dropbox. 8166 // Do not acquire a lock on this (am) in such cases, as it 8167 // could cause a potential deadlock, if and when watchdog 8168 // is invoked due to unavailability of lock on am and it 8169 // would prevent watchdog from killing system_server. 8170 if (process == null) { 8171 sb.append("Process: ").append(processName).append("\n"); 8172 return; 8173 } 8174 // Note: ProcessRecord 'process' is guarded by the service 8175 // instance. (notably process.pkgList, which could otherwise change 8176 // concurrently during execution of this method) 8177 synchronized (this) { 8178 sb.append("Process: ").append(processName).append("\n"); 8179 int flags = process.info.flags; 8180 IPackageManager pm = AppGlobals.getPackageManager(); 8181 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8182 for (String pkg : process.pkgList) { 8183 sb.append("Package: ").append(pkg); 8184 try { 8185 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8186 if (pi != null) { 8187 sb.append(" v").append(pi.versionCode); 8188 if (pi.versionName != null) { 8189 sb.append(" (").append(pi.versionName).append(")"); 8190 } 8191 } 8192 } catch (RemoteException e) { 8193 Slog.e(TAG, "Error getting package info: " + pkg, e); 8194 } 8195 sb.append("\n"); 8196 } 8197 } 8198 } 8199 8200 private static String processClass(ProcessRecord process) { 8201 if (process == null || process.pid == MY_PID) { 8202 return "system_server"; 8203 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8204 return "system_app"; 8205 } else { 8206 return "data_app"; 8207 } 8208 } 8209 8210 /** 8211 * Write a description of an error (crash, WTF, ANR) to the drop box. 8212 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8213 * @param process which caused the error, null means the system server 8214 * @param activity which triggered the error, null if unknown 8215 * @param parent activity related to the error, null if unknown 8216 * @param subject line related to the error, null if absent 8217 * @param report in long form describing the error, null if absent 8218 * @param logFile to include in the report, null if none 8219 * @param crashInfo giving an application stack trace, null if absent 8220 */ 8221 public void addErrorToDropBox(String eventType, 8222 ProcessRecord process, String processName, ActivityRecord activity, 8223 ActivityRecord parent, String subject, 8224 final String report, final File logFile, 8225 final ApplicationErrorReport.CrashInfo crashInfo) { 8226 // NOTE -- this must never acquire the ActivityManagerService lock, 8227 // otherwise the watchdog may be prevented from resetting the system. 8228 8229 final String dropboxTag = processClass(process) + "_" + eventType; 8230 final DropBoxManager dbox = (DropBoxManager) 8231 mContext.getSystemService(Context.DROPBOX_SERVICE); 8232 8233 // Exit early if the dropbox isn't configured to accept this report type. 8234 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8235 8236 final StringBuilder sb = new StringBuilder(1024); 8237 appendDropBoxProcessHeaders(process, processName, sb); 8238 if (activity != null) { 8239 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8240 } 8241 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8242 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8243 } 8244 if (parent != null && parent != activity) { 8245 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8246 } 8247 if (subject != null) { 8248 sb.append("Subject: ").append(subject).append("\n"); 8249 } 8250 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8251 if (Debug.isDebuggerConnected()) { 8252 sb.append("Debugger: Connected\n"); 8253 } 8254 sb.append("\n"); 8255 8256 // Do the rest in a worker thread to avoid blocking the caller on I/O 8257 // (After this point, we shouldn't access AMS internal data structures.) 8258 Thread worker = new Thread("Error dump: " + dropboxTag) { 8259 @Override 8260 public void run() { 8261 if (report != null) { 8262 sb.append(report); 8263 } 8264 if (logFile != null) { 8265 try { 8266 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8267 } catch (IOException e) { 8268 Slog.e(TAG, "Error reading " + logFile, e); 8269 } 8270 } 8271 if (crashInfo != null && crashInfo.stackTrace != null) { 8272 sb.append(crashInfo.stackTrace); 8273 } 8274 8275 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8276 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8277 if (lines > 0) { 8278 sb.append("\n"); 8279 8280 // Merge several logcat streams, and take the last N lines 8281 InputStreamReader input = null; 8282 try { 8283 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8284 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8285 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8286 8287 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8288 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8289 input = new InputStreamReader(logcat.getInputStream()); 8290 8291 int num; 8292 char[] buf = new char[8192]; 8293 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8294 } catch (IOException e) { 8295 Slog.e(TAG, "Error running logcat", e); 8296 } finally { 8297 if (input != null) try { input.close(); } catch (IOException e) {} 8298 } 8299 } 8300 8301 dbox.addText(dropboxTag, sb.toString()); 8302 } 8303 }; 8304 8305 if (process == null) { 8306 // If process is null, we are being called from some internal code 8307 // and may be about to die -- run this synchronously. 8308 worker.run(); 8309 } else { 8310 worker.start(); 8311 } 8312 } 8313 8314 /** 8315 * Bring up the "unexpected error" dialog box for a crashing app. 8316 * Deal with edge cases (intercepts from instrumented applications, 8317 * ActivityController, error intent receivers, that sort of thing). 8318 * @param r the application crashing 8319 * @param crashInfo describing the failure 8320 */ 8321 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8322 long timeMillis = System.currentTimeMillis(); 8323 String shortMsg = crashInfo.exceptionClassName; 8324 String longMsg = crashInfo.exceptionMessage; 8325 String stackTrace = crashInfo.stackTrace; 8326 if (shortMsg != null && longMsg != null) { 8327 longMsg = shortMsg + ": " + longMsg; 8328 } else if (shortMsg != null) { 8329 longMsg = shortMsg; 8330 } 8331 8332 AppErrorResult result = new AppErrorResult(); 8333 synchronized (this) { 8334 if (mController != null) { 8335 try { 8336 String name = r != null ? r.processName : null; 8337 int pid = r != null ? r.pid : Binder.getCallingPid(); 8338 if (!mController.appCrashed(name, pid, 8339 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8340 Slog.w(TAG, "Force-killing crashed app " + name 8341 + " at watcher's request"); 8342 Process.killProcess(pid); 8343 return; 8344 } 8345 } catch (RemoteException e) { 8346 mController = null; 8347 } 8348 } 8349 8350 final long origId = Binder.clearCallingIdentity(); 8351 8352 // If this process is running instrumentation, finish it. 8353 if (r != null && r.instrumentationClass != null) { 8354 Slog.w(TAG, "Error in app " + r.processName 8355 + " running instrumentation " + r.instrumentationClass + ":"); 8356 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8357 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8358 Bundle info = new Bundle(); 8359 info.putString("shortMsg", shortMsg); 8360 info.putString("longMsg", longMsg); 8361 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8362 Binder.restoreCallingIdentity(origId); 8363 return; 8364 } 8365 8366 // If we can't identify the process or it's already exceeded its crash quota, 8367 // quit right away without showing a crash dialog. 8368 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8369 Binder.restoreCallingIdentity(origId); 8370 return; 8371 } 8372 8373 Message msg = Message.obtain(); 8374 msg.what = SHOW_ERROR_MSG; 8375 HashMap data = new HashMap(); 8376 data.put("result", result); 8377 data.put("app", r); 8378 msg.obj = data; 8379 mHandler.sendMessage(msg); 8380 8381 Binder.restoreCallingIdentity(origId); 8382 } 8383 8384 int res = result.get(); 8385 8386 Intent appErrorIntent = null; 8387 synchronized (this) { 8388 if (r != null && !r.isolated) { 8389 // XXX Can't keep track of crash time for isolated processes, 8390 // since they don't have a persistent identity. 8391 mProcessCrashTimes.put(r.info.processName, r.uid, 8392 SystemClock.uptimeMillis()); 8393 } 8394 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8395 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8396 } 8397 } 8398 8399 if (appErrorIntent != null) { 8400 try { 8401 mContext.startActivity(appErrorIntent); 8402 } catch (ActivityNotFoundException e) { 8403 Slog.w(TAG, "bug report receiver dissappeared", e); 8404 } 8405 } 8406 } 8407 8408 Intent createAppErrorIntentLocked(ProcessRecord r, 8409 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8410 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8411 if (report == null) { 8412 return null; 8413 } 8414 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8415 result.setComponent(r.errorReportReceiver); 8416 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8417 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8418 return result; 8419 } 8420 8421 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8422 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8423 if (r.errorReportReceiver == null) { 8424 return null; 8425 } 8426 8427 if (!r.crashing && !r.notResponding) { 8428 return null; 8429 } 8430 8431 ApplicationErrorReport report = new ApplicationErrorReport(); 8432 report.packageName = r.info.packageName; 8433 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8434 report.processName = r.processName; 8435 report.time = timeMillis; 8436 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8437 8438 if (r.crashing) { 8439 report.type = ApplicationErrorReport.TYPE_CRASH; 8440 report.crashInfo = crashInfo; 8441 } else if (r.notResponding) { 8442 report.type = ApplicationErrorReport.TYPE_ANR; 8443 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8444 8445 report.anrInfo.activity = r.notRespondingReport.tag; 8446 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8447 report.anrInfo.info = r.notRespondingReport.longMsg; 8448 } 8449 8450 return report; 8451 } 8452 8453 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8454 enforceNotIsolatedCaller("getProcessesInErrorState"); 8455 // assume our apps are happy - lazy create the list 8456 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8457 8458 final boolean allUsers = ActivityManager.checkUidPermission( 8459 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8460 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8461 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8462 8463 synchronized (this) { 8464 8465 // iterate across all processes 8466 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8467 ProcessRecord app = mLruProcesses.get(i); 8468 if (!allUsers && app.userId != userId) { 8469 continue; 8470 } 8471 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8472 // This one's in trouble, so we'll generate a report for it 8473 // crashes are higher priority (in case there's a crash *and* an anr) 8474 ActivityManager.ProcessErrorStateInfo report = null; 8475 if (app.crashing) { 8476 report = app.crashingReport; 8477 } else if (app.notResponding) { 8478 report = app.notRespondingReport; 8479 } 8480 8481 if (report != null) { 8482 if (errList == null) { 8483 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8484 } 8485 errList.add(report); 8486 } else { 8487 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8488 " crashing = " + app.crashing + 8489 " notResponding = " + app.notResponding); 8490 } 8491 } 8492 } 8493 } 8494 8495 return errList; 8496 } 8497 8498 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8499 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8500 if (currApp != null) { 8501 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8502 } 8503 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8504 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8505 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8506 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8507 if (currApp != null) { 8508 currApp.lru = 0; 8509 } 8510 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8511 } else if (adj >= ProcessList.SERVICE_ADJ) { 8512 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8513 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8514 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8515 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8516 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8517 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8518 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8519 } else { 8520 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8521 } 8522 } 8523 8524 private void fillInProcMemInfo(ProcessRecord app, 8525 ActivityManager.RunningAppProcessInfo outInfo) { 8526 outInfo.pid = app.pid; 8527 outInfo.uid = app.info.uid; 8528 if (mHeavyWeightProcess == app) { 8529 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8530 } 8531 if (app.persistent) { 8532 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8533 } 8534 if (app.hasActivities) { 8535 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8536 } 8537 outInfo.lastTrimLevel = app.trimMemoryLevel; 8538 int adj = app.curAdj; 8539 outInfo.importance = oomAdjToImportance(adj, outInfo); 8540 outInfo.importanceReasonCode = app.adjTypeCode; 8541 } 8542 8543 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8544 enforceNotIsolatedCaller("getRunningAppProcesses"); 8545 // Lazy instantiation of list 8546 List<ActivityManager.RunningAppProcessInfo> runList = null; 8547 final boolean allUsers = ActivityManager.checkUidPermission( 8548 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8549 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8550 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8551 synchronized (this) { 8552 // Iterate across all processes 8553 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8554 ProcessRecord app = mLruProcesses.get(i); 8555 if (!allUsers && app.userId != userId) { 8556 continue; 8557 } 8558 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8559 // Generate process state info for running application 8560 ActivityManager.RunningAppProcessInfo currApp = 8561 new ActivityManager.RunningAppProcessInfo(app.processName, 8562 app.pid, app.getPackageList()); 8563 fillInProcMemInfo(app, currApp); 8564 if (app.adjSource instanceof ProcessRecord) { 8565 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8566 currApp.importanceReasonImportance = oomAdjToImportance( 8567 app.adjSourceOom, null); 8568 } else if (app.adjSource instanceof ActivityRecord) { 8569 ActivityRecord r = (ActivityRecord)app.adjSource; 8570 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8571 } 8572 if (app.adjTarget instanceof ComponentName) { 8573 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8574 } 8575 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8576 // + " lru=" + currApp.lru); 8577 if (runList == null) { 8578 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8579 } 8580 runList.add(currApp); 8581 } 8582 } 8583 } 8584 return runList; 8585 } 8586 8587 public List<ApplicationInfo> getRunningExternalApplications() { 8588 enforceNotIsolatedCaller("getRunningExternalApplications"); 8589 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8590 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8591 if (runningApps != null && runningApps.size() > 0) { 8592 Set<String> extList = new HashSet<String>(); 8593 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8594 if (app.pkgList != null) { 8595 for (String pkg : app.pkgList) { 8596 extList.add(pkg); 8597 } 8598 } 8599 } 8600 IPackageManager pm = AppGlobals.getPackageManager(); 8601 for (String pkg : extList) { 8602 try { 8603 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8604 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8605 retList.add(info); 8606 } 8607 } catch (RemoteException e) { 8608 } 8609 } 8610 } 8611 return retList; 8612 } 8613 8614 @Override 8615 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8616 enforceNotIsolatedCaller("getMyMemoryState"); 8617 synchronized (this) { 8618 ProcessRecord proc; 8619 synchronized (mPidsSelfLocked) { 8620 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8621 } 8622 fillInProcMemInfo(proc, outInfo); 8623 } 8624 } 8625 8626 @Override 8627 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8628 if (checkCallingPermission(android.Manifest.permission.DUMP) 8629 != PackageManager.PERMISSION_GRANTED) { 8630 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8631 + Binder.getCallingPid() 8632 + ", uid=" + Binder.getCallingUid() 8633 + " without permission " 8634 + android.Manifest.permission.DUMP); 8635 return; 8636 } 8637 8638 boolean dumpAll = false; 8639 boolean dumpClient = false; 8640 String dumpPackage = null; 8641 8642 int opti = 0; 8643 while (opti < args.length) { 8644 String opt = args[opti]; 8645 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8646 break; 8647 } 8648 opti++; 8649 if ("-a".equals(opt)) { 8650 dumpAll = true; 8651 } else if ("-c".equals(opt)) { 8652 dumpClient = true; 8653 } else if ("-h".equals(opt)) { 8654 pw.println("Activity manager dump options:"); 8655 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8656 pw.println(" cmd may be one of:"); 8657 pw.println(" a[ctivities]: activity stack state"); 8658 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8659 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8660 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8661 pw.println(" o[om]: out of memory management"); 8662 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8663 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8664 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8665 pw.println(" service [COMP_SPEC]: service client-side state"); 8666 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8667 pw.println(" all: dump all activities"); 8668 pw.println(" top: dump the top activity"); 8669 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8670 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8671 pw.println(" a partial substring in a component name, a"); 8672 pw.println(" hex object identifier."); 8673 pw.println(" -a: include all available server state."); 8674 pw.println(" -c: include client state."); 8675 return; 8676 } else { 8677 pw.println("Unknown argument: " + opt + "; use -h for help"); 8678 } 8679 } 8680 8681 long origId = Binder.clearCallingIdentity(); 8682 boolean more = false; 8683 // Is the caller requesting to dump a particular piece of data? 8684 if (opti < args.length) { 8685 String cmd = args[opti]; 8686 opti++; 8687 if ("activities".equals(cmd) || "a".equals(cmd)) { 8688 synchronized (this) { 8689 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8690 } 8691 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8692 String[] newArgs; 8693 String name; 8694 if (opti >= args.length) { 8695 name = null; 8696 newArgs = EMPTY_STRING_ARRAY; 8697 } else { 8698 name = args[opti]; 8699 opti++; 8700 newArgs = new String[args.length - opti]; 8701 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8702 args.length - opti); 8703 } 8704 synchronized (this) { 8705 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8706 } 8707 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8708 String[] newArgs; 8709 String name; 8710 if (opti >= args.length) { 8711 name = null; 8712 newArgs = EMPTY_STRING_ARRAY; 8713 } else { 8714 name = args[opti]; 8715 opti++; 8716 newArgs = new String[args.length - opti]; 8717 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8718 args.length - opti); 8719 } 8720 synchronized (this) { 8721 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8722 } 8723 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8724 String[] newArgs; 8725 String name; 8726 if (opti >= args.length) { 8727 name = null; 8728 newArgs = EMPTY_STRING_ARRAY; 8729 } else { 8730 name = args[opti]; 8731 opti++; 8732 newArgs = new String[args.length - opti]; 8733 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8734 args.length - opti); 8735 } 8736 synchronized (this) { 8737 dumpProcessesLocked(fd, pw, args, opti, true, name); 8738 } 8739 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8740 synchronized (this) { 8741 dumpOomLocked(fd, pw, args, opti, true); 8742 } 8743 } else if ("provider".equals(cmd)) { 8744 String[] newArgs; 8745 String name; 8746 if (opti >= args.length) { 8747 name = null; 8748 newArgs = EMPTY_STRING_ARRAY; 8749 } else { 8750 name = args[opti]; 8751 opti++; 8752 newArgs = new String[args.length - opti]; 8753 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8754 } 8755 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8756 pw.println("No providers match: " + name); 8757 pw.println("Use -h for help."); 8758 } 8759 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8760 synchronized (this) { 8761 dumpProvidersLocked(fd, pw, args, opti, true, null); 8762 } 8763 } else if ("service".equals(cmd)) { 8764 String[] newArgs; 8765 String name; 8766 if (opti >= args.length) { 8767 name = null; 8768 newArgs = EMPTY_STRING_ARRAY; 8769 } else { 8770 name = args[opti]; 8771 opti++; 8772 newArgs = new String[args.length - opti]; 8773 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8774 args.length - opti); 8775 } 8776 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8777 pw.println("No services match: " + name); 8778 pw.println("Use -h for help."); 8779 } 8780 } else if ("package".equals(cmd)) { 8781 String[] newArgs; 8782 if (opti >= args.length) { 8783 pw.println("package: no package name specified"); 8784 pw.println("Use -h for help."); 8785 } else { 8786 dumpPackage = args[opti]; 8787 opti++; 8788 newArgs = new String[args.length - opti]; 8789 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8790 args.length - opti); 8791 args = newArgs; 8792 opti = 0; 8793 more = true; 8794 } 8795 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8796 synchronized (this) { 8797 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8798 } 8799 } else { 8800 // Dumping a single activity? 8801 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8802 pw.println("Bad activity command, or no activities match: " + cmd); 8803 pw.println("Use -h for help."); 8804 } 8805 } 8806 if (!more) { 8807 Binder.restoreCallingIdentity(origId); 8808 return; 8809 } 8810 } 8811 8812 // No piece of data specified, dump everything. 8813 synchronized (this) { 8814 boolean needSep; 8815 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8816 if (needSep) { 8817 pw.println(" "); 8818 } 8819 if (dumpAll) { 8820 pw.println("-------------------------------------------------------------------------------"); 8821 } 8822 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8823 if (needSep) { 8824 pw.println(" "); 8825 } 8826 if (dumpAll) { 8827 pw.println("-------------------------------------------------------------------------------"); 8828 } 8829 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8830 if (needSep) { 8831 pw.println(" "); 8832 } 8833 if (dumpAll) { 8834 pw.println("-------------------------------------------------------------------------------"); 8835 } 8836 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8837 if (needSep) { 8838 pw.println(" "); 8839 } 8840 if (dumpAll) { 8841 pw.println("-------------------------------------------------------------------------------"); 8842 } 8843 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8844 if (needSep) { 8845 pw.println(" "); 8846 } 8847 if (dumpAll) { 8848 pw.println("-------------------------------------------------------------------------------"); 8849 } 8850 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8851 } 8852 Binder.restoreCallingIdentity(origId); 8853 } 8854 8855 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8856 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8857 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8858 pw.println(" Main stack:"); 8859 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8860 dumpPackage); 8861 pw.println(" "); 8862 pw.println(" Running activities (most recent first):"); 8863 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8864 dumpPackage); 8865 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8866 pw.println(" "); 8867 pw.println(" Activities waiting for another to become visible:"); 8868 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8869 !dumpAll, false, dumpPackage); 8870 } 8871 if (mMainStack.mStoppingActivities.size() > 0) { 8872 pw.println(" "); 8873 pw.println(" Activities waiting to stop:"); 8874 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8875 !dumpAll, false, dumpPackage); 8876 } 8877 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8878 pw.println(" "); 8879 pw.println(" Activities waiting to sleep:"); 8880 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8881 !dumpAll, false, dumpPackage); 8882 } 8883 if (mMainStack.mFinishingActivities.size() > 0) { 8884 pw.println(" "); 8885 pw.println(" Activities waiting to finish:"); 8886 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8887 !dumpAll, false, dumpPackage); 8888 } 8889 8890 pw.println(" "); 8891 if (mMainStack.mPausingActivity != null) { 8892 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8893 } 8894 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8895 pw.println(" mFocusedActivity: " + mFocusedActivity); 8896 if (dumpAll) { 8897 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8898 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8899 pw.println(" mDismissKeyguardOnNextActivity: " 8900 + mMainStack.mDismissKeyguardOnNextActivity); 8901 } 8902 8903 if (mRecentTasks.size() > 0) { 8904 pw.println(); 8905 pw.println(" Recent tasks:"); 8906 8907 final int N = mRecentTasks.size(); 8908 for (int i=0; i<N; i++) { 8909 TaskRecord tr = mRecentTasks.get(i); 8910 if (dumpPackage != null) { 8911 if (tr.realActivity == null || 8912 !dumpPackage.equals(tr.realActivity)) { 8913 continue; 8914 } 8915 } 8916 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8917 pw.println(tr); 8918 if (dumpAll) { 8919 mRecentTasks.get(i).dump(pw, " "); 8920 } 8921 } 8922 } 8923 8924 if (dumpAll) { 8925 pw.println(" "); 8926 pw.println(" mCurTask: " + mCurTask); 8927 } 8928 8929 return true; 8930 } 8931 8932 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8933 int opti, boolean dumpAll, String dumpPackage) { 8934 boolean needSep = false; 8935 int numPers = 0; 8936 8937 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8938 8939 if (dumpAll) { 8940 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8941 final int NA = procs.size(); 8942 for (int ia=0; ia<NA; ia++) { 8943 ProcessRecord r = procs.valueAt(ia); 8944 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8945 continue; 8946 } 8947 if (!needSep) { 8948 pw.println(" All known processes:"); 8949 needSep = true; 8950 } 8951 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8952 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8953 pw.print(" "); pw.println(r); 8954 r.dump(pw, " "); 8955 if (r.persistent) { 8956 numPers++; 8957 } 8958 } 8959 } 8960 } 8961 8962 if (mIsolatedProcesses.size() > 0) { 8963 if (needSep) pw.println(" "); 8964 needSep = true; 8965 pw.println(" Isolated process list (sorted by uid):"); 8966 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8967 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8968 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8969 continue; 8970 } 8971 pw.println(String.format("%sIsolated #%2d: %s", 8972 " ", i, r.toString())); 8973 } 8974 } 8975 8976 if (mLruProcesses.size() > 0) { 8977 if (needSep) pw.println(" "); 8978 needSep = true; 8979 pw.println(" Process LRU list (sorted by oom_adj):"); 8980 dumpProcessOomList(pw, this, mLruProcesses, " ", 8981 "Proc", "PERS", false, dumpPackage); 8982 needSep = true; 8983 } 8984 8985 if (dumpAll) { 8986 synchronized (mPidsSelfLocked) { 8987 boolean printed = false; 8988 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8989 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8990 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8991 continue; 8992 } 8993 if (!printed) { 8994 if (needSep) pw.println(" "); 8995 needSep = true; 8996 pw.println(" PID mappings:"); 8997 printed = true; 8998 } 8999 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9000 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9001 } 9002 } 9003 } 9004 9005 if (mForegroundProcesses.size() > 0) { 9006 synchronized (mPidsSelfLocked) { 9007 boolean printed = false; 9008 for (int i=0; i<mForegroundProcesses.size(); i++) { 9009 ProcessRecord r = mPidsSelfLocked.get( 9010 mForegroundProcesses.valueAt(i).pid); 9011 if (dumpPackage != null && (r == null 9012 || !dumpPackage.equals(r.info.packageName))) { 9013 continue; 9014 } 9015 if (!printed) { 9016 if (needSep) pw.println(" "); 9017 needSep = true; 9018 pw.println(" Foreground Processes:"); 9019 printed = true; 9020 } 9021 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9022 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9023 } 9024 } 9025 } 9026 9027 if (mPersistentStartingProcesses.size() > 0) { 9028 if (needSep) pw.println(" "); 9029 needSep = true; 9030 pw.println(" Persisent processes that are starting:"); 9031 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9032 "Starting Norm", "Restarting PERS", dumpPackage); 9033 } 9034 9035 if (mRemovedProcesses.size() > 0) { 9036 if (needSep) pw.println(" "); 9037 needSep = true; 9038 pw.println(" Processes that are being removed:"); 9039 dumpProcessList(pw, this, mRemovedProcesses, " ", 9040 "Removed Norm", "Removed PERS", dumpPackage); 9041 } 9042 9043 if (mProcessesOnHold.size() > 0) { 9044 if (needSep) pw.println(" "); 9045 needSep = true; 9046 pw.println(" Processes that are on old until the system is ready:"); 9047 dumpProcessList(pw, this, mProcessesOnHold, " ", 9048 "OnHold Norm", "OnHold PERS", dumpPackage); 9049 } 9050 9051 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9052 9053 if (mProcessCrashTimes.getMap().size() > 0) { 9054 boolean printed = false; 9055 long now = SystemClock.uptimeMillis(); 9056 for (Map.Entry<String, SparseArray<Long>> procs 9057 : mProcessCrashTimes.getMap().entrySet()) { 9058 String pname = procs.getKey(); 9059 SparseArray<Long> uids = procs.getValue(); 9060 final int N = uids.size(); 9061 for (int i=0; i<N; i++) { 9062 int puid = uids.keyAt(i); 9063 ProcessRecord r = mProcessNames.get(pname, puid); 9064 if (dumpPackage != null && (r == null 9065 || !dumpPackage.equals(r.info.packageName))) { 9066 continue; 9067 } 9068 if (!printed) { 9069 if (needSep) pw.println(" "); 9070 needSep = true; 9071 pw.println(" Time since processes crashed:"); 9072 printed = true; 9073 } 9074 pw.print(" Process "); pw.print(pname); 9075 pw.print(" uid "); pw.print(puid); 9076 pw.print(": last crashed "); 9077 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9078 pw.println(" ago"); 9079 } 9080 } 9081 } 9082 9083 if (mBadProcesses.getMap().size() > 0) { 9084 boolean printed = false; 9085 for (Map.Entry<String, SparseArray<Long>> procs 9086 : mBadProcesses.getMap().entrySet()) { 9087 String pname = procs.getKey(); 9088 SparseArray<Long> uids = procs.getValue(); 9089 final int N = uids.size(); 9090 for (int i=0; i<N; i++) { 9091 int puid = uids.keyAt(i); 9092 ProcessRecord r = mProcessNames.get(pname, puid); 9093 if (dumpPackage != null && (r == null 9094 || !dumpPackage.equals(r.info.packageName))) { 9095 continue; 9096 } 9097 if (!printed) { 9098 if (needSep) pw.println(" "); 9099 needSep = true; 9100 pw.println(" Bad processes:"); 9101 } 9102 pw.print(" Bad process "); pw.print(pname); 9103 pw.print(" uid "); pw.print(puid); 9104 pw.print(": crashed at time "); 9105 pw.println(uids.valueAt(i)); 9106 } 9107 } 9108 } 9109 9110 pw.println(); 9111 pw.println(" mStartedUsers:"); 9112 for (int i=0; i<mStartedUsers.size(); i++) { 9113 UserStartedState uss = mStartedUsers.valueAt(i); 9114 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9115 pw.println(":"); 9116 uss.dump(" ", pw); 9117 } 9118 pw.println(" mHomeProcess: " + mHomeProcess); 9119 pw.println(" mPreviousProcess: " + mPreviousProcess); 9120 if (dumpAll) { 9121 StringBuilder sb = new StringBuilder(128); 9122 sb.append(" mPreviousProcessVisibleTime: "); 9123 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9124 pw.println(sb); 9125 } 9126 if (mHeavyWeightProcess != null) { 9127 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9128 } 9129 pw.println(" mConfiguration: " + mConfiguration); 9130 if (dumpAll) { 9131 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9132 if (mCompatModePackages.getPackages().size() > 0) { 9133 boolean printed = false; 9134 for (Map.Entry<String, Integer> entry 9135 : mCompatModePackages.getPackages().entrySet()) { 9136 String pkg = entry.getKey(); 9137 int mode = entry.getValue(); 9138 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9139 continue; 9140 } 9141 if (!printed) { 9142 pw.println(" mScreenCompatPackages:"); 9143 printed = true; 9144 } 9145 pw.print(" "); pw.print(pkg); pw.print(": "); 9146 pw.print(mode); pw.println(); 9147 } 9148 } 9149 } 9150 if (mSleeping || mWentToSleep || mLockScreenShown) { 9151 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9152 + " mLockScreenShown " + mLockScreenShown); 9153 } 9154 if (mShuttingDown) { 9155 pw.println(" mShuttingDown=" + mShuttingDown); 9156 } 9157 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9158 || mOrigWaitForDebugger) { 9159 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9160 + " mDebugTransient=" + mDebugTransient 9161 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9162 } 9163 if (mOpenGlTraceApp != null) { 9164 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9165 } 9166 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9167 || mProfileFd != null) { 9168 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9169 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9170 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9171 + mAutoStopProfiler); 9172 } 9173 if (mAlwaysFinishActivities || mController != null) { 9174 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9175 + " mController=" + mController); 9176 } 9177 if (dumpAll) { 9178 pw.println(" Total persistent processes: " + numPers); 9179 pw.println(" mStartRunning=" + mStartRunning 9180 + " mProcessesReady=" + mProcessesReady 9181 + " mSystemReady=" + mSystemReady); 9182 pw.println(" mBooting=" + mBooting 9183 + " mBooted=" + mBooted 9184 + " mFactoryTest=" + mFactoryTest); 9185 pw.print(" mLastPowerCheckRealtime="); 9186 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9187 pw.println(""); 9188 pw.print(" mLastPowerCheckUptime="); 9189 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9190 pw.println(""); 9191 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9192 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9193 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9194 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9195 + " mNumHiddenProcs=" + mNumHiddenProcs 9196 + " mNumServiceProcs=" + mNumServiceProcs 9197 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9198 } 9199 9200 return true; 9201 } 9202 9203 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9204 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9205 if (mProcessesToGc.size() > 0) { 9206 boolean printed = false; 9207 long now = SystemClock.uptimeMillis(); 9208 for (int i=0; i<mProcessesToGc.size(); i++) { 9209 ProcessRecord proc = mProcessesToGc.get(i); 9210 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9211 continue; 9212 } 9213 if (!printed) { 9214 if (needSep) pw.println(" "); 9215 needSep = true; 9216 pw.println(" Processes that are waiting to GC:"); 9217 printed = true; 9218 } 9219 pw.print(" Process "); pw.println(proc); 9220 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9221 pw.print(", last gced="); 9222 pw.print(now-proc.lastRequestedGc); 9223 pw.print(" ms ago, last lowMem="); 9224 pw.print(now-proc.lastLowMemory); 9225 pw.println(" ms ago"); 9226 9227 } 9228 } 9229 return needSep; 9230 } 9231 9232 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9233 int opti, boolean dumpAll) { 9234 boolean needSep = false; 9235 9236 if (mLruProcesses.size() > 0) { 9237 if (needSep) pw.println(" "); 9238 needSep = true; 9239 pw.println(" OOM levels:"); 9240 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9241 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9242 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9243 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9244 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9245 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9246 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9247 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9248 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9249 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9250 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9251 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9252 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9253 9254 if (needSep) pw.println(" "); 9255 needSep = true; 9256 pw.println(" Process OOM control:"); 9257 dumpProcessOomList(pw, this, mLruProcesses, " ", 9258 "Proc", "PERS", true, null); 9259 needSep = true; 9260 } 9261 9262 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9263 9264 pw.println(); 9265 pw.println(" mHomeProcess: " + mHomeProcess); 9266 pw.println(" mPreviousProcess: " + mPreviousProcess); 9267 if (mHeavyWeightProcess != null) { 9268 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9269 } 9270 9271 return true; 9272 } 9273 9274 /** 9275 * There are three ways to call this: 9276 * - no provider specified: dump all the providers 9277 * - a flattened component name that matched an existing provider was specified as the 9278 * first arg: dump that one provider 9279 * - the first arg isn't the flattened component name of an existing provider: 9280 * dump all providers whose component contains the first arg as a substring 9281 */ 9282 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9283 int opti, boolean dumpAll) { 9284 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9285 } 9286 9287 static class ItemMatcher { 9288 ArrayList<ComponentName> components; 9289 ArrayList<String> strings; 9290 ArrayList<Integer> objects; 9291 boolean all; 9292 9293 ItemMatcher() { 9294 all = true; 9295 } 9296 9297 void build(String name) { 9298 ComponentName componentName = ComponentName.unflattenFromString(name); 9299 if (componentName != null) { 9300 if (components == null) { 9301 components = new ArrayList<ComponentName>(); 9302 } 9303 components.add(componentName); 9304 all = false; 9305 } else { 9306 int objectId = 0; 9307 // Not a '/' separated full component name; maybe an object ID? 9308 try { 9309 objectId = Integer.parseInt(name, 16); 9310 if (objects == null) { 9311 objects = new ArrayList<Integer>(); 9312 } 9313 objects.add(objectId); 9314 all = false; 9315 } catch (RuntimeException e) { 9316 // Not an integer; just do string match. 9317 if (strings == null) { 9318 strings = new ArrayList<String>(); 9319 } 9320 strings.add(name); 9321 all = false; 9322 } 9323 } 9324 } 9325 9326 int build(String[] args, int opti) { 9327 for (; opti<args.length; opti++) { 9328 String name = args[opti]; 9329 if ("--".equals(name)) { 9330 return opti+1; 9331 } 9332 build(name); 9333 } 9334 return opti; 9335 } 9336 9337 boolean match(Object object, ComponentName comp) { 9338 if (all) { 9339 return true; 9340 } 9341 if (components != null) { 9342 for (int i=0; i<components.size(); i++) { 9343 if (components.get(i).equals(comp)) { 9344 return true; 9345 } 9346 } 9347 } 9348 if (objects != null) { 9349 for (int i=0; i<objects.size(); i++) { 9350 if (System.identityHashCode(object) == objects.get(i)) { 9351 return true; 9352 } 9353 } 9354 } 9355 if (strings != null) { 9356 String flat = comp.flattenToString(); 9357 for (int i=0; i<strings.size(); i++) { 9358 if (flat.contains(strings.get(i))) { 9359 return true; 9360 } 9361 } 9362 } 9363 return false; 9364 } 9365 } 9366 9367 /** 9368 * There are three things that cmd can be: 9369 * - a flattened component name that matches an existing activity 9370 * - the cmd arg isn't the flattened component name of an existing activity: 9371 * dump all activity whose component contains the cmd as a substring 9372 * - A hex number of the ActivityRecord object instance. 9373 */ 9374 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9375 int opti, boolean dumpAll) { 9376 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9377 9378 if ("all".equals(name)) { 9379 synchronized (this) { 9380 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9381 activities.add(r1); 9382 } 9383 } 9384 } else if ("top".equals(name)) { 9385 synchronized (this) { 9386 final int N = mMainStack.mHistory.size(); 9387 if (N > 0) { 9388 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9389 } 9390 } 9391 } else { 9392 ItemMatcher matcher = new ItemMatcher(); 9393 matcher.build(name); 9394 9395 synchronized (this) { 9396 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9397 if (matcher.match(r1, r1.intent.getComponent())) { 9398 activities.add(r1); 9399 } 9400 } 9401 } 9402 } 9403 9404 if (activities.size() <= 0) { 9405 return false; 9406 } 9407 9408 String[] newArgs = new String[args.length - opti]; 9409 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9410 9411 TaskRecord lastTask = null; 9412 boolean needSep = false; 9413 for (int i=activities.size()-1; i>=0; i--) { 9414 ActivityRecord r = (ActivityRecord)activities.get(i); 9415 if (needSep) { 9416 pw.println(); 9417 } 9418 needSep = true; 9419 synchronized (this) { 9420 if (lastTask != r.task) { 9421 lastTask = r.task; 9422 pw.print("TASK "); pw.print(lastTask.affinity); 9423 pw.print(" id="); pw.println(lastTask.taskId); 9424 if (dumpAll) { 9425 lastTask.dump(pw, " "); 9426 } 9427 } 9428 } 9429 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9430 } 9431 return true; 9432 } 9433 9434 /** 9435 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9436 * there is a thread associated with the activity. 9437 */ 9438 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9439 final ActivityRecord r, String[] args, boolean dumpAll) { 9440 String innerPrefix = prefix + " "; 9441 synchronized (this) { 9442 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9443 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9444 pw.print(" pid="); 9445 if (r.app != null) pw.println(r.app.pid); 9446 else pw.println("(not running)"); 9447 if (dumpAll) { 9448 r.dump(pw, innerPrefix); 9449 } 9450 } 9451 if (r.app != null && r.app.thread != null) { 9452 // flush anything that is already in the PrintWriter since the thread is going 9453 // to write to the file descriptor directly 9454 pw.flush(); 9455 try { 9456 TransferPipe tp = new TransferPipe(); 9457 try { 9458 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9459 r.appToken, innerPrefix, args); 9460 tp.go(fd); 9461 } finally { 9462 tp.kill(); 9463 } 9464 } catch (IOException e) { 9465 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9466 } catch (RemoteException e) { 9467 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9468 } 9469 } 9470 } 9471 9472 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9473 int opti, boolean dumpAll, String dumpPackage) { 9474 boolean needSep = false; 9475 boolean onlyHistory = false; 9476 9477 if ("history".equals(dumpPackage)) { 9478 onlyHistory = true; 9479 dumpPackage = null; 9480 } 9481 9482 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9483 if (!onlyHistory && dumpAll) { 9484 if (mRegisteredReceivers.size() > 0) { 9485 boolean printed = false; 9486 Iterator it = mRegisteredReceivers.values().iterator(); 9487 while (it.hasNext()) { 9488 ReceiverList r = (ReceiverList)it.next(); 9489 if (dumpPackage != null && (r.app == null || 9490 !dumpPackage.equals(r.app.info.packageName))) { 9491 continue; 9492 } 9493 if (!printed) { 9494 pw.println(" Registered Receivers:"); 9495 needSep = true; 9496 printed = true; 9497 } 9498 pw.print(" * "); pw.println(r); 9499 r.dump(pw, " "); 9500 } 9501 } 9502 9503 if (mReceiverResolver.dump(pw, needSep ? 9504 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9505 " ", dumpPackage, false)) { 9506 needSep = true; 9507 } 9508 } 9509 9510 for (BroadcastQueue q : mBroadcastQueues) { 9511 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9512 } 9513 9514 needSep = true; 9515 9516 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9517 if (needSep) { 9518 pw.println(); 9519 } 9520 needSep = true; 9521 pw.println(" Sticky broadcasts:"); 9522 StringBuilder sb = new StringBuilder(128); 9523 for (Map.Entry<String, ArrayList<Intent>> ent 9524 : mStickyBroadcasts.entrySet()) { 9525 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9526 if (dumpAll) { 9527 pw.println(":"); 9528 ArrayList<Intent> intents = ent.getValue(); 9529 final int N = intents.size(); 9530 for (int i=0; i<N; i++) { 9531 sb.setLength(0); 9532 sb.append(" Intent: "); 9533 intents.get(i).toShortString(sb, false, true, false, false); 9534 pw.println(sb.toString()); 9535 Bundle bundle = intents.get(i).getExtras(); 9536 if (bundle != null) { 9537 pw.print(" "); 9538 pw.println(bundle.toString()); 9539 } 9540 } 9541 } else { 9542 pw.println(""); 9543 } 9544 } 9545 needSep = true; 9546 } 9547 9548 if (!onlyHistory && dumpAll) { 9549 pw.println(); 9550 for (BroadcastQueue queue : mBroadcastQueues) { 9551 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9552 + queue.mBroadcastsScheduled); 9553 } 9554 pw.println(" mHandler:"); 9555 mHandler.dump(new PrintWriterPrinter(pw), " "); 9556 needSep = true; 9557 } 9558 9559 return needSep; 9560 } 9561 9562 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9563 int opti, boolean dumpAll, String dumpPackage) { 9564 boolean needSep = true; 9565 9566 ItemMatcher matcher = new ItemMatcher(); 9567 matcher.build(args, opti); 9568 9569 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9570 9571 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9572 9573 if (mLaunchingProviders.size() > 0) { 9574 boolean printed = false; 9575 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9576 ContentProviderRecord r = mLaunchingProviders.get(i); 9577 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9578 continue; 9579 } 9580 if (!printed) { 9581 if (needSep) pw.println(" "); 9582 needSep = true; 9583 pw.println(" Launching content providers:"); 9584 printed = true; 9585 } 9586 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9587 pw.println(r); 9588 } 9589 } 9590 9591 if (mGrantedUriPermissions.size() > 0) { 9592 if (needSep) pw.println(); 9593 needSep = true; 9594 pw.println("Granted Uri Permissions:"); 9595 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9596 int uid = mGrantedUriPermissions.keyAt(i); 9597 HashMap<Uri, UriPermission> perms 9598 = mGrantedUriPermissions.valueAt(i); 9599 pw.print(" * UID "); pw.print(uid); 9600 pw.println(" holds:"); 9601 for (UriPermission perm : perms.values()) { 9602 pw.print(" "); pw.println(perm); 9603 if (dumpAll) { 9604 perm.dump(pw, " "); 9605 } 9606 } 9607 } 9608 needSep = true; 9609 } 9610 9611 return needSep; 9612 } 9613 9614 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9615 int opti, boolean dumpAll, String dumpPackage) { 9616 boolean needSep = false; 9617 9618 if (mIntentSenderRecords.size() > 0) { 9619 boolean printed = false; 9620 Iterator<WeakReference<PendingIntentRecord>> it 9621 = mIntentSenderRecords.values().iterator(); 9622 while (it.hasNext()) { 9623 WeakReference<PendingIntentRecord> ref = it.next(); 9624 PendingIntentRecord rec = ref != null ? ref.get(): null; 9625 if (dumpPackage != null && (rec == null 9626 || !dumpPackage.equals(rec.key.packageName))) { 9627 continue; 9628 } 9629 if (!printed) { 9630 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9631 printed = true; 9632 } 9633 needSep = true; 9634 if (rec != null) { 9635 pw.print(" * "); pw.println(rec); 9636 if (dumpAll) { 9637 rec.dump(pw, " "); 9638 } 9639 } else { 9640 pw.print(" * "); pw.println(ref); 9641 } 9642 } 9643 } 9644 9645 return needSep; 9646 } 9647 9648 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9649 String prefix, String label, boolean complete, boolean brief, boolean client, 9650 String dumpPackage) { 9651 TaskRecord lastTask = null; 9652 boolean needNL = false; 9653 final String innerPrefix = prefix + " "; 9654 final String[] args = new String[0]; 9655 for (int i=list.size()-1; i>=0; i--) { 9656 final ActivityRecord r = (ActivityRecord)list.get(i); 9657 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9658 continue; 9659 } 9660 final boolean full = !brief && (complete || !r.isInHistory()); 9661 if (needNL) { 9662 pw.println(" "); 9663 needNL = false; 9664 } 9665 if (lastTask != r.task) { 9666 lastTask = r.task; 9667 pw.print(prefix); 9668 pw.print(full ? "* " : " "); 9669 pw.println(lastTask); 9670 if (full) { 9671 lastTask.dump(pw, prefix + " "); 9672 } else if (complete) { 9673 // Complete + brief == give a summary. Isn't that obvious?!? 9674 if (lastTask.intent != null) { 9675 pw.print(prefix); pw.print(" "); 9676 pw.println(lastTask.intent.toInsecureStringWithClip()); 9677 } 9678 } 9679 } 9680 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9681 pw.print(" #"); pw.print(i); pw.print(": "); 9682 pw.println(r); 9683 if (full) { 9684 r.dump(pw, innerPrefix); 9685 } else if (complete) { 9686 // Complete + brief == give a summary. Isn't that obvious?!? 9687 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9688 if (r.app != null) { 9689 pw.print(innerPrefix); pw.println(r.app); 9690 } 9691 } 9692 if (client && r.app != null && r.app.thread != null) { 9693 // flush anything that is already in the PrintWriter since the thread is going 9694 // to write to the file descriptor directly 9695 pw.flush(); 9696 try { 9697 TransferPipe tp = new TransferPipe(); 9698 try { 9699 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9700 r.appToken, innerPrefix, args); 9701 // Short timeout, since blocking here can 9702 // deadlock with the application. 9703 tp.go(fd, 2000); 9704 } finally { 9705 tp.kill(); 9706 } 9707 } catch (IOException e) { 9708 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9709 } catch (RemoteException e) { 9710 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9711 } 9712 needNL = true; 9713 } 9714 } 9715 } 9716 9717 private static String buildOomTag(String prefix, String space, int val, int base) { 9718 if (val == base) { 9719 if (space == null) return prefix; 9720 return prefix + " "; 9721 } 9722 return prefix + "+" + Integer.toString(val-base); 9723 } 9724 9725 private static final int dumpProcessList(PrintWriter pw, 9726 ActivityManagerService service, List list, 9727 String prefix, String normalLabel, String persistentLabel, 9728 String dumpPackage) { 9729 int numPers = 0; 9730 final int N = list.size()-1; 9731 for (int i=N; i>=0; i--) { 9732 ProcessRecord r = (ProcessRecord)list.get(i); 9733 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9734 continue; 9735 } 9736 pw.println(String.format("%s%s #%2d: %s", 9737 prefix, (r.persistent ? persistentLabel : normalLabel), 9738 i, r.toString())); 9739 if (r.persistent) { 9740 numPers++; 9741 } 9742 } 9743 return numPers; 9744 } 9745 9746 private static final boolean dumpProcessOomList(PrintWriter pw, 9747 ActivityManagerService service, List<ProcessRecord> origList, 9748 String prefix, String normalLabel, String persistentLabel, 9749 boolean inclDetails, String dumpPackage) { 9750 9751 ArrayList<Pair<ProcessRecord, Integer>> list 9752 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9753 for (int i=0; i<origList.size(); i++) { 9754 ProcessRecord r = origList.get(i); 9755 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9756 continue; 9757 } 9758 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9759 } 9760 9761 if (list.size() <= 0) { 9762 return false; 9763 } 9764 9765 Comparator<Pair<ProcessRecord, Integer>> comparator 9766 = new Comparator<Pair<ProcessRecord, Integer>>() { 9767 @Override 9768 public int compare(Pair<ProcessRecord, Integer> object1, 9769 Pair<ProcessRecord, Integer> object2) { 9770 if (object1.first.setAdj != object2.first.setAdj) { 9771 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9772 } 9773 if (object1.second.intValue() != object2.second.intValue()) { 9774 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9775 } 9776 return 0; 9777 } 9778 }; 9779 9780 Collections.sort(list, comparator); 9781 9782 final long curRealtime = SystemClock.elapsedRealtime(); 9783 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9784 final long curUptime = SystemClock.uptimeMillis(); 9785 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9786 9787 for (int i=list.size()-1; i>=0; i--) { 9788 ProcessRecord r = list.get(i).first; 9789 String oomAdj; 9790 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9791 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9792 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9793 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9794 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9795 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9796 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9797 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9798 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9799 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9800 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9801 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9802 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9803 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9804 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9805 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9806 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9807 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9808 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9809 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9810 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9811 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9812 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9813 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9814 } else { 9815 oomAdj = Integer.toString(r.setAdj); 9816 } 9817 String schedGroup; 9818 switch (r.setSchedGroup) { 9819 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9820 schedGroup = "B"; 9821 break; 9822 case Process.THREAD_GROUP_DEFAULT: 9823 schedGroup = "F"; 9824 break; 9825 default: 9826 schedGroup = Integer.toString(r.setSchedGroup); 9827 break; 9828 } 9829 String foreground; 9830 if (r.foregroundActivities) { 9831 foreground = "A"; 9832 } else if (r.foregroundServices) { 9833 foreground = "S"; 9834 } else { 9835 foreground = " "; 9836 } 9837 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9838 prefix, (r.persistent ? persistentLabel : normalLabel), 9839 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9840 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9841 if (r.adjSource != null || r.adjTarget != null) { 9842 pw.print(prefix); 9843 pw.print(" "); 9844 if (r.adjTarget instanceof ComponentName) { 9845 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9846 } else if (r.adjTarget != null) { 9847 pw.print(r.adjTarget.toString()); 9848 } else { 9849 pw.print("{null}"); 9850 } 9851 pw.print("<="); 9852 if (r.adjSource instanceof ProcessRecord) { 9853 pw.print("Proc{"); 9854 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9855 pw.println("}"); 9856 } else if (r.adjSource != null) { 9857 pw.println(r.adjSource.toString()); 9858 } else { 9859 pw.println("{null}"); 9860 } 9861 } 9862 if (inclDetails) { 9863 pw.print(prefix); 9864 pw.print(" "); 9865 pw.print("oom: max="); pw.print(r.maxAdj); 9866 pw.print(" hidden="); pw.print(r.hiddenAdj); 9867 pw.print(" empty="); pw.print(r.emptyAdj); 9868 pw.print(" curRaw="); pw.print(r.curRawAdj); 9869 pw.print(" setRaw="); pw.print(r.setRawAdj); 9870 pw.print(" cur="); pw.print(r.curAdj); 9871 pw.print(" set="); pw.println(r.setAdj); 9872 pw.print(prefix); 9873 pw.print(" "); 9874 pw.print("keeping="); pw.print(r.keeping); 9875 pw.print(" hidden="); pw.print(r.hidden); 9876 pw.print(" empty="); pw.print(r.empty); 9877 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9878 9879 if (!r.keeping) { 9880 if (r.lastWakeTime != 0) { 9881 long wtime; 9882 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9883 synchronized (stats) { 9884 wtime = stats.getProcessWakeTime(r.info.uid, 9885 r.pid, curRealtime); 9886 } 9887 long timeUsed = wtime - r.lastWakeTime; 9888 pw.print(prefix); 9889 pw.print(" "); 9890 pw.print("keep awake over "); 9891 TimeUtils.formatDuration(realtimeSince, pw); 9892 pw.print(" used "); 9893 TimeUtils.formatDuration(timeUsed, pw); 9894 pw.print(" ("); 9895 pw.print((timeUsed*100)/realtimeSince); 9896 pw.println("%)"); 9897 } 9898 if (r.lastCpuTime != 0) { 9899 long timeUsed = r.curCpuTime - r.lastCpuTime; 9900 pw.print(prefix); 9901 pw.print(" "); 9902 pw.print("run cpu over "); 9903 TimeUtils.formatDuration(uptimeSince, pw); 9904 pw.print(" used "); 9905 TimeUtils.formatDuration(timeUsed, pw); 9906 pw.print(" ("); 9907 pw.print((timeUsed*100)/uptimeSince); 9908 pw.println("%)"); 9909 } 9910 } 9911 } 9912 } 9913 return true; 9914 } 9915 9916 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9917 ArrayList<ProcessRecord> procs; 9918 synchronized (this) { 9919 if (args != null && args.length > start 9920 && args[start].charAt(0) != '-') { 9921 procs = new ArrayList<ProcessRecord>(); 9922 int pid = -1; 9923 try { 9924 pid = Integer.parseInt(args[start]); 9925 } catch (NumberFormatException e) { 9926 9927 } 9928 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9929 ProcessRecord proc = mLruProcesses.get(i); 9930 if (proc.pid == pid) { 9931 procs.add(proc); 9932 } else if (proc.processName.equals(args[start])) { 9933 procs.add(proc); 9934 } 9935 } 9936 if (procs.size() <= 0) { 9937 pw.println("No process found for: " + args[start]); 9938 return null; 9939 } 9940 } else { 9941 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9942 } 9943 } 9944 return procs; 9945 } 9946 9947 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9948 PrintWriter pw, String[] args) { 9949 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9950 if (procs == null) { 9951 return; 9952 } 9953 9954 long uptime = SystemClock.uptimeMillis(); 9955 long realtime = SystemClock.elapsedRealtime(); 9956 pw.println("Applications Graphics Acceleration Info:"); 9957 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9958 9959 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9960 ProcessRecord r = procs.get(i); 9961 if (r.thread != null) { 9962 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9963 pw.flush(); 9964 try { 9965 TransferPipe tp = new TransferPipe(); 9966 try { 9967 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9968 tp.go(fd); 9969 } finally { 9970 tp.kill(); 9971 } 9972 } catch (IOException e) { 9973 pw.println("Failure while dumping the app: " + r); 9974 pw.flush(); 9975 } catch (RemoteException e) { 9976 pw.println("Got a RemoteException while dumping the app " + r); 9977 pw.flush(); 9978 } 9979 } 9980 } 9981 } 9982 9983 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9984 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9985 if (procs == null) { 9986 return; 9987 } 9988 9989 pw.println("Applications Database Info:"); 9990 9991 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9992 ProcessRecord r = procs.get(i); 9993 if (r.thread != null) { 9994 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9995 pw.flush(); 9996 try { 9997 TransferPipe tp = new TransferPipe(); 9998 try { 9999 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10000 tp.go(fd); 10001 } finally { 10002 tp.kill(); 10003 } 10004 } catch (IOException e) { 10005 pw.println("Failure while dumping the app: " + r); 10006 pw.flush(); 10007 } catch (RemoteException e) { 10008 pw.println("Got a RemoteException while dumping the app " + r); 10009 pw.flush(); 10010 } 10011 } 10012 } 10013 } 10014 10015 final static class MemItem { 10016 final String label; 10017 final String shortLabel; 10018 final long pss; 10019 final int id; 10020 ArrayList<MemItem> subitems; 10021 10022 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10023 label = _label; 10024 shortLabel = _shortLabel; 10025 pss = _pss; 10026 id = _id; 10027 } 10028 } 10029 10030 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10031 boolean sort) { 10032 if (sort) { 10033 Collections.sort(items, new Comparator<MemItem>() { 10034 @Override 10035 public int compare(MemItem lhs, MemItem rhs) { 10036 if (lhs.pss < rhs.pss) { 10037 return 1; 10038 } else if (lhs.pss > rhs.pss) { 10039 return -1; 10040 } 10041 return 0; 10042 } 10043 }); 10044 } 10045 10046 for (int i=0; i<items.size(); i++) { 10047 MemItem mi = items.get(i); 10048 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10049 if (mi.subitems != null) { 10050 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10051 } 10052 } 10053 } 10054 10055 // These are in KB. 10056 static final long[] DUMP_MEM_BUCKETS = new long[] { 10057 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10058 120*1024, 160*1024, 200*1024, 10059 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10060 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10061 }; 10062 10063 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10064 boolean stackLike) { 10065 int start = label.lastIndexOf('.'); 10066 if (start >= 0) start++; 10067 else start = 0; 10068 int end = label.length(); 10069 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10070 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10071 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10072 out.append(bucket); 10073 out.append(stackLike ? "MB." : "MB "); 10074 out.append(label, start, end); 10075 return; 10076 } 10077 } 10078 out.append(memKB/1024); 10079 out.append(stackLike ? "MB." : "MB "); 10080 out.append(label, start, end); 10081 } 10082 10083 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10084 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10085 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10086 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10087 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10088 }; 10089 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10090 "System", "Persistent", "Foreground", 10091 "Visible", "Perceptible", "Heavy Weight", 10092 "Backup", "A Services", "Home", "Previous", 10093 "B Services", "Background" 10094 }; 10095 10096 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10097 PrintWriter pw, String prefix, String[] args, boolean brief, 10098 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10099 boolean dumpAll = false; 10100 boolean oomOnly = false; 10101 10102 int opti = 0; 10103 while (opti < args.length) { 10104 String opt = args[opti]; 10105 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10106 break; 10107 } 10108 opti++; 10109 if ("-a".equals(opt)) { 10110 dumpAll = true; 10111 } else if ("--oom".equals(opt)) { 10112 oomOnly = true; 10113 } else if ("-h".equals(opt)) { 10114 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10115 pw.println(" -a: include all available information for each process."); 10116 pw.println(" --oom: only show processes organized by oom adj."); 10117 pw.println("If [process] is specified it can be the name or "); 10118 pw.println("pid of a specific process to dump."); 10119 return; 10120 } else { 10121 pw.println("Unknown argument: " + opt + "; use -h for help"); 10122 } 10123 } 10124 10125 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10126 if (procs == null) { 10127 return; 10128 } 10129 10130 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10131 long uptime = SystemClock.uptimeMillis(); 10132 long realtime = SystemClock.elapsedRealtime(); 10133 10134 if (procs.size() == 1 || isCheckinRequest) { 10135 dumpAll = true; 10136 } 10137 10138 if (isCheckinRequest) { 10139 // short checkin version 10140 pw.println(uptime + "," + realtime); 10141 pw.flush(); 10142 } else { 10143 pw.println("Applications Memory Usage (kB):"); 10144 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10145 } 10146 10147 String[] innerArgs = new String[args.length-opti]; 10148 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10149 10150 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10151 long nativePss=0, dalvikPss=0, otherPss=0; 10152 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10153 10154 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10155 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10156 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10157 10158 long totalPss = 0; 10159 10160 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10161 ProcessRecord r = procs.get(i); 10162 if (r.thread != null) { 10163 if (!isCheckinRequest && dumpAll) { 10164 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10165 pw.flush(); 10166 } 10167 Debug.MemoryInfo mi = null; 10168 if (dumpAll) { 10169 try { 10170 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10171 } catch (RemoteException e) { 10172 if (!isCheckinRequest) { 10173 pw.println("Got RemoteException!"); 10174 pw.flush(); 10175 } 10176 } 10177 } else { 10178 mi = new Debug.MemoryInfo(); 10179 Debug.getMemoryInfo(r.pid, mi); 10180 } 10181 10182 if (!isCheckinRequest && mi != null) { 10183 long myTotalPss = mi.getTotalPss(); 10184 totalPss += myTotalPss; 10185 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10186 r.processName, myTotalPss, 0); 10187 procMems.add(pssItem); 10188 10189 nativePss += mi.nativePss; 10190 dalvikPss += mi.dalvikPss; 10191 otherPss += mi.otherPss; 10192 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10193 long mem = mi.getOtherPss(j); 10194 miscPss[j] += mem; 10195 otherPss -= mem; 10196 } 10197 10198 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10199 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10200 || oomIndex == (oomPss.length-1)) { 10201 oomPss[oomIndex] += myTotalPss; 10202 if (oomProcs[oomIndex] == null) { 10203 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10204 } 10205 oomProcs[oomIndex].add(pssItem); 10206 break; 10207 } 10208 } 10209 } 10210 } 10211 } 10212 10213 if (!isCheckinRequest && procs.size() > 1) { 10214 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10215 10216 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10217 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10218 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10219 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10220 String label = Debug.MemoryInfo.getOtherLabel(j); 10221 catMems.add(new MemItem(label, label, miscPss[j], j)); 10222 } 10223 10224 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10225 for (int j=0; j<oomPss.length; j++) { 10226 if (oomPss[j] != 0) { 10227 String label = DUMP_MEM_OOM_LABEL[j]; 10228 MemItem item = new MemItem(label, label, oomPss[j], 10229 DUMP_MEM_OOM_ADJ[j]); 10230 item.subitems = oomProcs[j]; 10231 oomMems.add(item); 10232 } 10233 } 10234 10235 if (outTag != null || outStack != null) { 10236 if (outTag != null) { 10237 appendMemBucket(outTag, totalPss, "total", false); 10238 } 10239 if (outStack != null) { 10240 appendMemBucket(outStack, totalPss, "total", true); 10241 } 10242 boolean firstLine = true; 10243 for (int i=0; i<oomMems.size(); i++) { 10244 MemItem miCat = oomMems.get(i); 10245 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10246 continue; 10247 } 10248 if (miCat.id < ProcessList.SERVICE_ADJ 10249 || miCat.id == ProcessList.HOME_APP_ADJ 10250 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10251 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10252 outTag.append(" / "); 10253 } 10254 if (outStack != null) { 10255 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10256 if (firstLine) { 10257 outStack.append(":"); 10258 firstLine = false; 10259 } 10260 outStack.append("\n\t at "); 10261 } else { 10262 outStack.append("$"); 10263 } 10264 } 10265 for (int j=0; j<miCat.subitems.size(); j++) { 10266 MemItem mi = miCat.subitems.get(j); 10267 if (j > 0) { 10268 if (outTag != null) { 10269 outTag.append(" "); 10270 } 10271 if (outStack != null) { 10272 outStack.append("$"); 10273 } 10274 } 10275 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10276 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10277 } 10278 if (outStack != null) { 10279 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10280 } 10281 } 10282 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10283 outStack.append("("); 10284 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10285 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10286 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10287 outStack.append(":"); 10288 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10289 } 10290 } 10291 outStack.append(")"); 10292 } 10293 } 10294 } 10295 } 10296 10297 if (!brief && !oomOnly) { 10298 pw.println(); 10299 pw.println("Total PSS by process:"); 10300 dumpMemItems(pw, " ", procMems, true); 10301 pw.println(); 10302 } 10303 pw.println("Total PSS by OOM adjustment:"); 10304 dumpMemItems(pw, " ", oomMems, false); 10305 if (!oomOnly) { 10306 PrintWriter out = categoryPw != null ? categoryPw : pw; 10307 out.println(); 10308 out.println("Total PSS by category:"); 10309 dumpMemItems(out, " ", catMems, true); 10310 } 10311 pw.println(); 10312 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10313 final int[] SINGLE_LONG_FORMAT = new int[] { 10314 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10315 }; 10316 long[] longOut = new long[1]; 10317 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10318 SINGLE_LONG_FORMAT, null, longOut, null); 10319 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10320 longOut[0] = 0; 10321 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10322 SINGLE_LONG_FORMAT, null, longOut, null); 10323 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10324 longOut[0] = 0; 10325 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10326 SINGLE_LONG_FORMAT, null, longOut, null); 10327 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10328 longOut[0] = 0; 10329 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10330 SINGLE_LONG_FORMAT, null, longOut, null); 10331 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10332 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10333 pw.print(shared); pw.println(" kB"); 10334 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10335 pw.print(voltile); pw.println(" kB volatile"); 10336 } 10337 } 10338 10339 /** 10340 * Searches array of arguments for the specified string 10341 * @param args array of argument strings 10342 * @param value value to search for 10343 * @return true if the value is contained in the array 10344 */ 10345 private static boolean scanArgs(String[] args, String value) { 10346 if (args != null) { 10347 for (String arg : args) { 10348 if (value.equals(arg)) { 10349 return true; 10350 } 10351 } 10352 } 10353 return false; 10354 } 10355 10356 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10357 ContentProviderRecord cpr, boolean always) { 10358 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10359 10360 if (!inLaunching || always) { 10361 synchronized (cpr) { 10362 cpr.launchingApp = null; 10363 cpr.notifyAll(); 10364 } 10365 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10366 String names[] = cpr.info.authority.split(";"); 10367 for (int j = 0; j < names.length; j++) { 10368 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10369 } 10370 } 10371 10372 for (int i=0; i<cpr.connections.size(); i++) { 10373 ContentProviderConnection conn = cpr.connections.get(i); 10374 if (conn.waiting) { 10375 // If this connection is waiting for the provider, then we don't 10376 // need to mess with its process unless we are always removing 10377 // or for some reason the provider is not currently launching. 10378 if (inLaunching && !always) { 10379 continue; 10380 } 10381 } 10382 ProcessRecord capp = conn.client; 10383 conn.dead = true; 10384 if (conn.stableCount > 0) { 10385 if (!capp.persistent && capp.thread != null 10386 && capp.pid != 0 10387 && capp.pid != MY_PID) { 10388 Slog.i(TAG, "Kill " + capp.processName 10389 + " (pid " + capp.pid + "): provider " + cpr.info.name 10390 + " in dying process " + (proc != null ? proc.processName : "??")); 10391 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10392 capp.processName, capp.setAdj, "dying provider " 10393 + cpr.name.toShortString()); 10394 Process.killProcessQuiet(capp.pid); 10395 } 10396 } else if (capp.thread != null && conn.provider.provider != null) { 10397 try { 10398 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10399 } catch (RemoteException e) { 10400 } 10401 // In the protocol here, we don't expect the client to correctly 10402 // clean up this connection, we'll just remove it. 10403 cpr.connections.remove(i); 10404 conn.client.conProviders.remove(conn); 10405 } 10406 } 10407 10408 if (inLaunching && always) { 10409 mLaunchingProviders.remove(cpr); 10410 } 10411 return inLaunching; 10412 } 10413 10414 /** 10415 * Main code for cleaning up a process when it has gone away. This is 10416 * called both as a result of the process dying, or directly when stopping 10417 * a process when running in single process mode. 10418 */ 10419 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10420 boolean restarting, boolean allowRestart, int index) { 10421 if (index >= 0) { 10422 mLruProcesses.remove(index); 10423 } 10424 10425 mProcessesToGc.remove(app); 10426 10427 // Dismiss any open dialogs. 10428 if (app.crashDialog != null) { 10429 app.crashDialog.dismiss(); 10430 app.crashDialog = null; 10431 } 10432 if (app.anrDialog != null) { 10433 app.anrDialog.dismiss(); 10434 app.anrDialog = null; 10435 } 10436 if (app.waitDialog != null) { 10437 app.waitDialog.dismiss(); 10438 app.waitDialog = null; 10439 } 10440 10441 app.crashing = false; 10442 app.notResponding = false; 10443 10444 app.resetPackageList(); 10445 app.unlinkDeathRecipient(); 10446 app.thread = null; 10447 app.forcingToForeground = null; 10448 app.foregroundServices = false; 10449 app.foregroundActivities = false; 10450 app.hasShownUi = false; 10451 app.hasAboveClient = false; 10452 10453 mServices.killServicesLocked(app, allowRestart); 10454 10455 boolean restart = false; 10456 10457 // Remove published content providers. 10458 if (!app.pubProviders.isEmpty()) { 10459 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10460 while (it.hasNext()) { 10461 ContentProviderRecord cpr = it.next(); 10462 10463 final boolean always = app.bad || !allowRestart; 10464 if (removeDyingProviderLocked(app, cpr, always) || always) { 10465 // We left the provider in the launching list, need to 10466 // restart it. 10467 restart = true; 10468 } 10469 10470 cpr.provider = null; 10471 cpr.proc = null; 10472 } 10473 app.pubProviders.clear(); 10474 } 10475 10476 // Take care of any launching providers waiting for this process. 10477 if (checkAppInLaunchingProvidersLocked(app, false)) { 10478 restart = true; 10479 } 10480 10481 // Unregister from connected content providers. 10482 if (!app.conProviders.isEmpty()) { 10483 for (int i=0; i<app.conProviders.size(); i++) { 10484 ContentProviderConnection conn = app.conProviders.get(i); 10485 conn.provider.connections.remove(conn); 10486 } 10487 app.conProviders.clear(); 10488 } 10489 10490 // At this point there may be remaining entries in mLaunchingProviders 10491 // where we were the only one waiting, so they are no longer of use. 10492 // Look for these and clean up if found. 10493 // XXX Commented out for now. Trying to figure out a way to reproduce 10494 // the actual situation to identify what is actually going on. 10495 if (false) { 10496 for (int i=0; i<mLaunchingProviders.size(); i++) { 10497 ContentProviderRecord cpr = (ContentProviderRecord) 10498 mLaunchingProviders.get(i); 10499 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10500 synchronized (cpr) { 10501 cpr.launchingApp = null; 10502 cpr.notifyAll(); 10503 } 10504 } 10505 } 10506 } 10507 10508 skipCurrentReceiverLocked(app); 10509 10510 // Unregister any receivers. 10511 if (app.receivers.size() > 0) { 10512 Iterator<ReceiverList> it = app.receivers.iterator(); 10513 while (it.hasNext()) { 10514 removeReceiverLocked(it.next()); 10515 } 10516 app.receivers.clear(); 10517 } 10518 10519 // If the app is undergoing backup, tell the backup manager about it 10520 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10521 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10522 try { 10523 IBackupManager bm = IBackupManager.Stub.asInterface( 10524 ServiceManager.getService(Context.BACKUP_SERVICE)); 10525 bm.agentDisconnected(app.info.packageName); 10526 } catch (RemoteException e) { 10527 // can't happen; backup manager is local 10528 } 10529 } 10530 10531 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10532 ProcessChangeItem item = mPendingProcessChanges.get(i); 10533 if (item.pid == app.pid) { 10534 mPendingProcessChanges.remove(i); 10535 mAvailProcessChanges.add(item); 10536 } 10537 } 10538 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10539 10540 // If the caller is restarting this app, then leave it in its 10541 // current lists and let the caller take care of it. 10542 if (restarting) { 10543 return; 10544 } 10545 10546 if (!app.persistent || app.isolated) { 10547 if (DEBUG_PROCESSES) Slog.v(TAG, 10548 "Removing non-persistent process during cleanup: " + app); 10549 mProcessNames.remove(app.processName, app.uid); 10550 mIsolatedProcesses.remove(app.uid); 10551 if (mHeavyWeightProcess == app) { 10552 mHeavyWeightProcess = null; 10553 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10554 } 10555 } else if (!app.removed) { 10556 // This app is persistent, so we need to keep its record around. 10557 // If it is not already on the pending app list, add it there 10558 // and start a new process for it. 10559 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10560 mPersistentStartingProcesses.add(app); 10561 restart = true; 10562 } 10563 } 10564 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10565 "Clean-up removing on hold: " + app); 10566 mProcessesOnHold.remove(app); 10567 10568 if (app == mHomeProcess) { 10569 mHomeProcess = null; 10570 } 10571 if (app == mPreviousProcess) { 10572 mPreviousProcess = null; 10573 } 10574 10575 if (restart && !app.isolated) { 10576 // We have components that still need to be running in the 10577 // process, so re-launch it. 10578 mProcessNames.put(app.processName, app.uid, app); 10579 startProcessLocked(app, "restart", app.processName); 10580 } else if (app.pid > 0 && app.pid != MY_PID) { 10581 // Goodbye! 10582 synchronized (mPidsSelfLocked) { 10583 mPidsSelfLocked.remove(app.pid); 10584 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10585 } 10586 app.setPid(0); 10587 } 10588 } 10589 10590 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10591 // Look through the content providers we are waiting to have launched, 10592 // and if any run in this process then either schedule a restart of 10593 // the process or kill the client waiting for it if this process has 10594 // gone bad. 10595 int NL = mLaunchingProviders.size(); 10596 boolean restart = false; 10597 for (int i=0; i<NL; i++) { 10598 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10599 if (cpr.launchingApp == app) { 10600 if (!alwaysBad && !app.bad) { 10601 restart = true; 10602 } else { 10603 removeDyingProviderLocked(app, cpr, true); 10604 NL = mLaunchingProviders.size(); 10605 } 10606 } 10607 } 10608 return restart; 10609 } 10610 10611 // ========================================================= 10612 // SERVICES 10613 // ========================================================= 10614 10615 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10616 int flags) { 10617 enforceNotIsolatedCaller("getServices"); 10618 synchronized (this) { 10619 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10620 } 10621 } 10622 10623 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10624 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10625 synchronized (this) { 10626 return mServices.getRunningServiceControlPanelLocked(name); 10627 } 10628 } 10629 10630 public ComponentName startService(IApplicationThread caller, Intent service, 10631 String resolvedType, int userId) { 10632 enforceNotIsolatedCaller("startService"); 10633 // Refuse possible leaked file descriptors 10634 if (service != null && service.hasFileDescriptors() == true) { 10635 throw new IllegalArgumentException("File descriptors passed in Intent"); 10636 } 10637 10638 if (DEBUG_SERVICE) 10639 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10640 synchronized(this) { 10641 final int callingPid = Binder.getCallingPid(); 10642 final int callingUid = Binder.getCallingUid(); 10643 checkValidCaller(callingUid, userId); 10644 final long origId = Binder.clearCallingIdentity(); 10645 ComponentName res = mServices.startServiceLocked(caller, service, 10646 resolvedType, callingPid, callingUid, userId); 10647 Binder.restoreCallingIdentity(origId); 10648 return res; 10649 } 10650 } 10651 10652 ComponentName startServiceInPackage(int uid, 10653 Intent service, String resolvedType) { 10654 synchronized(this) { 10655 if (DEBUG_SERVICE) 10656 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10657 final long origId = Binder.clearCallingIdentity(); 10658 ComponentName res = mServices.startServiceLocked(null, service, 10659 resolvedType, -1, uid, UserHandle.getUserId(uid)); 10660 Binder.restoreCallingIdentity(origId); 10661 return res; 10662 } 10663 } 10664 10665 public int stopService(IApplicationThread caller, Intent service, 10666 String resolvedType, int userId) { 10667 enforceNotIsolatedCaller("stopService"); 10668 // Refuse possible leaked file descriptors 10669 if (service != null && service.hasFileDescriptors() == true) { 10670 throw new IllegalArgumentException("File descriptors passed in Intent"); 10671 } 10672 10673 checkValidCaller(Binder.getCallingUid(), userId); 10674 10675 synchronized(this) { 10676 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10677 } 10678 } 10679 10680 public IBinder peekService(Intent service, String resolvedType) { 10681 enforceNotIsolatedCaller("peekService"); 10682 // Refuse possible leaked file descriptors 10683 if (service != null && service.hasFileDescriptors() == true) { 10684 throw new IllegalArgumentException("File descriptors passed in Intent"); 10685 } 10686 synchronized(this) { 10687 return mServices.peekServiceLocked(service, resolvedType); 10688 } 10689 } 10690 10691 public boolean stopServiceToken(ComponentName className, IBinder token, 10692 int startId) { 10693 synchronized(this) { 10694 return mServices.stopServiceTokenLocked(className, token, startId); 10695 } 10696 } 10697 10698 public void setServiceForeground(ComponentName className, IBinder token, 10699 int id, Notification notification, boolean removeNotification) { 10700 synchronized(this) { 10701 mServices.setServiceForegroundLocked(className, token, id, notification, 10702 removeNotification); 10703 } 10704 } 10705 10706 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10707 String className, int flags) { 10708 boolean result = false; 10709 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10710 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10711 if (ActivityManager.checkUidPermission( 10712 android.Manifest.permission.INTERACT_ACROSS_USERS, 10713 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10714 ComponentName comp = new ComponentName(aInfo.packageName, className); 10715 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10716 + " requests FLAG_SINGLE_USER, but app does not hold " 10717 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10718 Slog.w(TAG, msg); 10719 throw new SecurityException(msg); 10720 } 10721 result = true; 10722 } 10723 } else if (componentProcessName == aInfo.packageName) { 10724 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10725 } else if ("system".equals(componentProcessName)) { 10726 result = true; 10727 } 10728 if (DEBUG_MU) { 10729 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10730 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10731 } 10732 return result; 10733 } 10734 10735 public int bindService(IApplicationThread caller, IBinder token, 10736 Intent service, String resolvedType, 10737 IServiceConnection connection, int flags, int userId) { 10738 enforceNotIsolatedCaller("bindService"); 10739 // Refuse possible leaked file descriptors 10740 if (service != null && service.hasFileDescriptors() == true) { 10741 throw new IllegalArgumentException("File descriptors passed in Intent"); 10742 } 10743 10744 checkValidCaller(Binder.getCallingUid(), userId); 10745 10746 synchronized(this) { 10747 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10748 connection, flags, userId); 10749 } 10750 } 10751 10752 public boolean unbindService(IServiceConnection connection) { 10753 synchronized (this) { 10754 return mServices.unbindServiceLocked(connection); 10755 } 10756 } 10757 10758 public void publishService(IBinder token, Intent intent, IBinder service) { 10759 // Refuse possible leaked file descriptors 10760 if (intent != null && intent.hasFileDescriptors() == true) { 10761 throw new IllegalArgumentException("File descriptors passed in Intent"); 10762 } 10763 10764 synchronized(this) { 10765 if (!(token instanceof ServiceRecord)) { 10766 throw new IllegalArgumentException("Invalid service token"); 10767 } 10768 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10769 } 10770 } 10771 10772 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10773 // Refuse possible leaked file descriptors 10774 if (intent != null && intent.hasFileDescriptors() == true) { 10775 throw new IllegalArgumentException("File descriptors passed in Intent"); 10776 } 10777 10778 synchronized(this) { 10779 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10780 } 10781 } 10782 10783 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10784 synchronized(this) { 10785 if (!(token instanceof ServiceRecord)) { 10786 throw new IllegalArgumentException("Invalid service token"); 10787 } 10788 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10789 } 10790 } 10791 10792 // ========================================================= 10793 // BACKUP AND RESTORE 10794 // ========================================================= 10795 10796 // Cause the target app to be launched if necessary and its backup agent 10797 // instantiated. The backup agent will invoke backupAgentCreated() on the 10798 // activity manager to announce its creation. 10799 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10800 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10801 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10802 10803 synchronized(this) { 10804 // !!! TODO: currently no check here that we're already bound 10805 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10806 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10807 synchronized (stats) { 10808 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10809 } 10810 10811 // Backup agent is now in use, its package can't be stopped. 10812 try { 10813 AppGlobals.getPackageManager().setPackageStoppedState( 10814 app.packageName, false, UserHandle.getUserId(app.uid)); 10815 } catch (RemoteException e) { 10816 } catch (IllegalArgumentException e) { 10817 Slog.w(TAG, "Failed trying to unstop package " 10818 + app.packageName + ": " + e); 10819 } 10820 10821 BackupRecord r = new BackupRecord(ss, app, backupMode); 10822 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10823 ? new ComponentName(app.packageName, app.backupAgentName) 10824 : new ComponentName("android", "FullBackupAgent"); 10825 // startProcessLocked() returns existing proc's record if it's already running 10826 ProcessRecord proc = startProcessLocked(app.processName, app, 10827 false, 0, "backup", hostingName, false, false); 10828 if (proc == null) { 10829 Slog.e(TAG, "Unable to start backup agent process " + r); 10830 return false; 10831 } 10832 10833 r.app = proc; 10834 mBackupTarget = r; 10835 mBackupAppName = app.packageName; 10836 10837 // Try not to kill the process during backup 10838 updateOomAdjLocked(proc); 10839 10840 // If the process is already attached, schedule the creation of the backup agent now. 10841 // If it is not yet live, this will be done when it attaches to the framework. 10842 if (proc.thread != null) { 10843 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10844 try { 10845 proc.thread.scheduleCreateBackupAgent(app, 10846 compatibilityInfoForPackageLocked(app), backupMode); 10847 } catch (RemoteException e) { 10848 // Will time out on the backup manager side 10849 } 10850 } else { 10851 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10852 } 10853 // Invariants: at this point, the target app process exists and the application 10854 // is either already running or in the process of coming up. mBackupTarget and 10855 // mBackupAppName describe the app, so that when it binds back to the AM we 10856 // know that it's scheduled for a backup-agent operation. 10857 } 10858 10859 return true; 10860 } 10861 10862 // A backup agent has just come up 10863 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10864 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10865 + " = " + agent); 10866 10867 synchronized(this) { 10868 if (!agentPackageName.equals(mBackupAppName)) { 10869 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10870 return; 10871 } 10872 } 10873 10874 long oldIdent = Binder.clearCallingIdentity(); 10875 try { 10876 IBackupManager bm = IBackupManager.Stub.asInterface( 10877 ServiceManager.getService(Context.BACKUP_SERVICE)); 10878 bm.agentConnected(agentPackageName, agent); 10879 } catch (RemoteException e) { 10880 // can't happen; the backup manager service is local 10881 } catch (Exception e) { 10882 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10883 e.printStackTrace(); 10884 } finally { 10885 Binder.restoreCallingIdentity(oldIdent); 10886 } 10887 } 10888 10889 // done with this agent 10890 public void unbindBackupAgent(ApplicationInfo appInfo) { 10891 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10892 if (appInfo == null) { 10893 Slog.w(TAG, "unbind backup agent for null app"); 10894 return; 10895 } 10896 10897 synchronized(this) { 10898 if (mBackupAppName == null) { 10899 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10900 return; 10901 } 10902 10903 if (!mBackupAppName.equals(appInfo.packageName)) { 10904 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10905 return; 10906 } 10907 10908 ProcessRecord proc = mBackupTarget.app; 10909 mBackupTarget = null; 10910 mBackupAppName = null; 10911 10912 // Not backing this app up any more; reset its OOM adjustment 10913 updateOomAdjLocked(proc); 10914 10915 // If the app crashed during backup, 'thread' will be null here 10916 if (proc.thread != null) { 10917 try { 10918 proc.thread.scheduleDestroyBackupAgent(appInfo, 10919 compatibilityInfoForPackageLocked(appInfo)); 10920 } catch (Exception e) { 10921 Slog.e(TAG, "Exception when unbinding backup agent:"); 10922 e.printStackTrace(); 10923 } 10924 } 10925 } 10926 } 10927 // ========================================================= 10928 // BROADCASTS 10929 // ========================================================= 10930 10931 private final List getStickiesLocked(String action, IntentFilter filter, 10932 List cur) { 10933 final ContentResolver resolver = mContext.getContentResolver(); 10934 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10935 if (list == null) { 10936 return cur; 10937 } 10938 int N = list.size(); 10939 for (int i=0; i<N; i++) { 10940 Intent intent = list.get(i); 10941 if (filter.match(resolver, intent, true, TAG) >= 0) { 10942 if (cur == null) { 10943 cur = new ArrayList<Intent>(); 10944 } 10945 cur.add(intent); 10946 } 10947 } 10948 return cur; 10949 } 10950 10951 boolean isPendingBroadcastProcessLocked(int pid) { 10952 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10953 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10954 } 10955 10956 void skipPendingBroadcastLocked(int pid) { 10957 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10958 for (BroadcastQueue queue : mBroadcastQueues) { 10959 queue.skipPendingBroadcastLocked(pid); 10960 } 10961 } 10962 10963 // The app just attached; send any pending broadcasts that it should receive 10964 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10965 boolean didSomething = false; 10966 for (BroadcastQueue queue : mBroadcastQueues) { 10967 didSomething |= queue.sendPendingBroadcastsLocked(app); 10968 } 10969 return didSomething; 10970 } 10971 10972 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10973 IIntentReceiver receiver, IntentFilter filter, String permission) { 10974 enforceNotIsolatedCaller("registerReceiver"); 10975 int callingUid; 10976 synchronized(this) { 10977 ProcessRecord callerApp = null; 10978 if (caller != null) { 10979 callerApp = getRecordForAppLocked(caller); 10980 if (callerApp == null) { 10981 throw new SecurityException( 10982 "Unable to find app for caller " + caller 10983 + " (pid=" + Binder.getCallingPid() 10984 + ") when registering receiver " + receiver); 10985 } 10986 if (callerApp.info.uid != Process.SYSTEM_UID && 10987 !callerApp.pkgList.contains(callerPackage)) { 10988 throw new SecurityException("Given caller package " + callerPackage 10989 + " is not running in process " + callerApp); 10990 } 10991 callingUid = callerApp.info.uid; 10992 } else { 10993 callerPackage = null; 10994 callingUid = Binder.getCallingUid(); 10995 } 10996 10997 List allSticky = null; 10998 10999 // Look for any matching sticky broadcasts... 11000 Iterator actions = filter.actionsIterator(); 11001 if (actions != null) { 11002 while (actions.hasNext()) { 11003 String action = (String)actions.next(); 11004 allSticky = getStickiesLocked(action, filter, allSticky); 11005 } 11006 } else { 11007 allSticky = getStickiesLocked(null, filter, allSticky); 11008 } 11009 11010 // The first sticky in the list is returned directly back to 11011 // the client. 11012 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11013 11014 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11015 + ": " + sticky); 11016 11017 if (receiver == null) { 11018 return sticky; 11019 } 11020 11021 ReceiverList rl 11022 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11023 if (rl == null) { 11024 rl = new ReceiverList(this, callerApp, 11025 Binder.getCallingPid(), 11026 Binder.getCallingUid(), receiver); 11027 if (rl.app != null) { 11028 rl.app.receivers.add(rl); 11029 } else { 11030 try { 11031 receiver.asBinder().linkToDeath(rl, 0); 11032 } catch (RemoteException e) { 11033 return sticky; 11034 } 11035 rl.linkedToDeath = true; 11036 } 11037 mRegisteredReceivers.put(receiver.asBinder(), rl); 11038 } 11039 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11040 permission, callingUid); 11041 rl.add(bf); 11042 if (!bf.debugCheck()) { 11043 Slog.w(TAG, "==> For Dynamic broadast"); 11044 } 11045 mReceiverResolver.addFilter(bf); 11046 11047 // Enqueue broadcasts for all existing stickies that match 11048 // this filter. 11049 if (allSticky != null) { 11050 ArrayList receivers = new ArrayList(); 11051 receivers.add(bf); 11052 11053 int N = allSticky.size(); 11054 for (int i=0; i<N; i++) { 11055 Intent intent = (Intent)allSticky.get(i); 11056 BroadcastQueue queue = broadcastQueueForIntent(intent); 11057 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11058 null, -1, -1, null, receivers, null, 0, null, null, 11059 false, true, true, -1); 11060 queue.enqueueParallelBroadcastLocked(r); 11061 queue.scheduleBroadcastsLocked(); 11062 } 11063 } 11064 11065 return sticky; 11066 } 11067 } 11068 11069 public void unregisterReceiver(IIntentReceiver receiver) { 11070 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11071 11072 final long origId = Binder.clearCallingIdentity(); 11073 try { 11074 boolean doTrim = false; 11075 11076 synchronized(this) { 11077 ReceiverList rl 11078 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11079 if (rl != null) { 11080 if (rl.curBroadcast != null) { 11081 BroadcastRecord r = rl.curBroadcast; 11082 final boolean doNext = finishReceiverLocked( 11083 receiver.asBinder(), r.resultCode, r.resultData, 11084 r.resultExtras, r.resultAbort, true); 11085 if (doNext) { 11086 doTrim = true; 11087 r.queue.processNextBroadcast(false); 11088 } 11089 } 11090 11091 if (rl.app != null) { 11092 rl.app.receivers.remove(rl); 11093 } 11094 removeReceiverLocked(rl); 11095 if (rl.linkedToDeath) { 11096 rl.linkedToDeath = false; 11097 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11098 } 11099 } 11100 } 11101 11102 // If we actually concluded any broadcasts, we might now be able 11103 // to trim the recipients' apps from our working set 11104 if (doTrim) { 11105 trimApplications(); 11106 return; 11107 } 11108 11109 } finally { 11110 Binder.restoreCallingIdentity(origId); 11111 } 11112 } 11113 11114 void removeReceiverLocked(ReceiverList rl) { 11115 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11116 int N = rl.size(); 11117 for (int i=0; i<N; i++) { 11118 mReceiverResolver.removeFilter(rl.get(i)); 11119 } 11120 } 11121 11122 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11123 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11124 ProcessRecord r = mLruProcesses.get(i); 11125 if (r.thread != null) { 11126 try { 11127 r.thread.dispatchPackageBroadcast(cmd, packages); 11128 } catch (RemoteException ex) { 11129 } 11130 } 11131 } 11132 } 11133 11134 private final int broadcastIntentLocked(ProcessRecord callerApp, 11135 String callerPackage, Intent intent, String resolvedType, 11136 IIntentReceiver resultTo, int resultCode, String resultData, 11137 Bundle map, String requiredPermission, 11138 boolean ordered, boolean sticky, int callingPid, int callingUid, 11139 int userId) { 11140 intent = new Intent(intent); 11141 11142 // By default broadcasts do not go to stopped apps. 11143 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11144 11145 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11146 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11147 + " ordered=" + ordered + " userid=" + userId); 11148 if ((resultTo != null) && !ordered) { 11149 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11150 } 11151 11152 // If the caller is trying to send this broadcast to a different 11153 // user, verify that is allowed. 11154 if (UserHandle.getUserId(callingUid) != userId) { 11155 if (checkComponentPermission( 11156 android.Manifest.permission.INTERACT_ACROSS_USERS, 11157 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED 11158 && checkComponentPermission( 11159 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11160 callingPid, callingUid, -1, true) 11161 != PackageManager.PERMISSION_GRANTED) { 11162 String msg = "Permission Denial: " + intent.getAction() 11163 + " broadcast from " + callerPackage 11164 + " asks to send as user " + userId 11165 + " but is calling from user " + UserHandle.getUserId(callingUid) 11166 + "; this requires " 11167 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11168 Slog.w(TAG, msg); 11169 throw new SecurityException(msg); 11170 } else { 11171 if (userId == UserHandle.USER_CURRENT) { 11172 userId = mCurrentUserId; 11173 } 11174 } 11175 } 11176 11177 // Make sure that the user who is receiving this broadcast is started 11178 // If not, we will just skip it. 11179 if (mStartedUsers.get(userId) == null) { 11180 Slog.w(TAG, "Skipping broadcast of " + intent 11181 + ": user " + userId + " is stopped"); 11182 return ActivityManager.BROADCAST_SUCCESS; 11183 } 11184 11185 // Handle special intents: if this broadcast is from the package 11186 // manager about a package being removed, we need to remove all of 11187 // its activities from the history stack. 11188 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11189 intent.getAction()); 11190 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11191 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11192 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11193 || uidRemoved) { 11194 if (checkComponentPermission( 11195 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11196 callingPid, callingUid, -1, true) 11197 == PackageManager.PERMISSION_GRANTED) { 11198 if (uidRemoved) { 11199 final Bundle intentExtras = intent.getExtras(); 11200 final int uid = intentExtras != null 11201 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11202 if (uid >= 0) { 11203 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11204 synchronized (bs) { 11205 bs.removeUidStatsLocked(uid); 11206 } 11207 } 11208 } else { 11209 // If resources are unvailble just force stop all 11210 // those packages and flush the attribute cache as well. 11211 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11212 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11213 if (list != null && (list.length > 0)) { 11214 for (String pkg : list) { 11215 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11216 } 11217 sendPackageBroadcastLocked( 11218 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11219 } 11220 } else { 11221 Uri data = intent.getData(); 11222 String ssp; 11223 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11224 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11225 forceStopPackageLocked(ssp, 11226 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11227 false, userId); 11228 } 11229 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11230 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11231 new String[] {ssp}); 11232 } 11233 } 11234 } 11235 } 11236 } else { 11237 String msg = "Permission Denial: " + intent.getAction() 11238 + " broadcast from " + callerPackage + " (pid=" + callingPid 11239 + ", uid=" + callingUid + ")" 11240 + " requires " 11241 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11242 Slog.w(TAG, msg); 11243 throw new SecurityException(msg); 11244 } 11245 11246 // Special case for adding a package: by default turn on compatibility 11247 // mode. 11248 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11249 Uri data = intent.getData(); 11250 String ssp; 11251 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11252 mCompatModePackages.handlePackageAddedLocked(ssp, 11253 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11254 } 11255 } 11256 11257 /* 11258 * If this is the time zone changed action, queue up a message that will reset the timezone 11259 * of all currently running processes. This message will get queued up before the broadcast 11260 * happens. 11261 */ 11262 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11263 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11264 } 11265 11266 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11267 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11268 } 11269 11270 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11271 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11272 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11273 } 11274 11275 /* 11276 * Prevent non-system code (defined here to be non-persistent 11277 * processes) from sending protected broadcasts. 11278 */ 11279 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11280 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11281 callingUid == 0) { 11282 // Always okay. 11283 } else if (callerApp == null || !callerApp.persistent) { 11284 try { 11285 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11286 intent.getAction())) { 11287 String msg = "Permission Denial: not allowed to send broadcast " 11288 + intent.getAction() + " from pid=" 11289 + callingPid + ", uid=" + callingUid; 11290 Slog.w(TAG, msg); 11291 throw new SecurityException(msg); 11292 } 11293 } catch (RemoteException e) { 11294 Slog.w(TAG, "Remote exception", e); 11295 return ActivityManager.BROADCAST_SUCCESS; 11296 } 11297 } 11298 11299 // Add to the sticky list if requested. 11300 if (sticky) { 11301 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11302 callingPid, callingUid) 11303 != PackageManager.PERMISSION_GRANTED) { 11304 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11305 + callingPid + ", uid=" + callingUid 11306 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11307 Slog.w(TAG, msg); 11308 throw new SecurityException(msg); 11309 } 11310 if (requiredPermission != null) { 11311 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11312 + " and enforce permission " + requiredPermission); 11313 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11314 } 11315 if (intent.getComponent() != null) { 11316 throw new SecurityException( 11317 "Sticky broadcasts can't target a specific component"); 11318 } 11319 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11320 if (list == null) { 11321 list = new ArrayList<Intent>(); 11322 mStickyBroadcasts.put(intent.getAction(), list); 11323 } 11324 int N = list.size(); 11325 int i; 11326 for (i=0; i<N; i++) { 11327 if (intent.filterEquals(list.get(i))) { 11328 // This sticky already exists, replace it. 11329 list.set(i, new Intent(intent)); 11330 break; 11331 } 11332 } 11333 if (i >= N) { 11334 list.add(new Intent(intent)); 11335 } 11336 } 11337 11338 // Figure out who all will receive this broadcast. 11339 List receivers = null; 11340 List<BroadcastFilter> registeredReceivers = null; 11341 try { 11342 // Need to resolve the intent to interested receivers... 11343 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11344 == 0) { 11345 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11346 intent, resolvedType, STOCK_PM_FLAGS, userId); 11347 } 11348 if (intent.getComponent() == null) { 11349 registeredReceivers = mReceiverResolver.queryIntent(intent, 11350 resolvedType, false, userId); 11351 } 11352 } catch (RemoteException ex) { 11353 // pm is in same process, this will never happen. 11354 } 11355 11356 final boolean replacePending = 11357 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11358 11359 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11360 + " replacePending=" + replacePending); 11361 11362 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11363 if (!ordered && NR > 0) { 11364 // If we are not serializing this broadcast, then send the 11365 // registered receivers separately so they don't wait for the 11366 // components to be launched. 11367 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11368 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11369 callerPackage, callingPid, callingUid, requiredPermission, 11370 registeredReceivers, resultTo, resultCode, resultData, map, 11371 ordered, sticky, false, userId); 11372 if (DEBUG_BROADCAST) Slog.v( 11373 TAG, "Enqueueing parallel broadcast " + r); 11374 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11375 if (!replaced) { 11376 queue.enqueueParallelBroadcastLocked(r); 11377 queue.scheduleBroadcastsLocked(); 11378 } 11379 registeredReceivers = null; 11380 NR = 0; 11381 } 11382 11383 // Merge into one list. 11384 int ir = 0; 11385 if (receivers != null) { 11386 // A special case for PACKAGE_ADDED: do not allow the package 11387 // being added to see this broadcast. This prevents them from 11388 // using this as a back door to get run as soon as they are 11389 // installed. Maybe in the future we want to have a special install 11390 // broadcast or such for apps, but we'd like to deliberately make 11391 // this decision. 11392 String skipPackages[] = null; 11393 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11394 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11395 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11396 Uri data = intent.getData(); 11397 if (data != null) { 11398 String pkgName = data.getSchemeSpecificPart(); 11399 if (pkgName != null) { 11400 skipPackages = new String[] { pkgName }; 11401 } 11402 } 11403 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11404 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11405 } 11406 if (skipPackages != null && (skipPackages.length > 0)) { 11407 for (String skipPackage : skipPackages) { 11408 if (skipPackage != null) { 11409 int NT = receivers.size(); 11410 for (int it=0; it<NT; it++) { 11411 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11412 if (curt.activityInfo.packageName.equals(skipPackage)) { 11413 receivers.remove(it); 11414 it--; 11415 NT--; 11416 } 11417 } 11418 } 11419 } 11420 } 11421 11422 int NT = receivers != null ? receivers.size() : 0; 11423 int it = 0; 11424 ResolveInfo curt = null; 11425 BroadcastFilter curr = null; 11426 while (it < NT && ir < NR) { 11427 if (curt == null) { 11428 curt = (ResolveInfo)receivers.get(it); 11429 } 11430 if (curr == null) { 11431 curr = registeredReceivers.get(ir); 11432 } 11433 if (curr.getPriority() >= curt.priority) { 11434 // Insert this broadcast record into the final list. 11435 receivers.add(it, curr); 11436 ir++; 11437 curr = null; 11438 it++; 11439 NT++; 11440 } else { 11441 // Skip to the next ResolveInfo in the final list. 11442 it++; 11443 curt = null; 11444 } 11445 } 11446 } 11447 while (ir < NR) { 11448 if (receivers == null) { 11449 receivers = new ArrayList(); 11450 } 11451 receivers.add(registeredReceivers.get(ir)); 11452 ir++; 11453 } 11454 11455 if ((receivers != null && receivers.size() > 0) 11456 || resultTo != null) { 11457 BroadcastQueue queue = broadcastQueueForIntent(intent); 11458 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11459 callerPackage, callingPid, callingUid, requiredPermission, 11460 receivers, resultTo, resultCode, resultData, map, ordered, 11461 sticky, false, userId); 11462 if (DEBUG_BROADCAST) Slog.v( 11463 TAG, "Enqueueing ordered broadcast " + r 11464 + ": prev had " + queue.mOrderedBroadcasts.size()); 11465 if (DEBUG_BROADCAST) { 11466 int seq = r.intent.getIntExtra("seq", -1); 11467 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11468 } 11469 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11470 if (!replaced) { 11471 queue.enqueueOrderedBroadcastLocked(r); 11472 queue.scheduleBroadcastsLocked(); 11473 } 11474 } 11475 11476 return ActivityManager.BROADCAST_SUCCESS; 11477 } 11478 11479 final Intent verifyBroadcastLocked(Intent intent) { 11480 // Refuse possible leaked file descriptors 11481 if (intent != null && intent.hasFileDescriptors() == true) { 11482 throw new IllegalArgumentException("File descriptors passed in Intent"); 11483 } 11484 11485 int flags = intent.getFlags(); 11486 11487 if (!mProcessesReady) { 11488 // if the caller really truly claims to know what they're doing, go 11489 // ahead and allow the broadcast without launching any receivers 11490 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11491 intent = new Intent(intent); 11492 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11493 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11494 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11495 + " before boot completion"); 11496 throw new IllegalStateException("Cannot broadcast before boot completed"); 11497 } 11498 } 11499 11500 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11501 throw new IllegalArgumentException( 11502 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11503 } 11504 11505 return intent; 11506 } 11507 11508 public final int broadcastIntent(IApplicationThread caller, 11509 Intent intent, String resolvedType, IIntentReceiver resultTo, 11510 int resultCode, String resultData, Bundle map, 11511 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11512 enforceNotIsolatedCaller("broadcastIntent"); 11513 synchronized(this) { 11514 intent = verifyBroadcastLocked(intent); 11515 11516 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11517 final int callingPid = Binder.getCallingPid(); 11518 final int callingUid = Binder.getCallingUid(); 11519 final long origId = Binder.clearCallingIdentity(); 11520 int res = broadcastIntentLocked(callerApp, 11521 callerApp != null ? callerApp.info.packageName : null, 11522 intent, resolvedType, resultTo, 11523 resultCode, resultData, map, requiredPermission, serialized, sticky, 11524 callingPid, callingUid, userId); 11525 Binder.restoreCallingIdentity(origId); 11526 return res; 11527 } 11528 } 11529 11530 int broadcastIntentInPackage(String packageName, int uid, 11531 Intent intent, String resolvedType, IIntentReceiver resultTo, 11532 int resultCode, String resultData, Bundle map, 11533 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11534 synchronized(this) { 11535 intent = verifyBroadcastLocked(intent); 11536 11537 final long origId = Binder.clearCallingIdentity(); 11538 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11539 resultTo, resultCode, resultData, map, requiredPermission, 11540 serialized, sticky, -1, uid, userId); 11541 Binder.restoreCallingIdentity(origId); 11542 return res; 11543 } 11544 } 11545 11546 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11547 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11548 // Refuse possible leaked file descriptors 11549 if (intent != null && intent.hasFileDescriptors() == true) { 11550 throw new IllegalArgumentException("File descriptors passed in Intent"); 11551 } 11552 11553 synchronized(this) { 11554 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11555 != PackageManager.PERMISSION_GRANTED) { 11556 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11557 + Binder.getCallingPid() 11558 + ", uid=" + Binder.getCallingUid() 11559 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11560 Slog.w(TAG, msg); 11561 throw new SecurityException(msg); 11562 } 11563 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11564 if (list != null) { 11565 int N = list.size(); 11566 int i; 11567 for (i=0; i<N; i++) { 11568 if (intent.filterEquals(list.get(i))) { 11569 list.remove(i); 11570 break; 11571 } 11572 } 11573 } 11574 } 11575 } 11576 11577 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11578 String resultData, Bundle resultExtras, boolean resultAbort, 11579 boolean explicit) { 11580 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11581 if (r == null) { 11582 Slog.w(TAG, "finishReceiver called but not found on queue"); 11583 return false; 11584 } 11585 11586 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11587 explicit); 11588 } 11589 11590 public void finishReceiver(IBinder who, int resultCode, String resultData, 11591 Bundle resultExtras, boolean resultAbort) { 11592 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11593 11594 // Refuse possible leaked file descriptors 11595 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11596 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11597 } 11598 11599 final long origId = Binder.clearCallingIdentity(); 11600 try { 11601 boolean doNext = false; 11602 BroadcastRecord r = null; 11603 11604 synchronized(this) { 11605 r = broadcastRecordForReceiverLocked(who); 11606 if (r != null) { 11607 doNext = r.queue.finishReceiverLocked(r, resultCode, 11608 resultData, resultExtras, resultAbort, true); 11609 } 11610 } 11611 11612 if (doNext) { 11613 r.queue.processNextBroadcast(false); 11614 } 11615 trimApplications(); 11616 } finally { 11617 Binder.restoreCallingIdentity(origId); 11618 } 11619 } 11620 11621 // ========================================================= 11622 // INSTRUMENTATION 11623 // ========================================================= 11624 11625 public boolean startInstrumentation(ComponentName className, 11626 String profileFile, int flags, Bundle arguments, 11627 IInstrumentationWatcher watcher) { 11628 enforceNotIsolatedCaller("startInstrumentation"); 11629 // Refuse possible leaked file descriptors 11630 if (arguments != null && arguments.hasFileDescriptors()) { 11631 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11632 } 11633 11634 synchronized(this) { 11635 InstrumentationInfo ii = null; 11636 ApplicationInfo ai = null; 11637 try { 11638 ii = mContext.getPackageManager().getInstrumentationInfo( 11639 className, STOCK_PM_FLAGS); 11640 ai = mContext.getPackageManager().getApplicationInfo( 11641 ii.targetPackage, STOCK_PM_FLAGS); 11642 } catch (PackageManager.NameNotFoundException e) { 11643 } 11644 if (ii == null) { 11645 reportStartInstrumentationFailure(watcher, className, 11646 "Unable to find instrumentation info for: " + className); 11647 return false; 11648 } 11649 if (ai == null) { 11650 reportStartInstrumentationFailure(watcher, className, 11651 "Unable to find instrumentation target package: " + ii.targetPackage); 11652 return false; 11653 } 11654 11655 int match = mContext.getPackageManager().checkSignatures( 11656 ii.targetPackage, ii.packageName); 11657 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11658 String msg = "Permission Denial: starting instrumentation " 11659 + className + " from pid=" 11660 + Binder.getCallingPid() 11661 + ", uid=" + Binder.getCallingPid() 11662 + " not allowed because package " + ii.packageName 11663 + " does not have a signature matching the target " 11664 + ii.targetPackage; 11665 reportStartInstrumentationFailure(watcher, className, msg); 11666 throw new SecurityException(msg); 11667 } 11668 11669 int userId = UserHandle.getCallingUserId(); 11670 final long origId = Binder.clearCallingIdentity(); 11671 // Instrumentation can kill and relaunch even persistent processes 11672 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11673 ProcessRecord app = addAppLocked(ai, false); 11674 app.instrumentationClass = className; 11675 app.instrumentationInfo = ai; 11676 app.instrumentationProfileFile = profileFile; 11677 app.instrumentationArguments = arguments; 11678 app.instrumentationWatcher = watcher; 11679 app.instrumentationResultClass = className; 11680 Binder.restoreCallingIdentity(origId); 11681 } 11682 11683 return true; 11684 } 11685 11686 /** 11687 * Report errors that occur while attempting to start Instrumentation. Always writes the 11688 * error to the logs, but if somebody is watching, send the report there too. This enables 11689 * the "am" command to report errors with more information. 11690 * 11691 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11692 * @param cn The component name of the instrumentation. 11693 * @param report The error report. 11694 */ 11695 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11696 ComponentName cn, String report) { 11697 Slog.w(TAG, report); 11698 try { 11699 if (watcher != null) { 11700 Bundle results = new Bundle(); 11701 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11702 results.putString("Error", report); 11703 watcher.instrumentationStatus(cn, -1, results); 11704 } 11705 } catch (RemoteException e) { 11706 Slog.w(TAG, e); 11707 } 11708 } 11709 11710 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11711 if (app.instrumentationWatcher != null) { 11712 try { 11713 // NOTE: IInstrumentationWatcher *must* be oneway here 11714 app.instrumentationWatcher.instrumentationFinished( 11715 app.instrumentationClass, 11716 resultCode, 11717 results); 11718 } catch (RemoteException e) { 11719 } 11720 } 11721 app.instrumentationWatcher = null; 11722 app.instrumentationClass = null; 11723 app.instrumentationInfo = null; 11724 app.instrumentationProfileFile = null; 11725 app.instrumentationArguments = null; 11726 11727 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 11728 } 11729 11730 public void finishInstrumentation(IApplicationThread target, 11731 int resultCode, Bundle results) { 11732 int userId = UserHandle.getCallingUserId(); 11733 // Refuse possible leaked file descriptors 11734 if (results != null && results.hasFileDescriptors()) { 11735 throw new IllegalArgumentException("File descriptors passed in Intent"); 11736 } 11737 11738 synchronized(this) { 11739 ProcessRecord app = getRecordForAppLocked(target); 11740 if (app == null) { 11741 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11742 return; 11743 } 11744 final long origId = Binder.clearCallingIdentity(); 11745 finishInstrumentationLocked(app, resultCode, results); 11746 Binder.restoreCallingIdentity(origId); 11747 } 11748 } 11749 11750 // ========================================================= 11751 // CONFIGURATION 11752 // ========================================================= 11753 11754 public ConfigurationInfo getDeviceConfigurationInfo() { 11755 ConfigurationInfo config = new ConfigurationInfo(); 11756 synchronized (this) { 11757 config.reqTouchScreen = mConfiguration.touchscreen; 11758 config.reqKeyboardType = mConfiguration.keyboard; 11759 config.reqNavigation = mConfiguration.navigation; 11760 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11761 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11762 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11763 } 11764 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11765 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11766 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11767 } 11768 config.reqGlEsVersion = GL_ES_VERSION; 11769 } 11770 return config; 11771 } 11772 11773 public Configuration getConfiguration() { 11774 Configuration ci; 11775 synchronized(this) { 11776 ci = new Configuration(mConfiguration); 11777 } 11778 return ci; 11779 } 11780 11781 public void updatePersistentConfiguration(Configuration values) { 11782 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11783 "updateConfiguration()"); 11784 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11785 "updateConfiguration()"); 11786 if (values == null) { 11787 throw new NullPointerException("Configuration must not be null"); 11788 } 11789 11790 synchronized(this) { 11791 final long origId = Binder.clearCallingIdentity(); 11792 updateConfigurationLocked(values, null, true, false); 11793 Binder.restoreCallingIdentity(origId); 11794 } 11795 } 11796 11797 public void updateConfiguration(Configuration values) { 11798 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11799 "updateConfiguration()"); 11800 11801 synchronized(this) { 11802 if (values == null && mWindowManager != null) { 11803 // sentinel: fetch the current configuration from the window manager 11804 values = mWindowManager.computeNewConfiguration(); 11805 } 11806 11807 if (mWindowManager != null) { 11808 mProcessList.applyDisplaySize(mWindowManager); 11809 } 11810 11811 final long origId = Binder.clearCallingIdentity(); 11812 if (values != null) { 11813 Settings.System.clearConfiguration(values); 11814 } 11815 updateConfigurationLocked(values, null, false, false); 11816 Binder.restoreCallingIdentity(origId); 11817 } 11818 } 11819 11820 /** 11821 * Do either or both things: (1) change the current configuration, and (2) 11822 * make sure the given activity is running with the (now) current 11823 * configuration. Returns true if the activity has been left running, or 11824 * false if <var>starting</var> is being destroyed to match the new 11825 * configuration. 11826 * @param persistent TODO 11827 */ 11828 boolean updateConfigurationLocked(Configuration values, 11829 ActivityRecord starting, boolean persistent, boolean initLocale) { 11830 // do nothing if we are headless 11831 if (mHeadless) return true; 11832 11833 int changes = 0; 11834 11835 boolean kept = true; 11836 11837 if (values != null) { 11838 Configuration newConfig = new Configuration(mConfiguration); 11839 changes = newConfig.updateFrom(values); 11840 if (changes != 0) { 11841 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11842 Slog.i(TAG, "Updating configuration to: " + values); 11843 } 11844 11845 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11846 11847 if (values.locale != null && !initLocale) { 11848 saveLocaleLocked(values.locale, 11849 !values.locale.equals(mConfiguration.locale), 11850 values.userSetLocale); 11851 } 11852 11853 mConfigurationSeq++; 11854 if (mConfigurationSeq <= 0) { 11855 mConfigurationSeq = 1; 11856 } 11857 newConfig.seq = mConfigurationSeq; 11858 mConfiguration = newConfig; 11859 Slog.i(TAG, "Config changed: " + newConfig); 11860 11861 final Configuration configCopy = new Configuration(mConfiguration); 11862 11863 // TODO: If our config changes, should we auto dismiss any currently 11864 // showing dialogs? 11865 mShowDialogs = shouldShowDialogs(newConfig); 11866 11867 AttributeCache ac = AttributeCache.instance(); 11868 if (ac != null) { 11869 ac.updateConfiguration(configCopy); 11870 } 11871 11872 // Make sure all resources in our process are updated 11873 // right now, so that anyone who is going to retrieve 11874 // resource values after we return will be sure to get 11875 // the new ones. This is especially important during 11876 // boot, where the first config change needs to guarantee 11877 // all resources have that config before following boot 11878 // code is executed. 11879 mSystemThread.applyConfigurationToResources(configCopy); 11880 11881 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11882 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11883 msg.obj = new Configuration(configCopy); 11884 mHandler.sendMessage(msg); 11885 } 11886 11887 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11888 ProcessRecord app = mLruProcesses.get(i); 11889 try { 11890 if (app.thread != null) { 11891 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11892 + app.processName + " new config " + mConfiguration); 11893 app.thread.scheduleConfigurationChanged(configCopy); 11894 } 11895 } catch (Exception e) { 11896 } 11897 } 11898 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11899 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11900 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11901 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11902 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11903 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11904 broadcastIntentLocked(null, null, 11905 new Intent(Intent.ACTION_LOCALE_CHANGED), 11906 null, null, 0, null, null, 11907 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11908 } 11909 } 11910 } 11911 11912 if (changes != 0 && starting == null) { 11913 // If the configuration changed, and the caller is not already 11914 // in the process of starting an activity, then find the top 11915 // activity to check if its configuration needs to change. 11916 starting = mMainStack.topRunningActivityLocked(null); 11917 } 11918 11919 if (starting != null) { 11920 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11921 // And we need to make sure at this point that all other activities 11922 // are made visible with the correct configuration. 11923 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11924 } 11925 11926 if (values != null && mWindowManager != null) { 11927 mWindowManager.setNewConfiguration(mConfiguration); 11928 } 11929 11930 return kept; 11931 } 11932 11933 /** 11934 * Decide based on the configuration whether we should shouw the ANR, 11935 * crash, etc dialogs. The idea is that if there is no affordnace to 11936 * press the on-screen buttons, we shouldn't show the dialog. 11937 * 11938 * A thought: SystemUI might also want to get told about this, the Power 11939 * dialog / global actions also might want different behaviors. 11940 */ 11941 private static final boolean shouldShowDialogs(Configuration config) { 11942 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11943 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11944 } 11945 11946 /** 11947 * Save the locale. You must be inside a synchronized (this) block. 11948 */ 11949 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11950 if(isDiff) { 11951 SystemProperties.set("user.language", l.getLanguage()); 11952 SystemProperties.set("user.region", l.getCountry()); 11953 } 11954 11955 if(isPersist) { 11956 SystemProperties.set("persist.sys.language", l.getLanguage()); 11957 SystemProperties.set("persist.sys.country", l.getCountry()); 11958 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11959 } 11960 } 11961 11962 @Override 11963 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11964 ActivityRecord srec = ActivityRecord.forToken(token); 11965 return srec != null && srec.task.affinity != null && 11966 srec.task.affinity.equals(destAffinity); 11967 } 11968 11969 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11970 Intent resultData) { 11971 ComponentName dest = destIntent.getComponent(); 11972 11973 synchronized (this) { 11974 ActivityRecord srec = ActivityRecord.forToken(token); 11975 if (srec == null) { 11976 return false; 11977 } 11978 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11979 final int start = history.indexOf(srec); 11980 if (start < 0) { 11981 // Current activity is not in history stack; do nothing. 11982 return false; 11983 } 11984 int finishTo = start - 1; 11985 ActivityRecord parent = null; 11986 boolean foundParentInTask = false; 11987 if (dest != null) { 11988 TaskRecord tr = srec.task; 11989 for (int i = start - 1; i >= 0; i--) { 11990 ActivityRecord r = history.get(i); 11991 if (tr != r.task) { 11992 // Couldn't find parent in the same task; stop at the one above this. 11993 // (Root of current task; in-app "home" behavior) 11994 // Always at least finish the current activity. 11995 finishTo = Math.min(start - 1, i + 1); 11996 parent = history.get(finishTo); 11997 break; 11998 } else if (r.info.packageName.equals(dest.getPackageName()) && 11999 r.info.name.equals(dest.getClassName())) { 12000 finishTo = i; 12001 parent = r; 12002 foundParentInTask = true; 12003 break; 12004 } 12005 } 12006 } 12007 12008 if (mController != null) { 12009 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12010 if (next != null) { 12011 // ask watcher if this is allowed 12012 boolean resumeOK = true; 12013 try { 12014 resumeOK = mController.activityResuming(next.packageName); 12015 } catch (RemoteException e) { 12016 mController = null; 12017 } 12018 12019 if (!resumeOK) { 12020 return false; 12021 } 12022 } 12023 } 12024 final long origId = Binder.clearCallingIdentity(); 12025 for (int i = start; i > finishTo; i--) { 12026 ActivityRecord r = history.get(i); 12027 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12028 "navigate-up"); 12029 // Only return the supplied result for the first activity finished 12030 resultCode = Activity.RESULT_CANCELED; 12031 resultData = null; 12032 } 12033 12034 if (parent != null && foundParentInTask) { 12035 final int parentLaunchMode = parent.info.launchMode; 12036 final int destIntentFlags = destIntent.getFlags(); 12037 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12038 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12039 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12040 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12041 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12042 } else { 12043 try { 12044 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12045 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12046 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12047 null, aInfo, parent.appToken, null, 12048 0, -1, parent.launchedFromUid, 0, null, true, null); 12049 foundParentInTask = res == ActivityManager.START_SUCCESS; 12050 } catch (RemoteException e) { 12051 foundParentInTask = false; 12052 } 12053 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12054 resultData, "navigate-up"); 12055 } 12056 } 12057 Binder.restoreCallingIdentity(origId); 12058 return foundParentInTask; 12059 } 12060 } 12061 12062 public int getLaunchedFromUid(IBinder activityToken) { 12063 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12064 if (srec == null) { 12065 return -1; 12066 } 12067 return srec.launchedFromUid; 12068 } 12069 12070 // ========================================================= 12071 // LIFETIME MANAGEMENT 12072 // ========================================================= 12073 12074 // Returns which broadcast queue the app is the current [or imminent] receiver 12075 // on, or 'null' if the app is not an active broadcast recipient. 12076 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12077 BroadcastRecord r = app.curReceiver; 12078 if (r != null) { 12079 return r.queue; 12080 } 12081 12082 // It's not the current receiver, but it might be starting up to become one 12083 synchronized (this) { 12084 for (BroadcastQueue queue : mBroadcastQueues) { 12085 r = queue.mPendingBroadcast; 12086 if (r != null && r.curApp == app) { 12087 // found it; report which queue it's in 12088 return queue; 12089 } 12090 } 12091 } 12092 12093 return null; 12094 } 12095 12096 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12097 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12098 if (mAdjSeq == app.adjSeq) { 12099 // This adjustment has already been computed. If we are calling 12100 // from the top, we may have already computed our adjustment with 12101 // an earlier hidden adjustment that isn't really for us... if 12102 // so, use the new hidden adjustment. 12103 if (!recursed && app.hidden) { 12104 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12105 app.hasActivities ? hiddenAdj : emptyAdj; 12106 } 12107 return app.curRawAdj; 12108 } 12109 12110 if (app.thread == null) { 12111 app.adjSeq = mAdjSeq; 12112 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12113 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12114 } 12115 12116 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12117 app.adjSource = null; 12118 app.adjTarget = null; 12119 app.empty = false; 12120 app.hidden = false; 12121 12122 final int activitiesSize = app.activities.size(); 12123 12124 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12125 // The max adjustment doesn't allow this app to be anything 12126 // below foreground, so it is not worth doing work for it. 12127 app.adjType = "fixed"; 12128 app.adjSeq = mAdjSeq; 12129 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12130 app.hasActivities = false; 12131 app.foregroundActivities = false; 12132 app.keeping = true; 12133 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12134 // System process can do UI, and when they do we want to have 12135 // them trim their memory after the user leaves the UI. To 12136 // facilitate this, here we need to determine whether or not it 12137 // is currently showing UI. 12138 app.systemNoUi = true; 12139 if (app == TOP_APP) { 12140 app.systemNoUi = false; 12141 app.hasActivities = true; 12142 } else if (activitiesSize > 0) { 12143 for (int j = 0; j < activitiesSize; j++) { 12144 final ActivityRecord r = app.activities.get(j); 12145 if (r.visible) { 12146 app.systemNoUi = false; 12147 } 12148 if (r.app == app) { 12149 app.hasActivities = true; 12150 } 12151 } 12152 } 12153 return (app.curAdj=app.maxAdj); 12154 } 12155 12156 app.keeping = false; 12157 app.systemNoUi = false; 12158 app.hasActivities = false; 12159 12160 // Determine the importance of the process, starting with most 12161 // important to least, and assign an appropriate OOM adjustment. 12162 int adj; 12163 int schedGroup; 12164 boolean foregroundActivities = false; 12165 boolean interesting = false; 12166 BroadcastQueue queue; 12167 if (app == TOP_APP) { 12168 // The last app on the list is the foreground app. 12169 adj = ProcessList.FOREGROUND_APP_ADJ; 12170 schedGroup = Process.THREAD_GROUP_DEFAULT; 12171 app.adjType = "top-activity"; 12172 foregroundActivities = true; 12173 interesting = true; 12174 app.hasActivities = true; 12175 } else if (app.instrumentationClass != null) { 12176 // Don't want to kill running instrumentation. 12177 adj = ProcessList.FOREGROUND_APP_ADJ; 12178 schedGroup = Process.THREAD_GROUP_DEFAULT; 12179 app.adjType = "instrumentation"; 12180 interesting = true; 12181 } else if ((queue = isReceivingBroadcast(app)) != null) { 12182 // An app that is currently receiving a broadcast also 12183 // counts as being in the foreground for OOM killer purposes. 12184 // It's placed in a sched group based on the nature of the 12185 // broadcast as reflected by which queue it's active in. 12186 adj = ProcessList.FOREGROUND_APP_ADJ; 12187 schedGroup = (queue == mFgBroadcastQueue) 12188 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12189 app.adjType = "broadcast"; 12190 } else if (app.executingServices.size() > 0) { 12191 // An app that is currently executing a service callback also 12192 // counts as being in the foreground. 12193 adj = ProcessList.FOREGROUND_APP_ADJ; 12194 schedGroup = Process.THREAD_GROUP_DEFAULT; 12195 app.adjType = "exec-service"; 12196 } else { 12197 // Assume process is hidden (has activities); we will correct 12198 // later if this is not the case. 12199 adj = hiddenAdj; 12200 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12201 app.hidden = true; 12202 app.adjType = "bg-activities"; 12203 } 12204 12205 boolean hasStoppingActivities = false; 12206 12207 // Examine all activities if not already foreground. 12208 if (!foregroundActivities && activitiesSize > 0) { 12209 for (int j = 0; j < activitiesSize; j++) { 12210 final ActivityRecord r = app.activities.get(j); 12211 if (r.visible) { 12212 // App has a visible activity; only upgrade adjustment. 12213 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12214 adj = ProcessList.VISIBLE_APP_ADJ; 12215 app.adjType = "visible"; 12216 } 12217 schedGroup = Process.THREAD_GROUP_DEFAULT; 12218 app.hidden = false; 12219 app.hasActivities = true; 12220 foregroundActivities = true; 12221 break; 12222 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12223 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12224 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12225 app.adjType = "pausing"; 12226 } 12227 app.hidden = false; 12228 foregroundActivities = true; 12229 } else if (r.state == ActivityState.STOPPING) { 12230 // We will apply the actual adjustment later, because 12231 // we want to allow this process to immediately go through 12232 // any memory trimming that is in effect. 12233 app.hidden = false; 12234 foregroundActivities = true; 12235 hasStoppingActivities = true; 12236 } 12237 if (r.app == app) { 12238 app.hasActivities = true; 12239 } 12240 } 12241 } 12242 12243 if (adj == hiddenAdj && !app.hasActivities) { 12244 // Whoops, this process is completely empty as far as we know 12245 // at this point. 12246 adj = emptyAdj; 12247 app.empty = true; 12248 app.adjType = "bg-empty"; 12249 } 12250 12251 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12252 if (app.foregroundServices) { 12253 // The user is aware of this app, so make it visible. 12254 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12255 app.hidden = false; 12256 app.adjType = "foreground-service"; 12257 schedGroup = Process.THREAD_GROUP_DEFAULT; 12258 } else if (app.forcingToForeground != null) { 12259 // The user is aware of this app, so make it visible. 12260 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12261 app.hidden = false; 12262 app.adjType = "force-foreground"; 12263 app.adjSource = app.forcingToForeground; 12264 schedGroup = Process.THREAD_GROUP_DEFAULT; 12265 } 12266 } 12267 12268 if (app.foregroundServices) { 12269 interesting = true; 12270 } 12271 12272 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12273 // We don't want to kill the current heavy-weight process. 12274 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12275 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12276 app.hidden = false; 12277 app.adjType = "heavy"; 12278 } 12279 12280 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12281 // This process is hosting what we currently consider to be the 12282 // home app, so we don't want to let it go into the background. 12283 adj = ProcessList.HOME_APP_ADJ; 12284 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12285 app.hidden = false; 12286 app.adjType = "home"; 12287 } 12288 12289 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12290 && app.activities.size() > 0) { 12291 // This was the previous process that showed UI to the user. 12292 // We want to try to keep it around more aggressively, to give 12293 // a good experience around switching between two apps. 12294 adj = ProcessList.PREVIOUS_APP_ADJ; 12295 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12296 app.hidden = false; 12297 app.adjType = "previous"; 12298 } 12299 12300 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12301 + " reason=" + app.adjType); 12302 12303 // By default, we use the computed adjustment. It may be changed if 12304 // there are applications dependent on our services or providers, but 12305 // this gives us a baseline and makes sure we don't get into an 12306 // infinite recursion. 12307 app.adjSeq = mAdjSeq; 12308 app.curRawAdj = app.nonStoppingAdj = adj; 12309 12310 if (mBackupTarget != null && app == mBackupTarget.app) { 12311 // If possible we want to avoid killing apps while they're being backed up 12312 if (adj > ProcessList.BACKUP_APP_ADJ) { 12313 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12314 adj = ProcessList.BACKUP_APP_ADJ; 12315 app.adjType = "backup"; 12316 app.hidden = false; 12317 } 12318 } 12319 12320 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12321 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12322 final long now = SystemClock.uptimeMillis(); 12323 // This process is more important if the top activity is 12324 // bound to the service. 12325 Iterator<ServiceRecord> jt = app.services.iterator(); 12326 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12327 ServiceRecord s = jt.next(); 12328 if (s.startRequested) { 12329 if (app.hasShownUi && app != mHomeProcess) { 12330 // If this process has shown some UI, let it immediately 12331 // go to the LRU list because it may be pretty heavy with 12332 // UI stuff. We'll tag it with a label just to help 12333 // debug and understand what is going on. 12334 if (adj > ProcessList.SERVICE_ADJ) { 12335 app.adjType = "started-bg-ui-services"; 12336 } 12337 } else { 12338 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12339 // This service has seen some activity within 12340 // recent memory, so we will keep its process ahead 12341 // of the background processes. 12342 if (adj > ProcessList.SERVICE_ADJ) { 12343 adj = ProcessList.SERVICE_ADJ; 12344 app.adjType = "started-services"; 12345 app.hidden = false; 12346 } 12347 } 12348 // If we have let the service slide into the background 12349 // state, still have some text describing what it is doing 12350 // even though the service no longer has an impact. 12351 if (adj > ProcessList.SERVICE_ADJ) { 12352 app.adjType = "started-bg-services"; 12353 } 12354 } 12355 // Don't kill this process because it is doing work; it 12356 // has said it is doing work. 12357 app.keeping = true; 12358 } 12359 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12360 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12361 Iterator<ArrayList<ConnectionRecord>> kt 12362 = s.connections.values().iterator(); 12363 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12364 ArrayList<ConnectionRecord> clist = kt.next(); 12365 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12366 // XXX should compute this based on the max of 12367 // all connected clients. 12368 ConnectionRecord cr = clist.get(i); 12369 if (cr.binding.client == app) { 12370 // Binding to ourself is not interesting. 12371 continue; 12372 } 12373 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12374 ProcessRecord client = cr.binding.client; 12375 int clientAdj = adj; 12376 int myHiddenAdj = hiddenAdj; 12377 if (myHiddenAdj > client.hiddenAdj) { 12378 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12379 myHiddenAdj = client.hiddenAdj; 12380 } else { 12381 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12382 } 12383 } 12384 int myEmptyAdj = emptyAdj; 12385 if (myEmptyAdj > client.emptyAdj) { 12386 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12387 myEmptyAdj = client.emptyAdj; 12388 } else { 12389 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12390 } 12391 } 12392 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12393 myEmptyAdj, TOP_APP, true, doingAll); 12394 String adjType = null; 12395 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12396 // Not doing bind OOM management, so treat 12397 // this guy more like a started service. 12398 if (app.hasShownUi && app != mHomeProcess) { 12399 // If this process has shown some UI, let it immediately 12400 // go to the LRU list because it may be pretty heavy with 12401 // UI stuff. We'll tag it with a label just to help 12402 // debug and understand what is going on. 12403 if (adj > clientAdj) { 12404 adjType = "bound-bg-ui-services"; 12405 } 12406 app.hidden = false; 12407 clientAdj = adj; 12408 } else { 12409 if (now >= (s.lastActivity 12410 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12411 // This service has not seen activity within 12412 // recent memory, so allow it to drop to the 12413 // LRU list if there is no other reason to keep 12414 // it around. We'll also tag it with a label just 12415 // to help debug and undertand what is going on. 12416 if (adj > clientAdj) { 12417 adjType = "bound-bg-services"; 12418 } 12419 clientAdj = adj; 12420 } 12421 } 12422 } 12423 if (adj > clientAdj) { 12424 // If this process has recently shown UI, and 12425 // the process that is binding to it is less 12426 // important than being visible, then we don't 12427 // care about the binding as much as we care 12428 // about letting this process get into the LRU 12429 // list to be killed and restarted if needed for 12430 // memory. 12431 if (app.hasShownUi && app != mHomeProcess 12432 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12433 adjType = "bound-bg-ui-services"; 12434 } else { 12435 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12436 |Context.BIND_IMPORTANT)) != 0) { 12437 adj = clientAdj; 12438 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12439 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12440 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12441 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12442 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12443 adj = clientAdj; 12444 } else { 12445 app.pendingUiClean = true; 12446 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12447 adj = ProcessList.VISIBLE_APP_ADJ; 12448 } 12449 } 12450 if (!client.hidden) { 12451 app.hidden = false; 12452 } 12453 if (client.keeping) { 12454 app.keeping = true; 12455 } 12456 adjType = "service"; 12457 } 12458 } 12459 if (adjType != null) { 12460 app.adjType = adjType; 12461 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12462 .REASON_SERVICE_IN_USE; 12463 app.adjSource = cr.binding.client; 12464 app.adjSourceOom = clientAdj; 12465 app.adjTarget = s.name; 12466 } 12467 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12468 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12469 schedGroup = Process.THREAD_GROUP_DEFAULT; 12470 } 12471 } 12472 } 12473 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12474 ActivityRecord a = cr.activity; 12475 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12476 (a.visible || a.state == ActivityState.RESUMED 12477 || a.state == ActivityState.PAUSING)) { 12478 adj = ProcessList.FOREGROUND_APP_ADJ; 12479 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12480 schedGroup = Process.THREAD_GROUP_DEFAULT; 12481 } 12482 app.hidden = false; 12483 app.adjType = "service"; 12484 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12485 .REASON_SERVICE_IN_USE; 12486 app.adjSource = a; 12487 app.adjSourceOom = adj; 12488 app.adjTarget = s.name; 12489 } 12490 } 12491 } 12492 } 12493 } 12494 } 12495 12496 // Finally, if this process has active services running in it, we 12497 // would like to avoid killing it unless it would prevent the current 12498 // application from running. By default we put the process in 12499 // with the rest of the background processes; as we scan through 12500 // its services we may bump it up from there. 12501 if (adj > hiddenAdj) { 12502 adj = hiddenAdj; 12503 app.hidden = false; 12504 app.adjType = "bg-services"; 12505 } 12506 } 12507 12508 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12509 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12510 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12511 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12512 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12513 ContentProviderRecord cpr = jt.next(); 12514 for (int i = cpr.connections.size()-1; 12515 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12516 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12517 i--) { 12518 ContentProviderConnection conn = cpr.connections.get(i); 12519 ProcessRecord client = conn.client; 12520 if (client == app) { 12521 // Being our own client is not interesting. 12522 continue; 12523 } 12524 int myHiddenAdj = hiddenAdj; 12525 if (myHiddenAdj > client.hiddenAdj) { 12526 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12527 myHiddenAdj = client.hiddenAdj; 12528 } else { 12529 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12530 } 12531 } 12532 int myEmptyAdj = emptyAdj; 12533 if (myEmptyAdj > client.emptyAdj) { 12534 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12535 myEmptyAdj = client.emptyAdj; 12536 } else { 12537 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12538 } 12539 } 12540 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12541 myEmptyAdj, TOP_APP, true, doingAll); 12542 if (adj > clientAdj) { 12543 if (app.hasShownUi && app != mHomeProcess 12544 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12545 app.adjType = "bg-ui-provider"; 12546 } else { 12547 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12548 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12549 app.adjType = "provider"; 12550 } 12551 if (!client.hidden) { 12552 app.hidden = false; 12553 } 12554 if (client.keeping) { 12555 app.keeping = true; 12556 } 12557 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12558 .REASON_PROVIDER_IN_USE; 12559 app.adjSource = client; 12560 app.adjSourceOom = clientAdj; 12561 app.adjTarget = cpr.name; 12562 } 12563 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12564 schedGroup = Process.THREAD_GROUP_DEFAULT; 12565 } 12566 } 12567 // If the provider has external (non-framework) process 12568 // dependencies, ensure that its adjustment is at least 12569 // FOREGROUND_APP_ADJ. 12570 if (cpr.hasExternalProcessHandles()) { 12571 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12572 adj = ProcessList.FOREGROUND_APP_ADJ; 12573 schedGroup = Process.THREAD_GROUP_DEFAULT; 12574 app.hidden = false; 12575 app.keeping = true; 12576 app.adjType = "provider"; 12577 app.adjTarget = cpr.name; 12578 } 12579 } 12580 } 12581 } 12582 12583 if (adj == ProcessList.SERVICE_ADJ) { 12584 if (doingAll) { 12585 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12586 mNewNumServiceProcs++; 12587 } 12588 if (app.serviceb) { 12589 adj = ProcessList.SERVICE_B_ADJ; 12590 } 12591 } else { 12592 app.serviceb = false; 12593 } 12594 12595 app.nonStoppingAdj = adj; 12596 12597 if (hasStoppingActivities) { 12598 // Only upgrade adjustment. 12599 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12600 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12601 app.adjType = "stopping"; 12602 } 12603 } 12604 12605 app.curRawAdj = adj; 12606 12607 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12608 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12609 if (adj > app.maxAdj) { 12610 adj = app.maxAdj; 12611 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12612 schedGroup = Process.THREAD_GROUP_DEFAULT; 12613 } 12614 } 12615 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12616 app.keeping = true; 12617 } 12618 12619 if (app.hasAboveClient) { 12620 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12621 // then we need to drop its adjustment to be lower than the service's 12622 // in order to honor the request. We want to drop it by one adjustment 12623 // level... but there is special meaning applied to various levels so 12624 // we will skip some of them. 12625 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12626 // System process will not get dropped, ever 12627 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12628 adj = ProcessList.VISIBLE_APP_ADJ; 12629 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12630 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12631 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12632 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12633 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12634 adj++; 12635 } 12636 } 12637 12638 int importance = app.memImportance; 12639 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12640 app.curAdj = adj; 12641 app.curSchedGroup = schedGroup; 12642 if (!interesting) { 12643 // For this reporting, if there is not something explicitly 12644 // interesting in this process then we will push it to the 12645 // background importance. 12646 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12647 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12648 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12649 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12650 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12651 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12652 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12653 } else if (adj >= ProcessList.SERVICE_ADJ) { 12654 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12655 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12656 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12657 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12658 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12659 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12660 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12661 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12662 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12663 } else { 12664 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12665 } 12666 } 12667 12668 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12669 if (foregroundActivities != app.foregroundActivities) { 12670 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12671 } 12672 if (changes != 0) { 12673 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12674 app.memImportance = importance; 12675 app.foregroundActivities = foregroundActivities; 12676 int i = mPendingProcessChanges.size()-1; 12677 ProcessChangeItem item = null; 12678 while (i >= 0) { 12679 item = mPendingProcessChanges.get(i); 12680 if (item.pid == app.pid) { 12681 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12682 break; 12683 } 12684 i--; 12685 } 12686 if (i < 0) { 12687 // No existing item in pending changes; need a new one. 12688 final int NA = mAvailProcessChanges.size(); 12689 if (NA > 0) { 12690 item = mAvailProcessChanges.remove(NA-1); 12691 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12692 } else { 12693 item = new ProcessChangeItem(); 12694 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12695 } 12696 item.changes = 0; 12697 item.pid = app.pid; 12698 item.uid = app.info.uid; 12699 if (mPendingProcessChanges.size() == 0) { 12700 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12701 "*** Enqueueing dispatch processes changed!"); 12702 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12703 } 12704 mPendingProcessChanges.add(item); 12705 } 12706 item.changes |= changes; 12707 item.importance = importance; 12708 item.foregroundActivities = foregroundActivities; 12709 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12710 + Integer.toHexString(System.identityHashCode(item)) 12711 + " " + app.toShortString() + ": changes=" + item.changes 12712 + " importance=" + item.importance 12713 + " foreground=" + item.foregroundActivities 12714 + " type=" + app.adjType + " source=" + app.adjSource 12715 + " target=" + app.adjTarget); 12716 } 12717 12718 return app.curRawAdj; 12719 } 12720 12721 /** 12722 * Ask a given process to GC right now. 12723 */ 12724 final void performAppGcLocked(ProcessRecord app) { 12725 try { 12726 app.lastRequestedGc = SystemClock.uptimeMillis(); 12727 if (app.thread != null) { 12728 if (app.reportLowMemory) { 12729 app.reportLowMemory = false; 12730 app.thread.scheduleLowMemory(); 12731 } else { 12732 app.thread.processInBackground(); 12733 } 12734 } 12735 } catch (Exception e) { 12736 // whatever. 12737 } 12738 } 12739 12740 /** 12741 * Returns true if things are idle enough to perform GCs. 12742 */ 12743 private final boolean canGcNowLocked() { 12744 boolean processingBroadcasts = false; 12745 for (BroadcastQueue q : mBroadcastQueues) { 12746 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12747 processingBroadcasts = true; 12748 } 12749 } 12750 return !processingBroadcasts 12751 && (mSleeping || (mMainStack.mResumedActivity != null && 12752 mMainStack.mResumedActivity.idle)); 12753 } 12754 12755 /** 12756 * Perform GCs on all processes that are waiting for it, but only 12757 * if things are idle. 12758 */ 12759 final void performAppGcsLocked() { 12760 final int N = mProcessesToGc.size(); 12761 if (N <= 0) { 12762 return; 12763 } 12764 if (canGcNowLocked()) { 12765 while (mProcessesToGc.size() > 0) { 12766 ProcessRecord proc = mProcessesToGc.remove(0); 12767 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12768 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12769 <= SystemClock.uptimeMillis()) { 12770 // To avoid spamming the system, we will GC processes one 12771 // at a time, waiting a few seconds between each. 12772 performAppGcLocked(proc); 12773 scheduleAppGcsLocked(); 12774 return; 12775 } else { 12776 // It hasn't been long enough since we last GCed this 12777 // process... put it in the list to wait for its time. 12778 addProcessToGcListLocked(proc); 12779 break; 12780 } 12781 } 12782 } 12783 12784 scheduleAppGcsLocked(); 12785 } 12786 } 12787 12788 /** 12789 * If all looks good, perform GCs on all processes waiting for them. 12790 */ 12791 final void performAppGcsIfAppropriateLocked() { 12792 if (canGcNowLocked()) { 12793 performAppGcsLocked(); 12794 return; 12795 } 12796 // Still not idle, wait some more. 12797 scheduleAppGcsLocked(); 12798 } 12799 12800 /** 12801 * Schedule the execution of all pending app GCs. 12802 */ 12803 final void scheduleAppGcsLocked() { 12804 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12805 12806 if (mProcessesToGc.size() > 0) { 12807 // Schedule a GC for the time to the next process. 12808 ProcessRecord proc = mProcessesToGc.get(0); 12809 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12810 12811 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12812 long now = SystemClock.uptimeMillis(); 12813 if (when < (now+GC_TIMEOUT)) { 12814 when = now + GC_TIMEOUT; 12815 } 12816 mHandler.sendMessageAtTime(msg, when); 12817 } 12818 } 12819 12820 /** 12821 * Add a process to the array of processes waiting to be GCed. Keeps the 12822 * list in sorted order by the last GC time. The process can't already be 12823 * on the list. 12824 */ 12825 final void addProcessToGcListLocked(ProcessRecord proc) { 12826 boolean added = false; 12827 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12828 if (mProcessesToGc.get(i).lastRequestedGc < 12829 proc.lastRequestedGc) { 12830 added = true; 12831 mProcessesToGc.add(i+1, proc); 12832 break; 12833 } 12834 } 12835 if (!added) { 12836 mProcessesToGc.add(0, proc); 12837 } 12838 } 12839 12840 /** 12841 * Set up to ask a process to GC itself. This will either do it 12842 * immediately, or put it on the list of processes to gc the next 12843 * time things are idle. 12844 */ 12845 final void scheduleAppGcLocked(ProcessRecord app) { 12846 long now = SystemClock.uptimeMillis(); 12847 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12848 return; 12849 } 12850 if (!mProcessesToGc.contains(app)) { 12851 addProcessToGcListLocked(app); 12852 scheduleAppGcsLocked(); 12853 } 12854 } 12855 12856 final void checkExcessivePowerUsageLocked(boolean doKills) { 12857 updateCpuStatsNow(); 12858 12859 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12860 boolean doWakeKills = doKills; 12861 boolean doCpuKills = doKills; 12862 if (mLastPowerCheckRealtime == 0) { 12863 doWakeKills = false; 12864 } 12865 if (mLastPowerCheckUptime == 0) { 12866 doCpuKills = false; 12867 } 12868 if (stats.isScreenOn()) { 12869 doWakeKills = false; 12870 } 12871 final long curRealtime = SystemClock.elapsedRealtime(); 12872 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12873 final long curUptime = SystemClock.uptimeMillis(); 12874 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12875 mLastPowerCheckRealtime = curRealtime; 12876 mLastPowerCheckUptime = curUptime; 12877 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12878 doWakeKills = false; 12879 } 12880 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12881 doCpuKills = false; 12882 } 12883 int i = mLruProcesses.size(); 12884 while (i > 0) { 12885 i--; 12886 ProcessRecord app = mLruProcesses.get(i); 12887 if (!app.keeping) { 12888 long wtime; 12889 synchronized (stats) { 12890 wtime = stats.getProcessWakeTime(app.info.uid, 12891 app.pid, curRealtime); 12892 } 12893 long wtimeUsed = wtime - app.lastWakeTime; 12894 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12895 if (DEBUG_POWER) { 12896 StringBuilder sb = new StringBuilder(128); 12897 sb.append("Wake for "); 12898 app.toShortString(sb); 12899 sb.append(": over "); 12900 TimeUtils.formatDuration(realtimeSince, sb); 12901 sb.append(" used "); 12902 TimeUtils.formatDuration(wtimeUsed, sb); 12903 sb.append(" ("); 12904 sb.append((wtimeUsed*100)/realtimeSince); 12905 sb.append("%)"); 12906 Slog.i(TAG, sb.toString()); 12907 sb.setLength(0); 12908 sb.append("CPU for "); 12909 app.toShortString(sb); 12910 sb.append(": over "); 12911 TimeUtils.formatDuration(uptimeSince, sb); 12912 sb.append(" used "); 12913 TimeUtils.formatDuration(cputimeUsed, sb); 12914 sb.append(" ("); 12915 sb.append((cputimeUsed*100)/uptimeSince); 12916 sb.append("%)"); 12917 Slog.i(TAG, sb.toString()); 12918 } 12919 // If a process has held a wake lock for more 12920 // than 50% of the time during this period, 12921 // that sounds bad. Kill! 12922 if (doWakeKills && realtimeSince > 0 12923 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12924 synchronized (stats) { 12925 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12926 realtimeSince, wtimeUsed); 12927 } 12928 Slog.w(TAG, "Excessive wake lock in " + app.processName 12929 + " (pid " + app.pid + "): held " + wtimeUsed 12930 + " during " + realtimeSince); 12931 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12932 app.processName, app.setAdj, "excessive wake lock"); 12933 Process.killProcessQuiet(app.pid); 12934 } else if (doCpuKills && uptimeSince > 0 12935 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12936 synchronized (stats) { 12937 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12938 uptimeSince, cputimeUsed); 12939 } 12940 Slog.w(TAG, "Excessive CPU in " + app.processName 12941 + " (pid " + app.pid + "): used " + cputimeUsed 12942 + " during " + uptimeSince); 12943 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12944 app.processName, app.setAdj, "excessive cpu"); 12945 Process.killProcessQuiet(app.pid); 12946 } else { 12947 app.lastWakeTime = wtime; 12948 app.lastCpuTime = app.curCpuTime; 12949 } 12950 } 12951 } 12952 } 12953 12954 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12955 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12956 app.hiddenAdj = hiddenAdj; 12957 app.emptyAdj = emptyAdj; 12958 12959 if (app.thread == null) { 12960 return false; 12961 } 12962 12963 final boolean wasKeeping = app.keeping; 12964 12965 boolean success = true; 12966 12967 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12968 12969 if (app.curRawAdj != app.setRawAdj) { 12970 if (wasKeeping && !app.keeping) { 12971 // This app is no longer something we want to keep. Note 12972 // its current wake lock time to later know to kill it if 12973 // it is not behaving well. 12974 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12975 synchronized (stats) { 12976 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12977 app.pid, SystemClock.elapsedRealtime()); 12978 } 12979 app.lastCpuTime = app.curCpuTime; 12980 } 12981 12982 app.setRawAdj = app.curRawAdj; 12983 } 12984 12985 if (app.curAdj != app.setAdj) { 12986 if (Process.setOomAdj(app.pid, app.curAdj)) { 12987 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12988 TAG, "Set " + app.pid + " " + app.processName + 12989 " adj " + app.curAdj + ": " + app.adjType); 12990 app.setAdj = app.curAdj; 12991 } else { 12992 success = false; 12993 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12994 } 12995 } 12996 if (app.setSchedGroup != app.curSchedGroup) { 12997 app.setSchedGroup = app.curSchedGroup; 12998 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12999 "Setting process group of " + app.processName 13000 + " to " + app.curSchedGroup); 13001 if (app.waitingToKill != null && 13002 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13003 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13004 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13005 app.processName, app.setAdj, app.waitingToKill); 13006 app.killedBackground = true; 13007 Process.killProcessQuiet(app.pid); 13008 success = false; 13009 } else { 13010 if (true) { 13011 long oldId = Binder.clearCallingIdentity(); 13012 try { 13013 Process.setProcessGroup(app.pid, app.curSchedGroup); 13014 } catch (Exception e) { 13015 Slog.w(TAG, "Failed setting process group of " + app.pid 13016 + " to " + app.curSchedGroup); 13017 e.printStackTrace(); 13018 } finally { 13019 Binder.restoreCallingIdentity(oldId); 13020 } 13021 } else { 13022 if (app.thread != null) { 13023 try { 13024 app.thread.setSchedulingGroup(app.curSchedGroup); 13025 } catch (RemoteException e) { 13026 } 13027 } 13028 } 13029 } 13030 } 13031 return success; 13032 } 13033 13034 private final ActivityRecord resumedAppLocked() { 13035 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13036 if (resumedActivity == null || resumedActivity.app == null) { 13037 resumedActivity = mMainStack.mPausingActivity; 13038 if (resumedActivity == null || resumedActivity.app == null) { 13039 resumedActivity = mMainStack.topRunningActivityLocked(null); 13040 } 13041 } 13042 return resumedActivity; 13043 } 13044 13045 final boolean updateOomAdjLocked(ProcessRecord app) { 13046 final ActivityRecord TOP_ACT = resumedAppLocked(); 13047 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13048 int curAdj = app.curAdj; 13049 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13050 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13051 13052 mAdjSeq++; 13053 13054 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13055 TOP_APP, false); 13056 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13057 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13058 if (nowHidden != wasHidden) { 13059 // Changed to/from hidden state, so apps after it in the LRU 13060 // list may also be changed. 13061 updateOomAdjLocked(); 13062 } 13063 return success; 13064 } 13065 13066 final void updateOomAdjLocked() { 13067 final ActivityRecord TOP_ACT = resumedAppLocked(); 13068 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13069 13070 if (false) { 13071 RuntimeException e = new RuntimeException(); 13072 e.fillInStackTrace(); 13073 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13074 } 13075 13076 mAdjSeq++; 13077 mNewNumServiceProcs = 0; 13078 13079 // Let's determine how many processes we have running vs. 13080 // how many slots we have for background processes; we may want 13081 // to put multiple processes in a slot of there are enough of 13082 // them. 13083 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13084 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13085 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13086 if (emptyFactor < 1) emptyFactor = 1; 13087 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13088 if (hiddenFactor < 1) hiddenFactor = 1; 13089 int stepHidden = 0; 13090 int stepEmpty = 0; 13091 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13092 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13093 int numHidden = 0; 13094 int numEmpty = 0; 13095 int numTrimming = 0; 13096 13097 mNumNonHiddenProcs = 0; 13098 mNumHiddenProcs = 0; 13099 13100 // First update the OOM adjustment for each of the 13101 // application processes based on their current state. 13102 int i = mLruProcesses.size(); 13103 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13104 int nextHiddenAdj = curHiddenAdj+1; 13105 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13106 int nextEmptyAdj = curEmptyAdj+2; 13107 while (i > 0) { 13108 i--; 13109 ProcessRecord app = mLruProcesses.get(i); 13110 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13111 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13112 if (!app.killedBackground) { 13113 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13114 // This process was assigned as a hidden process... step the 13115 // hidden level. 13116 mNumHiddenProcs++; 13117 if (curHiddenAdj != nextHiddenAdj) { 13118 stepHidden++; 13119 if (stepHidden >= hiddenFactor) { 13120 stepHidden = 0; 13121 curHiddenAdj = nextHiddenAdj; 13122 nextHiddenAdj += 2; 13123 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13124 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13125 } 13126 } 13127 } 13128 numHidden++; 13129 if (numHidden > hiddenProcessLimit) { 13130 Slog.i(TAG, "No longer want " + app.processName 13131 + " (pid " + app.pid + "): hidden #" + numHidden); 13132 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13133 app.processName, app.setAdj, "too many background"); 13134 app.killedBackground = true; 13135 Process.killProcessQuiet(app.pid); 13136 } 13137 } else { 13138 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13139 // This process was assigned as an empty process... step the 13140 // empty level. 13141 if (curEmptyAdj != nextEmptyAdj) { 13142 stepEmpty++; 13143 if (stepEmpty >= emptyFactor) { 13144 stepEmpty = 0; 13145 curEmptyAdj = nextEmptyAdj; 13146 nextEmptyAdj += 2; 13147 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13148 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13149 } 13150 } 13151 } 13152 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13153 mNumNonHiddenProcs++; 13154 } 13155 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13156 numEmpty++; 13157 if (numEmpty > emptyProcessLimit) { 13158 Slog.i(TAG, "No longer want " + app.processName 13159 + " (pid " + app.pid + "): empty #" + numEmpty); 13160 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13161 app.processName, app.setAdj, "too many background"); 13162 app.killedBackground = true; 13163 Process.killProcessQuiet(app.pid); 13164 } 13165 } 13166 } 13167 if (app.isolated && app.services.size() <= 0) { 13168 // If this is an isolated process, and there are no 13169 // services running in it, then the process is no longer 13170 // needed. We agressively kill these because we can by 13171 // definition not re-use the same process again, and it is 13172 // good to avoid having whatever code was running in them 13173 // left sitting around after no longer needed. 13174 Slog.i(TAG, "Isolated process " + app.processName 13175 + " (pid " + app.pid + ") no longer needed"); 13176 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13177 app.processName, app.setAdj, "isolated not needed"); 13178 app.killedBackground = true; 13179 Process.killProcessQuiet(app.pid); 13180 } 13181 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13182 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13183 && !app.killedBackground) { 13184 numTrimming++; 13185 } 13186 } 13187 } 13188 13189 mNumServiceProcs = mNewNumServiceProcs; 13190 13191 // Now determine the memory trimming level of background processes. 13192 // Unfortunately we need to start at the back of the list to do this 13193 // properly. We only do this if the number of background apps we 13194 // are managing to keep around is less than half the maximum we desire; 13195 // if we are keeping a good number around, we'll let them use whatever 13196 // memory they want. 13197 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13198 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13199 final int numHiddenAndEmpty = numHidden + numEmpty; 13200 final int N = mLruProcesses.size(); 13201 int factor = numTrimming/3; 13202 int minFactor = 2; 13203 if (mHomeProcess != null) minFactor++; 13204 if (mPreviousProcess != null) minFactor++; 13205 if (factor < minFactor) factor = minFactor; 13206 int step = 0; 13207 int fgTrimLevel; 13208 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13209 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13210 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13211 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13212 } else { 13213 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13214 } 13215 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13216 for (i=0; i<N; i++) { 13217 ProcessRecord app = mLruProcesses.get(i); 13218 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13219 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13220 && !app.killedBackground) { 13221 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13222 try { 13223 app.thread.scheduleTrimMemory(curLevel); 13224 } catch (RemoteException e) { 13225 } 13226 if (false) { 13227 // For now we won't do this; our memory trimming seems 13228 // to be good enough at this point that destroying 13229 // activities causes more harm than good. 13230 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13231 && app != mHomeProcess && app != mPreviousProcess) { 13232 // Need to do this on its own message because the stack may not 13233 // be in a consistent state at this point. 13234 // For these apps we will also finish their activities 13235 // to help them free memory. 13236 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13237 } 13238 } 13239 } 13240 app.trimMemoryLevel = curLevel; 13241 step++; 13242 if (step >= factor) { 13243 step = 0; 13244 switch (curLevel) { 13245 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13246 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13247 break; 13248 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13249 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13250 break; 13251 } 13252 } 13253 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13254 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13255 && app.thread != null) { 13256 try { 13257 app.thread.scheduleTrimMemory( 13258 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13259 } catch (RemoteException e) { 13260 } 13261 } 13262 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13263 } else { 13264 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13265 && app.pendingUiClean) { 13266 // If this application is now in the background and it 13267 // had done UI, then give it the special trim level to 13268 // have it free UI resources. 13269 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13270 if (app.trimMemoryLevel < level && app.thread != null) { 13271 try { 13272 app.thread.scheduleTrimMemory(level); 13273 } catch (RemoteException e) { 13274 } 13275 } 13276 app.pendingUiClean = false; 13277 } 13278 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13279 try { 13280 app.thread.scheduleTrimMemory(fgTrimLevel); 13281 } catch (RemoteException e) { 13282 } 13283 } 13284 app.trimMemoryLevel = fgTrimLevel; 13285 } 13286 } 13287 } else { 13288 final int N = mLruProcesses.size(); 13289 for (i=0; i<N; i++) { 13290 ProcessRecord app = mLruProcesses.get(i); 13291 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13292 && app.pendingUiClean) { 13293 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13294 && app.thread != null) { 13295 try { 13296 app.thread.scheduleTrimMemory( 13297 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13298 } catch (RemoteException e) { 13299 } 13300 } 13301 app.pendingUiClean = false; 13302 } 13303 app.trimMemoryLevel = 0; 13304 } 13305 } 13306 13307 if (mAlwaysFinishActivities) { 13308 // Need to do this on its own message because the stack may not 13309 // be in a consistent state at this point. 13310 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13311 } 13312 } 13313 13314 final void trimApplications() { 13315 synchronized (this) { 13316 int i; 13317 13318 // First remove any unused application processes whose package 13319 // has been removed. 13320 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13321 final ProcessRecord app = mRemovedProcesses.get(i); 13322 if (app.activities.size() == 0 13323 && app.curReceiver == null && app.services.size() == 0) { 13324 Slog.i( 13325 TAG, "Exiting empty application process " 13326 + app.processName + " (" 13327 + (app.thread != null ? app.thread.asBinder() : null) 13328 + ")\n"); 13329 if (app.pid > 0 && app.pid != MY_PID) { 13330 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13331 app.processName, app.setAdj, "empty"); 13332 Process.killProcessQuiet(app.pid); 13333 } else { 13334 try { 13335 app.thread.scheduleExit(); 13336 } catch (Exception e) { 13337 // Ignore exceptions. 13338 } 13339 } 13340 cleanUpApplicationRecordLocked(app, false, true, -1); 13341 mRemovedProcesses.remove(i); 13342 13343 if (app.persistent) { 13344 if (app.persistent) { 13345 addAppLocked(app.info, false); 13346 } 13347 } 13348 } 13349 } 13350 13351 // Now update the oom adj for all processes. 13352 updateOomAdjLocked(); 13353 } 13354 } 13355 13356 /** This method sends the specified signal to each of the persistent apps */ 13357 public void signalPersistentProcesses(int sig) throws RemoteException { 13358 if (sig != Process.SIGNAL_USR1) { 13359 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13360 } 13361 13362 synchronized (this) { 13363 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13364 != PackageManager.PERMISSION_GRANTED) { 13365 throw new SecurityException("Requires permission " 13366 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13367 } 13368 13369 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13370 ProcessRecord r = mLruProcesses.get(i); 13371 if (r.thread != null && r.persistent) { 13372 Process.sendSignal(r.pid, sig); 13373 } 13374 } 13375 } 13376 } 13377 13378 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13379 if (proc == null || proc == mProfileProc) { 13380 proc = mProfileProc; 13381 path = mProfileFile; 13382 profileType = mProfileType; 13383 clearProfilerLocked(); 13384 } 13385 if (proc == null) { 13386 return; 13387 } 13388 try { 13389 proc.thread.profilerControl(false, path, null, profileType); 13390 } catch (RemoteException e) { 13391 throw new IllegalStateException("Process disappeared"); 13392 } 13393 } 13394 13395 private void clearProfilerLocked() { 13396 if (mProfileFd != null) { 13397 try { 13398 mProfileFd.close(); 13399 } catch (IOException e) { 13400 } 13401 } 13402 mProfileApp = null; 13403 mProfileProc = null; 13404 mProfileFile = null; 13405 mProfileType = 0; 13406 mAutoStopProfiler = false; 13407 } 13408 13409 public boolean profileControl(String process, boolean start, 13410 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13411 13412 try { 13413 synchronized (this) { 13414 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13415 // its own permission. 13416 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13417 != PackageManager.PERMISSION_GRANTED) { 13418 throw new SecurityException("Requires permission " 13419 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13420 } 13421 13422 if (start && fd == null) { 13423 throw new IllegalArgumentException("null fd"); 13424 } 13425 13426 ProcessRecord proc = null; 13427 if (process != null) { 13428 try { 13429 int pid = Integer.parseInt(process); 13430 synchronized (mPidsSelfLocked) { 13431 proc = mPidsSelfLocked.get(pid); 13432 } 13433 } catch (NumberFormatException e) { 13434 } 13435 13436 if (proc == null) { 13437 HashMap<String, SparseArray<ProcessRecord>> all 13438 = mProcessNames.getMap(); 13439 SparseArray<ProcessRecord> procs = all.get(process); 13440 if (procs != null && procs.size() > 0) { 13441 proc = procs.valueAt(0); 13442 } 13443 } 13444 } 13445 13446 if (start && (proc == null || proc.thread == null)) { 13447 throw new IllegalArgumentException("Unknown process: " + process); 13448 } 13449 13450 if (start) { 13451 stopProfilerLocked(null, null, 0); 13452 setProfileApp(proc.info, proc.processName, path, fd, false); 13453 mProfileProc = proc; 13454 mProfileType = profileType; 13455 try { 13456 fd = fd.dup(); 13457 } catch (IOException e) { 13458 fd = null; 13459 } 13460 proc.thread.profilerControl(start, path, fd, profileType); 13461 fd = null; 13462 mProfileFd = null; 13463 } else { 13464 stopProfilerLocked(proc, path, profileType); 13465 if (fd != null) { 13466 try { 13467 fd.close(); 13468 } catch (IOException e) { 13469 } 13470 } 13471 } 13472 13473 return true; 13474 } 13475 } catch (RemoteException e) { 13476 throw new IllegalStateException("Process disappeared"); 13477 } finally { 13478 if (fd != null) { 13479 try { 13480 fd.close(); 13481 } catch (IOException e) { 13482 } 13483 } 13484 } 13485 } 13486 13487 public boolean dumpHeap(String process, boolean managed, 13488 String path, ParcelFileDescriptor fd) throws RemoteException { 13489 13490 try { 13491 synchronized (this) { 13492 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13493 // its own permission (same as profileControl). 13494 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13495 != PackageManager.PERMISSION_GRANTED) { 13496 throw new SecurityException("Requires permission " 13497 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13498 } 13499 13500 if (fd == null) { 13501 throw new IllegalArgumentException("null fd"); 13502 } 13503 13504 ProcessRecord proc = null; 13505 try { 13506 int pid = Integer.parseInt(process); 13507 synchronized (mPidsSelfLocked) { 13508 proc = mPidsSelfLocked.get(pid); 13509 } 13510 } catch (NumberFormatException e) { 13511 } 13512 13513 if (proc == null) { 13514 HashMap<String, SparseArray<ProcessRecord>> all 13515 = mProcessNames.getMap(); 13516 SparseArray<ProcessRecord> procs = all.get(process); 13517 if (procs != null && procs.size() > 0) { 13518 proc = procs.valueAt(0); 13519 } 13520 } 13521 13522 if (proc == null || proc.thread == null) { 13523 throw new IllegalArgumentException("Unknown process: " + process); 13524 } 13525 13526 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13527 if (!isDebuggable) { 13528 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13529 throw new SecurityException("Process not debuggable: " + proc); 13530 } 13531 } 13532 13533 proc.thread.dumpHeap(managed, path, fd); 13534 fd = null; 13535 return true; 13536 } 13537 } catch (RemoteException e) { 13538 throw new IllegalStateException("Process disappeared"); 13539 } finally { 13540 if (fd != null) { 13541 try { 13542 fd.close(); 13543 } catch (IOException e) { 13544 } 13545 } 13546 } 13547 } 13548 13549 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13550 public void monitor() { 13551 synchronized (this) { } 13552 } 13553 13554 void onCoreSettingsChange(Bundle settings) { 13555 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13556 ProcessRecord processRecord = mLruProcesses.get(i); 13557 try { 13558 if (processRecord.thread != null) { 13559 processRecord.thread.setCoreSettings(settings); 13560 } 13561 } catch (RemoteException re) { 13562 /* ignore */ 13563 } 13564 } 13565 } 13566 13567 // Multi-user methods 13568 13569 @Override 13570 public boolean switchUser(int userId) { 13571 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13572 != PackageManager.PERMISSION_GRANTED) { 13573 String msg = "Permission Denial: switchUser() from pid=" 13574 + Binder.getCallingPid() 13575 + ", uid=" + Binder.getCallingUid() 13576 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13577 Slog.w(TAG, msg); 13578 throw new SecurityException(msg); 13579 } 13580 synchronized (this) { 13581 if (mCurrentUserId == userId) { 13582 return true; 13583 } 13584 13585 // If the user we are switching to is not currently started, then 13586 // we need to start it now. 13587 if (mStartedUsers.get(userId) == null) { 13588 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13589 } 13590 13591 mCurrentUserId = userId; 13592 boolean haveActivities = mMainStack.switchUser(userId); 13593 if (!haveActivities) { 13594 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13595 } 13596 } 13597 13598 long ident = Binder.clearCallingIdentity(); 13599 try { 13600 // Inform of user switch 13601 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13602 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13603 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13604 } finally { 13605 Binder.restoreCallingIdentity(ident); 13606 } 13607 13608 return true; 13609 } 13610 13611 void finishUserSwitch(UserStartedState uss) { 13612 synchronized (this) { 13613 if (uss.mState == UserStartedState.STATE_BOOTING 13614 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13615 uss.mState = UserStartedState.STATE_RUNNING; 13616 broadcastIntentLocked(null, null, 13617 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 13618 null, null, 0, null, null, 13619 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13620 false, false, MY_PID, Process.SYSTEM_UID, uss.mHandle.getIdentifier()); 13621 } 13622 } 13623 } 13624 13625 @Override 13626 public int stopUser(final int userId, final IStopUserCallback callback) { 13627 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13628 != PackageManager.PERMISSION_GRANTED) { 13629 String msg = "Permission Denial: switchUser() from pid=" 13630 + Binder.getCallingPid() 13631 + ", uid=" + Binder.getCallingUid() 13632 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13633 Slog.w(TAG, msg); 13634 throw new SecurityException(msg); 13635 } 13636 if (userId <= 0) { 13637 throw new IllegalArgumentException("Can't stop primary user " + userId); 13638 } 13639 synchronized (this) { 13640 if (mCurrentUserId == userId) { 13641 return ActivityManager.USER_OP_IS_CURRENT; 13642 } 13643 13644 final UserStartedState uss = mStartedUsers.get(userId); 13645 if (uss == null) { 13646 // User is not started, nothing to do... but we do need to 13647 // callback if requested. 13648 if (callback != null) { 13649 mHandler.post(new Runnable() { 13650 @Override 13651 public void run() { 13652 try { 13653 callback.userStopped(userId); 13654 } catch (RemoteException e) { 13655 } 13656 } 13657 }); 13658 } 13659 return ActivityManager.USER_OP_SUCCESS; 13660 } 13661 13662 if (callback != null) { 13663 uss.mStopCallbacks.add(callback); 13664 } 13665 13666 if (uss.mState != UserStartedState.STATE_STOPPING) { 13667 uss.mState = UserStartedState.STATE_STOPPING; 13668 13669 long ident = Binder.clearCallingIdentity(); 13670 try { 13671 // Inform of user switch 13672 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13673 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13674 @Override 13675 public void performReceive(Intent intent, int resultCode, String data, 13676 Bundle extras, boolean ordered, boolean sticky) { 13677 finishUserStop(uss); 13678 } 13679 }; 13680 broadcastIntentLocked(null, null, intent, 13681 null, resultReceiver, 0, null, null, null, 13682 true, false, MY_PID, Process.SYSTEM_UID, userId); 13683 } finally { 13684 Binder.restoreCallingIdentity(ident); 13685 } 13686 } 13687 } 13688 13689 return ActivityManager.USER_OP_SUCCESS; 13690 } 13691 13692 void finishUserStop(UserStartedState uss) { 13693 final int userId = uss.mHandle.getIdentifier(); 13694 boolean stopped; 13695 ArrayList<IStopUserCallback> callbacks; 13696 synchronized (this) { 13697 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 13698 if (uss.mState != UserStartedState.STATE_STOPPING 13699 || mStartedUsers.get(userId) != uss) { 13700 stopped = false; 13701 } else { 13702 stopped = true; 13703 // User can no longer run. 13704 mStartedUsers.remove(userId); 13705 13706 // Clean up all state and processes associated with the user. 13707 // Kill all the processes for the user. 13708 forceStopUserLocked(userId); 13709 } 13710 } 13711 13712 for (int i=0; i<callbacks.size(); i++) { 13713 try { 13714 if (stopped) callbacks.get(i).userStopped(userId); 13715 else callbacks.get(i).userStopAborted(userId); 13716 } catch (RemoteException e) { 13717 } 13718 } 13719 } 13720 13721 @Override 13722 public UserInfo getCurrentUser() { 13723 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13724 != PackageManager.PERMISSION_GRANTED) { 13725 String msg = "Permission Denial: getCurrentUser() from pid=" 13726 + Binder.getCallingPid() 13727 + ", uid=" + Binder.getCallingUid() 13728 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13729 Slog.w(TAG, msg); 13730 throw new SecurityException(msg); 13731 } 13732 synchronized (this) { 13733 return getUserManager().getUserInfo(mCurrentUserId); 13734 } 13735 } 13736 13737 private boolean userExists(int userId) { 13738 UserInfo user = getUserManager().getUserInfo(userId); 13739 return user != null; 13740 } 13741 13742 UserManager getUserManager() { 13743 if (mUserManager == null) { 13744 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13745 } 13746 return mUserManager; 13747 } 13748 13749 private void checkValidCaller(int uid, int userId) { 13750 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13751 13752 throw new SecurityException("Caller uid=" + uid 13753 + " is not privileged to communicate with user=" + userId); 13754 } 13755 13756 private int applyUserId(int uid, int userId) { 13757 return UserHandle.getUid(userId, uid); 13758 } 13759 13760 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13761 if (info == null) return null; 13762 ApplicationInfo newInfo = new ApplicationInfo(info); 13763 newInfo.uid = applyUserId(info.uid, userId); 13764 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13765 + info.packageName; 13766 return newInfo; 13767 } 13768 13769 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13770 if (aInfo == null 13771 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13772 return aInfo; 13773 } 13774 13775 ActivityInfo info = new ActivityInfo(aInfo); 13776 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13777 return info; 13778 } 13779} 13780