ActivityManagerService.java revision 5b1ada2562c17921adf6a62ea62bcb445160983c
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IThumbnailReceiver; 51import android.app.Instrumentation; 52import android.app.Notification; 53import android.app.NotificationManager; 54import android.app.PendingIntent; 55import android.app.Service; 56import android.app.backup.IBackupManager; 57import android.content.ActivityNotFoundException; 58import android.content.BroadcastReceiver; 59import android.content.ClipData; 60import android.content.ComponentCallbacks2; 61import android.content.ComponentName; 62import android.content.ContentProvider; 63import android.content.ContentResolver; 64import android.content.Context; 65import android.content.DialogInterface; 66import android.content.IContentProvider; 67import android.content.IIntentReceiver; 68import android.content.IIntentSender; 69import android.content.Intent; 70import android.content.IntentFilter; 71import android.content.IntentSender; 72import android.content.pm.ActivityInfo; 73import android.content.pm.ApplicationInfo; 74import android.content.pm.ConfigurationInfo; 75import android.content.pm.IPackageDataObserver; 76import android.content.pm.IPackageManager; 77import android.content.pm.InstrumentationInfo; 78import android.content.pm.PackageInfo; 79import android.content.pm.PackageManager; 80import android.content.pm.UserInfo; 81import android.content.pm.PackageManager.NameNotFoundException; 82import android.content.pm.PathPermission; 83import android.content.pm.ProviderInfo; 84import android.content.pm.ResolveInfo; 85import android.content.pm.ServiceInfo; 86import android.content.res.CompatibilityInfo; 87import android.content.res.Configuration; 88import android.graphics.Bitmap; 89import android.net.Proxy; 90import android.net.ProxyProperties; 91import android.net.Uri; 92import android.os.Binder; 93import android.os.Build; 94import android.os.Bundle; 95import android.os.Debug; 96import android.os.DropBoxManager; 97import android.os.Environment; 98import android.os.FileObserver; 99import android.os.FileUtils; 100import android.os.Handler; 101import android.os.IBinder; 102import android.os.IPermissionController; 103import android.os.Looper; 104import android.os.Message; 105import android.os.Parcel; 106import android.os.ParcelFileDescriptor; 107import android.os.Process; 108import android.os.RemoteCallbackList; 109import android.os.RemoteException; 110import android.os.ServiceManager; 111import android.os.StrictMode; 112import android.os.SystemClock; 113import android.os.SystemProperties; 114import android.os.UserId; 115import android.os.UserManager; 116import android.provider.Settings; 117import android.text.format.Time; 118import android.util.EventLog; 119import android.util.Log; 120import android.util.Pair; 121import android.util.PrintWriterPrinter; 122import android.util.Slog; 123import android.util.SparseArray; 124import android.util.SparseIntArray; 125import android.util.TimeUtils; 126import android.view.Gravity; 127import android.view.LayoutInflater; 128import android.view.View; 129import android.view.WindowManager; 130import android.view.WindowManagerPolicy; 131 132import java.io.BufferedInputStream; 133import java.io.BufferedOutputStream; 134import java.io.BufferedReader; 135import java.io.DataInputStream; 136import java.io.DataOutputStream; 137import java.io.File; 138import java.io.FileDescriptor; 139import java.io.FileInputStream; 140import java.io.FileNotFoundException; 141import java.io.FileOutputStream; 142import java.io.IOException; 143import java.io.InputStreamReader; 144import java.io.PrintWriter; 145import java.io.StringWriter; 146import java.lang.ref.WeakReference; 147import java.util.ArrayList; 148import java.util.Collection; 149import java.util.Collections; 150import java.util.Comparator; 151import java.util.HashMap; 152import java.util.HashSet; 153import java.util.Iterator; 154import java.util.List; 155import java.util.Locale; 156import java.util.Map; 157import java.util.Map.Entry; 158import java.util.Set; 159import java.util.concurrent.atomic.AtomicBoolean; 160import java.util.concurrent.atomic.AtomicLong; 161 162public final class ActivityManagerService extends ActivityManagerNative 163 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 164 private static final String USER_DATA_DIR = "/data/user/"; 165 static final String TAG = "ActivityManager"; 166 static final String TAG_MU = "ActivityManagerServiceMU"; 167 static final boolean DEBUG = false; 168 static final boolean localLOGV = DEBUG; 169 static final boolean DEBUG_SWITCH = localLOGV || false; 170 static final boolean DEBUG_TASKS = localLOGV || false; 171 static final boolean DEBUG_PAUSE = localLOGV || false; 172 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 173 static final boolean DEBUG_TRANSITION = localLOGV || false; 174 static final boolean DEBUG_BROADCAST = localLOGV || false; 175 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 177 static final boolean DEBUG_SERVICE = localLOGV || false; 178 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 179 static final boolean DEBUG_VISBILITY = localLOGV || false; 180 static final boolean DEBUG_PROCESSES = localLOGV || false; 181 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 182 static final boolean DEBUG_PROVIDER = localLOGV || false; 183 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 184 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 185 static final boolean DEBUG_RESULTS = localLOGV || false; 186 static final boolean DEBUG_BACKUP = localLOGV || false; 187 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 188 static final boolean DEBUG_POWER = localLOGV || false; 189 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 190 static final boolean DEBUG_MU = localLOGV || false; 191 static final boolean VALIDATE_TOKENS = false; 192 static final boolean SHOW_ACTIVITY_START_TIME = true; 193 194 // Control over CPU and battery monitoring. 195 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 196 static final boolean MONITOR_CPU_USAGE = true; 197 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 198 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 199 static final boolean MONITOR_THREAD_CPU_USAGE = false; 200 201 // The flags that are set for all calls we make to the package manager. 202 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 203 204 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 205 206 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 207 208 // Maximum number of recent tasks that we can remember. 209 static final int MAX_RECENT_TASKS = 20; 210 211 // Amount of time after a call to stopAppSwitches() during which we will 212 // prevent further untrusted switches from happening. 213 static final long APP_SWITCH_DELAY_TIME = 5*1000; 214 215 // How long we wait for a launched process to attach to the activity manager 216 // before we decide it's never going to come up for real. 217 static final int PROC_START_TIMEOUT = 10*1000; 218 219 // How long we wait for a launched process to attach to the activity manager 220 // before we decide it's never going to come up for real, when the process was 221 // started with a wrapper for instrumentation (such as Valgrind) because it 222 // could take much longer than usual. 223 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 224 225 // How long to wait after going idle before forcing apps to GC. 226 static final int GC_TIMEOUT = 5*1000; 227 228 // The minimum amount of time between successive GC requests for a process. 229 static final int GC_MIN_INTERVAL = 60*1000; 230 231 // The rate at which we check for apps using excessive power -- 15 mins. 232 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 233 234 // The minimum sample duration we will allow before deciding we have 235 // enough data on wake locks to start killing things. 236 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 237 238 // The minimum sample duration we will allow before deciding we have 239 // enough data on CPU usage to start killing things. 240 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 241 242 // How long we allow a receiver to run before giving up on it. 243 static final int BROADCAST_FG_TIMEOUT = 10*1000; 244 static final int BROADCAST_BG_TIMEOUT = 60*1000; 245 246 // How long we wait until we timeout on key dispatching. 247 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 248 249 // How long we wait until we timeout on key dispatching during instrumentation. 250 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 251 252 static final int MY_PID = Process.myPid(); 253 254 static final String[] EMPTY_STRING_ARRAY = new String[0]; 255 256 public ActivityStack mMainStack; 257 258 private final boolean mHeadless; 259 260 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 261 // default actuion automatically. Important for devices without direct input 262 // devices. 263 private boolean mShowDialogs = true; 264 265 /** 266 * Description of a request to start a new activity, which has been held 267 * due to app switches being disabled. 268 */ 269 static class PendingActivityLaunch { 270 ActivityRecord r; 271 ActivityRecord sourceRecord; 272 int startFlags; 273 } 274 275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 276 = new ArrayList<PendingActivityLaunch>(); 277 278 279 BroadcastQueue mFgBroadcastQueue; 280 BroadcastQueue mBgBroadcastQueue; 281 // Convenient for easy iteration over the queues. Foreground is first 282 // so that dispatch of foreground broadcasts gets precedence. 283 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 284 285 BroadcastQueue broadcastQueueForIntent(Intent intent) { 286 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 287 if (DEBUG_BACKGROUND_BROADCAST) { 288 Slog.i(TAG, "Broadcast intent " + intent + " on " 289 + (isFg ? "foreground" : "background") 290 + " queue"); 291 } 292 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 293 } 294 295 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 296 for (BroadcastQueue queue : mBroadcastQueues) { 297 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 298 if (r != null) { 299 return r; 300 } 301 } 302 return null; 303 } 304 305 /** 306 * Activity we have told the window manager to have key focus. 307 */ 308 ActivityRecord mFocusedActivity = null; 309 /** 310 * List of intents that were used to start the most recent tasks. 311 */ 312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 313 314 /** 315 * Process management. 316 */ 317 final ProcessList mProcessList = new ProcessList(); 318 319 /** 320 * All of the applications we currently have running organized by name. 321 * The keys are strings of the application package name (as 322 * returned by the package manager), and the keys are ApplicationRecord 323 * objects. 324 */ 325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 326 327 /** 328 * The currently running isolated processes. 329 */ 330 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 331 332 /** 333 * Counter for assigning isolated process uids, to avoid frequently reusing the 334 * same ones. 335 */ 336 int mNextIsolatedProcessUid = 0; 337 338 /** 339 * The currently running heavy-weight process, if any. 340 */ 341 ProcessRecord mHeavyWeightProcess = null; 342 343 /** 344 * The last time that various processes have crashed. 345 */ 346 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 347 348 /** 349 * Set of applications that we consider to be bad, and will reject 350 * incoming broadcasts from (which the user has no control over). 351 * Processes are added to this set when they have crashed twice within 352 * a minimum amount of time; they are removed from it when they are 353 * later restarted (hopefully due to some user action). The value is the 354 * time it was added to the list. 355 */ 356 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 357 358 /** 359 * All of the processes we currently have running organized by pid. 360 * The keys are the pid running the application. 361 * 362 * <p>NOTE: This object is protected by its own lock, NOT the global 363 * activity manager lock! 364 */ 365 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 366 367 /** 368 * All of the processes that have been forced to be foreground. The key 369 * is the pid of the caller who requested it (we hold a death 370 * link on it). 371 */ 372 abstract class ForegroundToken implements IBinder.DeathRecipient { 373 int pid; 374 IBinder token; 375 } 376 final SparseArray<ForegroundToken> mForegroundProcesses 377 = new SparseArray<ForegroundToken>(); 378 379 /** 380 * List of records for processes that someone had tried to start before the 381 * system was ready. We don't start them at that point, but ensure they 382 * are started by the time booting is complete. 383 */ 384 final ArrayList<ProcessRecord> mProcessesOnHold 385 = new ArrayList<ProcessRecord>(); 386 387 /** 388 * List of persistent applications that are in the process 389 * of being started. 390 */ 391 final ArrayList<ProcessRecord> mPersistentStartingProcesses 392 = new ArrayList<ProcessRecord>(); 393 394 /** 395 * Processes that are being forcibly torn down. 396 */ 397 final ArrayList<ProcessRecord> mRemovedProcesses 398 = new ArrayList<ProcessRecord>(); 399 400 /** 401 * List of running applications, sorted by recent usage. 402 * The first entry in the list is the least recently used. 403 * It contains ApplicationRecord objects. This list does NOT include 404 * any persistent application records (since we never want to exit them). 405 */ 406 final ArrayList<ProcessRecord> mLruProcesses 407 = new ArrayList<ProcessRecord>(); 408 409 /** 410 * List of processes that should gc as soon as things are idle. 411 */ 412 final ArrayList<ProcessRecord> mProcessesToGc 413 = new ArrayList<ProcessRecord>(); 414 415 /** 416 * This is the process holding what we currently consider to be 417 * the "home" activity. 418 */ 419 ProcessRecord mHomeProcess; 420 421 /** 422 * This is the process holding the activity the user last visited that 423 * is in a different process from the one they are currently in. 424 */ 425 ProcessRecord mPreviousProcess; 426 427 /** 428 * The time at which the previous process was last visible. 429 */ 430 long mPreviousProcessVisibleTime; 431 432 /** 433 * Packages that the user has asked to have run in screen size 434 * compatibility mode instead of filling the screen. 435 */ 436 final CompatModePackages mCompatModePackages; 437 438 /** 439 * Set of PendingResultRecord objects that are currently active. 440 */ 441 final HashSet mPendingResultRecords = new HashSet(); 442 443 /** 444 * Set of IntentSenderRecord objects that are currently active. 445 */ 446 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 447 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 448 449 /** 450 * Fingerprints (hashCode()) of stack traces that we've 451 * already logged DropBox entries for. Guarded by itself. If 452 * something (rogue user app) forces this over 453 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 454 */ 455 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 456 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 457 458 /** 459 * Strict Mode background batched logging state. 460 * 461 * The string buffer is guarded by itself, and its lock is also 462 * used to determine if another batched write is already 463 * in-flight. 464 */ 465 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 466 467 /** 468 * Keeps track of all IIntentReceivers that have been registered for 469 * broadcasts. Hash keys are the receiver IBinder, hash value is 470 * a ReceiverList. 471 */ 472 final HashMap mRegisteredReceivers = new HashMap(); 473 474 /** 475 * Resolver for broadcast intents to registered receivers. 476 * Holds BroadcastFilter (subclass of IntentFilter). 477 */ 478 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 479 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 480 @Override 481 protected boolean allowFilterResult( 482 BroadcastFilter filter, List<BroadcastFilter> dest) { 483 IBinder target = filter.receiverList.receiver.asBinder(); 484 for (int i=dest.size()-1; i>=0; i--) { 485 if (dest.get(i).receiverList.receiver.asBinder() == target) { 486 return false; 487 } 488 } 489 return true; 490 } 491 492 @Override 493 protected BroadcastFilter[] newArray(int size) { 494 return new BroadcastFilter[size]; 495 } 496 497 @Override 498 protected String packageForFilter(BroadcastFilter filter) { 499 return filter.packageName; 500 } 501 }; 502 503 /** 504 * State of all active sticky broadcasts. Keys are the action of the 505 * sticky Intent, values are an ArrayList of all broadcasted intents with 506 * that action (which should usually be one). 507 */ 508 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 509 new HashMap<String, ArrayList<Intent>>(); 510 511 final ActiveServices mServices; 512 513 /** 514 * Backup/restore process management 515 */ 516 String mBackupAppName = null; 517 BackupRecord mBackupTarget = null; 518 519 /** 520 * List of PendingThumbnailsRecord objects of clients who are still 521 * waiting to receive all of the thumbnails for a task. 522 */ 523 final ArrayList mPendingThumbnails = new ArrayList(); 524 525 /** 526 * List of HistoryRecord objects that have been finished and must 527 * still report back to a pending thumbnail receiver. 528 */ 529 final ArrayList mCancelledThumbnails = new ArrayList(); 530 531 final ProviderMap mProviderMap = new ProviderMap(); 532 533 /** 534 * List of content providers who have clients waiting for them. The 535 * application is currently being launched and the provider will be 536 * removed from this list once it is published. 537 */ 538 final ArrayList<ContentProviderRecord> mLaunchingProviders 539 = new ArrayList<ContentProviderRecord>(); 540 541 /** 542 * Global set of specific Uri permissions that have been granted. 543 */ 544 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 545 = new SparseArray<HashMap<Uri, UriPermission>>(); 546 547 CoreSettingsObserver mCoreSettingsObserver; 548 549 /** 550 * Thread-local storage used to carry caller permissions over through 551 * indirect content-provider access. 552 * @see #ActivityManagerService.openContentUri() 553 */ 554 private class Identity { 555 public int pid; 556 public int uid; 557 558 Identity(int _pid, int _uid) { 559 pid = _pid; 560 uid = _uid; 561 } 562 } 563 564 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 565 566 /** 567 * All information we have collected about the runtime performance of 568 * any user id that can impact battery performance. 569 */ 570 final BatteryStatsService mBatteryStatsService; 571 572 /** 573 * information about component usage 574 */ 575 final UsageStatsService mUsageStatsService; 576 577 /** 578 * Current configuration information. HistoryRecord objects are given 579 * a reference to this object to indicate which configuration they are 580 * currently running in, so this object must be kept immutable. 581 */ 582 Configuration mConfiguration = new Configuration(); 583 584 /** 585 * Current sequencing integer of the configuration, for skipping old 586 * configurations. 587 */ 588 int mConfigurationSeq = 0; 589 590 /** 591 * Hardware-reported OpenGLES version. 592 */ 593 final int GL_ES_VERSION; 594 595 /** 596 * List of initialization arguments to pass to all processes when binding applications to them. 597 * For example, references to the commonly used services. 598 */ 599 HashMap<String, IBinder> mAppBindArgs; 600 601 /** 602 * Temporary to avoid allocations. Protected by main lock. 603 */ 604 final StringBuilder mStringBuilder = new StringBuilder(256); 605 606 /** 607 * Used to control how we initialize the service. 608 */ 609 boolean mStartRunning = false; 610 ComponentName mTopComponent; 611 String mTopAction; 612 String mTopData; 613 boolean mProcessesReady = false; 614 boolean mSystemReady = false; 615 boolean mBooting = false; 616 boolean mWaitingUpdate = false; 617 boolean mDidUpdate = false; 618 boolean mOnBattery = false; 619 boolean mLaunchWarningShown = false; 620 621 Context mContext; 622 623 int mFactoryTest; 624 625 boolean mCheckedForSetup; 626 627 /** 628 * The time at which we will allow normal application switches again, 629 * after a call to {@link #stopAppSwitches()}. 630 */ 631 long mAppSwitchesAllowedTime; 632 633 /** 634 * This is set to true after the first switch after mAppSwitchesAllowedTime 635 * is set; any switches after that will clear the time. 636 */ 637 boolean mDidAppSwitch; 638 639 /** 640 * Last time (in realtime) at which we checked for power usage. 641 */ 642 long mLastPowerCheckRealtime; 643 644 /** 645 * Last time (in uptime) at which we checked for power usage. 646 */ 647 long mLastPowerCheckUptime; 648 649 /** 650 * Set while we are wanting to sleep, to prevent any 651 * activities from being started/resumed. 652 */ 653 boolean mSleeping = false; 654 655 /** 656 * State of external calls telling us if the device is asleep. 657 */ 658 boolean mWentToSleep = false; 659 660 /** 661 * State of external call telling us if the lock screen is shown. 662 */ 663 boolean mLockScreenShown = false; 664 665 /** 666 * Set if we are shutting down the system, similar to sleeping. 667 */ 668 boolean mShuttingDown = false; 669 670 /** 671 * Task identifier that activities are currently being started 672 * in. Incremented each time a new task is created. 673 * todo: Replace this with a TokenSpace class that generates non-repeating 674 * integers that won't wrap. 675 */ 676 int mCurTask = 1; 677 678 /** 679 * Current sequence id for oom_adj computation traversal. 680 */ 681 int mAdjSeq = 0; 682 683 /** 684 * Current sequence id for process LRU updating. 685 */ 686 int mLruSeq = 0; 687 688 /** 689 * Keep track of the number of service processes we last found, to 690 * determine on the next iteration which should be B services. 691 */ 692 int mNumServiceProcs = 0; 693 int mNewNumServiceProcs = 0; 694 695 /** 696 * System monitoring: number of processes that died since the last 697 * N procs were started. 698 */ 699 int[] mProcDeaths = new int[20]; 700 701 /** 702 * This is set if we had to do a delayed dexopt of an app before launching 703 * it, to increasing the ANR timeouts in that case. 704 */ 705 boolean mDidDexOpt; 706 707 String mDebugApp = null; 708 boolean mWaitForDebugger = false; 709 boolean mDebugTransient = false; 710 String mOrigDebugApp = null; 711 boolean mOrigWaitForDebugger = false; 712 boolean mAlwaysFinishActivities = false; 713 IActivityController mController = null; 714 String mProfileApp = null; 715 ProcessRecord mProfileProc = null; 716 String mProfileFile; 717 ParcelFileDescriptor mProfileFd; 718 int mProfileType = 0; 719 boolean mAutoStopProfiler = false; 720 String mOpenGlTraceApp = null; 721 722 static class ProcessChangeItem { 723 static final int CHANGE_ACTIVITIES = 1<<0; 724 static final int CHANGE_IMPORTANCE= 1<<1; 725 int changes; 726 int uid; 727 int pid; 728 int importance; 729 boolean foregroundActivities; 730 } 731 732 final RemoteCallbackList<IProcessObserver> mProcessObservers 733 = new RemoteCallbackList<IProcessObserver>(); 734 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 735 736 final ArrayList<ProcessChangeItem> mPendingProcessChanges 737 = new ArrayList<ProcessChangeItem>(); 738 final ArrayList<ProcessChangeItem> mAvailProcessChanges 739 = new ArrayList<ProcessChangeItem>(); 740 741 /** 742 * Callback of last caller to {@link #requestPss}. 743 */ 744 Runnable mRequestPssCallback; 745 746 /** 747 * Remaining processes for which we are waiting results from the last 748 * call to {@link #requestPss}. 749 */ 750 final ArrayList<ProcessRecord> mRequestPssList 751 = new ArrayList<ProcessRecord>(); 752 753 /** 754 * Runtime statistics collection thread. This object's lock is used to 755 * protect all related state. 756 */ 757 final Thread mProcessStatsThread; 758 759 /** 760 * Used to collect process stats when showing not responding dialog. 761 * Protected by mProcessStatsThread. 762 */ 763 final ProcessStats mProcessStats = new ProcessStats( 764 MONITOR_THREAD_CPU_USAGE); 765 final AtomicLong mLastCpuTime = new AtomicLong(0); 766 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 767 768 long mLastWriteTime = 0; 769 770 /** 771 * Set to true after the system has finished booting. 772 */ 773 boolean mBooted = false; 774 775 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 776 int mProcessLimitOverride = -1; 777 778 WindowManagerService mWindowManager; 779 780 static ActivityManagerService mSelf; 781 static ActivityThread mSystemThread; 782 783 private int mCurrentUserId; 784 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 785 private UserManager mUserManager; 786 787 private final class AppDeathRecipient implements IBinder.DeathRecipient { 788 final ProcessRecord mApp; 789 final int mPid; 790 final IApplicationThread mAppThread; 791 792 AppDeathRecipient(ProcessRecord app, int pid, 793 IApplicationThread thread) { 794 if (localLOGV) Slog.v( 795 TAG, "New death recipient " + this 796 + " for thread " + thread.asBinder()); 797 mApp = app; 798 mPid = pid; 799 mAppThread = thread; 800 } 801 802 public void binderDied() { 803 if (localLOGV) Slog.v( 804 TAG, "Death received in " + this 805 + " for thread " + mAppThread.asBinder()); 806 synchronized(ActivityManagerService.this) { 807 appDiedLocked(mApp, mPid, mAppThread); 808 } 809 } 810 } 811 812 static final int SHOW_ERROR_MSG = 1; 813 static final int SHOW_NOT_RESPONDING_MSG = 2; 814 static final int SHOW_FACTORY_ERROR_MSG = 3; 815 static final int UPDATE_CONFIGURATION_MSG = 4; 816 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 817 static final int WAIT_FOR_DEBUGGER_MSG = 6; 818 static final int SERVICE_TIMEOUT_MSG = 12; 819 static final int UPDATE_TIME_ZONE = 13; 820 static final int SHOW_UID_ERROR_MSG = 14; 821 static final int IM_FEELING_LUCKY_MSG = 15; 822 static final int PROC_START_TIMEOUT_MSG = 20; 823 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 824 static final int KILL_APPLICATION_MSG = 22; 825 static final int FINALIZE_PENDING_INTENT_MSG = 23; 826 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 827 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 828 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 829 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 830 static final int CLEAR_DNS_CACHE = 28; 831 static final int UPDATE_HTTP_PROXY = 29; 832 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 833 static final int DISPATCH_PROCESSES_CHANGED = 31; 834 static final int DISPATCH_PROCESS_DIED = 32; 835 static final int REPORT_MEM_USAGE = 33; 836 837 static final int FIRST_ACTIVITY_STACK_MSG = 100; 838 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 839 static final int FIRST_COMPAT_MODE_MSG = 300; 840 841 AlertDialog mUidAlert; 842 CompatModeDialog mCompatModeDialog; 843 long mLastMemUsageReportTime = 0; 844 845 final Handler mHandler = new Handler() { 846 //public Handler() { 847 // if (localLOGV) Slog.v(TAG, "Handler started!"); 848 //} 849 850 public void handleMessage(Message msg) { 851 switch (msg.what) { 852 case SHOW_ERROR_MSG: { 853 HashMap data = (HashMap) msg.obj; 854 synchronized (ActivityManagerService.this) { 855 ProcessRecord proc = (ProcessRecord)data.get("app"); 856 if (proc != null && proc.crashDialog != null) { 857 Slog.e(TAG, "App already has crash dialog: " + proc); 858 return; 859 } 860 AppErrorResult res = (AppErrorResult) data.get("result"); 861 if (mShowDialogs && !mSleeping && !mShuttingDown) { 862 Dialog d = new AppErrorDialog(mContext, res, proc); 863 d.show(); 864 proc.crashDialog = d; 865 } else { 866 // The device is asleep, so just pretend that the user 867 // saw a crash dialog and hit "force quit". 868 res.set(0); 869 } 870 } 871 872 ensureBootCompleted(); 873 } break; 874 case SHOW_NOT_RESPONDING_MSG: { 875 synchronized (ActivityManagerService.this) { 876 HashMap data = (HashMap) msg.obj; 877 ProcessRecord proc = (ProcessRecord)data.get("app"); 878 if (proc != null && proc.anrDialog != null) { 879 Slog.e(TAG, "App already has anr dialog: " + proc); 880 return; 881 } 882 883 Intent intent = new Intent("android.intent.action.ANR"); 884 if (!mProcessesReady) { 885 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 886 | Intent.FLAG_RECEIVER_FOREGROUND); 887 } 888 broadcastIntentLocked(null, null, intent, 889 null, null, 0, null, null, null, 890 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 891 892 if (mShowDialogs) { 893 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 894 mContext, proc, (ActivityRecord)data.get("activity")); 895 d.show(); 896 proc.anrDialog = d; 897 } else { 898 // Just kill the app if there is no dialog to be shown. 899 killAppAtUsersRequest(proc, null); 900 } 901 } 902 903 ensureBootCompleted(); 904 } break; 905 case SHOW_STRICT_MODE_VIOLATION_MSG: { 906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 907 synchronized (ActivityManagerService.this) { 908 ProcessRecord proc = (ProcessRecord) data.get("app"); 909 if (proc == null) { 910 Slog.e(TAG, "App not found when showing strict mode dialog."); 911 break; 912 } 913 if (proc.crashDialog != null) { 914 Slog.e(TAG, "App already has strict mode dialog: " + proc); 915 return; 916 } 917 AppErrorResult res = (AppErrorResult) data.get("result"); 918 if (mShowDialogs && !mSleeping && !mShuttingDown) { 919 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 920 d.show(); 921 proc.crashDialog = d; 922 } else { 923 // The device is asleep, so just pretend that the user 924 // saw a crash dialog and hit "force quit". 925 res.set(0); 926 } 927 } 928 ensureBootCompleted(); 929 } break; 930 case SHOW_FACTORY_ERROR_MSG: { 931 Dialog d = new FactoryErrorDialog( 932 mContext, msg.getData().getCharSequence("msg")); 933 d.show(); 934 ensureBootCompleted(); 935 } break; 936 case UPDATE_CONFIGURATION_MSG: { 937 final ContentResolver resolver = mContext.getContentResolver(); 938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 939 } break; 940 case GC_BACKGROUND_PROCESSES_MSG: { 941 synchronized (ActivityManagerService.this) { 942 performAppGcsIfAppropriateLocked(); 943 } 944 } break; 945 case WAIT_FOR_DEBUGGER_MSG: { 946 synchronized (ActivityManagerService.this) { 947 ProcessRecord app = (ProcessRecord)msg.obj; 948 if (msg.arg1 != 0) { 949 if (!app.waitedForDebugger) { 950 Dialog d = new AppWaitingForDebuggerDialog( 951 ActivityManagerService.this, 952 mContext, app); 953 app.waitDialog = d; 954 app.waitedForDebugger = true; 955 d.show(); 956 } 957 } else { 958 if (app.waitDialog != null) { 959 app.waitDialog.dismiss(); 960 app.waitDialog = null; 961 } 962 } 963 } 964 } break; 965 case SERVICE_TIMEOUT_MSG: { 966 if (mDidDexOpt) { 967 mDidDexOpt = false; 968 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 969 nmsg.obj = msg.obj; 970 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 971 return; 972 } 973 mServices.serviceTimeout((ProcessRecord)msg.obj); 974 } break; 975 case UPDATE_TIME_ZONE: { 976 synchronized (ActivityManagerService.this) { 977 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 978 ProcessRecord r = mLruProcesses.get(i); 979 if (r.thread != null) { 980 try { 981 r.thread.updateTimeZone(); 982 } catch (RemoteException ex) { 983 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 984 } 985 } 986 } 987 } 988 } break; 989 case CLEAR_DNS_CACHE: { 990 synchronized (ActivityManagerService.this) { 991 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 992 ProcessRecord r = mLruProcesses.get(i); 993 if (r.thread != null) { 994 try { 995 r.thread.clearDnsCache(); 996 } catch (RemoteException ex) { 997 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 998 } 999 } 1000 } 1001 } 1002 } break; 1003 case UPDATE_HTTP_PROXY: { 1004 ProxyProperties proxy = (ProxyProperties)msg.obj; 1005 String host = ""; 1006 String port = ""; 1007 String exclList = ""; 1008 if (proxy != null) { 1009 host = proxy.getHost(); 1010 port = Integer.toString(proxy.getPort()); 1011 exclList = proxy.getExclusionList(); 1012 } 1013 synchronized (ActivityManagerService.this) { 1014 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1015 ProcessRecord r = mLruProcesses.get(i); 1016 if (r.thread != null) { 1017 try { 1018 r.thread.setHttpProxy(host, port, exclList); 1019 } catch (RemoteException ex) { 1020 Slog.w(TAG, "Failed to update http proxy for: " + 1021 r.info.processName); 1022 } 1023 } 1024 } 1025 } 1026 } break; 1027 case SHOW_UID_ERROR_MSG: { 1028 String title = "System UIDs Inconsistent"; 1029 String text = "UIDs on the system are inconsistent, you need to wipe your" 1030 + " data partition or your device will be unstable."; 1031 Log.e(TAG, title + ": " + text); 1032 if (mShowDialogs) { 1033 // XXX This is a temporary dialog, no need to localize. 1034 AlertDialog d = new BaseErrorDialog(mContext); 1035 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1036 d.setCancelable(false); 1037 d.setTitle(title); 1038 d.setMessage(text); 1039 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1040 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1041 mUidAlert = d; 1042 d.show(); 1043 } 1044 } break; 1045 case IM_FEELING_LUCKY_MSG: { 1046 if (mUidAlert != null) { 1047 mUidAlert.dismiss(); 1048 mUidAlert = null; 1049 } 1050 } break; 1051 case PROC_START_TIMEOUT_MSG: { 1052 if (mDidDexOpt) { 1053 mDidDexOpt = false; 1054 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1055 nmsg.obj = msg.obj; 1056 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1057 return; 1058 } 1059 ProcessRecord app = (ProcessRecord)msg.obj; 1060 synchronized (ActivityManagerService.this) { 1061 processStartTimedOutLocked(app); 1062 } 1063 } break; 1064 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1065 synchronized (ActivityManagerService.this) { 1066 doPendingActivityLaunchesLocked(true); 1067 } 1068 } break; 1069 case KILL_APPLICATION_MSG: { 1070 synchronized (ActivityManagerService.this) { 1071 int uid = msg.arg1; 1072 boolean restart = (msg.arg2 == 1); 1073 String pkg = (String) msg.obj; 1074 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1075 UserId.getUserId(uid)); 1076 } 1077 } break; 1078 case FINALIZE_PENDING_INTENT_MSG: { 1079 ((PendingIntentRecord)msg.obj).completeFinalize(); 1080 } break; 1081 case POST_HEAVY_NOTIFICATION_MSG: { 1082 INotificationManager inm = NotificationManager.getService(); 1083 if (inm == null) { 1084 return; 1085 } 1086 1087 ActivityRecord root = (ActivityRecord)msg.obj; 1088 ProcessRecord process = root.app; 1089 if (process == null) { 1090 return; 1091 } 1092 1093 try { 1094 Context context = mContext.createPackageContext(process.info.packageName, 0); 1095 String text = mContext.getString(R.string.heavy_weight_notification, 1096 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1097 Notification notification = new Notification(); 1098 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1099 notification.when = 0; 1100 notification.flags = Notification.FLAG_ONGOING_EVENT; 1101 notification.tickerText = text; 1102 notification.defaults = 0; // please be quiet 1103 notification.sound = null; 1104 notification.vibrate = null; 1105 notification.setLatestEventInfo(context, text, 1106 mContext.getText(R.string.heavy_weight_notification_detail), 1107 PendingIntent.getActivity(mContext, 0, root.intent, 1108 PendingIntent.FLAG_CANCEL_CURRENT)); 1109 1110 try { 1111 int[] outId = new int[1]; 1112 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1113 notification, outId); 1114 } catch (RuntimeException e) { 1115 Slog.w(ActivityManagerService.TAG, 1116 "Error showing notification for heavy-weight app", e); 1117 } catch (RemoteException e) { 1118 } 1119 } catch (NameNotFoundException e) { 1120 Slog.w(TAG, "Unable to create context for heavy notification", e); 1121 } 1122 } break; 1123 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1124 INotificationManager inm = NotificationManager.getService(); 1125 if (inm == null) { 1126 return; 1127 } 1128 try { 1129 inm.cancelNotification("android", 1130 R.string.heavy_weight_notification); 1131 } catch (RuntimeException e) { 1132 Slog.w(ActivityManagerService.TAG, 1133 "Error canceling notification for service", e); 1134 } catch (RemoteException e) { 1135 } 1136 } break; 1137 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1138 synchronized (ActivityManagerService.this) { 1139 checkExcessivePowerUsageLocked(true); 1140 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1141 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1142 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1143 } 1144 } break; 1145 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 ActivityRecord ar = (ActivityRecord)msg.obj; 1148 if (mCompatModeDialog != null) { 1149 if (mCompatModeDialog.mAppInfo.packageName.equals( 1150 ar.info.applicationInfo.packageName)) { 1151 return; 1152 } 1153 mCompatModeDialog.dismiss(); 1154 mCompatModeDialog = null; 1155 } 1156 if (ar != null && false) { 1157 if (mCompatModePackages.getPackageAskCompatModeLocked( 1158 ar.packageName)) { 1159 int mode = mCompatModePackages.computeCompatModeLocked( 1160 ar.info.applicationInfo); 1161 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1162 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1163 mCompatModeDialog = new CompatModeDialog( 1164 ActivityManagerService.this, mContext, 1165 ar.info.applicationInfo); 1166 mCompatModeDialog.show(); 1167 } 1168 } 1169 } 1170 } 1171 break; 1172 } 1173 case DISPATCH_PROCESSES_CHANGED: { 1174 dispatchProcessesChanged(); 1175 break; 1176 } 1177 case DISPATCH_PROCESS_DIED: { 1178 final int pid = msg.arg1; 1179 final int uid = msg.arg2; 1180 dispatchProcessDied(pid, uid); 1181 break; 1182 } 1183 case REPORT_MEM_USAGE: { 1184 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1185 if (!isDebuggable) { 1186 return; 1187 } 1188 synchronized (ActivityManagerService.this) { 1189 long now = SystemClock.uptimeMillis(); 1190 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1191 // Don't report more than every 5 minutes to somewhat 1192 // avoid spamming. 1193 return; 1194 } 1195 mLastMemUsageReportTime = now; 1196 } 1197 Thread thread = new Thread() { 1198 @Override public void run() { 1199 StringBuilder dropBuilder = new StringBuilder(1024); 1200 StringBuilder logBuilder = new StringBuilder(1024); 1201 StringWriter oomSw = new StringWriter(); 1202 PrintWriter oomPw = new PrintWriter(oomSw); 1203 StringWriter catSw = new StringWriter(); 1204 PrintWriter catPw = new PrintWriter(catSw); 1205 String[] emptyArgs = new String[] { }; 1206 StringBuilder tag = new StringBuilder(128); 1207 StringBuilder stack = new StringBuilder(128); 1208 tag.append("Low on memory -- "); 1209 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1210 tag, stack); 1211 dropBuilder.append(stack); 1212 dropBuilder.append('\n'); 1213 dropBuilder.append('\n'); 1214 String oomString = oomSw.toString(); 1215 dropBuilder.append(oomString); 1216 dropBuilder.append('\n'); 1217 logBuilder.append(oomString); 1218 try { 1219 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1220 "procrank", }); 1221 final InputStreamReader converter = new InputStreamReader( 1222 proc.getInputStream()); 1223 BufferedReader in = new BufferedReader(converter); 1224 String line; 1225 while (true) { 1226 line = in.readLine(); 1227 if (line == null) { 1228 break; 1229 } 1230 if (line.length() > 0) { 1231 logBuilder.append(line); 1232 logBuilder.append('\n'); 1233 } 1234 dropBuilder.append(line); 1235 dropBuilder.append('\n'); 1236 } 1237 converter.close(); 1238 } catch (IOException e) { 1239 } 1240 synchronized (ActivityManagerService.this) { 1241 catPw.println(); 1242 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1243 catPw.println(); 1244 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1245 false, false, null); 1246 catPw.println(); 1247 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1248 } 1249 dropBuilder.append(catSw.toString()); 1250 addErrorToDropBox("lowmem", null, "system_server", null, 1251 null, tag.toString(), dropBuilder.toString(), null, null); 1252 Slog.i(TAG, logBuilder.toString()); 1253 synchronized (ActivityManagerService.this) { 1254 long now = SystemClock.uptimeMillis(); 1255 if (mLastMemUsageReportTime < now) { 1256 mLastMemUsageReportTime = now; 1257 } 1258 } 1259 } 1260 }; 1261 thread.start(); 1262 break; 1263 } 1264 } 1265 } 1266 }; 1267 1268 public static void setSystemProcess() { 1269 try { 1270 ActivityManagerService m = mSelf; 1271 1272 ServiceManager.addService("activity", m, true); 1273 ServiceManager.addService("meminfo", new MemBinder(m)); 1274 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1275 ServiceManager.addService("dbinfo", new DbBinder(m)); 1276 if (MONITOR_CPU_USAGE) { 1277 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1278 } 1279 ServiceManager.addService("permission", new PermissionController(m)); 1280 1281 ApplicationInfo info = 1282 mSelf.mContext.getPackageManager().getApplicationInfo( 1283 "android", STOCK_PM_FLAGS); 1284 mSystemThread.installSystemApplicationInfo(info); 1285 1286 synchronized (mSelf) { 1287 ProcessRecord app = mSelf.newProcessRecordLocked( 1288 mSystemThread.getApplicationThread(), info, 1289 info.processName, false); 1290 app.persistent = true; 1291 app.pid = MY_PID; 1292 app.maxAdj = ProcessList.SYSTEM_ADJ; 1293 mSelf.mProcessNames.put(app.processName, app.uid, app); 1294 synchronized (mSelf.mPidsSelfLocked) { 1295 mSelf.mPidsSelfLocked.put(app.pid, app); 1296 } 1297 mSelf.updateLruProcessLocked(app, true, true); 1298 } 1299 } catch (PackageManager.NameNotFoundException e) { 1300 throw new RuntimeException( 1301 "Unable to find android system package", e); 1302 } 1303 } 1304 1305 public void setWindowManager(WindowManagerService wm) { 1306 mWindowManager = wm; 1307 } 1308 1309 public static final Context main(int factoryTest) { 1310 AThread thr = new AThread(); 1311 thr.start(); 1312 1313 synchronized (thr) { 1314 while (thr.mService == null) { 1315 try { 1316 thr.wait(); 1317 } catch (InterruptedException e) { 1318 } 1319 } 1320 } 1321 1322 ActivityManagerService m = thr.mService; 1323 mSelf = m; 1324 ActivityThread at = ActivityThread.systemMain(); 1325 mSystemThread = at; 1326 Context context = at.getSystemContext(); 1327 context.setTheme(android.R.style.Theme_Holo); 1328 m.mContext = context; 1329 m.mFactoryTest = factoryTest; 1330 m.mMainStack = new ActivityStack(m, context, true); 1331 1332 m.mBatteryStatsService.publish(context); 1333 m.mUsageStatsService.publish(context); 1334 1335 synchronized (thr) { 1336 thr.mReady = true; 1337 thr.notifyAll(); 1338 } 1339 1340 m.startRunning(null, null, null, null); 1341 1342 return context; 1343 } 1344 1345 public static ActivityManagerService self() { 1346 return mSelf; 1347 } 1348 1349 static class AThread extends Thread { 1350 ActivityManagerService mService; 1351 boolean mReady = false; 1352 1353 public AThread() { 1354 super("ActivityManager"); 1355 } 1356 1357 public void run() { 1358 Looper.prepare(); 1359 1360 android.os.Process.setThreadPriority( 1361 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1362 android.os.Process.setCanSelfBackground(false); 1363 1364 ActivityManagerService m = new ActivityManagerService(); 1365 1366 synchronized (this) { 1367 mService = m; 1368 notifyAll(); 1369 } 1370 1371 synchronized (this) { 1372 while (!mReady) { 1373 try { 1374 wait(); 1375 } catch (InterruptedException e) { 1376 } 1377 } 1378 } 1379 1380 // For debug builds, log event loop stalls to dropbox for analysis. 1381 if (StrictMode.conditionallyEnableDebugLogging()) { 1382 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1383 } 1384 1385 Looper.loop(); 1386 } 1387 } 1388 1389 static class MemBinder extends Binder { 1390 ActivityManagerService mActivityManagerService; 1391 MemBinder(ActivityManagerService activityManagerService) { 1392 mActivityManagerService = activityManagerService; 1393 } 1394 1395 @Override 1396 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1397 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1398 != PackageManager.PERMISSION_GRANTED) { 1399 pw.println("Permission Denial: can't dump meminfo from from pid=" 1400 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1401 + " without permission " + android.Manifest.permission.DUMP); 1402 return; 1403 } 1404 1405 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1406 false, null, null, null); 1407 } 1408 } 1409 1410 static class GraphicsBinder extends Binder { 1411 ActivityManagerService mActivityManagerService; 1412 GraphicsBinder(ActivityManagerService activityManagerService) { 1413 mActivityManagerService = activityManagerService; 1414 } 1415 1416 @Override 1417 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1418 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1419 != PackageManager.PERMISSION_GRANTED) { 1420 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1421 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1422 + " without permission " + android.Manifest.permission.DUMP); 1423 return; 1424 } 1425 1426 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1427 } 1428 } 1429 1430 static class DbBinder extends Binder { 1431 ActivityManagerService mActivityManagerService; 1432 DbBinder(ActivityManagerService activityManagerService) { 1433 mActivityManagerService = activityManagerService; 1434 } 1435 1436 @Override 1437 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1438 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1439 != PackageManager.PERMISSION_GRANTED) { 1440 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1441 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1442 + " without permission " + android.Manifest.permission.DUMP); 1443 return; 1444 } 1445 1446 mActivityManagerService.dumpDbInfo(fd, pw, args); 1447 } 1448 } 1449 1450 static class CpuBinder extends Binder { 1451 ActivityManagerService mActivityManagerService; 1452 CpuBinder(ActivityManagerService activityManagerService) { 1453 mActivityManagerService = activityManagerService; 1454 } 1455 1456 @Override 1457 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1458 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1459 != PackageManager.PERMISSION_GRANTED) { 1460 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1461 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1462 + " without permission " + android.Manifest.permission.DUMP); 1463 return; 1464 } 1465 1466 synchronized (mActivityManagerService.mProcessStatsThread) { 1467 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1468 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1469 SystemClock.uptimeMillis())); 1470 } 1471 } 1472 } 1473 1474 private ActivityManagerService() { 1475 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1476 1477 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1478 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1479 mBroadcastQueues[0] = mFgBroadcastQueue; 1480 mBroadcastQueues[1] = mBgBroadcastQueue; 1481 1482 mServices = new ActiveServices(this); 1483 1484 File dataDir = Environment.getDataDirectory(); 1485 File systemDir = new File(dataDir, "system"); 1486 systemDir.mkdirs(); 1487 mBatteryStatsService = new BatteryStatsService(new File( 1488 systemDir, "batterystats.bin").toString()); 1489 mBatteryStatsService.getActiveStatistics().readLocked(); 1490 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1491 mOnBattery = DEBUG_POWER ? true 1492 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1493 mBatteryStatsService.getActiveStatistics().setCallback(this); 1494 1495 mUsageStatsService = new UsageStatsService(new File( 1496 systemDir, "usagestats").toString()); 1497 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1498 1499 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1500 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1501 1502 mConfiguration.setToDefaults(); 1503 mConfiguration.locale = Locale.getDefault(); 1504 mConfigurationSeq = mConfiguration.seq = 1; 1505 mProcessStats.init(); 1506 1507 mCompatModePackages = new CompatModePackages(this, systemDir); 1508 1509 // Add ourself to the Watchdog monitors. 1510 Watchdog.getInstance().addMonitor(this); 1511 1512 mProcessStatsThread = new Thread("ProcessStats") { 1513 public void run() { 1514 while (true) { 1515 try { 1516 try { 1517 synchronized(this) { 1518 final long now = SystemClock.uptimeMillis(); 1519 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1520 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1521 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1522 // + ", write delay=" + nextWriteDelay); 1523 if (nextWriteDelay < nextCpuDelay) { 1524 nextCpuDelay = nextWriteDelay; 1525 } 1526 if (nextCpuDelay > 0) { 1527 mProcessStatsMutexFree.set(true); 1528 this.wait(nextCpuDelay); 1529 } 1530 } 1531 } catch (InterruptedException e) { 1532 } 1533 updateCpuStatsNow(); 1534 } catch (Exception e) { 1535 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1536 } 1537 } 1538 } 1539 }; 1540 mProcessStatsThread.start(); 1541 } 1542 1543 @Override 1544 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1545 throws RemoteException { 1546 if (code == SYSPROPS_TRANSACTION) { 1547 // We need to tell all apps about the system property change. 1548 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1549 synchronized(this) { 1550 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1551 final int NA = apps.size(); 1552 for (int ia=0; ia<NA; ia++) { 1553 ProcessRecord app = apps.valueAt(ia); 1554 if (app.thread != null) { 1555 procs.add(app.thread.asBinder()); 1556 } 1557 } 1558 } 1559 } 1560 1561 int N = procs.size(); 1562 for (int i=0; i<N; i++) { 1563 Parcel data2 = Parcel.obtain(); 1564 try { 1565 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1566 } catch (RemoteException e) { 1567 } 1568 data2.recycle(); 1569 } 1570 } 1571 try { 1572 return super.onTransact(code, data, reply, flags); 1573 } catch (RuntimeException e) { 1574 // The activity manager only throws security exceptions, so let's 1575 // log all others. 1576 if (!(e instanceof SecurityException)) { 1577 Slog.e(TAG, "Activity Manager Crash", e); 1578 } 1579 throw e; 1580 } 1581 } 1582 1583 void updateCpuStats() { 1584 final long now = SystemClock.uptimeMillis(); 1585 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1586 return; 1587 } 1588 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1589 synchronized (mProcessStatsThread) { 1590 mProcessStatsThread.notify(); 1591 } 1592 } 1593 } 1594 1595 void updateCpuStatsNow() { 1596 synchronized (mProcessStatsThread) { 1597 mProcessStatsMutexFree.set(false); 1598 final long now = SystemClock.uptimeMillis(); 1599 boolean haveNewCpuStats = false; 1600 1601 if (MONITOR_CPU_USAGE && 1602 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1603 mLastCpuTime.set(now); 1604 haveNewCpuStats = true; 1605 mProcessStats.update(); 1606 //Slog.i(TAG, mProcessStats.printCurrentState()); 1607 //Slog.i(TAG, "Total CPU usage: " 1608 // + mProcessStats.getTotalCpuPercent() + "%"); 1609 1610 // Slog the cpu usage if the property is set. 1611 if ("true".equals(SystemProperties.get("events.cpu"))) { 1612 int user = mProcessStats.getLastUserTime(); 1613 int system = mProcessStats.getLastSystemTime(); 1614 int iowait = mProcessStats.getLastIoWaitTime(); 1615 int irq = mProcessStats.getLastIrqTime(); 1616 int softIrq = mProcessStats.getLastSoftIrqTime(); 1617 int idle = mProcessStats.getLastIdleTime(); 1618 1619 int total = user + system + iowait + irq + softIrq + idle; 1620 if (total == 0) total = 1; 1621 1622 EventLog.writeEvent(EventLogTags.CPU, 1623 ((user+system+iowait+irq+softIrq) * 100) / total, 1624 (user * 100) / total, 1625 (system * 100) / total, 1626 (iowait * 100) / total, 1627 (irq * 100) / total, 1628 (softIrq * 100) / total); 1629 } 1630 } 1631 1632 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1633 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1634 synchronized(bstats) { 1635 synchronized(mPidsSelfLocked) { 1636 if (haveNewCpuStats) { 1637 if (mOnBattery) { 1638 int perc = bstats.startAddingCpuLocked(); 1639 int totalUTime = 0; 1640 int totalSTime = 0; 1641 final int N = mProcessStats.countStats(); 1642 for (int i=0; i<N; i++) { 1643 ProcessStats.Stats st = mProcessStats.getStats(i); 1644 if (!st.working) { 1645 continue; 1646 } 1647 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1648 int otherUTime = (st.rel_utime*perc)/100; 1649 int otherSTime = (st.rel_stime*perc)/100; 1650 totalUTime += otherUTime; 1651 totalSTime += otherSTime; 1652 if (pr != null) { 1653 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1654 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1655 st.rel_stime-otherSTime); 1656 ps.addSpeedStepTimes(cpuSpeedTimes); 1657 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1658 } else { 1659 BatteryStatsImpl.Uid.Proc ps = 1660 bstats.getProcessStatsLocked(st.name, st.pid); 1661 if (ps != null) { 1662 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1663 st.rel_stime-otherSTime); 1664 ps.addSpeedStepTimes(cpuSpeedTimes); 1665 } 1666 } 1667 } 1668 bstats.finishAddingCpuLocked(perc, totalUTime, 1669 totalSTime, cpuSpeedTimes); 1670 } 1671 } 1672 } 1673 1674 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1675 mLastWriteTime = now; 1676 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1677 } 1678 } 1679 } 1680 } 1681 1682 @Override 1683 public void batteryNeedsCpuUpdate() { 1684 updateCpuStatsNow(); 1685 } 1686 1687 @Override 1688 public void batteryPowerChanged(boolean onBattery) { 1689 // When plugging in, update the CPU stats first before changing 1690 // the plug state. 1691 updateCpuStatsNow(); 1692 synchronized (this) { 1693 synchronized(mPidsSelfLocked) { 1694 mOnBattery = DEBUG_POWER ? true : onBattery; 1695 } 1696 } 1697 } 1698 1699 /** 1700 * Initialize the application bind args. These are passed to each 1701 * process when the bindApplication() IPC is sent to the process. They're 1702 * lazily setup to make sure the services are running when they're asked for. 1703 */ 1704 private HashMap<String, IBinder> getCommonServicesLocked() { 1705 if (mAppBindArgs == null) { 1706 mAppBindArgs = new HashMap<String, IBinder>(); 1707 1708 // Setup the application init args 1709 mAppBindArgs.put("package", ServiceManager.getService("package")); 1710 mAppBindArgs.put("window", ServiceManager.getService("window")); 1711 mAppBindArgs.put(Context.ALARM_SERVICE, 1712 ServiceManager.getService(Context.ALARM_SERVICE)); 1713 } 1714 return mAppBindArgs; 1715 } 1716 1717 final void setFocusedActivityLocked(ActivityRecord r) { 1718 if (mFocusedActivity != r) { 1719 mFocusedActivity = r; 1720 if (r != null) { 1721 mWindowManager.setFocusedApp(r.appToken, true); 1722 } 1723 } 1724 } 1725 1726 private final void updateLruProcessInternalLocked(ProcessRecord app, 1727 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1728 // put it on the LRU to keep track of when it should be exited. 1729 int lrui = mLruProcesses.indexOf(app); 1730 if (lrui >= 0) mLruProcesses.remove(lrui); 1731 1732 int i = mLruProcesses.size()-1; 1733 int skipTop = 0; 1734 1735 app.lruSeq = mLruSeq; 1736 1737 // compute the new weight for this process. 1738 if (updateActivityTime) { 1739 app.lastActivityTime = SystemClock.uptimeMillis(); 1740 } 1741 if (app.activities.size() > 0) { 1742 // If this process has activities, we more strongly want to keep 1743 // it around. 1744 app.lruWeight = app.lastActivityTime; 1745 } else if (app.pubProviders.size() > 0) { 1746 // If this process contains content providers, we want to keep 1747 // it a little more strongly. 1748 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1749 // Also don't let it kick out the first few "real" hidden processes. 1750 skipTop = ProcessList.MIN_HIDDEN_APPS; 1751 } else { 1752 // If this process doesn't have activities, we less strongly 1753 // want to keep it around, and generally want to avoid getting 1754 // in front of any very recently used activities. 1755 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1756 // Also don't let it kick out the first few "real" hidden processes. 1757 skipTop = ProcessList.MIN_HIDDEN_APPS; 1758 } 1759 1760 while (i >= 0) { 1761 ProcessRecord p = mLruProcesses.get(i); 1762 // If this app shouldn't be in front of the first N background 1763 // apps, then skip over that many that are currently hidden. 1764 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1765 skipTop--; 1766 } 1767 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1768 mLruProcesses.add(i+1, app); 1769 break; 1770 } 1771 i--; 1772 } 1773 if (i < 0) { 1774 mLruProcesses.add(0, app); 1775 } 1776 1777 // If the app is currently using a content provider or service, 1778 // bump those processes as well. 1779 if (app.connections.size() > 0) { 1780 for (ConnectionRecord cr : app.connections) { 1781 if (cr.binding != null && cr.binding.service != null 1782 && cr.binding.service.app != null 1783 && cr.binding.service.app.lruSeq != mLruSeq) { 1784 updateLruProcessInternalLocked(cr.binding.service.app, false, 1785 updateActivityTime, i+1); 1786 } 1787 } 1788 } 1789 for (int j=app.conProviders.size()-1; j>=0; j--) { 1790 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1791 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1792 updateLruProcessInternalLocked(cpr.proc, false, 1793 updateActivityTime, i+1); 1794 } 1795 } 1796 1797 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1798 if (oomAdj) { 1799 updateOomAdjLocked(); 1800 } 1801 } 1802 1803 final void updateLruProcessLocked(ProcessRecord app, 1804 boolean oomAdj, boolean updateActivityTime) { 1805 mLruSeq++; 1806 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1807 } 1808 1809 final ProcessRecord getProcessRecordLocked( 1810 String processName, int uid) { 1811 if (uid == Process.SYSTEM_UID) { 1812 // The system gets to run in any process. If there are multiple 1813 // processes with the same uid, just pick the first (this 1814 // should never happen). 1815 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1816 processName); 1817 if (procs == null) return null; 1818 final int N = procs.size(); 1819 for (int i = 0; i < N; i++) { 1820 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1821 } 1822 } 1823 ProcessRecord proc = mProcessNames.get(processName, uid); 1824 return proc; 1825 } 1826 1827 void ensurePackageDexOpt(String packageName) { 1828 IPackageManager pm = AppGlobals.getPackageManager(); 1829 try { 1830 if (pm.performDexOpt(packageName)) { 1831 mDidDexOpt = true; 1832 } 1833 } catch (RemoteException e) { 1834 } 1835 } 1836 1837 boolean isNextTransitionForward() { 1838 int transit = mWindowManager.getPendingAppTransition(); 1839 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1840 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1841 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1842 } 1843 1844 final ProcessRecord startProcessLocked(String processName, 1845 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1846 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1847 boolean isolated) { 1848 ProcessRecord app; 1849 if (!isolated) { 1850 app = getProcessRecordLocked(processName, info.uid); 1851 } else { 1852 // If this is an isolated process, it can't re-use an existing process. 1853 app = null; 1854 } 1855 // We don't have to do anything more if: 1856 // (1) There is an existing application record; and 1857 // (2) The caller doesn't think it is dead, OR there is no thread 1858 // object attached to it so we know it couldn't have crashed; and 1859 // (3) There is a pid assigned to it, so it is either starting or 1860 // already running. 1861 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1862 + " app=" + app + " knownToBeDead=" + knownToBeDead 1863 + " thread=" + (app != null ? app.thread : null) 1864 + " pid=" + (app != null ? app.pid : -1)); 1865 if (app != null && app.pid > 0) { 1866 if (!knownToBeDead || app.thread == null) { 1867 // We already have the app running, or are waiting for it to 1868 // come up (we have a pid but not yet its thread), so keep it. 1869 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1870 // If this is a new package in the process, add the package to the list 1871 app.addPackage(info.packageName); 1872 return app; 1873 } else { 1874 // An application record is attached to a previous process, 1875 // clean it up now. 1876 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1877 handleAppDiedLocked(app, true, true); 1878 } 1879 } 1880 1881 String hostingNameStr = hostingName != null 1882 ? hostingName.flattenToShortString() : null; 1883 1884 if (!isolated) { 1885 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1886 // If we are in the background, then check to see if this process 1887 // is bad. If so, we will just silently fail. 1888 if (mBadProcesses.get(info.processName, info.uid) != null) { 1889 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1890 + "/" + info.processName); 1891 return null; 1892 } 1893 } else { 1894 // When the user is explicitly starting a process, then clear its 1895 // crash count so that we won't make it bad until they see at 1896 // least one crash dialog again, and make the process good again 1897 // if it had been bad. 1898 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1899 + "/" + info.processName); 1900 mProcessCrashTimes.remove(info.processName, info.uid); 1901 if (mBadProcesses.get(info.processName, info.uid) != null) { 1902 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1903 info.processName); 1904 mBadProcesses.remove(info.processName, info.uid); 1905 if (app != null) { 1906 app.bad = false; 1907 } 1908 } 1909 } 1910 } 1911 1912 if (app == null) { 1913 app = newProcessRecordLocked(null, info, processName, isolated); 1914 if (app == null) { 1915 Slog.w(TAG, "Failed making new process record for " 1916 + processName + "/" + info.uid + " isolated=" + isolated); 1917 return null; 1918 } 1919 mProcessNames.put(processName, app.uid, app); 1920 if (isolated) { 1921 mIsolatedProcesses.put(app.uid, app); 1922 } 1923 } else { 1924 // If this is a new package in the process, add the package to the list 1925 app.addPackage(info.packageName); 1926 } 1927 1928 // If the system is not ready yet, then hold off on starting this 1929 // process until it is. 1930 if (!mProcessesReady 1931 && !isAllowedWhileBooting(info) 1932 && !allowWhileBooting) { 1933 if (!mProcessesOnHold.contains(app)) { 1934 mProcessesOnHold.add(app); 1935 } 1936 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1937 return app; 1938 } 1939 1940 startProcessLocked(app, hostingType, hostingNameStr); 1941 return (app.pid != 0) ? app : null; 1942 } 1943 1944 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1945 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1946 } 1947 1948 private final void startProcessLocked(ProcessRecord app, 1949 String hostingType, String hostingNameStr) { 1950 if (app.pid > 0 && app.pid != MY_PID) { 1951 synchronized (mPidsSelfLocked) { 1952 mPidsSelfLocked.remove(app.pid); 1953 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1954 } 1955 app.pid = 0; 1956 } 1957 1958 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1959 "startProcessLocked removing on hold: " + app); 1960 mProcessesOnHold.remove(app); 1961 1962 updateCpuStats(); 1963 1964 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1965 mProcDeaths[0] = 0; 1966 1967 try { 1968 int uid = app.uid; 1969 1970 int[] gids = null; 1971 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1972 if (!app.isolated) { 1973 try { 1974 final PackageManager pm = mContext.getPackageManager(); 1975 gids = pm.getPackageGids(app.info.packageName); 1976 if (pm.checkPermission( 1977 android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName) 1978 == PERMISSION_GRANTED) { 1979 if (Environment.isExternalStorageEmulated()) { 1980 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1981 } else { 1982 mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER; 1983 } 1984 } 1985 } catch (PackageManager.NameNotFoundException e) { 1986 Slog.w(TAG, "Unable to retrieve gids", e); 1987 } 1988 } 1989 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1990 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1991 && mTopComponent != null 1992 && app.processName.equals(mTopComponent.getPackageName())) { 1993 uid = 0; 1994 } 1995 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1996 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1997 uid = 0; 1998 } 1999 } 2000 int debugFlags = 0; 2001 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2002 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2003 // Also turn on CheckJNI for debuggable apps. It's quite 2004 // awkward to turn on otherwise. 2005 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2006 } 2007 // Run the app in safe mode if its manifest requests so or the 2008 // system is booted in safe mode. 2009 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2010 Zygote.systemInSafeMode == true) { 2011 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2012 } 2013 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2014 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2015 } 2016 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2017 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2018 } 2019 if ("1".equals(SystemProperties.get("debug.assert"))) { 2020 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2021 } 2022 2023 // Start the process. It will either succeed and return a result containing 2024 // the PID of the new process, or else throw a RuntimeException. 2025 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2026 app.processName, uid, uid, gids, debugFlags, mountExternal, 2027 app.info.targetSdkVersion, null, null); 2028 2029 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2030 synchronized (bs) { 2031 if (bs.isOnBattery()) { 2032 app.batteryStats.incStartsLocked(); 2033 } 2034 } 2035 2036 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2037 app.processName, hostingType, 2038 hostingNameStr != null ? hostingNameStr : ""); 2039 2040 if (app.persistent) { 2041 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2042 } 2043 2044 StringBuilder buf = mStringBuilder; 2045 buf.setLength(0); 2046 buf.append("Start proc "); 2047 buf.append(app.processName); 2048 buf.append(" for "); 2049 buf.append(hostingType); 2050 if (hostingNameStr != null) { 2051 buf.append(" "); 2052 buf.append(hostingNameStr); 2053 } 2054 buf.append(": pid="); 2055 buf.append(startResult.pid); 2056 buf.append(" uid="); 2057 buf.append(uid); 2058 buf.append(" gids={"); 2059 if (gids != null) { 2060 for (int gi=0; gi<gids.length; gi++) { 2061 if (gi != 0) buf.append(", "); 2062 buf.append(gids[gi]); 2063 2064 } 2065 } 2066 buf.append("}"); 2067 Slog.i(TAG, buf.toString()); 2068 app.pid = startResult.pid; 2069 app.usingWrapper = startResult.usingWrapper; 2070 app.removed = false; 2071 synchronized (mPidsSelfLocked) { 2072 this.mPidsSelfLocked.put(startResult.pid, app); 2073 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2074 msg.obj = app; 2075 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2076 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2077 } 2078 } catch (RuntimeException e) { 2079 // XXX do better error recovery. 2080 app.pid = 0; 2081 Slog.e(TAG, "Failure starting process " + app.processName, e); 2082 } 2083 } 2084 2085 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2086 if (resumed) { 2087 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2088 } else { 2089 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2090 } 2091 } 2092 2093 boolean startHomeActivityLocked(int userId) { 2094 if (mHeadless) { 2095 // Added because none of the other calls to ensureBootCompleted seem to fire 2096 // when running headless. 2097 ensureBootCompleted(); 2098 return false; 2099 } 2100 2101 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2102 && mTopAction == null) { 2103 // We are running in factory test mode, but unable to find 2104 // the factory test app, so just sit around displaying the 2105 // error message and don't try to start anything. 2106 return false; 2107 } 2108 Intent intent = new Intent( 2109 mTopAction, 2110 mTopData != null ? Uri.parse(mTopData) : null); 2111 intent.setComponent(mTopComponent); 2112 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2113 intent.addCategory(Intent.CATEGORY_HOME); 2114 } 2115 ActivityInfo aInfo = 2116 intent.resolveActivityInfo(mContext.getPackageManager(), 2117 STOCK_PM_FLAGS); 2118 if (aInfo != null) { 2119 intent.setComponent(new ComponentName( 2120 aInfo.applicationInfo.packageName, aInfo.name)); 2121 // Don't do this if the home app is currently being 2122 // instrumented. 2123 aInfo = new ActivityInfo(aInfo); 2124 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2125 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2126 aInfo.applicationInfo.uid); 2127 if (app == null || app.instrumentationClass == null) { 2128 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2129 mMainStack.startActivityLocked(null, intent, null, aInfo, 2130 null, null, 0, 0, 0, 0, null, false, null); 2131 } 2132 } 2133 2134 return true; 2135 } 2136 2137 /** 2138 * Starts the "new version setup screen" if appropriate. 2139 */ 2140 void startSetupActivityLocked() { 2141 // Only do this once per boot. 2142 if (mCheckedForSetup) { 2143 return; 2144 } 2145 2146 // We will show this screen if the current one is a different 2147 // version than the last one shown, and we are not running in 2148 // low-level factory test mode. 2149 final ContentResolver resolver = mContext.getContentResolver(); 2150 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2151 Settings.Secure.getInt(resolver, 2152 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2153 mCheckedForSetup = true; 2154 2155 // See if we should be showing the platform update setup UI. 2156 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2157 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2158 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2159 2160 // We don't allow third party apps to replace this. 2161 ResolveInfo ri = null; 2162 for (int i=0; ris != null && i<ris.size(); i++) { 2163 if ((ris.get(i).activityInfo.applicationInfo.flags 2164 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2165 ri = ris.get(i); 2166 break; 2167 } 2168 } 2169 2170 if (ri != null) { 2171 String vers = ri.activityInfo.metaData != null 2172 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2173 : null; 2174 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2175 vers = ri.activityInfo.applicationInfo.metaData.getString( 2176 Intent.METADATA_SETUP_VERSION); 2177 } 2178 String lastVers = Settings.Secure.getString( 2179 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2180 if (vers != null && !vers.equals(lastVers)) { 2181 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2182 intent.setComponent(new ComponentName( 2183 ri.activityInfo.packageName, ri.activityInfo.name)); 2184 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2185 null, null, 0, 0, 0, 0, null, false, null); 2186 } 2187 } 2188 } 2189 } 2190 2191 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2192 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2193 } 2194 2195 void enforceNotIsolatedCaller(String caller) { 2196 if (UserId.isIsolated(Binder.getCallingUid())) { 2197 throw new SecurityException("Isolated process not allowed to call " + caller); 2198 } 2199 } 2200 2201 public int getFrontActivityScreenCompatMode() { 2202 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2203 synchronized (this) { 2204 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2205 } 2206 } 2207 2208 public void setFrontActivityScreenCompatMode(int mode) { 2209 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2210 "setFrontActivityScreenCompatMode"); 2211 synchronized (this) { 2212 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2213 } 2214 } 2215 2216 public int getPackageScreenCompatMode(String packageName) { 2217 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2218 synchronized (this) { 2219 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2220 } 2221 } 2222 2223 public void setPackageScreenCompatMode(String packageName, int mode) { 2224 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2225 "setPackageScreenCompatMode"); 2226 synchronized (this) { 2227 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2228 } 2229 } 2230 2231 public boolean getPackageAskScreenCompat(String packageName) { 2232 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2233 synchronized (this) { 2234 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2235 } 2236 } 2237 2238 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2240 "setPackageAskScreenCompat"); 2241 synchronized (this) { 2242 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2243 } 2244 } 2245 2246 void reportResumedActivityLocked(ActivityRecord r) { 2247 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2248 updateUsageStats(r, true); 2249 } 2250 2251 private void dispatchProcessesChanged() { 2252 int N; 2253 synchronized (this) { 2254 N = mPendingProcessChanges.size(); 2255 if (mActiveProcessChanges.length < N) { 2256 mActiveProcessChanges = new ProcessChangeItem[N]; 2257 } 2258 mPendingProcessChanges.toArray(mActiveProcessChanges); 2259 mAvailProcessChanges.addAll(mPendingProcessChanges); 2260 mPendingProcessChanges.clear(); 2261 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2262 } 2263 int i = mProcessObservers.beginBroadcast(); 2264 while (i > 0) { 2265 i--; 2266 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2267 if (observer != null) { 2268 try { 2269 for (int j=0; j<N; j++) { 2270 ProcessChangeItem item = mActiveProcessChanges[j]; 2271 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2272 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2273 + item.pid + " uid=" + item.uid + ": " 2274 + item.foregroundActivities); 2275 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2276 item.foregroundActivities); 2277 } 2278 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2279 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2280 + item.pid + " uid=" + item.uid + ": " + item.importance); 2281 observer.onImportanceChanged(item.pid, item.uid, 2282 item.importance); 2283 } 2284 } 2285 } catch (RemoteException e) { 2286 } 2287 } 2288 } 2289 mProcessObservers.finishBroadcast(); 2290 } 2291 2292 private void dispatchProcessDied(int pid, int uid) { 2293 int i = mProcessObservers.beginBroadcast(); 2294 while (i > 0) { 2295 i--; 2296 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2297 if (observer != null) { 2298 try { 2299 observer.onProcessDied(pid, uid); 2300 } catch (RemoteException e) { 2301 } 2302 } 2303 } 2304 mProcessObservers.finishBroadcast(); 2305 } 2306 2307 final void doPendingActivityLaunchesLocked(boolean doResume) { 2308 final int N = mPendingActivityLaunches.size(); 2309 if (N <= 0) { 2310 return; 2311 } 2312 for (int i=0; i<N; i++) { 2313 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2314 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2315 pal.startFlags, doResume && i == (N-1), null); 2316 } 2317 mPendingActivityLaunches.clear(); 2318 } 2319 2320 public final int startActivity(IApplicationThread caller, 2321 Intent intent, String resolvedType, IBinder resultTo, 2322 String resultWho, int requestCode, int startFlags, 2323 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2324 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2325 startFlags, profileFile, profileFd, options, UserId.getCallingUserId()); 2326 } 2327 2328 public final int startActivityAsUser(IApplicationThread caller, 2329 Intent intent, String resolvedType, IBinder resultTo, 2330 String resultWho, int requestCode, int startFlags, 2331 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2332 enforceNotIsolatedCaller("startActivity"); 2333 if (userId != UserId.getCallingUserId()) { 2334 // Requesting a different user, make sure that they have the permission 2335 if (checkComponentPermission( 2336 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2337 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2338 == PackageManager.PERMISSION_GRANTED) { 2339 // Translate to the current user id, if caller wasn't aware 2340 if (userId == UserId.USER_CURRENT) { 2341 userId = mCurrentUserId; 2342 } 2343 } else { 2344 String msg = "Permission Denial: " 2345 + "Request to startActivity as user " + userId 2346 + " but is calling from user " + UserId.getCallingUserId() 2347 + "; this requires " 2348 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2349 Slog.w(TAG, msg); 2350 throw new SecurityException(msg); 2351 } 2352 } else { 2353 if (intent.getCategories() != null 2354 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2355 // Requesting home, set the identity to the current user 2356 // HACK! 2357 userId = mCurrentUserId; 2358 } else { 2359 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2360 // the current user's userId 2361 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2362 userId = 0; 2363 } else { 2364 userId = Binder.getOrigCallingUser(); 2365 } 2366 } 2367 } 2368 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2369 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2370 null, null, options, userId); 2371 } 2372 2373 public final WaitResult startActivityAndWait(IApplicationThread caller, 2374 Intent intent, String resolvedType, IBinder resultTo, 2375 String resultWho, int requestCode, int startFlags, String profileFile, 2376 ParcelFileDescriptor profileFd, Bundle options) { 2377 enforceNotIsolatedCaller("startActivityAndWait"); 2378 WaitResult res = new WaitResult(); 2379 int userId = Binder.getOrigCallingUser(); 2380 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2381 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2382 res, null, options, userId); 2383 return res; 2384 } 2385 2386 public final int startActivityWithConfig(IApplicationThread caller, 2387 Intent intent, String resolvedType, IBinder resultTo, 2388 String resultWho, int requestCode, int startFlags, Configuration config, 2389 Bundle options) { 2390 enforceNotIsolatedCaller("startActivityWithConfig"); 2391 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2392 resultTo, resultWho, requestCode, startFlags, 2393 null, null, null, config, options, Binder.getOrigCallingUser()); 2394 return ret; 2395 } 2396 2397 public int startActivityIntentSender(IApplicationThread caller, 2398 IntentSender intent, Intent fillInIntent, String resolvedType, 2399 IBinder resultTo, String resultWho, int requestCode, 2400 int flagsMask, int flagsValues, Bundle options) { 2401 enforceNotIsolatedCaller("startActivityIntentSender"); 2402 // Refuse possible leaked file descriptors 2403 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2404 throw new IllegalArgumentException("File descriptors passed in Intent"); 2405 } 2406 2407 IIntentSender sender = intent.getTarget(); 2408 if (!(sender instanceof PendingIntentRecord)) { 2409 throw new IllegalArgumentException("Bad PendingIntent object"); 2410 } 2411 2412 PendingIntentRecord pir = (PendingIntentRecord)sender; 2413 2414 synchronized (this) { 2415 // If this is coming from the currently resumed activity, it is 2416 // effectively saying that app switches are allowed at this point. 2417 if (mMainStack.mResumedActivity != null 2418 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2419 Binder.getCallingUid()) { 2420 mAppSwitchesAllowedTime = 0; 2421 } 2422 } 2423 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2424 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2425 return ret; 2426 } 2427 2428 public boolean startNextMatchingActivity(IBinder callingActivity, 2429 Intent intent, Bundle options) { 2430 // Refuse possible leaked file descriptors 2431 if (intent != null && intent.hasFileDescriptors() == true) { 2432 throw new IllegalArgumentException("File descriptors passed in Intent"); 2433 } 2434 2435 synchronized (this) { 2436 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2437 if (r == null) { 2438 ActivityOptions.abort(options); 2439 return false; 2440 } 2441 if (r.app == null || r.app.thread == null) { 2442 // The caller is not running... d'oh! 2443 ActivityOptions.abort(options); 2444 return false; 2445 } 2446 intent = new Intent(intent); 2447 // The caller is not allowed to change the data. 2448 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2449 // And we are resetting to find the next component... 2450 intent.setComponent(null); 2451 2452 ActivityInfo aInfo = null; 2453 try { 2454 List<ResolveInfo> resolves = 2455 AppGlobals.getPackageManager().queryIntentActivities( 2456 intent, r.resolvedType, 2457 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2458 UserId.getCallingUserId()); 2459 2460 // Look for the original activity in the list... 2461 final int N = resolves != null ? resolves.size() : 0; 2462 for (int i=0; i<N; i++) { 2463 ResolveInfo rInfo = resolves.get(i); 2464 if (rInfo.activityInfo.packageName.equals(r.packageName) 2465 && rInfo.activityInfo.name.equals(r.info.name)) { 2466 // We found the current one... the next matching is 2467 // after it. 2468 i++; 2469 if (i<N) { 2470 aInfo = resolves.get(i).activityInfo; 2471 } 2472 break; 2473 } 2474 } 2475 } catch (RemoteException e) { 2476 } 2477 2478 if (aInfo == null) { 2479 // Nobody who is next! 2480 ActivityOptions.abort(options); 2481 return false; 2482 } 2483 2484 intent.setComponent(new ComponentName( 2485 aInfo.applicationInfo.packageName, aInfo.name)); 2486 intent.setFlags(intent.getFlags()&~( 2487 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2488 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2489 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2490 Intent.FLAG_ACTIVITY_NEW_TASK)); 2491 2492 // Okay now we need to start the new activity, replacing the 2493 // currently running activity. This is a little tricky because 2494 // we want to start the new one as if the current one is finished, 2495 // but not finish the current one first so that there is no flicker. 2496 // And thus... 2497 final boolean wasFinishing = r.finishing; 2498 r.finishing = true; 2499 2500 // Propagate reply information over to the new activity. 2501 final ActivityRecord resultTo = r.resultTo; 2502 final String resultWho = r.resultWho; 2503 final int requestCode = r.requestCode; 2504 r.resultTo = null; 2505 if (resultTo != null) { 2506 resultTo.removeResultsLocked(r, resultWho, requestCode); 2507 } 2508 2509 final long origId = Binder.clearCallingIdentity(); 2510 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2511 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2512 resultWho, requestCode, -1, r.launchedFromUid, 0, 2513 options, false, null); 2514 Binder.restoreCallingIdentity(origId); 2515 2516 r.finishing = wasFinishing; 2517 if (res != ActivityManager.START_SUCCESS) { 2518 return false; 2519 } 2520 return true; 2521 } 2522 } 2523 2524 public final int startActivityInPackage(int uid, 2525 Intent intent, String resolvedType, IBinder resultTo, 2526 String resultWho, int requestCode, int startFlags, Bundle options) { 2527 2528 // This is so super not safe, that only the system (or okay root) 2529 // can do it. 2530 int userId = Binder.getOrigCallingUser(); 2531 final int callingUid = Binder.getCallingUid(); 2532 if (callingUid != 0 && callingUid != Process.myUid()) { 2533 throw new SecurityException( 2534 "startActivityInPackage only available to the system"); 2535 } 2536 2537 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2538 resultTo, resultWho, requestCode, startFlags, 2539 null, null, null, null, options, userId); 2540 return ret; 2541 } 2542 2543 public final int startActivities(IApplicationThread caller, 2544 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2545 enforceNotIsolatedCaller("startActivities"); 2546 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2547 options, Binder.getOrigCallingUser()); 2548 return ret; 2549 } 2550 2551 public final int startActivitiesInPackage(int uid, 2552 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2553 Bundle options) { 2554 2555 // This is so super not safe, that only the system (or okay root) 2556 // can do it. 2557 final int callingUid = Binder.getCallingUid(); 2558 if (callingUid != 0 && callingUid != Process.myUid()) { 2559 throw new SecurityException( 2560 "startActivityInPackage only available to the system"); 2561 } 2562 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2563 options, UserId.getUserId(uid)); 2564 return ret; 2565 } 2566 2567 final void addRecentTaskLocked(TaskRecord task) { 2568 int N = mRecentTasks.size(); 2569 // Quick case: check if the top-most recent task is the same. 2570 if (N > 0 && mRecentTasks.get(0) == task) { 2571 return; 2572 } 2573 // Remove any existing entries that are the same kind of task. 2574 for (int i=0; i<N; i++) { 2575 TaskRecord tr = mRecentTasks.get(i); 2576 if (task.userId == tr.userId 2577 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2578 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2579 mRecentTasks.remove(i); 2580 i--; 2581 N--; 2582 if (task.intent == null) { 2583 // If the new recent task we are adding is not fully 2584 // specified, then replace it with the existing recent task. 2585 task = tr; 2586 } 2587 } 2588 } 2589 if (N >= MAX_RECENT_TASKS) { 2590 mRecentTasks.remove(N-1); 2591 } 2592 mRecentTasks.add(0, task); 2593 } 2594 2595 public void setRequestedOrientation(IBinder token, 2596 int requestedOrientation) { 2597 synchronized (this) { 2598 ActivityRecord r = mMainStack.isInStackLocked(token); 2599 if (r == null) { 2600 return; 2601 } 2602 final long origId = Binder.clearCallingIdentity(); 2603 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2604 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2605 mConfiguration, 2606 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2607 if (config != null) { 2608 r.frozenBeforeDestroy = true; 2609 if (!updateConfigurationLocked(config, r, false, false)) { 2610 mMainStack.resumeTopActivityLocked(null); 2611 } 2612 } 2613 Binder.restoreCallingIdentity(origId); 2614 } 2615 } 2616 2617 public int getRequestedOrientation(IBinder token) { 2618 synchronized (this) { 2619 ActivityRecord r = mMainStack.isInStackLocked(token); 2620 if (r == null) { 2621 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2622 } 2623 return mWindowManager.getAppOrientation(r.appToken); 2624 } 2625 } 2626 2627 /** 2628 * This is the internal entry point for handling Activity.finish(). 2629 * 2630 * @param token The Binder token referencing the Activity we want to finish. 2631 * @param resultCode Result code, if any, from this Activity. 2632 * @param resultData Result data (Intent), if any, from this Activity. 2633 * 2634 * @return Returns true if the activity successfully finished, or false if it is still running. 2635 */ 2636 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2637 // Refuse possible leaked file descriptors 2638 if (resultData != null && resultData.hasFileDescriptors() == true) { 2639 throw new IllegalArgumentException("File descriptors passed in Intent"); 2640 } 2641 2642 synchronized(this) { 2643 if (mController != null) { 2644 // Find the first activity that is not finishing. 2645 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2646 if (next != null) { 2647 // ask watcher if this is allowed 2648 boolean resumeOK = true; 2649 try { 2650 resumeOK = mController.activityResuming(next.packageName); 2651 } catch (RemoteException e) { 2652 mController = null; 2653 } 2654 2655 if (!resumeOK) { 2656 return false; 2657 } 2658 } 2659 } 2660 final long origId = Binder.clearCallingIdentity(); 2661 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2662 resultData, "app-request"); 2663 Binder.restoreCallingIdentity(origId); 2664 return res; 2665 } 2666 } 2667 2668 public final void finishHeavyWeightApp() { 2669 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2670 != PackageManager.PERMISSION_GRANTED) { 2671 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2672 + Binder.getCallingPid() 2673 + ", uid=" + Binder.getCallingUid() 2674 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2675 Slog.w(TAG, msg); 2676 throw new SecurityException(msg); 2677 } 2678 2679 synchronized(this) { 2680 if (mHeavyWeightProcess == null) { 2681 return; 2682 } 2683 2684 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2685 mHeavyWeightProcess.activities); 2686 for (int i=0; i<activities.size(); i++) { 2687 ActivityRecord r = activities.get(i); 2688 if (!r.finishing) { 2689 int index = mMainStack.indexOfTokenLocked(r.appToken); 2690 if (index >= 0) { 2691 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2692 null, "finish-heavy"); 2693 } 2694 } 2695 } 2696 2697 mHeavyWeightProcess = null; 2698 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2699 } 2700 } 2701 2702 public void crashApplication(int uid, int initialPid, String packageName, 2703 String message) { 2704 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2705 != PackageManager.PERMISSION_GRANTED) { 2706 String msg = "Permission Denial: crashApplication() from pid=" 2707 + Binder.getCallingPid() 2708 + ", uid=" + Binder.getCallingUid() 2709 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2710 Slog.w(TAG, msg); 2711 throw new SecurityException(msg); 2712 } 2713 2714 synchronized(this) { 2715 ProcessRecord proc = null; 2716 2717 // Figure out which process to kill. We don't trust that initialPid 2718 // still has any relation to current pids, so must scan through the 2719 // list. 2720 synchronized (mPidsSelfLocked) { 2721 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2722 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2723 if (p.uid != uid) { 2724 continue; 2725 } 2726 if (p.pid == initialPid) { 2727 proc = p; 2728 break; 2729 } 2730 for (String str : p.pkgList) { 2731 if (str.equals(packageName)) { 2732 proc = p; 2733 } 2734 } 2735 } 2736 } 2737 2738 if (proc == null) { 2739 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2740 + " initialPid=" + initialPid 2741 + " packageName=" + packageName); 2742 return; 2743 } 2744 2745 if (proc.thread != null) { 2746 if (proc.pid == Process.myPid()) { 2747 Log.w(TAG, "crashApplication: trying to crash self!"); 2748 return; 2749 } 2750 long ident = Binder.clearCallingIdentity(); 2751 try { 2752 proc.thread.scheduleCrash(message); 2753 } catch (RemoteException e) { 2754 } 2755 Binder.restoreCallingIdentity(ident); 2756 } 2757 } 2758 } 2759 2760 public final void finishSubActivity(IBinder token, String resultWho, 2761 int requestCode) { 2762 synchronized(this) { 2763 final long origId = Binder.clearCallingIdentity(); 2764 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2765 Binder.restoreCallingIdentity(origId); 2766 } 2767 } 2768 2769 public boolean finishActivityAffinity(IBinder token) { 2770 synchronized(this) { 2771 final long origId = Binder.clearCallingIdentity(); 2772 boolean res = mMainStack.finishActivityAffinityLocked(token); 2773 Binder.restoreCallingIdentity(origId); 2774 return res; 2775 } 2776 } 2777 2778 public boolean willActivityBeVisible(IBinder token) { 2779 synchronized(this) { 2780 int i; 2781 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2782 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2783 if (r.appToken == token) { 2784 return true; 2785 } 2786 if (r.fullscreen && !r.finishing) { 2787 return false; 2788 } 2789 } 2790 return true; 2791 } 2792 } 2793 2794 public void overridePendingTransition(IBinder token, String packageName, 2795 int enterAnim, int exitAnim) { 2796 synchronized(this) { 2797 ActivityRecord self = mMainStack.isInStackLocked(token); 2798 if (self == null) { 2799 return; 2800 } 2801 2802 final long origId = Binder.clearCallingIdentity(); 2803 2804 if (self.state == ActivityState.RESUMED 2805 || self.state == ActivityState.PAUSING) { 2806 mWindowManager.overridePendingAppTransition(packageName, 2807 enterAnim, exitAnim, null); 2808 } 2809 2810 Binder.restoreCallingIdentity(origId); 2811 } 2812 } 2813 2814 /** 2815 * Main function for removing an existing process from the activity manager 2816 * as a result of that process going away. Clears out all connections 2817 * to the process. 2818 */ 2819 private final void handleAppDiedLocked(ProcessRecord app, 2820 boolean restarting, boolean allowRestart) { 2821 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2822 if (!restarting) { 2823 mLruProcesses.remove(app); 2824 } 2825 2826 if (mProfileProc == app) { 2827 clearProfilerLocked(); 2828 } 2829 2830 // Just in case... 2831 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2832 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2833 mMainStack.mPausingActivity = null; 2834 } 2835 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2836 mMainStack.mLastPausedActivity = null; 2837 } 2838 2839 // Remove this application's activities from active lists. 2840 mMainStack.removeHistoryRecordsForAppLocked(app); 2841 2842 boolean atTop = true; 2843 boolean hasVisibleActivities = false; 2844 2845 // Clean out the history list. 2846 int i = mMainStack.mHistory.size(); 2847 if (localLOGV) Slog.v( 2848 TAG, "Removing app " + app + " from history with " + i + " entries"); 2849 while (i > 0) { 2850 i--; 2851 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2852 if (localLOGV) Slog.v( 2853 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2854 if (r.app == app) { 2855 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2856 if (ActivityStack.DEBUG_ADD_REMOVE) { 2857 RuntimeException here = new RuntimeException("here"); 2858 here.fillInStackTrace(); 2859 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2860 + ": haveState=" + r.haveState 2861 + " stateNotNeeded=" + r.stateNotNeeded 2862 + " finishing=" + r.finishing 2863 + " state=" + r.state, here); 2864 } 2865 if (!r.finishing) { 2866 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2867 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2868 System.identityHashCode(r), 2869 r.task.taskId, r.shortComponentName, 2870 "proc died without state saved"); 2871 } 2872 mMainStack.removeActivityFromHistoryLocked(r); 2873 2874 } else { 2875 // We have the current state for this activity, so 2876 // it can be restarted later when needed. 2877 if (localLOGV) Slog.v( 2878 TAG, "Keeping entry, setting app to null"); 2879 if (r.visible) { 2880 hasVisibleActivities = true; 2881 } 2882 r.app = null; 2883 r.nowVisible = false; 2884 if (!r.haveState) { 2885 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2886 "App died, clearing saved state of " + r); 2887 r.icicle = null; 2888 } 2889 } 2890 2891 r.stack.cleanUpActivityLocked(r, true, true); 2892 } 2893 atTop = false; 2894 } 2895 2896 app.activities.clear(); 2897 2898 if (app.instrumentationClass != null) { 2899 Slog.w(TAG, "Crash of app " + app.processName 2900 + " running instrumentation " + app.instrumentationClass); 2901 Bundle info = new Bundle(); 2902 info.putString("shortMsg", "Process crashed."); 2903 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2904 } 2905 2906 if (!restarting) { 2907 if (!mMainStack.resumeTopActivityLocked(null)) { 2908 // If there was nothing to resume, and we are not already 2909 // restarting this process, but there is a visible activity that 2910 // is hosted by the process... then make sure all visible 2911 // activities are running, taking care of restarting this 2912 // process. 2913 if (hasVisibleActivities) { 2914 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2915 } 2916 } 2917 } 2918 } 2919 2920 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2921 IBinder threadBinder = thread.asBinder(); 2922 // Find the application record. 2923 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2924 ProcessRecord rec = mLruProcesses.get(i); 2925 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2926 return i; 2927 } 2928 } 2929 return -1; 2930 } 2931 2932 final ProcessRecord getRecordForAppLocked( 2933 IApplicationThread thread) { 2934 if (thread == null) { 2935 return null; 2936 } 2937 2938 int appIndex = getLRURecordIndexForAppLocked(thread); 2939 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2940 } 2941 2942 final void appDiedLocked(ProcessRecord app, int pid, 2943 IApplicationThread thread) { 2944 2945 mProcDeaths[0]++; 2946 2947 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2948 synchronized (stats) { 2949 stats.noteProcessDiedLocked(app.info.uid, pid); 2950 } 2951 2952 // Clean up already done if the process has been re-started. 2953 if (app.pid == pid && app.thread != null && 2954 app.thread.asBinder() == thread.asBinder()) { 2955 if (!app.killedBackground) { 2956 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2957 + ") has died."); 2958 } 2959 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2960 if (localLOGV) Slog.v( 2961 TAG, "Dying app: " + app + ", pid: " + pid 2962 + ", thread: " + thread.asBinder()); 2963 boolean doLowMem = app.instrumentationClass == null; 2964 handleAppDiedLocked(app, false, true); 2965 2966 if (doLowMem) { 2967 // If there are no longer any background processes running, 2968 // and the app that died was not running instrumentation, 2969 // then tell everyone we are now low on memory. 2970 boolean haveBg = false; 2971 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2972 ProcessRecord rec = mLruProcesses.get(i); 2973 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2974 haveBg = true; 2975 break; 2976 } 2977 } 2978 2979 if (!haveBg) { 2980 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2981 long now = SystemClock.uptimeMillis(); 2982 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2983 ProcessRecord rec = mLruProcesses.get(i); 2984 if (rec != app && rec.thread != null && 2985 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2986 // The low memory report is overriding any current 2987 // state for a GC request. Make sure to do 2988 // heavy/important/visible/foreground processes first. 2989 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2990 rec.lastRequestedGc = 0; 2991 } else { 2992 rec.lastRequestedGc = rec.lastLowMemory; 2993 } 2994 rec.reportLowMemory = true; 2995 rec.lastLowMemory = now; 2996 mProcessesToGc.remove(rec); 2997 addProcessToGcListLocked(rec); 2998 } 2999 } 3000 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3001 scheduleAppGcsLocked(); 3002 } 3003 } 3004 } else if (app.pid != pid) { 3005 // A new process has already been started. 3006 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3007 + ") has died and restarted (pid " + app.pid + ")."); 3008 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3009 } else if (DEBUG_PROCESSES) { 3010 Slog.d(TAG, "Received spurious death notification for thread " 3011 + thread.asBinder()); 3012 } 3013 } 3014 3015 /** 3016 * If a stack trace dump file is configured, dump process stack traces. 3017 * @param clearTraces causes the dump file to be erased prior to the new 3018 * traces being written, if true; when false, the new traces will be 3019 * appended to any existing file content. 3020 * @param firstPids of dalvik VM processes to dump stack traces for first 3021 * @param lastPids of dalvik VM processes to dump stack traces for last 3022 * @param nativeProcs optional list of native process names to dump stack crawls 3023 * @return file containing stack traces, or null if no dump file is configured 3024 */ 3025 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3026 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3027 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3028 if (tracesPath == null || tracesPath.length() == 0) { 3029 return null; 3030 } 3031 3032 File tracesFile = new File(tracesPath); 3033 try { 3034 File tracesDir = tracesFile.getParentFile(); 3035 if (!tracesDir.exists()) tracesFile.mkdirs(); 3036 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3037 3038 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3039 tracesFile.createNewFile(); 3040 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3041 } catch (IOException e) { 3042 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3043 return null; 3044 } 3045 3046 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3047 return tracesFile; 3048 } 3049 3050 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3051 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3052 // Use a FileObserver to detect when traces finish writing. 3053 // The order of traces is considered important to maintain for legibility. 3054 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3055 public synchronized void onEvent(int event, String path) { notify(); } 3056 }; 3057 3058 try { 3059 observer.startWatching(); 3060 3061 // First collect all of the stacks of the most important pids. 3062 if (firstPids != null) { 3063 try { 3064 int num = firstPids.size(); 3065 for (int i = 0; i < num; i++) { 3066 synchronized (observer) { 3067 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3068 observer.wait(200); // Wait for write-close, give up after 200msec 3069 } 3070 } 3071 } catch (InterruptedException e) { 3072 Log.wtf(TAG, e); 3073 } 3074 } 3075 3076 // Next measure CPU usage. 3077 if (processStats != null) { 3078 processStats.init(); 3079 System.gc(); 3080 processStats.update(); 3081 try { 3082 synchronized (processStats) { 3083 processStats.wait(500); // measure over 1/2 second. 3084 } 3085 } catch (InterruptedException e) { 3086 } 3087 processStats.update(); 3088 3089 // We'll take the stack crawls of just the top apps using CPU. 3090 final int N = processStats.countWorkingStats(); 3091 int numProcs = 0; 3092 for (int i=0; i<N && numProcs<5; i++) { 3093 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3094 if (lastPids.indexOfKey(stats.pid) >= 0) { 3095 numProcs++; 3096 try { 3097 synchronized (observer) { 3098 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3099 observer.wait(200); // Wait for write-close, give up after 200msec 3100 } 3101 } catch (InterruptedException e) { 3102 Log.wtf(TAG, e); 3103 } 3104 3105 } 3106 } 3107 } 3108 3109 } finally { 3110 observer.stopWatching(); 3111 } 3112 3113 if (nativeProcs != null) { 3114 int[] pids = Process.getPidsForCommands(nativeProcs); 3115 if (pids != null) { 3116 for (int pid : pids) { 3117 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3118 } 3119 } 3120 } 3121 } 3122 3123 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3124 if (true || IS_USER_BUILD) { 3125 return; 3126 } 3127 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3128 if (tracesPath == null || tracesPath.length() == 0) { 3129 return; 3130 } 3131 3132 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3133 StrictMode.allowThreadDiskWrites(); 3134 try { 3135 final File tracesFile = new File(tracesPath); 3136 final File tracesDir = tracesFile.getParentFile(); 3137 final File tracesTmp = new File(tracesDir, "__tmp__"); 3138 try { 3139 if (!tracesDir.exists()) tracesFile.mkdirs(); 3140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3141 3142 if (tracesFile.exists()) { 3143 tracesTmp.delete(); 3144 tracesFile.renameTo(tracesTmp); 3145 } 3146 StringBuilder sb = new StringBuilder(); 3147 Time tobj = new Time(); 3148 tobj.set(System.currentTimeMillis()); 3149 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3150 sb.append(": "); 3151 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3152 sb.append(" since "); 3153 sb.append(msg); 3154 FileOutputStream fos = new FileOutputStream(tracesFile); 3155 fos.write(sb.toString().getBytes()); 3156 if (app == null) { 3157 fos.write("\n*** No application process!".getBytes()); 3158 } 3159 fos.close(); 3160 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3161 } catch (IOException e) { 3162 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3163 return; 3164 } 3165 3166 if (app != null) { 3167 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3168 firstPids.add(app.pid); 3169 dumpStackTraces(tracesPath, firstPids, null, null, null); 3170 } 3171 3172 File lastTracesFile = null; 3173 File curTracesFile = null; 3174 for (int i=9; i>=0; i--) { 3175 String name = String.format("slow%02d.txt", i); 3176 curTracesFile = new File(tracesDir, name); 3177 if (curTracesFile.exists()) { 3178 if (lastTracesFile != null) { 3179 curTracesFile.renameTo(lastTracesFile); 3180 } else { 3181 curTracesFile.delete(); 3182 } 3183 } 3184 lastTracesFile = curTracesFile; 3185 } 3186 tracesFile.renameTo(curTracesFile); 3187 if (tracesTmp.exists()) { 3188 tracesTmp.renameTo(tracesFile); 3189 } 3190 } finally { 3191 StrictMode.setThreadPolicy(oldPolicy); 3192 } 3193 } 3194 3195 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3196 ActivityRecord parent, final String annotation) { 3197 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3198 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3199 3200 if (mController != null) { 3201 try { 3202 // 0 == continue, -1 = kill process immediately 3203 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3204 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3205 } catch (RemoteException e) { 3206 mController = null; 3207 } 3208 } 3209 3210 long anrTime = SystemClock.uptimeMillis(); 3211 if (MONITOR_CPU_USAGE) { 3212 updateCpuStatsNow(); 3213 } 3214 3215 synchronized (this) { 3216 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3217 if (mShuttingDown) { 3218 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3219 return; 3220 } else if (app.notResponding) { 3221 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3222 return; 3223 } else if (app.crashing) { 3224 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3225 return; 3226 } 3227 3228 // In case we come through here for the same app before completing 3229 // this one, mark as anring now so we will bail out. 3230 app.notResponding = true; 3231 3232 // Log the ANR to the event log. 3233 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3234 annotation); 3235 3236 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3237 firstPids.add(app.pid); 3238 3239 int parentPid = app.pid; 3240 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3241 if (parentPid != app.pid) firstPids.add(parentPid); 3242 3243 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3244 3245 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3246 ProcessRecord r = mLruProcesses.get(i); 3247 if (r != null && r.thread != null) { 3248 int pid = r.pid; 3249 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3250 if (r.persistent) { 3251 firstPids.add(pid); 3252 } else { 3253 lastPids.put(pid, Boolean.TRUE); 3254 } 3255 } 3256 } 3257 } 3258 } 3259 3260 // Log the ANR to the main log. 3261 StringBuilder info = new StringBuilder(); 3262 info.setLength(0); 3263 info.append("ANR in ").append(app.processName); 3264 if (activity != null && activity.shortComponentName != null) { 3265 info.append(" (").append(activity.shortComponentName).append(")"); 3266 } 3267 info.append("\n"); 3268 if (annotation != null) { 3269 info.append("Reason: ").append(annotation).append("\n"); 3270 } 3271 if (parent != null && parent != activity) { 3272 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3273 } 3274 3275 final ProcessStats processStats = new ProcessStats(true); 3276 3277 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3278 3279 String cpuInfo = null; 3280 if (MONITOR_CPU_USAGE) { 3281 updateCpuStatsNow(); 3282 synchronized (mProcessStatsThread) { 3283 cpuInfo = mProcessStats.printCurrentState(anrTime); 3284 } 3285 info.append(processStats.printCurrentLoad()); 3286 info.append(cpuInfo); 3287 } 3288 3289 info.append(processStats.printCurrentState(anrTime)); 3290 3291 Slog.e(TAG, info.toString()); 3292 if (tracesFile == null) { 3293 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3294 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3295 } 3296 3297 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3298 cpuInfo, tracesFile, null); 3299 3300 if (mController != null) { 3301 try { 3302 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3303 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3304 if (res != 0) { 3305 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3306 return; 3307 } 3308 } catch (RemoteException e) { 3309 mController = null; 3310 } 3311 } 3312 3313 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3314 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3315 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3316 3317 synchronized (this) { 3318 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3319 Slog.w(TAG, "Killing " + app + ": background ANR"); 3320 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3321 app.processName, app.setAdj, "background ANR"); 3322 Process.killProcessQuiet(app.pid); 3323 return; 3324 } 3325 3326 // Set the app's notResponding state, and look up the errorReportReceiver 3327 makeAppNotRespondingLocked(app, 3328 activity != null ? activity.shortComponentName : null, 3329 annotation != null ? "ANR " + annotation : "ANR", 3330 info.toString()); 3331 3332 // Bring up the infamous App Not Responding dialog 3333 Message msg = Message.obtain(); 3334 HashMap map = new HashMap(); 3335 msg.what = SHOW_NOT_RESPONDING_MSG; 3336 msg.obj = map; 3337 map.put("app", app); 3338 if (activity != null) { 3339 map.put("activity", activity); 3340 } 3341 3342 mHandler.sendMessage(msg); 3343 } 3344 } 3345 3346 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3347 if (!mLaunchWarningShown) { 3348 mLaunchWarningShown = true; 3349 mHandler.post(new Runnable() { 3350 @Override 3351 public void run() { 3352 synchronized (ActivityManagerService.this) { 3353 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3354 d.show(); 3355 mHandler.postDelayed(new Runnable() { 3356 @Override 3357 public void run() { 3358 synchronized (ActivityManagerService.this) { 3359 d.dismiss(); 3360 mLaunchWarningShown = false; 3361 } 3362 } 3363 }, 4000); 3364 } 3365 } 3366 }); 3367 } 3368 } 3369 3370 public boolean clearApplicationUserData(final String packageName, 3371 final IPackageDataObserver observer, final int userId) { 3372 enforceNotIsolatedCaller("clearApplicationUserData"); 3373 int uid = Binder.getCallingUid(); 3374 int pid = Binder.getCallingPid(); 3375 long callingId = Binder.clearCallingIdentity(); 3376 try { 3377 IPackageManager pm = AppGlobals.getPackageManager(); 3378 int pkgUid = -1; 3379 synchronized(this) { 3380 try { 3381 pkgUid = pm.getPackageUid(packageName, userId); 3382 } catch (RemoteException e) { 3383 } 3384 if (pkgUid == -1) { 3385 Slog.w(TAG, "Invalid packageName:" + packageName); 3386 return false; 3387 } 3388 if (uid == pkgUid || checkComponentPermission( 3389 android.Manifest.permission.CLEAR_APP_USER_DATA, 3390 pid, uid, -1, true) 3391 == PackageManager.PERMISSION_GRANTED) { 3392 forceStopPackageLocked(packageName, pkgUid); 3393 } else { 3394 throw new SecurityException(pid+" does not have permission:"+ 3395 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3396 "for process:"+packageName); 3397 } 3398 } 3399 3400 try { 3401 //clear application user data 3402 pm.clearApplicationUserData(packageName, observer, userId); 3403 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3404 Uri.fromParts("package", packageName, null)); 3405 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3406 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3407 null, null, 0, null, null, null, false, false, userId); 3408 } catch (RemoteException e) { 3409 } 3410 } finally { 3411 Binder.restoreCallingIdentity(callingId); 3412 } 3413 return true; 3414 } 3415 3416 public void killBackgroundProcesses(final String packageName) { 3417 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3418 != PackageManager.PERMISSION_GRANTED && 3419 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3420 != PackageManager.PERMISSION_GRANTED) { 3421 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3422 + Binder.getCallingPid() 3423 + ", uid=" + Binder.getCallingUid() 3424 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3425 Slog.w(TAG, msg); 3426 throw new SecurityException(msg); 3427 } 3428 3429 int userId = UserId.getCallingUserId(); 3430 long callingId = Binder.clearCallingIdentity(); 3431 try { 3432 IPackageManager pm = AppGlobals.getPackageManager(); 3433 int pkgUid = -1; 3434 synchronized(this) { 3435 try { 3436 pkgUid = pm.getPackageUid(packageName, userId); 3437 } catch (RemoteException e) { 3438 } 3439 if (pkgUid == -1) { 3440 Slog.w(TAG, "Invalid packageName: " + packageName); 3441 return; 3442 } 3443 killPackageProcessesLocked(packageName, pkgUid, 3444 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3445 } 3446 } finally { 3447 Binder.restoreCallingIdentity(callingId); 3448 } 3449 } 3450 3451 public void killAllBackgroundProcesses() { 3452 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 long callingId = Binder.clearCallingIdentity(); 3463 try { 3464 synchronized(this) { 3465 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3466 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3467 final int NA = apps.size(); 3468 for (int ia=0; ia<NA; ia++) { 3469 ProcessRecord app = apps.valueAt(ia); 3470 if (app.persistent) { 3471 // we don't kill persistent processes 3472 continue; 3473 } 3474 if (app.removed) { 3475 procs.add(app); 3476 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3477 app.removed = true; 3478 procs.add(app); 3479 } 3480 } 3481 } 3482 3483 int N = procs.size(); 3484 for (int i=0; i<N; i++) { 3485 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3486 } 3487 } 3488 } finally { 3489 Binder.restoreCallingIdentity(callingId); 3490 } 3491 } 3492 3493 public void forceStopPackage(final String packageName) { 3494 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3495 != PackageManager.PERMISSION_GRANTED) { 3496 String msg = "Permission Denial: forceStopPackage() from pid=" 3497 + Binder.getCallingPid() 3498 + ", uid=" + Binder.getCallingUid() 3499 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3500 Slog.w(TAG, msg); 3501 throw new SecurityException(msg); 3502 } 3503 final int userId = UserId.getCallingUserId(); 3504 long callingId = Binder.clearCallingIdentity(); 3505 try { 3506 IPackageManager pm = AppGlobals.getPackageManager(); 3507 int pkgUid = -1; 3508 synchronized(this) { 3509 try { 3510 pkgUid = pm.getPackageUid(packageName, userId); 3511 } catch (RemoteException e) { 3512 } 3513 if (pkgUid == -1) { 3514 Slog.w(TAG, "Invalid packageName: " + packageName); 3515 return; 3516 } 3517 forceStopPackageLocked(packageName, pkgUid); 3518 try { 3519 pm.setPackageStoppedState(packageName, true, userId); 3520 } catch (RemoteException e) { 3521 } catch (IllegalArgumentException e) { 3522 Slog.w(TAG, "Failed trying to unstop package " 3523 + packageName + ": " + e); 3524 } 3525 } 3526 } finally { 3527 Binder.restoreCallingIdentity(callingId); 3528 } 3529 } 3530 3531 /* 3532 * The pkg name and uid have to be specified. 3533 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3534 */ 3535 public void killApplicationWithUid(String pkg, int uid) { 3536 if (pkg == null) { 3537 return; 3538 } 3539 // Make sure the uid is valid. 3540 if (uid < 0) { 3541 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3542 return; 3543 } 3544 int callerUid = Binder.getCallingUid(); 3545 // Only the system server can kill an application 3546 if (callerUid == Process.SYSTEM_UID) { 3547 // Post an aysnc message to kill the application 3548 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3549 msg.arg1 = uid; 3550 msg.arg2 = 0; 3551 msg.obj = pkg; 3552 mHandler.sendMessage(msg); 3553 } else { 3554 throw new SecurityException(callerUid + " cannot kill pkg: " + 3555 pkg); 3556 } 3557 } 3558 3559 public void closeSystemDialogs(String reason) { 3560 enforceNotIsolatedCaller("closeSystemDialogs"); 3561 3562 final int uid = Binder.getCallingUid(); 3563 final long origId = Binder.clearCallingIdentity(); 3564 synchronized (this) { 3565 closeSystemDialogsLocked(uid, reason); 3566 } 3567 Binder.restoreCallingIdentity(origId); 3568 } 3569 3570 void closeSystemDialogsLocked(int callingUid, String reason) { 3571 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3572 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3573 if (reason != null) { 3574 intent.putExtra("reason", reason); 3575 } 3576 mWindowManager.closeSystemDialogs(reason); 3577 3578 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3579 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3580 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3581 r.stack.finishActivityLocked(r, i, 3582 Activity.RESULT_CANCELED, null, "close-sys"); 3583 } 3584 } 3585 3586 broadcastIntentLocked(null, null, intent, null, 3587 null, 0, null, null, null, false, false, -1, 3588 callingUid, 0 /* TODO: Verify */); 3589 } 3590 3591 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3592 throws RemoteException { 3593 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3594 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3595 for (int i=pids.length-1; i>=0; i--) { 3596 infos[i] = new Debug.MemoryInfo(); 3597 Debug.getMemoryInfo(pids[i], infos[i]); 3598 } 3599 return infos; 3600 } 3601 3602 public long[] getProcessPss(int[] pids) throws RemoteException { 3603 enforceNotIsolatedCaller("getProcessPss"); 3604 long[] pss = new long[pids.length]; 3605 for (int i=pids.length-1; i>=0; i--) { 3606 pss[i] = Debug.getPss(pids[i]); 3607 } 3608 return pss; 3609 } 3610 3611 public void killApplicationProcess(String processName, int uid) { 3612 if (processName == null) { 3613 return; 3614 } 3615 3616 int callerUid = Binder.getCallingUid(); 3617 // Only the system server can kill an application 3618 if (callerUid == Process.SYSTEM_UID) { 3619 synchronized (this) { 3620 ProcessRecord app = getProcessRecordLocked(processName, uid); 3621 if (app != null && app.thread != null) { 3622 try { 3623 app.thread.scheduleSuicide(); 3624 } catch (RemoteException e) { 3625 // If the other end already died, then our work here is done. 3626 } 3627 } else { 3628 Slog.w(TAG, "Process/uid not found attempting kill of " 3629 + processName + " / " + uid); 3630 } 3631 } 3632 } else { 3633 throw new SecurityException(callerUid + " cannot kill app process: " + 3634 processName); 3635 } 3636 } 3637 3638 private void forceStopPackageLocked(final String packageName, int uid) { 3639 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3640 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3641 Uri.fromParts("package", packageName, null)); 3642 if (!mProcessesReady) { 3643 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3644 } 3645 intent.putExtra(Intent.EXTRA_UID, uid); 3646 broadcastIntentLocked(null, null, intent, 3647 null, null, 0, null, null, null, 3648 false, false, 3649 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3650 } 3651 3652 private final boolean killPackageProcessesLocked(String packageName, int uid, 3653 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3654 boolean evenPersistent, String reason) { 3655 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3656 3657 // Remove all processes this package may have touched: all with the 3658 // same UID (except for the system or root user), and all whose name 3659 // matches the package name. 3660 final String procNamePrefix = packageName + ":"; 3661 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3662 final int NA = apps.size(); 3663 for (int ia=0; ia<NA; ia++) { 3664 ProcessRecord app = apps.valueAt(ia); 3665 if (app.persistent && !evenPersistent) { 3666 // we don't kill persistent processes 3667 continue; 3668 } 3669 if (app.removed) { 3670 if (doit) { 3671 procs.add(app); 3672 } 3673 // If uid is specified and the uid and process name match 3674 // Or, the uid is not specified and the process name matches 3675 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3676 || ((app.processName.equals(packageName) 3677 || app.processName.startsWith(procNamePrefix)) 3678 && uid < 0))) { 3679 if (app.setAdj >= minOomAdj) { 3680 if (!doit) { 3681 return true; 3682 } 3683 app.removed = true; 3684 procs.add(app); 3685 } 3686 } 3687 } 3688 } 3689 3690 int N = procs.size(); 3691 for (int i=0; i<N; i++) { 3692 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3693 } 3694 return N > 0; 3695 } 3696 3697 private final boolean forceStopPackageLocked(String name, int uid, 3698 boolean callerWillRestart, boolean purgeCache, boolean doit, 3699 boolean evenPersistent, int userId) { 3700 int i; 3701 int N; 3702 3703 if (uid < 0) { 3704 try { 3705 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3706 } catch (RemoteException e) { 3707 } 3708 } 3709 3710 if (doit) { 3711 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3712 3713 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3714 while (badApps.hasNext()) { 3715 SparseArray<Long> ba = badApps.next(); 3716 if (ba.get(uid) != null) { 3717 badApps.remove(); 3718 } 3719 } 3720 } 3721 3722 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3723 callerWillRestart, false, doit, evenPersistent, "force stop"); 3724 3725 TaskRecord lastTask = null; 3726 for (i=0; i<mMainStack.mHistory.size(); i++) { 3727 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3728 final boolean samePackage = r.packageName.equals(name); 3729 if (r.userId == userId 3730 && (samePackage || r.task == lastTask) 3731 && (r.app == null || evenPersistent || !r.app.persistent)) { 3732 if (!doit) { 3733 if (r.finishing) { 3734 // If this activity is just finishing, then it is not 3735 // interesting as far as something to stop. 3736 continue; 3737 } 3738 return true; 3739 } 3740 didSomething = true; 3741 Slog.i(TAG, " Force finishing activity " + r); 3742 if (samePackage) { 3743 if (r.app != null) { 3744 r.app.removed = true; 3745 } 3746 r.app = null; 3747 } 3748 lastTask = r.task; 3749 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3750 null, "force-stop", true)) { 3751 i--; 3752 } 3753 } 3754 } 3755 3756 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3757 if (!doit) { 3758 return true; 3759 } 3760 didSomething = true; 3761 } 3762 3763 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3764 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3765 if (provider.info.packageName.equals(name) 3766 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3767 if (!doit) { 3768 return true; 3769 } 3770 didSomething = true; 3771 providers.add(provider); 3772 } 3773 } 3774 3775 N = providers.size(); 3776 for (i=0; i<N; i++) { 3777 removeDyingProviderLocked(null, providers.get(i), true); 3778 } 3779 3780 if (doit) { 3781 if (purgeCache) { 3782 AttributeCache ac = AttributeCache.instance(); 3783 if (ac != null) { 3784 ac.removePackage(name); 3785 } 3786 } 3787 if (mBooted) { 3788 mMainStack.resumeTopActivityLocked(null); 3789 mMainStack.scheduleIdleLocked(); 3790 } 3791 } 3792 3793 return didSomething; 3794 } 3795 3796 private final boolean removeProcessLocked(ProcessRecord app, 3797 boolean callerWillRestart, boolean allowRestart, String reason) { 3798 final String name = app.processName; 3799 final int uid = app.uid; 3800 if (DEBUG_PROCESSES) Slog.d( 3801 TAG, "Force removing proc " + app.toShortString() + " (" + name 3802 + "/" + uid + ")"); 3803 3804 mProcessNames.remove(name, uid); 3805 mIsolatedProcesses.remove(app.uid); 3806 if (mHeavyWeightProcess == app) { 3807 mHeavyWeightProcess = null; 3808 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3809 } 3810 boolean needRestart = false; 3811 if (app.pid > 0 && app.pid != MY_PID) { 3812 int pid = app.pid; 3813 synchronized (mPidsSelfLocked) { 3814 mPidsSelfLocked.remove(pid); 3815 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3816 } 3817 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3818 handleAppDiedLocked(app, true, allowRestart); 3819 mLruProcesses.remove(app); 3820 Process.killProcessQuiet(pid); 3821 3822 if (app.persistent && !app.isolated) { 3823 if (!callerWillRestart) { 3824 addAppLocked(app.info, false); 3825 } else { 3826 needRestart = true; 3827 } 3828 } 3829 } else { 3830 mRemovedProcesses.add(app); 3831 } 3832 3833 return needRestart; 3834 } 3835 3836 private final void processStartTimedOutLocked(ProcessRecord app) { 3837 final int pid = app.pid; 3838 boolean gone = false; 3839 synchronized (mPidsSelfLocked) { 3840 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3841 if (knownApp != null && knownApp.thread == null) { 3842 mPidsSelfLocked.remove(pid); 3843 gone = true; 3844 } 3845 } 3846 3847 if (gone) { 3848 Slog.w(TAG, "Process " + app + " failed to attach"); 3849 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3850 app.processName); 3851 mProcessNames.remove(app.processName, app.uid); 3852 mIsolatedProcesses.remove(app.uid); 3853 if (mHeavyWeightProcess == app) { 3854 mHeavyWeightProcess = null; 3855 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3856 } 3857 // Take care of any launching providers waiting for this process. 3858 checkAppInLaunchingProvidersLocked(app, true); 3859 // Take care of any services that are waiting for the process. 3860 mServices.processStartTimedOutLocked(app); 3861 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3862 app.processName, app.setAdj, "start timeout"); 3863 Process.killProcessQuiet(pid); 3864 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3865 Slog.w(TAG, "Unattached app died before backup, skipping"); 3866 try { 3867 IBackupManager bm = IBackupManager.Stub.asInterface( 3868 ServiceManager.getService(Context.BACKUP_SERVICE)); 3869 bm.agentDisconnected(app.info.packageName); 3870 } catch (RemoteException e) { 3871 // Can't happen; the backup manager is local 3872 } 3873 } 3874 if (isPendingBroadcastProcessLocked(pid)) { 3875 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3876 skipPendingBroadcastLocked(pid); 3877 } 3878 } else { 3879 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3880 } 3881 } 3882 3883 private final boolean attachApplicationLocked(IApplicationThread thread, 3884 int pid) { 3885 3886 // Find the application record that is being attached... either via 3887 // the pid if we are running in multiple processes, or just pull the 3888 // next app record if we are emulating process with anonymous threads. 3889 ProcessRecord app; 3890 if (pid != MY_PID && pid >= 0) { 3891 synchronized (mPidsSelfLocked) { 3892 app = mPidsSelfLocked.get(pid); 3893 } 3894 } else { 3895 app = null; 3896 } 3897 3898 if (app == null) { 3899 Slog.w(TAG, "No pending application record for pid " + pid 3900 + " (IApplicationThread " + thread + "); dropping process"); 3901 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3902 if (pid > 0 && pid != MY_PID) { 3903 Process.killProcessQuiet(pid); 3904 } else { 3905 try { 3906 thread.scheduleExit(); 3907 } catch (Exception e) { 3908 // Ignore exceptions. 3909 } 3910 } 3911 return false; 3912 } 3913 3914 // If this application record is still attached to a previous 3915 // process, clean it up now. 3916 if (app.thread != null) { 3917 handleAppDiedLocked(app, true, true); 3918 } 3919 3920 // Tell the process all about itself. 3921 3922 if (localLOGV) Slog.v( 3923 TAG, "Binding process pid " + pid + " to record " + app); 3924 3925 String processName = app.processName; 3926 try { 3927 AppDeathRecipient adr = new AppDeathRecipient( 3928 app, pid, thread); 3929 thread.asBinder().linkToDeath(adr, 0); 3930 app.deathRecipient = adr; 3931 } catch (RemoteException e) { 3932 app.resetPackageList(); 3933 startProcessLocked(app, "link fail", processName); 3934 return false; 3935 } 3936 3937 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3938 3939 app.thread = thread; 3940 app.curAdj = app.setAdj = -100; 3941 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3942 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3943 app.forcingToForeground = null; 3944 app.foregroundServices = false; 3945 app.hasShownUi = false; 3946 app.debugging = false; 3947 3948 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3949 3950 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3951 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3952 3953 if (!normalMode) { 3954 Slog.i(TAG, "Launching preboot mode app: " + app); 3955 } 3956 3957 if (localLOGV) Slog.v( 3958 TAG, "New app record " + app 3959 + " thread=" + thread.asBinder() + " pid=" + pid); 3960 try { 3961 int testMode = IApplicationThread.DEBUG_OFF; 3962 if (mDebugApp != null && mDebugApp.equals(processName)) { 3963 testMode = mWaitForDebugger 3964 ? IApplicationThread.DEBUG_WAIT 3965 : IApplicationThread.DEBUG_ON; 3966 app.debugging = true; 3967 if (mDebugTransient) { 3968 mDebugApp = mOrigDebugApp; 3969 mWaitForDebugger = mOrigWaitForDebugger; 3970 } 3971 } 3972 String profileFile = app.instrumentationProfileFile; 3973 ParcelFileDescriptor profileFd = null; 3974 boolean profileAutoStop = false; 3975 if (mProfileApp != null && mProfileApp.equals(processName)) { 3976 mProfileProc = app; 3977 profileFile = mProfileFile; 3978 profileFd = mProfileFd; 3979 profileAutoStop = mAutoStopProfiler; 3980 } 3981 boolean enableOpenGlTrace = false; 3982 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3983 enableOpenGlTrace = true; 3984 mOpenGlTraceApp = null; 3985 } 3986 3987 // If the app is being launched for restore or full backup, set it up specially 3988 boolean isRestrictedBackupMode = false; 3989 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3990 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3991 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3992 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3993 } 3994 3995 ensurePackageDexOpt(app.instrumentationInfo != null 3996 ? app.instrumentationInfo.packageName 3997 : app.info.packageName); 3998 if (app.instrumentationClass != null) { 3999 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4000 } 4001 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4002 + processName + " with config " + mConfiguration); 4003 ApplicationInfo appInfo = app.instrumentationInfo != null 4004 ? app.instrumentationInfo : app.info; 4005 app.compat = compatibilityInfoForPackageLocked(appInfo); 4006 if (profileFd != null) { 4007 profileFd = profileFd.dup(); 4008 } 4009 thread.bindApplication(processName, appInfo, providers, 4010 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4011 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4012 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4013 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4014 mCoreSettingsObserver.getCoreSettingsLocked()); 4015 updateLruProcessLocked(app, false, true); 4016 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4017 } catch (Exception e) { 4018 // todo: Yikes! What should we do? For now we will try to 4019 // start another process, but that could easily get us in 4020 // an infinite loop of restarting processes... 4021 Slog.w(TAG, "Exception thrown during bind!", e); 4022 4023 app.resetPackageList(); 4024 app.unlinkDeathRecipient(); 4025 startProcessLocked(app, "bind fail", processName); 4026 return false; 4027 } 4028 4029 // Remove this record from the list of starting applications. 4030 mPersistentStartingProcesses.remove(app); 4031 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4032 "Attach application locked removing on hold: " + app); 4033 mProcessesOnHold.remove(app); 4034 4035 boolean badApp = false; 4036 boolean didSomething = false; 4037 4038 // See if the top visible activity is waiting to run in this process... 4039 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4040 if (hr != null && normalMode) { 4041 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4042 && processName.equals(hr.processName)) { 4043 try { 4044 if (mHeadless) { 4045 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4046 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4047 didSomething = true; 4048 } 4049 } catch (Exception e) { 4050 Slog.w(TAG, "Exception in new application when starting activity " 4051 + hr.intent.getComponent().flattenToShortString(), e); 4052 badApp = true; 4053 } 4054 } else { 4055 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4056 } 4057 } 4058 4059 // Find any services that should be running in this process... 4060 if (!badApp) { 4061 try { 4062 didSomething |= mServices.attachApplicationLocked(app, processName); 4063 } catch (Exception e) { 4064 badApp = true; 4065 } 4066 } 4067 4068 // Check if a next-broadcast receiver is in this process... 4069 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4070 try { 4071 didSomething = sendPendingBroadcastsLocked(app); 4072 } catch (Exception e) { 4073 // If the app died trying to launch the receiver we declare it 'bad' 4074 badApp = true; 4075 } 4076 } 4077 4078 // Check whether the next backup agent is in this process... 4079 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4080 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4081 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4082 try { 4083 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4084 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4085 mBackupTarget.backupMode); 4086 } catch (Exception e) { 4087 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4088 e.printStackTrace(); 4089 } 4090 } 4091 4092 if (badApp) { 4093 // todo: Also need to kill application to deal with all 4094 // kinds of exceptions. 4095 handleAppDiedLocked(app, false, true); 4096 return false; 4097 } 4098 4099 if (!didSomething) { 4100 updateOomAdjLocked(); 4101 } 4102 4103 return true; 4104 } 4105 4106 public final void attachApplication(IApplicationThread thread) { 4107 synchronized (this) { 4108 int callingPid = Binder.getCallingPid(); 4109 final long origId = Binder.clearCallingIdentity(); 4110 attachApplicationLocked(thread, callingPid); 4111 Binder.restoreCallingIdentity(origId); 4112 } 4113 } 4114 4115 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4116 final long origId = Binder.clearCallingIdentity(); 4117 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4118 if (stopProfiling) { 4119 synchronized (this) { 4120 if (mProfileProc == r.app) { 4121 if (mProfileFd != null) { 4122 try { 4123 mProfileFd.close(); 4124 } catch (IOException e) { 4125 } 4126 clearProfilerLocked(); 4127 } 4128 } 4129 } 4130 } 4131 Binder.restoreCallingIdentity(origId); 4132 } 4133 4134 void enableScreenAfterBoot() { 4135 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4136 SystemClock.uptimeMillis()); 4137 mWindowManager.enableScreenAfterBoot(); 4138 4139 synchronized (this) { 4140 updateEventDispatchingLocked(); 4141 } 4142 } 4143 4144 public void showBootMessage(final CharSequence msg, final boolean always) { 4145 enforceNotIsolatedCaller("showBootMessage"); 4146 mWindowManager.showBootMessage(msg, always); 4147 } 4148 4149 public void dismissKeyguardOnNextActivity() { 4150 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4151 final long token = Binder.clearCallingIdentity(); 4152 try { 4153 synchronized (this) { 4154 if (mLockScreenShown) { 4155 mLockScreenShown = false; 4156 comeOutOfSleepIfNeededLocked(); 4157 } 4158 mMainStack.dismissKeyguardOnNextActivityLocked(); 4159 } 4160 } finally { 4161 Binder.restoreCallingIdentity(token); 4162 } 4163 } 4164 4165 final void finishBooting() { 4166 IntentFilter pkgFilter = new IntentFilter(); 4167 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4168 pkgFilter.addDataScheme("package"); 4169 mContext.registerReceiver(new BroadcastReceiver() { 4170 @Override 4171 public void onReceive(Context context, Intent intent) { 4172 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4173 if (pkgs != null) { 4174 for (String pkg : pkgs) { 4175 synchronized (ActivityManagerService.this) { 4176 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4177 setResultCode(Activity.RESULT_OK); 4178 return; 4179 } 4180 } 4181 } 4182 } 4183 } 4184 }, pkgFilter); 4185 4186 IntentFilter userFilter = new IntentFilter(); 4187 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4188 mContext.registerReceiver(new BroadcastReceiver() { 4189 @Override 4190 public void onReceive(Context context, Intent intent) { 4191 onUserRemoved(intent); 4192 } 4193 }, userFilter); 4194 4195 synchronized (this) { 4196 // Ensure that any processes we had put on hold are now started 4197 // up. 4198 final int NP = mProcessesOnHold.size(); 4199 if (NP > 0) { 4200 ArrayList<ProcessRecord> procs = 4201 new ArrayList<ProcessRecord>(mProcessesOnHold); 4202 for (int ip=0; ip<NP; ip++) { 4203 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4204 + procs.get(ip)); 4205 startProcessLocked(procs.get(ip), "on-hold", null); 4206 } 4207 } 4208 4209 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4210 // Start looking for apps that are abusing wake locks. 4211 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4212 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4213 // Tell anyone interested that we are done booting! 4214 SystemProperties.set("sys.boot_completed", "1"); 4215 SystemProperties.set("dev.bootcomplete", "1"); 4216 List<UserInfo> users = getUserManager().getUsers(); 4217 for (UserInfo user : users) { 4218 broadcastIntentLocked(null, null, 4219 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4220 null, null, 0, null, null, 4221 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4222 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4223 } 4224 } 4225 } 4226 } 4227 4228 final void ensureBootCompleted() { 4229 boolean booting; 4230 boolean enableScreen; 4231 synchronized (this) { 4232 booting = mBooting; 4233 mBooting = false; 4234 enableScreen = !mBooted; 4235 mBooted = true; 4236 } 4237 4238 if (booting) { 4239 finishBooting(); 4240 } 4241 4242 if (enableScreen) { 4243 enableScreenAfterBoot(); 4244 } 4245 } 4246 4247 public final void activityPaused(IBinder token) { 4248 final long origId = Binder.clearCallingIdentity(); 4249 mMainStack.activityPaused(token, false); 4250 Binder.restoreCallingIdentity(origId); 4251 } 4252 4253 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4254 CharSequence description) { 4255 if (localLOGV) Slog.v( 4256 TAG, "Activity stopped: token=" + token); 4257 4258 // Refuse possible leaked file descriptors 4259 if (icicle != null && icicle.hasFileDescriptors()) { 4260 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4261 } 4262 4263 ActivityRecord r = null; 4264 4265 final long origId = Binder.clearCallingIdentity(); 4266 4267 synchronized (this) { 4268 r = mMainStack.isInStackLocked(token); 4269 if (r != null) { 4270 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4271 } 4272 } 4273 4274 if (r != null) { 4275 sendPendingThumbnail(r, null, null, null, false); 4276 } 4277 4278 trimApplications(); 4279 4280 Binder.restoreCallingIdentity(origId); 4281 } 4282 4283 public final void activityDestroyed(IBinder token) { 4284 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4285 mMainStack.activityDestroyed(token); 4286 } 4287 4288 public String getCallingPackage(IBinder token) { 4289 synchronized (this) { 4290 ActivityRecord r = getCallingRecordLocked(token); 4291 return r != null && r.app != null ? r.info.packageName : null; 4292 } 4293 } 4294 4295 public ComponentName getCallingActivity(IBinder token) { 4296 synchronized (this) { 4297 ActivityRecord r = getCallingRecordLocked(token); 4298 return r != null ? r.intent.getComponent() : null; 4299 } 4300 } 4301 4302 private ActivityRecord getCallingRecordLocked(IBinder token) { 4303 ActivityRecord r = mMainStack.isInStackLocked(token); 4304 if (r == null) { 4305 return null; 4306 } 4307 return r.resultTo; 4308 } 4309 4310 public ComponentName getActivityClassForToken(IBinder token) { 4311 synchronized(this) { 4312 ActivityRecord r = mMainStack.isInStackLocked(token); 4313 if (r == null) { 4314 return null; 4315 } 4316 return r.intent.getComponent(); 4317 } 4318 } 4319 4320 public String getPackageForToken(IBinder token) { 4321 synchronized(this) { 4322 ActivityRecord r = mMainStack.isInStackLocked(token); 4323 if (r == null) { 4324 return null; 4325 } 4326 return r.packageName; 4327 } 4328 } 4329 4330 public IIntentSender getIntentSender(int type, 4331 String packageName, IBinder token, String resultWho, 4332 int requestCode, Intent[] intents, String[] resolvedTypes, 4333 int flags, Bundle options) { 4334 enforceNotIsolatedCaller("getIntentSender"); 4335 // Refuse possible leaked file descriptors 4336 if (intents != null) { 4337 if (intents.length < 1) { 4338 throw new IllegalArgumentException("Intents array length must be >= 1"); 4339 } 4340 for (int i=0; i<intents.length; i++) { 4341 Intent intent = intents[i]; 4342 if (intent != null) { 4343 if (intent.hasFileDescriptors()) { 4344 throw new IllegalArgumentException("File descriptors passed in Intent"); 4345 } 4346 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4347 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4348 throw new IllegalArgumentException( 4349 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4350 } 4351 intents[i] = new Intent(intent); 4352 } 4353 } 4354 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4355 throw new IllegalArgumentException( 4356 "Intent array length does not match resolvedTypes length"); 4357 } 4358 } 4359 if (options != null) { 4360 if (options.hasFileDescriptors()) { 4361 throw new IllegalArgumentException("File descriptors passed in options"); 4362 } 4363 } 4364 4365 synchronized(this) { 4366 int callingUid = Binder.getCallingUid(); 4367 try { 4368 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4369 int uid = AppGlobals.getPackageManager() 4370 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4371 if (!UserId.isSameApp(callingUid, uid)) { 4372 String msg = "Permission Denial: getIntentSender() from pid=" 4373 + Binder.getCallingPid() 4374 + ", uid=" + Binder.getCallingUid() 4375 + ", (need uid=" + uid + ")" 4376 + " is not allowed to send as package " + packageName; 4377 Slog.w(TAG, msg); 4378 throw new SecurityException(msg); 4379 } 4380 } 4381 4382 if (DEBUG_MU) 4383 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4384 + Binder.getOrigCallingUid()); 4385 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4386 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4387 4388 } catch (RemoteException e) { 4389 throw new SecurityException(e); 4390 } 4391 } 4392 } 4393 4394 IIntentSender getIntentSenderLocked(int type, 4395 String packageName, int callingUid, IBinder token, String resultWho, 4396 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4397 Bundle options) { 4398 if (DEBUG_MU) 4399 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4400 ActivityRecord activity = null; 4401 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4402 activity = mMainStack.isInStackLocked(token); 4403 if (activity == null) { 4404 return null; 4405 } 4406 if (activity.finishing) { 4407 return null; 4408 } 4409 } 4410 4411 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4412 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4413 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4414 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4415 |PendingIntent.FLAG_UPDATE_CURRENT); 4416 4417 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4418 type, packageName, activity, resultWho, 4419 requestCode, intents, resolvedTypes, flags, options); 4420 WeakReference<PendingIntentRecord> ref; 4421 ref = mIntentSenderRecords.get(key); 4422 PendingIntentRecord rec = ref != null ? ref.get() : null; 4423 if (rec != null) { 4424 if (!cancelCurrent) { 4425 if (updateCurrent) { 4426 if (rec.key.requestIntent != null) { 4427 rec.key.requestIntent.replaceExtras(intents != null ? 4428 intents[intents.length - 1] : null); 4429 } 4430 if (intents != null) { 4431 intents[intents.length-1] = rec.key.requestIntent; 4432 rec.key.allIntents = intents; 4433 rec.key.allResolvedTypes = resolvedTypes; 4434 } else { 4435 rec.key.allIntents = null; 4436 rec.key.allResolvedTypes = null; 4437 } 4438 } 4439 return rec; 4440 } 4441 rec.canceled = true; 4442 mIntentSenderRecords.remove(key); 4443 } 4444 if (noCreate) { 4445 return rec; 4446 } 4447 rec = new PendingIntentRecord(this, key, callingUid); 4448 mIntentSenderRecords.put(key, rec.ref); 4449 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4450 if (activity.pendingResults == null) { 4451 activity.pendingResults 4452 = new HashSet<WeakReference<PendingIntentRecord>>(); 4453 } 4454 activity.pendingResults.add(rec.ref); 4455 } 4456 return rec; 4457 } 4458 4459 public void cancelIntentSender(IIntentSender sender) { 4460 if (!(sender instanceof PendingIntentRecord)) { 4461 return; 4462 } 4463 synchronized(this) { 4464 PendingIntentRecord rec = (PendingIntentRecord)sender; 4465 try { 4466 int uid = AppGlobals.getPackageManager() 4467 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4468 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4469 String msg = "Permission Denial: cancelIntentSender() from pid=" 4470 + Binder.getCallingPid() 4471 + ", uid=" + Binder.getCallingUid() 4472 + " is not allowed to cancel packges " 4473 + rec.key.packageName; 4474 Slog.w(TAG, msg); 4475 throw new SecurityException(msg); 4476 } 4477 } catch (RemoteException e) { 4478 throw new SecurityException(e); 4479 } 4480 cancelIntentSenderLocked(rec, true); 4481 } 4482 } 4483 4484 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4485 rec.canceled = true; 4486 mIntentSenderRecords.remove(rec.key); 4487 if (cleanActivity && rec.key.activity != null) { 4488 rec.key.activity.pendingResults.remove(rec.ref); 4489 } 4490 } 4491 4492 public String getPackageForIntentSender(IIntentSender pendingResult) { 4493 if (!(pendingResult instanceof PendingIntentRecord)) { 4494 return null; 4495 } 4496 try { 4497 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4498 return res.key.packageName; 4499 } catch (ClassCastException e) { 4500 } 4501 return null; 4502 } 4503 4504 public int getUidForIntentSender(IIntentSender sender) { 4505 if (sender instanceof PendingIntentRecord) { 4506 try { 4507 PendingIntentRecord res = (PendingIntentRecord)sender; 4508 return res.uid; 4509 } catch (ClassCastException e) { 4510 } 4511 } 4512 return -1; 4513 } 4514 4515 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4516 if (!(pendingResult instanceof PendingIntentRecord)) { 4517 return false; 4518 } 4519 try { 4520 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4521 if (res.key.allIntents == null) { 4522 return false; 4523 } 4524 for (int i=0; i<res.key.allIntents.length; i++) { 4525 Intent intent = res.key.allIntents[i]; 4526 if (intent.getPackage() != null && intent.getComponent() != null) { 4527 return false; 4528 } 4529 } 4530 return true; 4531 } catch (ClassCastException e) { 4532 } 4533 return false; 4534 } 4535 4536 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4537 if (!(pendingResult instanceof PendingIntentRecord)) { 4538 return false; 4539 } 4540 try { 4541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4542 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4543 return true; 4544 } 4545 return false; 4546 } catch (ClassCastException e) { 4547 } 4548 return false; 4549 } 4550 4551 public void setProcessLimit(int max) { 4552 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4553 "setProcessLimit()"); 4554 synchronized (this) { 4555 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4556 mProcessLimitOverride = max; 4557 } 4558 trimApplications(); 4559 } 4560 4561 public int getProcessLimit() { 4562 synchronized (this) { 4563 return mProcessLimitOverride; 4564 } 4565 } 4566 4567 void foregroundTokenDied(ForegroundToken token) { 4568 synchronized (ActivityManagerService.this) { 4569 synchronized (mPidsSelfLocked) { 4570 ForegroundToken cur 4571 = mForegroundProcesses.get(token.pid); 4572 if (cur != token) { 4573 return; 4574 } 4575 mForegroundProcesses.remove(token.pid); 4576 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4577 if (pr == null) { 4578 return; 4579 } 4580 pr.forcingToForeground = null; 4581 pr.foregroundServices = false; 4582 } 4583 updateOomAdjLocked(); 4584 } 4585 } 4586 4587 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4588 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4589 "setProcessForeground()"); 4590 synchronized(this) { 4591 boolean changed = false; 4592 4593 synchronized (mPidsSelfLocked) { 4594 ProcessRecord pr = mPidsSelfLocked.get(pid); 4595 if (pr == null && isForeground) { 4596 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4597 return; 4598 } 4599 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4600 if (oldToken != null) { 4601 oldToken.token.unlinkToDeath(oldToken, 0); 4602 mForegroundProcesses.remove(pid); 4603 if (pr != null) { 4604 pr.forcingToForeground = null; 4605 } 4606 changed = true; 4607 } 4608 if (isForeground && token != null) { 4609 ForegroundToken newToken = new ForegroundToken() { 4610 public void binderDied() { 4611 foregroundTokenDied(this); 4612 } 4613 }; 4614 newToken.pid = pid; 4615 newToken.token = token; 4616 try { 4617 token.linkToDeath(newToken, 0); 4618 mForegroundProcesses.put(pid, newToken); 4619 pr.forcingToForeground = token; 4620 changed = true; 4621 } catch (RemoteException e) { 4622 // If the process died while doing this, we will later 4623 // do the cleanup with the process death link. 4624 } 4625 } 4626 } 4627 4628 if (changed) { 4629 updateOomAdjLocked(); 4630 } 4631 } 4632 } 4633 4634 // ========================================================= 4635 // PERMISSIONS 4636 // ========================================================= 4637 4638 static class PermissionController extends IPermissionController.Stub { 4639 ActivityManagerService mActivityManagerService; 4640 PermissionController(ActivityManagerService activityManagerService) { 4641 mActivityManagerService = activityManagerService; 4642 } 4643 4644 public boolean checkPermission(String permission, int pid, int uid) { 4645 return mActivityManagerService.checkPermission(permission, pid, 4646 uid) == PackageManager.PERMISSION_GRANTED; 4647 } 4648 } 4649 4650 /** 4651 * This can be called with or without the global lock held. 4652 */ 4653 int checkComponentPermission(String permission, int pid, int uid, 4654 int owningUid, boolean exported) { 4655 // We might be performing an operation on behalf of an indirect binder 4656 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4657 // client identity accordingly before proceeding. 4658 Identity tlsIdentity = sCallerIdentity.get(); 4659 if (tlsIdentity != null) { 4660 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4661 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4662 uid = tlsIdentity.uid; 4663 pid = tlsIdentity.pid; 4664 } 4665 4666 if (pid == MY_PID) { 4667 return PackageManager.PERMISSION_GRANTED; 4668 } 4669 4670 return ActivityManager.checkComponentPermission(permission, uid, 4671 owningUid, exported); 4672 } 4673 4674 /** 4675 * As the only public entry point for permissions checking, this method 4676 * can enforce the semantic that requesting a check on a null global 4677 * permission is automatically denied. (Internally a null permission 4678 * string is used when calling {@link #checkComponentPermission} in cases 4679 * when only uid-based security is needed.) 4680 * 4681 * This can be called with or without the global lock held. 4682 */ 4683 public int checkPermission(String permission, int pid, int uid) { 4684 if (permission == null) { 4685 return PackageManager.PERMISSION_DENIED; 4686 } 4687 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4688 } 4689 4690 /** 4691 * Binder IPC calls go through the public entry point. 4692 * This can be called with or without the global lock held. 4693 */ 4694 int checkCallingPermission(String permission) { 4695 return checkPermission(permission, 4696 Binder.getCallingPid(), 4697 UserId.getAppId(Binder.getCallingUid())); 4698 } 4699 4700 /** 4701 * This can be called with or without the global lock held. 4702 */ 4703 void enforceCallingPermission(String permission, String func) { 4704 if (checkCallingPermission(permission) 4705 == PackageManager.PERMISSION_GRANTED) { 4706 return; 4707 } 4708 4709 String msg = "Permission Denial: " + func + " from pid=" 4710 + Binder.getCallingPid() 4711 + ", uid=" + Binder.getCallingUid() 4712 + " requires " + permission; 4713 Slog.w(TAG, msg); 4714 throw new SecurityException(msg); 4715 } 4716 4717 /** 4718 * Determine if UID is holding permissions required to access {@link Uri} in 4719 * the given {@link ProviderInfo}. Final permission checking is always done 4720 * in {@link ContentProvider}. 4721 */ 4722 private final boolean checkHoldingPermissionsLocked( 4723 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4724 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4725 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4726 4727 if (pi.applicationInfo.uid == uid) { 4728 return true; 4729 } else if (!pi.exported) { 4730 return false; 4731 } 4732 4733 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4734 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4735 try { 4736 // check if target holds top-level <provider> permissions 4737 if (!readMet && pi.readPermission != null 4738 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4739 readMet = true; 4740 } 4741 if (!writeMet && pi.writePermission != null 4742 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4743 writeMet = true; 4744 } 4745 4746 // track if unprotected read/write is allowed; any denied 4747 // <path-permission> below removes this ability 4748 boolean allowDefaultRead = pi.readPermission == null; 4749 boolean allowDefaultWrite = pi.writePermission == null; 4750 4751 // check if target holds any <path-permission> that match uri 4752 final PathPermission[] pps = pi.pathPermissions; 4753 if (pps != null) { 4754 final String path = uri.getPath(); 4755 int i = pps.length; 4756 while (i > 0 && (!readMet || !writeMet)) { 4757 i--; 4758 PathPermission pp = pps[i]; 4759 if (pp.match(path)) { 4760 if (!readMet) { 4761 final String pprperm = pp.getReadPermission(); 4762 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4763 + pprperm + " for " + pp.getPath() 4764 + ": match=" + pp.match(path) 4765 + " check=" + pm.checkUidPermission(pprperm, uid)); 4766 if (pprperm != null) { 4767 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4768 readMet = true; 4769 } else { 4770 allowDefaultRead = false; 4771 } 4772 } 4773 } 4774 if (!writeMet) { 4775 final String ppwperm = pp.getWritePermission(); 4776 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4777 + ppwperm + " for " + pp.getPath() 4778 + ": match=" + pp.match(path) 4779 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4780 if (ppwperm != null) { 4781 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4782 writeMet = true; 4783 } else { 4784 allowDefaultWrite = false; 4785 } 4786 } 4787 } 4788 } 4789 } 4790 } 4791 4792 // grant unprotected <provider> read/write, if not blocked by 4793 // <path-permission> above 4794 if (allowDefaultRead) readMet = true; 4795 if (allowDefaultWrite) writeMet = true; 4796 4797 } catch (RemoteException e) { 4798 return false; 4799 } 4800 4801 return readMet && writeMet; 4802 } 4803 4804 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4805 int modeFlags) { 4806 // Root gets to do everything. 4807 if (uid == 0) { 4808 return true; 4809 } 4810 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4811 if (perms == null) return false; 4812 UriPermission perm = perms.get(uri); 4813 if (perm == null) return false; 4814 return (modeFlags&perm.modeFlags) == modeFlags; 4815 } 4816 4817 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4818 enforceNotIsolatedCaller("checkUriPermission"); 4819 4820 // Another redirected-binder-call permissions check as in 4821 // {@link checkComponentPermission}. 4822 Identity tlsIdentity = sCallerIdentity.get(); 4823 if (tlsIdentity != null) { 4824 uid = tlsIdentity.uid; 4825 pid = tlsIdentity.pid; 4826 } 4827 4828 uid = UserId.getAppId(uid); 4829 // Our own process gets to do everything. 4830 if (pid == MY_PID) { 4831 return PackageManager.PERMISSION_GRANTED; 4832 } 4833 synchronized(this) { 4834 return checkUriPermissionLocked(uri, uid, modeFlags) 4835 ? PackageManager.PERMISSION_GRANTED 4836 : PackageManager.PERMISSION_DENIED; 4837 } 4838 } 4839 4840 /** 4841 * Check if the targetPkg can be granted permission to access uri by 4842 * the callingUid using the given modeFlags. Throws a security exception 4843 * if callingUid is not allowed to do this. Returns the uid of the target 4844 * if the URI permission grant should be performed; returns -1 if it is not 4845 * needed (for example targetPkg already has permission to access the URI). 4846 * If you already know the uid of the target, you can supply it in 4847 * lastTargetUid else set that to -1. 4848 */ 4849 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4850 Uri uri, int modeFlags, int lastTargetUid) { 4851 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4852 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4853 if (modeFlags == 0) { 4854 return -1; 4855 } 4856 4857 if (targetPkg != null) { 4858 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4859 "Checking grant " + targetPkg + " permission to " + uri); 4860 } 4861 4862 final IPackageManager pm = AppGlobals.getPackageManager(); 4863 4864 // If this is not a content: uri, we can't do anything with it. 4865 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4867 "Can't grant URI permission for non-content URI: " + uri); 4868 return -1; 4869 } 4870 4871 String name = uri.getAuthority(); 4872 ProviderInfo pi = null; 4873 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4874 UserId.getUserId(callingUid)); 4875 if (cpr != null) { 4876 pi = cpr.info; 4877 } else { 4878 try { 4879 pi = pm.resolveContentProvider(name, 4880 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4881 } catch (RemoteException ex) { 4882 } 4883 } 4884 if (pi == null) { 4885 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4886 return -1; 4887 } 4888 4889 int targetUid = lastTargetUid; 4890 if (targetUid < 0 && targetPkg != null) { 4891 try { 4892 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4893 if (targetUid < 0) { 4894 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4895 "Can't grant URI permission no uid for: " + targetPkg); 4896 return -1; 4897 } 4898 } catch (RemoteException ex) { 4899 return -1; 4900 } 4901 } 4902 4903 if (targetUid >= 0) { 4904 // First... does the target actually need this permission? 4905 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4906 // No need to grant the target this permission. 4907 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4908 "Target " + targetPkg + " already has full permission to " + uri); 4909 return -1; 4910 } 4911 } else { 4912 // First... there is no target package, so can anyone access it? 4913 boolean allowed = pi.exported; 4914 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4915 if (pi.readPermission != null) { 4916 allowed = false; 4917 } 4918 } 4919 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4920 if (pi.writePermission != null) { 4921 allowed = false; 4922 } 4923 } 4924 if (allowed) { 4925 return -1; 4926 } 4927 } 4928 4929 // Second... is the provider allowing granting of URI permissions? 4930 if (!pi.grantUriPermissions) { 4931 throw new SecurityException("Provider " + pi.packageName 4932 + "/" + pi.name 4933 + " does not allow granting of Uri permissions (uri " 4934 + uri + ")"); 4935 } 4936 if (pi.uriPermissionPatterns != null) { 4937 final int N = pi.uriPermissionPatterns.length; 4938 boolean allowed = false; 4939 for (int i=0; i<N; i++) { 4940 if (pi.uriPermissionPatterns[i] != null 4941 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4942 allowed = true; 4943 break; 4944 } 4945 } 4946 if (!allowed) { 4947 throw new SecurityException("Provider " + pi.packageName 4948 + "/" + pi.name 4949 + " does not allow granting of permission to path of Uri " 4950 + uri); 4951 } 4952 } 4953 4954 // Third... does the caller itself have permission to access 4955 // this uri? 4956 if (callingUid != Process.myUid()) { 4957 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4958 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4959 throw new SecurityException("Uid " + callingUid 4960 + " does not have permission to uri " + uri); 4961 } 4962 } 4963 } 4964 4965 return targetUid; 4966 } 4967 4968 public int checkGrantUriPermission(int callingUid, String targetPkg, 4969 Uri uri, int modeFlags) { 4970 enforceNotIsolatedCaller("checkGrantUriPermission"); 4971 synchronized(this) { 4972 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4973 } 4974 } 4975 4976 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4977 Uri uri, int modeFlags, UriPermissionOwner owner) { 4978 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4979 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4980 if (modeFlags == 0) { 4981 return; 4982 } 4983 4984 // So here we are: the caller has the assumed permission 4985 // to the uri, and the target doesn't. Let's now give this to 4986 // the target. 4987 4988 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4989 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4990 4991 HashMap<Uri, UriPermission> targetUris 4992 = mGrantedUriPermissions.get(targetUid); 4993 if (targetUris == null) { 4994 targetUris = new HashMap<Uri, UriPermission>(); 4995 mGrantedUriPermissions.put(targetUid, targetUris); 4996 } 4997 4998 UriPermission perm = targetUris.get(uri); 4999 if (perm == null) { 5000 perm = new UriPermission(targetUid, uri); 5001 targetUris.put(uri, perm); 5002 } 5003 5004 perm.modeFlags |= modeFlags; 5005 if (owner == null) { 5006 perm.globalModeFlags |= modeFlags; 5007 } else { 5008 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5009 perm.readOwners.add(owner); 5010 owner.addReadPermission(perm); 5011 } 5012 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5013 perm.writeOwners.add(owner); 5014 owner.addWritePermission(perm); 5015 } 5016 } 5017 } 5018 5019 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5020 int modeFlags, UriPermissionOwner owner) { 5021 if (targetPkg == null) { 5022 throw new NullPointerException("targetPkg"); 5023 } 5024 5025 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5026 if (targetUid < 0) { 5027 return; 5028 } 5029 5030 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5031 } 5032 5033 static class NeededUriGrants extends ArrayList<Uri> { 5034 final String targetPkg; 5035 final int targetUid; 5036 final int flags; 5037 5038 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5039 targetPkg = _targetPkg; 5040 targetUid = _targetUid; 5041 flags = _flags; 5042 } 5043 } 5044 5045 /** 5046 * Like checkGrantUriPermissionLocked, but takes an Intent. 5047 */ 5048 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5049 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5050 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5051 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5052 + " clip=" + (intent != null ? intent.getClipData() : null) 5053 + " from " + intent + "; flags=0x" 5054 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5055 5056 if (targetPkg == null) { 5057 throw new NullPointerException("targetPkg"); 5058 } 5059 5060 if (intent == null) { 5061 return null; 5062 } 5063 Uri data = intent.getData(); 5064 ClipData clip = intent.getClipData(); 5065 if (data == null && clip == null) { 5066 return null; 5067 } 5068 if (data != null) { 5069 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5070 mode, needed != null ? needed.targetUid : -1); 5071 if (target > 0) { 5072 if (needed == null) { 5073 needed = new NeededUriGrants(targetPkg, target, mode); 5074 } 5075 needed.add(data); 5076 } 5077 } 5078 if (clip != null) { 5079 for (int i=0; i<clip.getItemCount(); i++) { 5080 Uri uri = clip.getItemAt(i).getUri(); 5081 if (uri != null) { 5082 int target = -1; 5083 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5084 mode, needed != null ? needed.targetUid : -1); 5085 if (target > 0) { 5086 if (needed == null) { 5087 needed = new NeededUriGrants(targetPkg, target, mode); 5088 } 5089 needed.add(uri); 5090 } 5091 } else { 5092 Intent clipIntent = clip.getItemAt(i).getIntent(); 5093 if (clipIntent != null) { 5094 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5095 callingUid, targetPkg, clipIntent, mode, needed); 5096 if (newNeeded != null) { 5097 needed = newNeeded; 5098 } 5099 } 5100 } 5101 } 5102 } 5103 5104 return needed; 5105 } 5106 5107 /** 5108 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5109 */ 5110 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5111 UriPermissionOwner owner) { 5112 if (needed != null) { 5113 for (int i=0; i<needed.size(); i++) { 5114 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5115 needed.get(i), needed.flags, owner); 5116 } 5117 } 5118 } 5119 5120 void grantUriPermissionFromIntentLocked(int callingUid, 5121 String targetPkg, Intent intent, UriPermissionOwner owner) { 5122 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5123 intent, intent != null ? intent.getFlags() : 0, null); 5124 if (needed == null) { 5125 return; 5126 } 5127 5128 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5129 } 5130 5131 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5132 Uri uri, int modeFlags) { 5133 enforceNotIsolatedCaller("grantUriPermission"); 5134 synchronized(this) { 5135 final ProcessRecord r = getRecordForAppLocked(caller); 5136 if (r == null) { 5137 throw new SecurityException("Unable to find app for caller " 5138 + caller 5139 + " when granting permission to uri " + uri); 5140 } 5141 if (targetPkg == null) { 5142 throw new IllegalArgumentException("null target"); 5143 } 5144 if (uri == null) { 5145 throw new IllegalArgumentException("null uri"); 5146 } 5147 5148 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5149 null); 5150 } 5151 } 5152 5153 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5154 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5155 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5156 HashMap<Uri, UriPermission> perms 5157 = mGrantedUriPermissions.get(perm.uid); 5158 if (perms != null) { 5159 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5160 "Removing " + perm.uid + " permission to " + perm.uri); 5161 perms.remove(perm.uri); 5162 if (perms.size() == 0) { 5163 mGrantedUriPermissions.remove(perm.uid); 5164 } 5165 } 5166 } 5167 } 5168 5169 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5170 int modeFlags) { 5171 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5172 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5173 if (modeFlags == 0) { 5174 return; 5175 } 5176 5177 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5178 "Revoking all granted permissions to " + uri); 5179 5180 final IPackageManager pm = AppGlobals.getPackageManager(); 5181 5182 final String authority = uri.getAuthority(); 5183 ProviderInfo pi = null; 5184 int userId = UserId.getUserId(callingUid); 5185 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5186 if (cpr != null) { 5187 pi = cpr.info; 5188 } else { 5189 try { 5190 pi = pm.resolveContentProvider(authority, 5191 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5192 } catch (RemoteException ex) { 5193 } 5194 } 5195 if (pi == null) { 5196 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5197 return; 5198 } 5199 5200 // Does the caller have this permission on the URI? 5201 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5202 // Right now, if you are not the original owner of the permission, 5203 // you are not allowed to revoke it. 5204 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5205 throw new SecurityException("Uid " + callingUid 5206 + " does not have permission to uri " + uri); 5207 //} 5208 } 5209 5210 // Go through all of the permissions and remove any that match. 5211 final List<String> SEGMENTS = uri.getPathSegments(); 5212 if (SEGMENTS != null) { 5213 final int NS = SEGMENTS.size(); 5214 int N = mGrantedUriPermissions.size(); 5215 for (int i=0; i<N; i++) { 5216 HashMap<Uri, UriPermission> perms 5217 = mGrantedUriPermissions.valueAt(i); 5218 Iterator<UriPermission> it = perms.values().iterator(); 5219 toploop: 5220 while (it.hasNext()) { 5221 UriPermission perm = it.next(); 5222 Uri targetUri = perm.uri; 5223 if (!authority.equals(targetUri.getAuthority())) { 5224 continue; 5225 } 5226 List<String> targetSegments = targetUri.getPathSegments(); 5227 if (targetSegments == null) { 5228 continue; 5229 } 5230 if (targetSegments.size() < NS) { 5231 continue; 5232 } 5233 for (int j=0; j<NS; j++) { 5234 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5235 continue toploop; 5236 } 5237 } 5238 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5239 "Revoking " + perm.uid + " permission to " + perm.uri); 5240 perm.clearModes(modeFlags); 5241 if (perm.modeFlags == 0) { 5242 it.remove(); 5243 } 5244 } 5245 if (perms.size() == 0) { 5246 mGrantedUriPermissions.remove( 5247 mGrantedUriPermissions.keyAt(i)); 5248 N--; 5249 i--; 5250 } 5251 } 5252 } 5253 } 5254 5255 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5256 int modeFlags) { 5257 enforceNotIsolatedCaller("revokeUriPermission"); 5258 synchronized(this) { 5259 final ProcessRecord r = getRecordForAppLocked(caller); 5260 if (r == null) { 5261 throw new SecurityException("Unable to find app for caller " 5262 + caller 5263 + " when revoking permission to uri " + uri); 5264 } 5265 if (uri == null) { 5266 Slog.w(TAG, "revokeUriPermission: null uri"); 5267 return; 5268 } 5269 5270 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5271 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5272 if (modeFlags == 0) { 5273 return; 5274 } 5275 5276 final IPackageManager pm = AppGlobals.getPackageManager(); 5277 5278 final String authority = uri.getAuthority(); 5279 ProviderInfo pi = null; 5280 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5281 if (cpr != null) { 5282 pi = cpr.info; 5283 } else { 5284 try { 5285 pi = pm.resolveContentProvider(authority, 5286 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5287 } catch (RemoteException ex) { 5288 } 5289 } 5290 if (pi == null) { 5291 Slog.w(TAG, "No content provider found for permission revoke: " 5292 + uri.toSafeString()); 5293 return; 5294 } 5295 5296 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5297 } 5298 } 5299 5300 @Override 5301 public IBinder newUriPermissionOwner(String name) { 5302 enforceNotIsolatedCaller("newUriPermissionOwner"); 5303 synchronized(this) { 5304 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5305 return owner.getExternalTokenLocked(); 5306 } 5307 } 5308 5309 @Override 5310 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5311 Uri uri, int modeFlags) { 5312 synchronized(this) { 5313 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5314 if (owner == null) { 5315 throw new IllegalArgumentException("Unknown owner: " + token); 5316 } 5317 if (fromUid != Binder.getCallingUid()) { 5318 if (Binder.getCallingUid() != Process.myUid()) { 5319 // Only system code can grant URI permissions on behalf 5320 // of other users. 5321 throw new SecurityException("nice try"); 5322 } 5323 } 5324 if (targetPkg == null) { 5325 throw new IllegalArgumentException("null target"); 5326 } 5327 if (uri == null) { 5328 throw new IllegalArgumentException("null uri"); 5329 } 5330 5331 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5332 } 5333 } 5334 5335 @Override 5336 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5337 synchronized(this) { 5338 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5339 if (owner == null) { 5340 throw new IllegalArgumentException("Unknown owner: " + token); 5341 } 5342 5343 if (uri == null) { 5344 owner.removeUriPermissionsLocked(mode); 5345 } else { 5346 owner.removeUriPermissionLocked(uri, mode); 5347 } 5348 } 5349 } 5350 5351 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5352 synchronized (this) { 5353 ProcessRecord app = 5354 who != null ? getRecordForAppLocked(who) : null; 5355 if (app == null) return; 5356 5357 Message msg = Message.obtain(); 5358 msg.what = WAIT_FOR_DEBUGGER_MSG; 5359 msg.obj = app; 5360 msg.arg1 = waiting ? 1 : 0; 5361 mHandler.sendMessage(msg); 5362 } 5363 } 5364 5365 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5366 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5367 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5368 outInfo.availMem = Process.getFreeMemory(); 5369 outInfo.totalMem = Process.getTotalMemory(); 5370 outInfo.threshold = homeAppMem; 5371 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5372 outInfo.hiddenAppThreshold = hiddenAppMem; 5373 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5374 ProcessList.SERVICE_ADJ); 5375 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5376 ProcessList.VISIBLE_APP_ADJ); 5377 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5378 ProcessList.FOREGROUND_APP_ADJ); 5379 } 5380 5381 // ========================================================= 5382 // TASK MANAGEMENT 5383 // ========================================================= 5384 5385 public List getTasks(int maxNum, int flags, 5386 IThumbnailReceiver receiver) { 5387 ArrayList list = new ArrayList(); 5388 5389 PendingThumbnailsRecord pending = null; 5390 IApplicationThread topThumbnail = null; 5391 ActivityRecord topRecord = null; 5392 5393 synchronized(this) { 5394 if (localLOGV) Slog.v( 5395 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5396 + ", receiver=" + receiver); 5397 5398 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5399 != PackageManager.PERMISSION_GRANTED) { 5400 if (receiver != null) { 5401 // If the caller wants to wait for pending thumbnails, 5402 // it ain't gonna get them. 5403 try { 5404 receiver.finished(); 5405 } catch (RemoteException ex) { 5406 } 5407 } 5408 String msg = "Permission Denial: getTasks() from pid=" 5409 + Binder.getCallingPid() 5410 + ", uid=" + Binder.getCallingUid() 5411 + " requires " + android.Manifest.permission.GET_TASKS; 5412 Slog.w(TAG, msg); 5413 throw new SecurityException(msg); 5414 } 5415 5416 int pos = mMainStack.mHistory.size()-1; 5417 ActivityRecord next = 5418 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5419 ActivityRecord top = null; 5420 TaskRecord curTask = null; 5421 int numActivities = 0; 5422 int numRunning = 0; 5423 while (pos >= 0 && maxNum > 0) { 5424 final ActivityRecord r = next; 5425 pos--; 5426 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5427 5428 // Initialize state for next task if needed. 5429 if (top == null || 5430 (top.state == ActivityState.INITIALIZING 5431 && top.task == r.task)) { 5432 top = r; 5433 curTask = r.task; 5434 numActivities = numRunning = 0; 5435 } 5436 5437 // Add 'r' into the current task. 5438 numActivities++; 5439 if (r.app != null && r.app.thread != null) { 5440 numRunning++; 5441 } 5442 5443 if (localLOGV) Slog.v( 5444 TAG, r.intent.getComponent().flattenToShortString() 5445 + ": task=" + r.task); 5446 5447 // If the next one is a different task, generate a new 5448 // TaskInfo entry for what we have. 5449 if (next == null || next.task != curTask) { 5450 ActivityManager.RunningTaskInfo ci 5451 = new ActivityManager.RunningTaskInfo(); 5452 ci.id = curTask.taskId; 5453 ci.baseActivity = r.intent.getComponent(); 5454 ci.topActivity = top.intent.getComponent(); 5455 if (top.thumbHolder != null) { 5456 ci.description = top.thumbHolder.lastDescription; 5457 } 5458 ci.numActivities = numActivities; 5459 ci.numRunning = numRunning; 5460 //System.out.println( 5461 // "#" + maxNum + ": " + " descr=" + ci.description); 5462 if (ci.thumbnail == null && receiver != null) { 5463 if (localLOGV) Slog.v( 5464 TAG, "State=" + top.state + "Idle=" + top.idle 5465 + " app=" + top.app 5466 + " thr=" + (top.app != null ? top.app.thread : null)); 5467 if (top.state == ActivityState.RESUMED 5468 || top.state == ActivityState.PAUSING) { 5469 if (top.idle && top.app != null 5470 && top.app.thread != null) { 5471 topRecord = top; 5472 topThumbnail = top.app.thread; 5473 } else { 5474 top.thumbnailNeeded = true; 5475 } 5476 } 5477 if (pending == null) { 5478 pending = new PendingThumbnailsRecord(receiver); 5479 } 5480 pending.pendingRecords.add(top); 5481 } 5482 list.add(ci); 5483 maxNum--; 5484 top = null; 5485 } 5486 } 5487 5488 if (pending != null) { 5489 mPendingThumbnails.add(pending); 5490 } 5491 } 5492 5493 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5494 5495 if (topThumbnail != null) { 5496 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5497 try { 5498 topThumbnail.requestThumbnail(topRecord.appToken); 5499 } catch (Exception e) { 5500 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5501 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5502 } 5503 } 5504 5505 if (pending == null && receiver != null) { 5506 // In this case all thumbnails were available and the client 5507 // is being asked to be told when the remaining ones come in... 5508 // which is unusually, since the top-most currently running 5509 // activity should never have a canned thumbnail! Oh well. 5510 try { 5511 receiver.finished(); 5512 } catch (RemoteException ex) { 5513 } 5514 } 5515 5516 return list; 5517 } 5518 5519 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5520 int flags, int userId) { 5521 final int callingUid = Binder.getCallingUid(); 5522 if (userId != UserId.getCallingUserId()) { 5523 // Check if the caller is holding permissions for cross-user requests. 5524 if (checkComponentPermission( 5525 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5526 Binder.getCallingPid(), callingUid, -1, true) 5527 != PackageManager.PERMISSION_GRANTED) { 5528 String msg = "Permission Denial: " 5529 + "Request to get recent tasks for user " + userId 5530 + " but is calling from user " + UserId.getUserId(callingUid) 5531 + "; this requires " 5532 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5533 Slog.w(TAG, msg); 5534 throw new SecurityException(msg); 5535 } else { 5536 if (userId == UserId.USER_CURRENT) { 5537 userId = mCurrentUserId; 5538 } 5539 } 5540 } 5541 5542 synchronized (this) { 5543 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5544 "getRecentTasks()"); 5545 final boolean detailed = checkCallingPermission( 5546 android.Manifest.permission.GET_DETAILED_TASKS) 5547 == PackageManager.PERMISSION_GRANTED; 5548 5549 IPackageManager pm = AppGlobals.getPackageManager(); 5550 5551 final int N = mRecentTasks.size(); 5552 ArrayList<ActivityManager.RecentTaskInfo> res 5553 = new ArrayList<ActivityManager.RecentTaskInfo>( 5554 maxNum < N ? maxNum : N); 5555 for (int i=0; i<N && maxNum > 0; i++) { 5556 TaskRecord tr = mRecentTasks.get(i); 5557 // Only add calling user's recent tasks 5558 if (tr.userId != userId) continue; 5559 // Return the entry if desired by the caller. We always return 5560 // the first entry, because callers always expect this to be the 5561 // foreground app. We may filter others if the caller has 5562 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5563 // we should exclude the entry. 5564 5565 if (i == 0 5566 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5567 || (tr.intent == null) 5568 || ((tr.intent.getFlags() 5569 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5570 ActivityManager.RecentTaskInfo rti 5571 = new ActivityManager.RecentTaskInfo(); 5572 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5573 rti.persistentId = tr.taskId; 5574 rti.baseIntent = new Intent( 5575 tr.intent != null ? tr.intent : tr.affinityIntent); 5576 if (!detailed) { 5577 rti.baseIntent.replaceExtras((Bundle)null); 5578 } 5579 rti.origActivity = tr.origActivity; 5580 rti.description = tr.lastDescription; 5581 5582 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5583 // Check whether this activity is currently available. 5584 try { 5585 if (rti.origActivity != null) { 5586 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5587 == null) { 5588 continue; 5589 } 5590 } else if (rti.baseIntent != null) { 5591 if (pm.queryIntentActivities(rti.baseIntent, 5592 null, 0, userId) == null) { 5593 continue; 5594 } 5595 } 5596 } catch (RemoteException e) { 5597 // Will never happen. 5598 } 5599 } 5600 5601 res.add(rti); 5602 maxNum--; 5603 } 5604 } 5605 return res; 5606 } 5607 } 5608 5609 private TaskRecord taskForIdLocked(int id) { 5610 final int N = mRecentTasks.size(); 5611 for (int i=0; i<N; i++) { 5612 TaskRecord tr = mRecentTasks.get(i); 5613 if (tr.taskId == id) { 5614 return tr; 5615 } 5616 } 5617 return null; 5618 } 5619 5620 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5621 synchronized (this) { 5622 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5623 "getTaskThumbnails()"); 5624 TaskRecord tr = taskForIdLocked(id); 5625 if (tr != null) { 5626 return mMainStack.getTaskThumbnailsLocked(tr); 5627 } 5628 } 5629 return null; 5630 } 5631 5632 public boolean removeSubTask(int taskId, int subTaskIndex) { 5633 synchronized (this) { 5634 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5635 "removeSubTask()"); 5636 long ident = Binder.clearCallingIdentity(); 5637 try { 5638 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5639 true) != null; 5640 } finally { 5641 Binder.restoreCallingIdentity(ident); 5642 } 5643 } 5644 } 5645 5646 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5647 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5648 Intent baseIntent = new Intent( 5649 tr.intent != null ? tr.intent : tr.affinityIntent); 5650 ComponentName component = baseIntent.getComponent(); 5651 if (component == null) { 5652 Slog.w(TAG, "Now component for base intent of task: " + tr); 5653 return; 5654 } 5655 5656 // Find any running services associated with this app. 5657 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5658 5659 if (killProcesses) { 5660 // Find any running processes associated with this app. 5661 final String pkg = component.getPackageName(); 5662 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5663 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5664 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5665 for (int i=0; i<uids.size(); i++) { 5666 ProcessRecord proc = uids.valueAt(i); 5667 if (proc.userId != tr.userId) { 5668 continue; 5669 } 5670 if (!proc.pkgList.contains(pkg)) { 5671 continue; 5672 } 5673 procs.add(proc); 5674 } 5675 } 5676 5677 // Kill the running processes. 5678 for (int i=0; i<procs.size(); i++) { 5679 ProcessRecord pr = procs.get(i); 5680 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5681 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5682 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5683 pr.processName, pr.setAdj, "remove task"); 5684 pr.killedBackground = true; 5685 Process.killProcessQuiet(pr.pid); 5686 } else { 5687 pr.waitingToKill = "remove task"; 5688 } 5689 } 5690 } 5691 } 5692 5693 public boolean removeTask(int taskId, int flags) { 5694 synchronized (this) { 5695 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5696 "removeTask()"); 5697 long ident = Binder.clearCallingIdentity(); 5698 try { 5699 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5700 false); 5701 if (r != null) { 5702 mRecentTasks.remove(r.task); 5703 cleanUpRemovedTaskLocked(r.task, flags); 5704 return true; 5705 } else { 5706 TaskRecord tr = null; 5707 int i=0; 5708 while (i < mRecentTasks.size()) { 5709 TaskRecord t = mRecentTasks.get(i); 5710 if (t.taskId == taskId) { 5711 tr = t; 5712 break; 5713 } 5714 i++; 5715 } 5716 if (tr != null) { 5717 if (tr.numActivities <= 0) { 5718 // Caller is just removing a recent task that is 5719 // not actively running. That is easy! 5720 mRecentTasks.remove(i); 5721 cleanUpRemovedTaskLocked(tr, flags); 5722 return true; 5723 } else { 5724 Slog.w(TAG, "removeTask: task " + taskId 5725 + " does not have activities to remove, " 5726 + " but numActivities=" + tr.numActivities 5727 + ": " + tr); 5728 } 5729 } 5730 } 5731 } finally { 5732 Binder.restoreCallingIdentity(ident); 5733 } 5734 } 5735 return false; 5736 } 5737 5738 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5739 int j; 5740 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5741 TaskRecord jt = startTask; 5742 5743 // First look backwards 5744 for (j=startIndex-1; j>=0; j--) { 5745 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5746 if (r.task != jt) { 5747 jt = r.task; 5748 if (affinity.equals(jt.affinity)) { 5749 return j; 5750 } 5751 } 5752 } 5753 5754 // Now look forwards 5755 final int N = mMainStack.mHistory.size(); 5756 jt = startTask; 5757 for (j=startIndex+1; j<N; j++) { 5758 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5759 if (r.task != jt) { 5760 if (affinity.equals(jt.affinity)) { 5761 return j; 5762 } 5763 jt = r.task; 5764 } 5765 } 5766 5767 // Might it be at the top? 5768 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5769 return N-1; 5770 } 5771 5772 return -1; 5773 } 5774 5775 /** 5776 * TODO: Add mController hook 5777 */ 5778 public void moveTaskToFront(int task, int flags, Bundle options) { 5779 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5780 "moveTaskToFront()"); 5781 5782 synchronized(this) { 5783 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5784 Binder.getCallingUid(), "Task to front")) { 5785 ActivityOptions.abort(options); 5786 return; 5787 } 5788 final long origId = Binder.clearCallingIdentity(); 5789 try { 5790 TaskRecord tr = taskForIdLocked(task); 5791 if (tr != null) { 5792 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5793 mMainStack.mUserLeaving = true; 5794 } 5795 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5796 // Caller wants the home activity moved with it. To accomplish this, 5797 // we'll just move the home task to the top first. 5798 mMainStack.moveHomeToFrontLocked(); 5799 } 5800 mMainStack.moveTaskToFrontLocked(tr, null, options); 5801 return; 5802 } 5803 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5804 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5805 if (hr.task.taskId == task) { 5806 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5807 mMainStack.mUserLeaving = true; 5808 } 5809 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5810 // Caller wants the home activity moved with it. To accomplish this, 5811 // we'll just move the home task to the top first. 5812 mMainStack.moveHomeToFrontLocked(); 5813 } 5814 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5815 return; 5816 } 5817 } 5818 } finally { 5819 Binder.restoreCallingIdentity(origId); 5820 } 5821 ActivityOptions.abort(options); 5822 } 5823 } 5824 5825 public void moveTaskToBack(int task) { 5826 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5827 "moveTaskToBack()"); 5828 5829 synchronized(this) { 5830 if (mMainStack.mResumedActivity != null 5831 && mMainStack.mResumedActivity.task.taskId == task) { 5832 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5833 Binder.getCallingUid(), "Task to back")) { 5834 return; 5835 } 5836 } 5837 final long origId = Binder.clearCallingIdentity(); 5838 mMainStack.moveTaskToBackLocked(task, null); 5839 Binder.restoreCallingIdentity(origId); 5840 } 5841 } 5842 5843 /** 5844 * Moves an activity, and all of the other activities within the same task, to the bottom 5845 * of the history stack. The activity's order within the task is unchanged. 5846 * 5847 * @param token A reference to the activity we wish to move 5848 * @param nonRoot If false then this only works if the activity is the root 5849 * of a task; if true it will work for any activity in a task. 5850 * @return Returns true if the move completed, false if not. 5851 */ 5852 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5853 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5854 synchronized(this) { 5855 final long origId = Binder.clearCallingIdentity(); 5856 int taskId = getTaskForActivityLocked(token, !nonRoot); 5857 if (taskId >= 0) { 5858 return mMainStack.moveTaskToBackLocked(taskId, null); 5859 } 5860 Binder.restoreCallingIdentity(origId); 5861 } 5862 return false; 5863 } 5864 5865 public void moveTaskBackwards(int task) { 5866 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5867 "moveTaskBackwards()"); 5868 5869 synchronized(this) { 5870 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5871 Binder.getCallingUid(), "Task backwards")) { 5872 return; 5873 } 5874 final long origId = Binder.clearCallingIdentity(); 5875 moveTaskBackwardsLocked(task); 5876 Binder.restoreCallingIdentity(origId); 5877 } 5878 } 5879 5880 private final void moveTaskBackwardsLocked(int task) { 5881 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5882 } 5883 5884 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5885 synchronized(this) { 5886 return getTaskForActivityLocked(token, onlyRoot); 5887 } 5888 } 5889 5890 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5891 final int N = mMainStack.mHistory.size(); 5892 TaskRecord lastTask = null; 5893 for (int i=0; i<N; i++) { 5894 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5895 if (r.appToken == token) { 5896 if (!onlyRoot || lastTask != r.task) { 5897 return r.task.taskId; 5898 } 5899 return -1; 5900 } 5901 lastTask = r.task; 5902 } 5903 5904 return -1; 5905 } 5906 5907 // ========================================================= 5908 // THUMBNAILS 5909 // ========================================================= 5910 5911 public void reportThumbnail(IBinder token, 5912 Bitmap thumbnail, CharSequence description) { 5913 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5914 final long origId = Binder.clearCallingIdentity(); 5915 sendPendingThumbnail(null, token, thumbnail, description, true); 5916 Binder.restoreCallingIdentity(origId); 5917 } 5918 5919 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5920 Bitmap thumbnail, CharSequence description, boolean always) { 5921 TaskRecord task = null; 5922 ArrayList receivers = null; 5923 5924 //System.out.println("Send pending thumbnail: " + r); 5925 5926 synchronized(this) { 5927 if (r == null) { 5928 r = mMainStack.isInStackLocked(token); 5929 if (r == null) { 5930 return; 5931 } 5932 } 5933 if (thumbnail == null && r.thumbHolder != null) { 5934 thumbnail = r.thumbHolder.lastThumbnail; 5935 description = r.thumbHolder.lastDescription; 5936 } 5937 if (thumbnail == null && !always) { 5938 // If there is no thumbnail, and this entry is not actually 5939 // going away, then abort for now and pick up the next 5940 // thumbnail we get. 5941 return; 5942 } 5943 task = r.task; 5944 5945 int N = mPendingThumbnails.size(); 5946 int i=0; 5947 while (i<N) { 5948 PendingThumbnailsRecord pr = 5949 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5950 //System.out.println("Looking in " + pr.pendingRecords); 5951 if (pr.pendingRecords.remove(r)) { 5952 if (receivers == null) { 5953 receivers = new ArrayList(); 5954 } 5955 receivers.add(pr); 5956 if (pr.pendingRecords.size() == 0) { 5957 pr.finished = true; 5958 mPendingThumbnails.remove(i); 5959 N--; 5960 continue; 5961 } 5962 } 5963 i++; 5964 } 5965 } 5966 5967 if (receivers != null) { 5968 final int N = receivers.size(); 5969 for (int i=0; i<N; i++) { 5970 try { 5971 PendingThumbnailsRecord pr = 5972 (PendingThumbnailsRecord)receivers.get(i); 5973 pr.receiver.newThumbnail( 5974 task != null ? task.taskId : -1, thumbnail, description); 5975 if (pr.finished) { 5976 pr.receiver.finished(); 5977 } 5978 } catch (Exception e) { 5979 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5980 } 5981 } 5982 } 5983 } 5984 5985 // ========================================================= 5986 // CONTENT PROVIDERS 5987 // ========================================================= 5988 5989 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5990 List<ProviderInfo> providers = null; 5991 try { 5992 providers = AppGlobals.getPackageManager(). 5993 queryContentProviders(app.processName, app.uid, 5994 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5995 } catch (RemoteException ex) { 5996 } 5997 if (DEBUG_MU) 5998 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 5999 int userId = app.userId; 6000 if (providers != null) { 6001 int N = providers.size(); 6002 for (int i=0; i<N; i++) { 6003 ProviderInfo cpi = 6004 (ProviderInfo)providers.get(i); 6005 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6006 cpi.name, cpi.flags); 6007 if (singleton && UserId.getUserId(app.uid) != 0) { 6008 // This is a singleton provider, but a user besides the 6009 // default user is asking to initialize a process it runs 6010 // in... well, no, it doesn't actually run in this process, 6011 // it runs in the process of the default user. Get rid of it. 6012 providers.remove(i); 6013 N--; 6014 continue; 6015 } 6016 6017 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6018 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6019 if (cpr == null) { 6020 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6021 mProviderMap.putProviderByClass(comp, cpr); 6022 } 6023 if (DEBUG_MU) 6024 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6025 app.pubProviders.put(cpi.name, cpr); 6026 app.addPackage(cpi.applicationInfo.packageName); 6027 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6028 } 6029 } 6030 return providers; 6031 } 6032 6033 /** 6034 * Check if {@link ProcessRecord} has a possible chance at accessing the 6035 * given {@link ProviderInfo}. Final permission checking is always done 6036 * in {@link ContentProvider}. 6037 */ 6038 private final String checkContentProviderPermissionLocked( 6039 ProviderInfo cpi, ProcessRecord r) { 6040 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6041 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6042 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6043 cpi.applicationInfo.uid, cpi.exported) 6044 == PackageManager.PERMISSION_GRANTED) { 6045 return null; 6046 } 6047 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6048 cpi.applicationInfo.uid, cpi.exported) 6049 == PackageManager.PERMISSION_GRANTED) { 6050 return null; 6051 } 6052 6053 PathPermission[] pps = cpi.pathPermissions; 6054 if (pps != null) { 6055 int i = pps.length; 6056 while (i > 0) { 6057 i--; 6058 PathPermission pp = pps[i]; 6059 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6060 cpi.applicationInfo.uid, cpi.exported) 6061 == PackageManager.PERMISSION_GRANTED) { 6062 return null; 6063 } 6064 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6065 cpi.applicationInfo.uid, cpi.exported) 6066 == PackageManager.PERMISSION_GRANTED) { 6067 return null; 6068 } 6069 } 6070 } 6071 6072 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6073 if (perms != null) { 6074 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6075 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6076 return null; 6077 } 6078 } 6079 } 6080 6081 String msg; 6082 if (!cpi.exported) { 6083 msg = "Permission Denial: opening provider " + cpi.name 6084 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6085 + ", uid=" + callingUid + ") that is not exported from uid " 6086 + cpi.applicationInfo.uid; 6087 } else { 6088 msg = "Permission Denial: opening provider " + cpi.name 6089 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6090 + ", uid=" + callingUid + ") requires " 6091 + cpi.readPermission + " or " + cpi.writePermission; 6092 } 6093 Slog.w(TAG, msg); 6094 return msg; 6095 } 6096 6097 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6098 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6099 if (r != null) { 6100 for (int i=0; i<r.conProviders.size(); i++) { 6101 ContentProviderConnection conn = r.conProviders.get(i); 6102 if (conn.provider == cpr) { 6103 if (DEBUG_PROVIDER) Slog.v(TAG, 6104 "Adding provider requested by " 6105 + r.processName + " from process " 6106 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6107 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6108 if (stable) { 6109 conn.stableCount++; 6110 conn.numStableIncs++; 6111 } else { 6112 conn.unstableCount++; 6113 conn.numUnstableIncs++; 6114 } 6115 return conn; 6116 } 6117 } 6118 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6119 if (stable) { 6120 conn.stableCount = 1; 6121 conn.numStableIncs = 1; 6122 } else { 6123 conn.unstableCount = 1; 6124 conn.numUnstableIncs = 1; 6125 } 6126 cpr.connections.add(conn); 6127 r.conProviders.add(conn); 6128 return conn; 6129 } 6130 cpr.addExternalProcessHandleLocked(externalProcessToken); 6131 return null; 6132 } 6133 6134 boolean decProviderCountLocked(ContentProviderConnection conn, 6135 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6136 if (conn != null) { 6137 cpr = conn.provider; 6138 if (DEBUG_PROVIDER) Slog.v(TAG, 6139 "Removing provider requested by " 6140 + conn.client.processName + " from process " 6141 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6142 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6143 if (stable) { 6144 conn.stableCount--; 6145 } else { 6146 conn.unstableCount--; 6147 } 6148 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6149 cpr.connections.remove(conn); 6150 conn.client.conProviders.remove(conn); 6151 return true; 6152 } 6153 return false; 6154 } 6155 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6156 return false; 6157 } 6158 6159 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6160 String name, IBinder token, boolean stable) { 6161 ContentProviderRecord cpr; 6162 ContentProviderConnection conn = null; 6163 ProviderInfo cpi = null; 6164 6165 synchronized(this) { 6166 ProcessRecord r = null; 6167 if (caller != null) { 6168 r = getRecordForAppLocked(caller); 6169 if (r == null) { 6170 throw new SecurityException( 6171 "Unable to find app for caller " + caller 6172 + " (pid=" + Binder.getCallingPid() 6173 + ") when getting content provider " + name); 6174 } 6175 } 6176 6177 // First check if this content provider has been published... 6178 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6179 cpr = mProviderMap.getProviderByName(name, userId); 6180 boolean providerRunning = cpr != null; 6181 if (providerRunning) { 6182 cpi = cpr.info; 6183 String msg; 6184 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6185 throw new SecurityException(msg); 6186 } 6187 6188 if (r != null && cpr.canRunHere(r)) { 6189 // This provider has been published or is in the process 6190 // of being published... but it is also allowed to run 6191 // in the caller's process, so don't make a connection 6192 // and just let the caller instantiate its own instance. 6193 ContentProviderHolder holder = cpr.newHolder(null); 6194 // don't give caller the provider object, it needs 6195 // to make its own. 6196 holder.provider = null; 6197 return holder; 6198 } 6199 6200 final long origId = Binder.clearCallingIdentity(); 6201 6202 // In this case the provider instance already exists, so we can 6203 // return it right away. 6204 conn = incProviderCountLocked(r, cpr, token, stable); 6205 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6206 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6207 // If this is a perceptible app accessing the provider, 6208 // make sure to count it as being accessed and thus 6209 // back up on the LRU list. This is good because 6210 // content providers are often expensive to start. 6211 updateLruProcessLocked(cpr.proc, false, true); 6212 } 6213 } 6214 6215 if (cpr.proc != null) { 6216 if (false) { 6217 if (cpr.name.flattenToShortString().equals( 6218 "com.android.providers.calendar/.CalendarProvider2")) { 6219 Slog.v(TAG, "****************** KILLING " 6220 + cpr.name.flattenToShortString()); 6221 Process.killProcess(cpr.proc.pid); 6222 } 6223 } 6224 boolean success = updateOomAdjLocked(cpr.proc); 6225 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6226 // NOTE: there is still a race here where a signal could be 6227 // pending on the process even though we managed to update its 6228 // adj level. Not sure what to do about this, but at least 6229 // the race is now smaller. 6230 if (!success) { 6231 // Uh oh... it looks like the provider's process 6232 // has been killed on us. We need to wait for a new 6233 // process to be started, and make sure its death 6234 // doesn't kill our process. 6235 Slog.i(TAG, 6236 "Existing provider " + cpr.name.flattenToShortString() 6237 + " is crashing; detaching " + r); 6238 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6239 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6240 if (!lastRef) { 6241 // This wasn't the last ref our process had on 6242 // the provider... we have now been killed, bail. 6243 return null; 6244 } 6245 providerRunning = false; 6246 conn = null; 6247 } 6248 } 6249 6250 Binder.restoreCallingIdentity(origId); 6251 } 6252 6253 boolean singleton; 6254 if (!providerRunning) { 6255 try { 6256 cpi = AppGlobals.getPackageManager(). 6257 resolveContentProvider(name, 6258 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6259 } catch (RemoteException ex) { 6260 } 6261 if (cpi == null) { 6262 return null; 6263 } 6264 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6265 cpi.name, cpi.flags); 6266 if (singleton) { 6267 userId = 0; 6268 } 6269 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6270 6271 String msg; 6272 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6273 throw new SecurityException(msg); 6274 } 6275 6276 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6277 && !cpi.processName.equals("system")) { 6278 // If this content provider does not run in the system 6279 // process, and the system is not yet ready to run other 6280 // processes, then fail fast instead of hanging. 6281 throw new IllegalArgumentException( 6282 "Attempt to launch content provider before system ready"); 6283 } 6284 6285 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6286 cpr = mProviderMap.getProviderByClass(comp, userId); 6287 final boolean firstClass = cpr == null; 6288 if (firstClass) { 6289 try { 6290 ApplicationInfo ai = 6291 AppGlobals.getPackageManager(). 6292 getApplicationInfo( 6293 cpi.applicationInfo.packageName, 6294 STOCK_PM_FLAGS, userId); 6295 if (ai == null) { 6296 Slog.w(TAG, "No package info for content provider " 6297 + cpi.name); 6298 return null; 6299 } 6300 ai = getAppInfoForUser(ai, userId); 6301 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6302 } catch (RemoteException ex) { 6303 // pm is in same process, this will never happen. 6304 } 6305 } 6306 6307 if (r != null && cpr.canRunHere(r)) { 6308 // If this is a multiprocess provider, then just return its 6309 // info and allow the caller to instantiate it. Only do 6310 // this if the provider is the same user as the caller's 6311 // process, or can run as root (so can be in any process). 6312 return cpr.newHolder(null); 6313 } 6314 6315 if (DEBUG_PROVIDER) { 6316 RuntimeException e = new RuntimeException("here"); 6317 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6318 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6319 } 6320 6321 // This is single process, and our app is now connecting to it. 6322 // See if we are already in the process of launching this 6323 // provider. 6324 final int N = mLaunchingProviders.size(); 6325 int i; 6326 for (i=0; i<N; i++) { 6327 if (mLaunchingProviders.get(i) == cpr) { 6328 break; 6329 } 6330 } 6331 6332 // If the provider is not already being launched, then get it 6333 // started. 6334 if (i >= N) { 6335 final long origId = Binder.clearCallingIdentity(); 6336 6337 try { 6338 // Content provider is now in use, its package can't be stopped. 6339 try { 6340 AppGlobals.getPackageManager().setPackageStoppedState( 6341 cpr.appInfo.packageName, false, userId); 6342 } catch (RemoteException e) { 6343 } catch (IllegalArgumentException e) { 6344 Slog.w(TAG, "Failed trying to unstop package " 6345 + cpr.appInfo.packageName + ": " + e); 6346 } 6347 6348 ProcessRecord proc = startProcessLocked(cpi.processName, 6349 cpr.appInfo, false, 0, "content provider", 6350 new ComponentName(cpi.applicationInfo.packageName, 6351 cpi.name), false, false); 6352 if (proc == null) { 6353 Slog.w(TAG, "Unable to launch app " 6354 + cpi.applicationInfo.packageName + "/" 6355 + cpi.applicationInfo.uid + " for provider " 6356 + name + ": process is bad"); 6357 return null; 6358 } 6359 cpr.launchingApp = proc; 6360 mLaunchingProviders.add(cpr); 6361 } finally { 6362 Binder.restoreCallingIdentity(origId); 6363 } 6364 } 6365 6366 // Make sure the provider is published (the same provider class 6367 // may be published under multiple names). 6368 if (firstClass) { 6369 mProviderMap.putProviderByClass(comp, cpr); 6370 } 6371 6372 mProviderMap.putProviderByName(name, cpr); 6373 conn = incProviderCountLocked(r, cpr, token, stable); 6374 if (conn != null) { 6375 conn.waiting = true; 6376 } 6377 } 6378 } 6379 6380 // Wait for the provider to be published... 6381 synchronized (cpr) { 6382 while (cpr.provider == null) { 6383 if (cpr.launchingApp == null) { 6384 Slog.w(TAG, "Unable to launch app " 6385 + cpi.applicationInfo.packageName + "/" 6386 + cpi.applicationInfo.uid + " for provider " 6387 + name + ": launching app became null"); 6388 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6389 cpi.applicationInfo.packageName, 6390 cpi.applicationInfo.uid, name); 6391 return null; 6392 } 6393 try { 6394 if (DEBUG_MU) { 6395 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6396 + cpr.launchingApp); 6397 } 6398 if (conn != null) { 6399 conn.waiting = true; 6400 } 6401 cpr.wait(); 6402 } catch (InterruptedException ex) { 6403 } finally { 6404 if (conn != null) { 6405 conn.waiting = false; 6406 } 6407 } 6408 } 6409 } 6410 return cpr != null ? cpr.newHolder(conn) : null; 6411 } 6412 6413 public final ContentProviderHolder getContentProvider( 6414 IApplicationThread caller, String name, boolean stable) { 6415 enforceNotIsolatedCaller("getContentProvider"); 6416 if (caller == null) { 6417 String msg = "null IApplicationThread when getting content provider " 6418 + name; 6419 Slog.w(TAG, msg); 6420 throw new SecurityException(msg); 6421 } 6422 6423 return getContentProviderImpl(caller, name, null, stable); 6424 } 6425 6426 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6427 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6428 "Do not have permission in call getContentProviderExternal()"); 6429 return getContentProviderExternalUnchecked(name, token); 6430 } 6431 6432 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6433 return getContentProviderImpl(null, name, token, true); 6434 } 6435 6436 /** 6437 * Drop a content provider from a ProcessRecord's bookkeeping 6438 * @param cpr 6439 */ 6440 public void removeContentProvider(IBinder connection, boolean stable) { 6441 enforceNotIsolatedCaller("removeContentProvider"); 6442 synchronized (this) { 6443 ContentProviderConnection conn; 6444 try { 6445 conn = (ContentProviderConnection)connection; 6446 } catch (ClassCastException e) { 6447 String msg ="removeContentProvider: " + connection 6448 + " not a ContentProviderConnection"; 6449 Slog.w(TAG, msg); 6450 throw new IllegalArgumentException(msg); 6451 } 6452 if (conn == null) { 6453 throw new NullPointerException("connection is null"); 6454 } 6455 if (decProviderCountLocked(conn, null, null, stable)) { 6456 updateOomAdjLocked(); 6457 } 6458 } 6459 } 6460 6461 public void removeContentProviderExternal(String name, IBinder token) { 6462 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6463 "Do not have permission in call removeContentProviderExternal()"); 6464 removeContentProviderExternalUnchecked(name, token); 6465 } 6466 6467 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6468 synchronized (this) { 6469 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6470 Binder.getOrigCallingUser()); 6471 if(cpr == null) { 6472 //remove from mProvidersByClass 6473 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6474 return; 6475 } 6476 6477 //update content provider record entry info 6478 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6479 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6480 Binder.getOrigCallingUser()); 6481 if (localCpr.hasExternalProcessHandles()) { 6482 if (localCpr.removeExternalProcessHandleLocked(token)) { 6483 updateOomAdjLocked(); 6484 } else { 6485 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6486 + " with no external reference for token: " 6487 + token + "."); 6488 } 6489 } else { 6490 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6491 + " with no external references."); 6492 } 6493 } 6494 } 6495 6496 public final void publishContentProviders(IApplicationThread caller, 6497 List<ContentProviderHolder> providers) { 6498 if (providers == null) { 6499 return; 6500 } 6501 6502 enforceNotIsolatedCaller("publishContentProviders"); 6503 synchronized (this) { 6504 final ProcessRecord r = getRecordForAppLocked(caller); 6505 if (DEBUG_MU) 6506 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6507 if (r == null) { 6508 throw new SecurityException( 6509 "Unable to find app for caller " + caller 6510 + " (pid=" + Binder.getCallingPid() 6511 + ") when publishing content providers"); 6512 } 6513 6514 final long origId = Binder.clearCallingIdentity(); 6515 6516 final int N = providers.size(); 6517 for (int i=0; i<N; i++) { 6518 ContentProviderHolder src = providers.get(i); 6519 if (src == null || src.info == null || src.provider == null) { 6520 continue; 6521 } 6522 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6523 if (DEBUG_MU) 6524 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6525 if (dst != null) { 6526 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6527 mProviderMap.putProviderByClass(comp, dst); 6528 String names[] = dst.info.authority.split(";"); 6529 for (int j = 0; j < names.length; j++) { 6530 mProviderMap.putProviderByName(names[j], dst); 6531 } 6532 6533 int NL = mLaunchingProviders.size(); 6534 int j; 6535 for (j=0; j<NL; j++) { 6536 if (mLaunchingProviders.get(j) == dst) { 6537 mLaunchingProviders.remove(j); 6538 j--; 6539 NL--; 6540 } 6541 } 6542 synchronized (dst) { 6543 dst.provider = src.provider; 6544 dst.proc = r; 6545 dst.notifyAll(); 6546 } 6547 updateOomAdjLocked(r); 6548 } 6549 } 6550 6551 Binder.restoreCallingIdentity(origId); 6552 } 6553 } 6554 6555 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6556 ContentProviderConnection conn; 6557 try { 6558 conn = (ContentProviderConnection)connection; 6559 } catch (ClassCastException e) { 6560 String msg ="refContentProvider: " + connection 6561 + " not a ContentProviderConnection"; 6562 Slog.w(TAG, msg); 6563 throw new IllegalArgumentException(msg); 6564 } 6565 if (conn == null) { 6566 throw new NullPointerException("connection is null"); 6567 } 6568 6569 synchronized (this) { 6570 if (stable > 0) { 6571 conn.numStableIncs += stable; 6572 } 6573 stable = conn.stableCount + stable; 6574 if (stable < 0) { 6575 throw new IllegalStateException("stableCount < 0: " + stable); 6576 } 6577 6578 if (unstable > 0) { 6579 conn.numUnstableIncs += unstable; 6580 } 6581 unstable = conn.unstableCount + unstable; 6582 if (unstable < 0) { 6583 throw new IllegalStateException("unstableCount < 0: " + unstable); 6584 } 6585 6586 if ((stable+unstable) <= 0) { 6587 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6588 + stable + " unstable=" + unstable); 6589 } 6590 conn.stableCount = stable; 6591 conn.unstableCount = unstable; 6592 return !conn.dead; 6593 } 6594 } 6595 6596 public void unstableProviderDied(IBinder connection) { 6597 ContentProviderConnection conn; 6598 try { 6599 conn = (ContentProviderConnection)connection; 6600 } catch (ClassCastException e) { 6601 String msg ="refContentProvider: " + connection 6602 + " not a ContentProviderConnection"; 6603 Slog.w(TAG, msg); 6604 throw new IllegalArgumentException(msg); 6605 } 6606 if (conn == null) { 6607 throw new NullPointerException("connection is null"); 6608 } 6609 6610 // Safely retrieve the content provider associated with the connection. 6611 IContentProvider provider; 6612 synchronized (this) { 6613 provider = conn.provider.provider; 6614 } 6615 6616 if (provider == null) { 6617 // Um, yeah, we're way ahead of you. 6618 return; 6619 } 6620 6621 // Make sure the caller is being honest with us. 6622 if (provider.asBinder().pingBinder()) { 6623 // Er, no, still looks good to us. 6624 synchronized (this) { 6625 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6626 + " says " + conn + " died, but we don't agree"); 6627 return; 6628 } 6629 } 6630 6631 // Well look at that! It's dead! 6632 synchronized (this) { 6633 if (conn.provider.provider != provider) { 6634 // But something changed... good enough. 6635 return; 6636 } 6637 6638 ProcessRecord proc = conn.provider.proc; 6639 if (proc == null || proc.thread == null) { 6640 // Seems like the process is already cleaned up. 6641 return; 6642 } 6643 6644 // As far as we're concerned, this is just like receiving a 6645 // death notification... just a bit prematurely. 6646 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6647 + ") early provider death"); 6648 final long ident = Binder.clearCallingIdentity(); 6649 try { 6650 appDiedLocked(proc, proc.pid, proc.thread); 6651 } finally { 6652 Binder.restoreCallingIdentity(ident); 6653 } 6654 } 6655 } 6656 6657 public static final void installSystemProviders() { 6658 List<ProviderInfo> providers; 6659 synchronized (mSelf) { 6660 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6661 providers = mSelf.generateApplicationProvidersLocked(app); 6662 if (providers != null) { 6663 for (int i=providers.size()-1; i>=0; i--) { 6664 ProviderInfo pi = (ProviderInfo)providers.get(i); 6665 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6666 Slog.w(TAG, "Not installing system proc provider " + pi.name 6667 + ": not system .apk"); 6668 providers.remove(i); 6669 } 6670 } 6671 } 6672 } 6673 if (providers != null) { 6674 mSystemThread.installSystemProviders(providers); 6675 } 6676 6677 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6678 6679 mSelf.mUsageStatsService.monitorPackages(); 6680 } 6681 6682 /** 6683 * Allows app to retrieve the MIME type of a URI without having permission 6684 * to access its content provider. 6685 * 6686 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6687 * 6688 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6689 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6690 */ 6691 public String getProviderMimeType(Uri uri) { 6692 enforceNotIsolatedCaller("getProviderMimeType"); 6693 final String name = uri.getAuthority(); 6694 final long ident = Binder.clearCallingIdentity(); 6695 ContentProviderHolder holder = null; 6696 6697 try { 6698 holder = getContentProviderExternalUnchecked(name, null); 6699 if (holder != null) { 6700 return holder.provider.getType(uri); 6701 } 6702 } catch (RemoteException e) { 6703 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6704 return null; 6705 } finally { 6706 if (holder != null) { 6707 removeContentProviderExternalUnchecked(name, null); 6708 } 6709 Binder.restoreCallingIdentity(ident); 6710 } 6711 6712 return null; 6713 } 6714 6715 // ========================================================= 6716 // GLOBAL MANAGEMENT 6717 // ========================================================= 6718 6719 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6720 ApplicationInfo info, String customProcess, boolean isolated) { 6721 String proc = customProcess != null ? customProcess : info.processName; 6722 BatteryStatsImpl.Uid.Proc ps = null; 6723 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6724 int uid = info.uid; 6725 if (isolated) { 6726 int userId = UserId.getUserId(uid); 6727 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6728 uid = 0; 6729 while (true) { 6730 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6731 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6732 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6733 } 6734 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6735 mNextIsolatedProcessUid++; 6736 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6737 // No process for this uid, use it. 6738 break; 6739 } 6740 stepsLeft--; 6741 if (stepsLeft <= 0) { 6742 return null; 6743 } 6744 } 6745 } 6746 synchronized (stats) { 6747 ps = stats.getProcessStatsLocked(info.uid, proc); 6748 } 6749 return new ProcessRecord(ps, thread, info, proc, uid); 6750 } 6751 6752 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6753 ProcessRecord app; 6754 if (!isolated) { 6755 app = getProcessRecordLocked(info.processName, info.uid); 6756 } else { 6757 app = null; 6758 } 6759 6760 if (app == null) { 6761 app = newProcessRecordLocked(null, info, null, isolated); 6762 mProcessNames.put(info.processName, app.uid, app); 6763 if (isolated) { 6764 mIsolatedProcesses.put(app.uid, app); 6765 } 6766 updateLruProcessLocked(app, true, true); 6767 } 6768 6769 // This package really, really can not be stopped. 6770 try { 6771 AppGlobals.getPackageManager().setPackageStoppedState( 6772 info.packageName, false, UserId.getUserId(app.uid)); 6773 } catch (RemoteException e) { 6774 } catch (IllegalArgumentException e) { 6775 Slog.w(TAG, "Failed trying to unstop package " 6776 + info.packageName + ": " + e); 6777 } 6778 6779 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6780 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6781 app.persistent = true; 6782 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6783 } 6784 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6785 mPersistentStartingProcesses.add(app); 6786 startProcessLocked(app, "added application", app.processName); 6787 } 6788 6789 return app; 6790 } 6791 6792 public void unhandledBack() { 6793 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6794 "unhandledBack()"); 6795 6796 synchronized(this) { 6797 int count = mMainStack.mHistory.size(); 6798 if (DEBUG_SWITCH) Slog.d( 6799 TAG, "Performing unhandledBack(): stack size = " + count); 6800 if (count > 1) { 6801 final long origId = Binder.clearCallingIdentity(); 6802 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6803 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6804 Binder.restoreCallingIdentity(origId); 6805 } 6806 } 6807 } 6808 6809 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6810 enforceNotIsolatedCaller("openContentUri"); 6811 String name = uri.getAuthority(); 6812 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6813 ParcelFileDescriptor pfd = null; 6814 if (cph != null) { 6815 // We record the binder invoker's uid in thread-local storage before 6816 // going to the content provider to open the file. Later, in the code 6817 // that handles all permissions checks, we look for this uid and use 6818 // that rather than the Activity Manager's own uid. The effect is that 6819 // we do the check against the caller's permissions even though it looks 6820 // to the content provider like the Activity Manager itself is making 6821 // the request. 6822 sCallerIdentity.set(new Identity( 6823 Binder.getCallingPid(), Binder.getCallingUid())); 6824 try { 6825 pfd = cph.provider.openFile(uri, "r"); 6826 } catch (FileNotFoundException e) { 6827 // do nothing; pfd will be returned null 6828 } finally { 6829 // Ensure that whatever happens, we clean up the identity state 6830 sCallerIdentity.remove(); 6831 } 6832 6833 // We've got the fd now, so we're done with the provider. 6834 removeContentProviderExternalUnchecked(name, null); 6835 } else { 6836 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6837 } 6838 return pfd; 6839 } 6840 6841 // Actually is sleeping or shutting down or whatever else in the future 6842 // is an inactive state. 6843 public boolean isSleeping() { 6844 return mSleeping || mShuttingDown; 6845 } 6846 6847 public void goingToSleep() { 6848 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6849 != PackageManager.PERMISSION_GRANTED) { 6850 throw new SecurityException("Requires permission " 6851 + android.Manifest.permission.DEVICE_POWER); 6852 } 6853 6854 synchronized(this) { 6855 mWentToSleep = true; 6856 updateEventDispatchingLocked(); 6857 6858 if (!mSleeping) { 6859 mSleeping = true; 6860 mMainStack.stopIfSleepingLocked(); 6861 6862 // Initialize the wake times of all processes. 6863 checkExcessivePowerUsageLocked(false); 6864 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6865 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6866 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6867 } 6868 } 6869 } 6870 6871 public boolean shutdown(int timeout) { 6872 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6873 != PackageManager.PERMISSION_GRANTED) { 6874 throw new SecurityException("Requires permission " 6875 + android.Manifest.permission.SHUTDOWN); 6876 } 6877 6878 boolean timedout = false; 6879 6880 synchronized(this) { 6881 mShuttingDown = true; 6882 updateEventDispatchingLocked(); 6883 6884 if (mMainStack.mResumedActivity != null) { 6885 mMainStack.stopIfSleepingLocked(); 6886 final long endTime = System.currentTimeMillis() + timeout; 6887 while (mMainStack.mResumedActivity != null 6888 || mMainStack.mPausingActivity != null) { 6889 long delay = endTime - System.currentTimeMillis(); 6890 if (delay <= 0) { 6891 Slog.w(TAG, "Activity manager shutdown timed out"); 6892 timedout = true; 6893 break; 6894 } 6895 try { 6896 this.wait(); 6897 } catch (InterruptedException e) { 6898 } 6899 } 6900 } 6901 } 6902 6903 mUsageStatsService.shutdown(); 6904 mBatteryStatsService.shutdown(); 6905 6906 return timedout; 6907 } 6908 6909 public final void activitySlept(IBinder token) { 6910 if (localLOGV) Slog.v( 6911 TAG, "Activity slept: token=" + token); 6912 6913 ActivityRecord r = null; 6914 6915 final long origId = Binder.clearCallingIdentity(); 6916 6917 synchronized (this) { 6918 r = mMainStack.isInStackLocked(token); 6919 if (r != null) { 6920 mMainStack.activitySleptLocked(r); 6921 } 6922 } 6923 6924 Binder.restoreCallingIdentity(origId); 6925 } 6926 6927 private void comeOutOfSleepIfNeededLocked() { 6928 if (!mWentToSleep && !mLockScreenShown) { 6929 if (mSleeping) { 6930 mSleeping = false; 6931 mMainStack.awakeFromSleepingLocked(); 6932 mMainStack.resumeTopActivityLocked(null); 6933 } 6934 } 6935 } 6936 6937 public void wakingUp() { 6938 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6939 != PackageManager.PERMISSION_GRANTED) { 6940 throw new SecurityException("Requires permission " 6941 + android.Manifest.permission.DEVICE_POWER); 6942 } 6943 6944 synchronized(this) { 6945 mWentToSleep = false; 6946 updateEventDispatchingLocked(); 6947 comeOutOfSleepIfNeededLocked(); 6948 } 6949 } 6950 6951 private void updateEventDispatchingLocked() { 6952 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6953 } 6954 6955 public void setLockScreenShown(boolean shown) { 6956 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6957 != PackageManager.PERMISSION_GRANTED) { 6958 throw new SecurityException("Requires permission " 6959 + android.Manifest.permission.DEVICE_POWER); 6960 } 6961 6962 synchronized(this) { 6963 mLockScreenShown = shown; 6964 comeOutOfSleepIfNeededLocked(); 6965 } 6966 } 6967 6968 public void stopAppSwitches() { 6969 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6970 != PackageManager.PERMISSION_GRANTED) { 6971 throw new SecurityException("Requires permission " 6972 + android.Manifest.permission.STOP_APP_SWITCHES); 6973 } 6974 6975 synchronized(this) { 6976 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6977 + APP_SWITCH_DELAY_TIME; 6978 mDidAppSwitch = false; 6979 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6980 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6981 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6982 } 6983 } 6984 6985 public void resumeAppSwitches() { 6986 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6987 != PackageManager.PERMISSION_GRANTED) { 6988 throw new SecurityException("Requires permission " 6989 + android.Manifest.permission.STOP_APP_SWITCHES); 6990 } 6991 6992 synchronized(this) { 6993 // Note that we don't execute any pending app switches... we will 6994 // let those wait until either the timeout, or the next start 6995 // activity request. 6996 mAppSwitchesAllowedTime = 0; 6997 } 6998 } 6999 7000 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7001 String name) { 7002 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7003 return true; 7004 } 7005 7006 final int perm = checkComponentPermission( 7007 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7008 callingUid, -1, true); 7009 if (perm == PackageManager.PERMISSION_GRANTED) { 7010 return true; 7011 } 7012 7013 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7014 return false; 7015 } 7016 7017 public void setDebugApp(String packageName, boolean waitForDebugger, 7018 boolean persistent) { 7019 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7020 "setDebugApp()"); 7021 7022 // Note that this is not really thread safe if there are multiple 7023 // callers into it at the same time, but that's not a situation we 7024 // care about. 7025 if (persistent) { 7026 final ContentResolver resolver = mContext.getContentResolver(); 7027 Settings.System.putString( 7028 resolver, Settings.System.DEBUG_APP, 7029 packageName); 7030 Settings.System.putInt( 7031 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7032 waitForDebugger ? 1 : 0); 7033 } 7034 7035 synchronized (this) { 7036 if (!persistent) { 7037 mOrigDebugApp = mDebugApp; 7038 mOrigWaitForDebugger = mWaitForDebugger; 7039 } 7040 mDebugApp = packageName; 7041 mWaitForDebugger = waitForDebugger; 7042 mDebugTransient = !persistent; 7043 if (packageName != null) { 7044 final long origId = Binder.clearCallingIdentity(); 7045 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7046 Binder.restoreCallingIdentity(origId); 7047 } 7048 } 7049 } 7050 7051 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7052 synchronized (this) { 7053 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7054 if (!isDebuggable) { 7055 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7056 throw new SecurityException("Process not debuggable: " + app.packageName); 7057 } 7058 } 7059 7060 mOpenGlTraceApp = processName; 7061 } 7062 } 7063 7064 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7065 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7066 synchronized (this) { 7067 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7068 if (!isDebuggable) { 7069 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7070 throw new SecurityException("Process not debuggable: " + app.packageName); 7071 } 7072 } 7073 mProfileApp = processName; 7074 mProfileFile = profileFile; 7075 if (mProfileFd != null) { 7076 try { 7077 mProfileFd.close(); 7078 } catch (IOException e) { 7079 } 7080 mProfileFd = null; 7081 } 7082 mProfileFd = profileFd; 7083 mProfileType = 0; 7084 mAutoStopProfiler = autoStopProfiler; 7085 } 7086 } 7087 7088 public void setAlwaysFinish(boolean enabled) { 7089 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7090 "setAlwaysFinish()"); 7091 7092 Settings.System.putInt( 7093 mContext.getContentResolver(), 7094 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7095 7096 synchronized (this) { 7097 mAlwaysFinishActivities = enabled; 7098 } 7099 } 7100 7101 public void setActivityController(IActivityController controller) { 7102 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7103 "setActivityController()"); 7104 synchronized (this) { 7105 mController = controller; 7106 } 7107 } 7108 7109 public boolean isUserAMonkey() { 7110 // For now the fact that there is a controller implies 7111 // we have a monkey. 7112 synchronized (this) { 7113 return mController != null; 7114 } 7115 } 7116 7117 public void registerProcessObserver(IProcessObserver observer) { 7118 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7119 "registerProcessObserver()"); 7120 synchronized (this) { 7121 mProcessObservers.register(observer); 7122 } 7123 } 7124 7125 public void unregisterProcessObserver(IProcessObserver observer) { 7126 synchronized (this) { 7127 mProcessObservers.unregister(observer); 7128 } 7129 } 7130 7131 public void setImmersive(IBinder token, boolean immersive) { 7132 synchronized(this) { 7133 ActivityRecord r = mMainStack.isInStackLocked(token); 7134 if (r == null) { 7135 throw new IllegalArgumentException(); 7136 } 7137 r.immersive = immersive; 7138 } 7139 } 7140 7141 public boolean isImmersive(IBinder token) { 7142 synchronized (this) { 7143 ActivityRecord r = mMainStack.isInStackLocked(token); 7144 if (r == null) { 7145 throw new IllegalArgumentException(); 7146 } 7147 return r.immersive; 7148 } 7149 } 7150 7151 public boolean isTopActivityImmersive() { 7152 enforceNotIsolatedCaller("startActivity"); 7153 synchronized (this) { 7154 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7155 return (r != null) ? r.immersive : false; 7156 } 7157 } 7158 7159 public final void enterSafeMode() { 7160 synchronized(this) { 7161 // It only makes sense to do this before the system is ready 7162 // and started launching other packages. 7163 if (!mSystemReady) { 7164 try { 7165 AppGlobals.getPackageManager().enterSafeMode(); 7166 } catch (RemoteException e) { 7167 } 7168 } 7169 } 7170 } 7171 7172 public final void showSafeModeOverlay() { 7173 View v = LayoutInflater.from(mContext).inflate( 7174 com.android.internal.R.layout.safe_mode, null); 7175 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7176 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7177 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7178 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7179 lp.gravity = Gravity.BOTTOM | Gravity.START; 7180 lp.format = v.getBackground().getOpacity(); 7181 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7182 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7183 ((WindowManager)mContext.getSystemService( 7184 Context.WINDOW_SERVICE)).addView(v, lp); 7185 } 7186 7187 public void noteWakeupAlarm(IIntentSender sender) { 7188 if (!(sender instanceof PendingIntentRecord)) { 7189 return; 7190 } 7191 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7192 synchronized (stats) { 7193 if (mBatteryStatsService.isOnBattery()) { 7194 mBatteryStatsService.enforceCallingPermission(); 7195 PendingIntentRecord rec = (PendingIntentRecord)sender; 7196 int MY_UID = Binder.getCallingUid(); 7197 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7198 BatteryStatsImpl.Uid.Pkg pkg = 7199 stats.getPackageStatsLocked(uid, rec.key.packageName); 7200 pkg.incWakeupsLocked(); 7201 } 7202 } 7203 } 7204 7205 public boolean killPids(int[] pids, String pReason, boolean secure) { 7206 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7207 throw new SecurityException("killPids only available to the system"); 7208 } 7209 String reason = (pReason == null) ? "Unknown" : pReason; 7210 // XXX Note: don't acquire main activity lock here, because the window 7211 // manager calls in with its locks held. 7212 7213 boolean killed = false; 7214 synchronized (mPidsSelfLocked) { 7215 int[] types = new int[pids.length]; 7216 int worstType = 0; 7217 for (int i=0; i<pids.length; i++) { 7218 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7219 if (proc != null) { 7220 int type = proc.setAdj; 7221 types[i] = type; 7222 if (type > worstType) { 7223 worstType = type; 7224 } 7225 } 7226 } 7227 7228 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7229 // then constrain it so we will kill all hidden procs. 7230 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7231 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7232 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7233 } 7234 7235 // If this is not a secure call, don't let it kill processes that 7236 // are important. 7237 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7238 worstType = ProcessList.SERVICE_ADJ; 7239 } 7240 7241 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7242 for (int i=0; i<pids.length; i++) { 7243 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7244 if (proc == null) { 7245 continue; 7246 } 7247 int adj = proc.setAdj; 7248 if (adj >= worstType && !proc.killedBackground) { 7249 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7250 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7251 proc.processName, adj, reason); 7252 killed = true; 7253 proc.killedBackground = true; 7254 Process.killProcessQuiet(pids[i]); 7255 } 7256 } 7257 } 7258 return killed; 7259 } 7260 7261 @Override 7262 public boolean killProcessesBelowForeground(String reason) { 7263 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7264 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7265 } 7266 7267 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7268 } 7269 7270 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7271 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7272 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7273 } 7274 7275 boolean killed = false; 7276 synchronized (mPidsSelfLocked) { 7277 final int size = mPidsSelfLocked.size(); 7278 for (int i = 0; i < size; i++) { 7279 final int pid = mPidsSelfLocked.keyAt(i); 7280 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7281 if (proc == null) continue; 7282 7283 final int adj = proc.setAdj; 7284 if (adj > belowAdj && !proc.killedBackground) { 7285 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7286 EventLog.writeEvent( 7287 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7288 killed = true; 7289 proc.killedBackground = true; 7290 Process.killProcessQuiet(pid); 7291 } 7292 } 7293 } 7294 return killed; 7295 } 7296 7297 public final void startRunning(String pkg, String cls, String action, 7298 String data) { 7299 synchronized(this) { 7300 if (mStartRunning) { 7301 return; 7302 } 7303 mStartRunning = true; 7304 mTopComponent = pkg != null && cls != null 7305 ? new ComponentName(pkg, cls) : null; 7306 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7307 mTopData = data; 7308 if (!mSystemReady) { 7309 return; 7310 } 7311 } 7312 7313 systemReady(null); 7314 } 7315 7316 private void retrieveSettings() { 7317 final ContentResolver resolver = mContext.getContentResolver(); 7318 String debugApp = Settings.System.getString( 7319 resolver, Settings.System.DEBUG_APP); 7320 boolean waitForDebugger = Settings.System.getInt( 7321 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7322 boolean alwaysFinishActivities = Settings.System.getInt( 7323 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7324 7325 Configuration configuration = new Configuration(); 7326 Settings.System.getConfiguration(resolver, configuration); 7327 7328 synchronized (this) { 7329 mDebugApp = mOrigDebugApp = debugApp; 7330 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7331 mAlwaysFinishActivities = alwaysFinishActivities; 7332 // This happens before any activities are started, so we can 7333 // change mConfiguration in-place. 7334 updateConfigurationLocked(configuration, null, false, true); 7335 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7336 } 7337 } 7338 7339 public boolean testIsSystemReady() { 7340 // no need to synchronize(this) just to read & return the value 7341 return mSystemReady; 7342 } 7343 7344 private static File getCalledPreBootReceiversFile() { 7345 File dataDir = Environment.getDataDirectory(); 7346 File systemDir = new File(dataDir, "system"); 7347 File fname = new File(systemDir, "called_pre_boots.dat"); 7348 return fname; 7349 } 7350 7351 static final int LAST_DONE_VERSION = 10000; 7352 7353 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7354 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7355 File file = getCalledPreBootReceiversFile(); 7356 FileInputStream fis = null; 7357 try { 7358 fis = new FileInputStream(file); 7359 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7360 int fvers = dis.readInt(); 7361 if (fvers == LAST_DONE_VERSION) { 7362 String vers = dis.readUTF(); 7363 String codename = dis.readUTF(); 7364 String build = dis.readUTF(); 7365 if (android.os.Build.VERSION.RELEASE.equals(vers) 7366 && android.os.Build.VERSION.CODENAME.equals(codename) 7367 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7368 int num = dis.readInt(); 7369 while (num > 0) { 7370 num--; 7371 String pkg = dis.readUTF(); 7372 String cls = dis.readUTF(); 7373 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7374 } 7375 } 7376 } 7377 } catch (FileNotFoundException e) { 7378 } catch (IOException e) { 7379 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7380 } finally { 7381 if (fis != null) { 7382 try { 7383 fis.close(); 7384 } catch (IOException e) { 7385 } 7386 } 7387 } 7388 return lastDoneReceivers; 7389 } 7390 7391 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7392 File file = getCalledPreBootReceiversFile(); 7393 FileOutputStream fos = null; 7394 DataOutputStream dos = null; 7395 try { 7396 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7397 fos = new FileOutputStream(file); 7398 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7399 dos.writeInt(LAST_DONE_VERSION); 7400 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7401 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7402 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7403 dos.writeInt(list.size()); 7404 for (int i=0; i<list.size(); i++) { 7405 dos.writeUTF(list.get(i).getPackageName()); 7406 dos.writeUTF(list.get(i).getClassName()); 7407 } 7408 } catch (IOException e) { 7409 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7410 file.delete(); 7411 } finally { 7412 FileUtils.sync(fos); 7413 if (dos != null) { 7414 try { 7415 dos.close(); 7416 } catch (IOException e) { 7417 // TODO Auto-generated catch block 7418 e.printStackTrace(); 7419 } 7420 } 7421 } 7422 } 7423 7424 public void systemReady(final Runnable goingCallback) { 7425 synchronized(this) { 7426 if (mSystemReady) { 7427 if (goingCallback != null) goingCallback.run(); 7428 return; 7429 } 7430 7431 // Check to see if there are any update receivers to run. 7432 if (!mDidUpdate) { 7433 if (mWaitingUpdate) { 7434 return; 7435 } 7436 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7437 List<ResolveInfo> ris = null; 7438 try { 7439 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7440 intent, null, 0, 0); 7441 } catch (RemoteException e) { 7442 } 7443 if (ris != null) { 7444 for (int i=ris.size()-1; i>=0; i--) { 7445 if ((ris.get(i).activityInfo.applicationInfo.flags 7446 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7447 ris.remove(i); 7448 } 7449 } 7450 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7451 7452 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7453 7454 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7455 for (int i=0; i<ris.size(); i++) { 7456 ActivityInfo ai = ris.get(i).activityInfo; 7457 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7458 if (lastDoneReceivers.contains(comp)) { 7459 ris.remove(i); 7460 i--; 7461 } 7462 } 7463 7464 for (int i=0; i<ris.size(); i++) { 7465 ActivityInfo ai = ris.get(i).activityInfo; 7466 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7467 doneReceivers.add(comp); 7468 intent.setComponent(comp); 7469 IIntentReceiver finisher = null; 7470 if (i == ris.size()-1) { 7471 finisher = new IIntentReceiver.Stub() { 7472 public void performReceive(Intent intent, int resultCode, 7473 String data, Bundle extras, boolean ordered, 7474 boolean sticky) { 7475 // The raw IIntentReceiver interface is called 7476 // with the AM lock held, so redispatch to 7477 // execute our code without the lock. 7478 mHandler.post(new Runnable() { 7479 public void run() { 7480 synchronized (ActivityManagerService.this) { 7481 mDidUpdate = true; 7482 } 7483 writeLastDonePreBootReceivers(doneReceivers); 7484 showBootMessage(mContext.getText( 7485 R.string.android_upgrading_complete), 7486 false); 7487 systemReady(goingCallback); 7488 } 7489 }); 7490 } 7491 }; 7492 } 7493 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7494 /* TODO: Send this to all users */ 7495 broadcastIntentLocked(null, null, intent, null, finisher, 7496 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7497 0 /* UserId zero */); 7498 if (finisher != null) { 7499 mWaitingUpdate = true; 7500 } 7501 } 7502 } 7503 if (mWaitingUpdate) { 7504 return; 7505 } 7506 mDidUpdate = true; 7507 } 7508 7509 mSystemReady = true; 7510 if (!mStartRunning) { 7511 return; 7512 } 7513 } 7514 7515 ArrayList<ProcessRecord> procsToKill = null; 7516 synchronized(mPidsSelfLocked) { 7517 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7518 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7519 if (!isAllowedWhileBooting(proc.info)){ 7520 if (procsToKill == null) { 7521 procsToKill = new ArrayList<ProcessRecord>(); 7522 } 7523 procsToKill.add(proc); 7524 } 7525 } 7526 } 7527 7528 synchronized(this) { 7529 if (procsToKill != null) { 7530 for (int i=procsToKill.size()-1; i>=0; i--) { 7531 ProcessRecord proc = procsToKill.get(i); 7532 Slog.i(TAG, "Removing system update proc: " + proc); 7533 removeProcessLocked(proc, true, false, "system update done"); 7534 } 7535 } 7536 7537 // Now that we have cleaned up any update processes, we 7538 // are ready to start launching real processes and know that 7539 // we won't trample on them any more. 7540 mProcessesReady = true; 7541 } 7542 7543 Slog.i(TAG, "System now ready"); 7544 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7545 SystemClock.uptimeMillis()); 7546 7547 synchronized(this) { 7548 // Make sure we have no pre-ready processes sitting around. 7549 7550 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7551 ResolveInfo ri = mContext.getPackageManager() 7552 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7553 STOCK_PM_FLAGS); 7554 CharSequence errorMsg = null; 7555 if (ri != null) { 7556 ActivityInfo ai = ri.activityInfo; 7557 ApplicationInfo app = ai.applicationInfo; 7558 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7559 mTopAction = Intent.ACTION_FACTORY_TEST; 7560 mTopData = null; 7561 mTopComponent = new ComponentName(app.packageName, 7562 ai.name); 7563 } else { 7564 errorMsg = mContext.getResources().getText( 7565 com.android.internal.R.string.factorytest_not_system); 7566 } 7567 } else { 7568 errorMsg = mContext.getResources().getText( 7569 com.android.internal.R.string.factorytest_no_action); 7570 } 7571 if (errorMsg != null) { 7572 mTopAction = null; 7573 mTopData = null; 7574 mTopComponent = null; 7575 Message msg = Message.obtain(); 7576 msg.what = SHOW_FACTORY_ERROR_MSG; 7577 msg.getData().putCharSequence("msg", errorMsg); 7578 mHandler.sendMessage(msg); 7579 } 7580 } 7581 } 7582 7583 retrieveSettings(); 7584 7585 if (goingCallback != null) goingCallback.run(); 7586 7587 synchronized (this) { 7588 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7589 try { 7590 List apps = AppGlobals.getPackageManager(). 7591 getPersistentApplications(STOCK_PM_FLAGS); 7592 if (apps != null) { 7593 int N = apps.size(); 7594 int i; 7595 for (i=0; i<N; i++) { 7596 ApplicationInfo info 7597 = (ApplicationInfo)apps.get(i); 7598 if (info != null && 7599 !info.packageName.equals("android")) { 7600 addAppLocked(info, false); 7601 } 7602 } 7603 } 7604 } catch (RemoteException ex) { 7605 // pm is in same process, this will never happen. 7606 } 7607 } 7608 7609 // Start up initial activity. 7610 mBooting = true; 7611 7612 try { 7613 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7614 Message msg = Message.obtain(); 7615 msg.what = SHOW_UID_ERROR_MSG; 7616 mHandler.sendMessage(msg); 7617 } 7618 } catch (RemoteException e) { 7619 } 7620 7621 mMainStack.resumeTopActivityLocked(null); 7622 } 7623 } 7624 7625 private boolean makeAppCrashingLocked(ProcessRecord app, 7626 String shortMsg, String longMsg, String stackTrace) { 7627 app.crashing = true; 7628 app.crashingReport = generateProcessError(app, 7629 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7630 startAppProblemLocked(app); 7631 app.stopFreezingAllLocked(); 7632 return handleAppCrashLocked(app); 7633 } 7634 7635 private void makeAppNotRespondingLocked(ProcessRecord app, 7636 String activity, String shortMsg, String longMsg) { 7637 app.notResponding = true; 7638 app.notRespondingReport = generateProcessError(app, 7639 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7640 activity, shortMsg, longMsg, null); 7641 startAppProblemLocked(app); 7642 app.stopFreezingAllLocked(); 7643 } 7644 7645 /** 7646 * Generate a process error record, suitable for attachment to a ProcessRecord. 7647 * 7648 * @param app The ProcessRecord in which the error occurred. 7649 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7650 * ActivityManager.AppErrorStateInfo 7651 * @param activity The activity associated with the crash, if known. 7652 * @param shortMsg Short message describing the crash. 7653 * @param longMsg Long message describing the crash. 7654 * @param stackTrace Full crash stack trace, may be null. 7655 * 7656 * @return Returns a fully-formed AppErrorStateInfo record. 7657 */ 7658 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7659 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7660 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7661 7662 report.condition = condition; 7663 report.processName = app.processName; 7664 report.pid = app.pid; 7665 report.uid = app.info.uid; 7666 report.tag = activity; 7667 report.shortMsg = shortMsg; 7668 report.longMsg = longMsg; 7669 report.stackTrace = stackTrace; 7670 7671 return report; 7672 } 7673 7674 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7675 synchronized (this) { 7676 app.crashing = false; 7677 app.crashingReport = null; 7678 app.notResponding = false; 7679 app.notRespondingReport = null; 7680 if (app.anrDialog == fromDialog) { 7681 app.anrDialog = null; 7682 } 7683 if (app.waitDialog == fromDialog) { 7684 app.waitDialog = null; 7685 } 7686 if (app.pid > 0 && app.pid != MY_PID) { 7687 handleAppCrashLocked(app); 7688 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7689 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7690 app.processName, app.setAdj, "user's request after error"); 7691 Process.killProcessQuiet(app.pid); 7692 } 7693 } 7694 } 7695 7696 private boolean handleAppCrashLocked(ProcessRecord app) { 7697 if (mHeadless) { 7698 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7699 return false; 7700 } 7701 long now = SystemClock.uptimeMillis(); 7702 7703 Long crashTime; 7704 if (!app.isolated) { 7705 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7706 } else { 7707 crashTime = null; 7708 } 7709 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7710 // This process loses! 7711 Slog.w(TAG, "Process " + app.info.processName 7712 + " has crashed too many times: killing!"); 7713 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7714 app.info.processName, app.uid); 7715 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7716 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7717 if (r.app == app) { 7718 Slog.w(TAG, " Force finishing activity " 7719 + r.intent.getComponent().flattenToShortString()); 7720 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7721 } 7722 } 7723 if (!app.persistent) { 7724 // We don't want to start this process again until the user 7725 // explicitly does so... but for persistent process, we really 7726 // need to keep it running. If a persistent process is actually 7727 // repeatedly crashing, then badness for everyone. 7728 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7729 app.info.processName); 7730 if (!app.isolated) { 7731 // XXX We don't have a way to mark isolated processes 7732 // as bad, since they don't have a peristent identity. 7733 mBadProcesses.put(app.info.processName, app.uid, now); 7734 mProcessCrashTimes.remove(app.info.processName, app.uid); 7735 } 7736 app.bad = true; 7737 app.removed = true; 7738 // Don't let services in this process be restarted and potentially 7739 // annoy the user repeatedly. Unless it is persistent, since those 7740 // processes run critical code. 7741 removeProcessLocked(app, false, false, "crash"); 7742 mMainStack.resumeTopActivityLocked(null); 7743 return false; 7744 } 7745 mMainStack.resumeTopActivityLocked(null); 7746 } else { 7747 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7748 if (r != null && r.app == app) { 7749 // If the top running activity is from this crashing 7750 // process, then terminate it to avoid getting in a loop. 7751 Slog.w(TAG, " Force finishing activity " 7752 + r.intent.getComponent().flattenToShortString()); 7753 int index = mMainStack.indexOfActivityLocked(r); 7754 r.stack.finishActivityLocked(r, index, 7755 Activity.RESULT_CANCELED, null, "crashed"); 7756 // Also terminate any activities below it that aren't yet 7757 // stopped, to avoid a situation where one will get 7758 // re-start our crashing activity once it gets resumed again. 7759 index--; 7760 if (index >= 0) { 7761 r = (ActivityRecord)mMainStack.mHistory.get(index); 7762 if (r.state == ActivityState.RESUMED 7763 || r.state == ActivityState.PAUSING 7764 || r.state == ActivityState.PAUSED) { 7765 if (!r.isHomeActivity || mHomeProcess != r.app) { 7766 Slog.w(TAG, " Force finishing activity " 7767 + r.intent.getComponent().flattenToShortString()); 7768 r.stack.finishActivityLocked(r, index, 7769 Activity.RESULT_CANCELED, null, "crashed"); 7770 } 7771 } 7772 } 7773 } 7774 } 7775 7776 // Bump up the crash count of any services currently running in the proc. 7777 if (app.services.size() != 0) { 7778 // Any services running in the application need to be placed 7779 // back in the pending list. 7780 Iterator<ServiceRecord> it = app.services.iterator(); 7781 while (it.hasNext()) { 7782 ServiceRecord sr = it.next(); 7783 sr.crashCount++; 7784 } 7785 } 7786 7787 // If the crashing process is what we consider to be the "home process" and it has been 7788 // replaced by a third-party app, clear the package preferred activities from packages 7789 // with a home activity running in the process to prevent a repeatedly crashing app 7790 // from blocking the user to manually clear the list. 7791 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7792 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7793 Iterator it = mHomeProcess.activities.iterator(); 7794 while (it.hasNext()) { 7795 ActivityRecord r = (ActivityRecord)it.next(); 7796 if (r.isHomeActivity) { 7797 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7798 try { 7799 ActivityThread.getPackageManager() 7800 .clearPackagePreferredActivities(r.packageName); 7801 } catch (RemoteException c) { 7802 // pm is in same process, this will never happen. 7803 } 7804 } 7805 } 7806 } 7807 7808 if (!app.isolated) { 7809 // XXX Can't keep track of crash times for isolated processes, 7810 // because they don't have a perisistent identity. 7811 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7812 } 7813 7814 return true; 7815 } 7816 7817 void startAppProblemLocked(ProcessRecord app) { 7818 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7819 mContext, app.info.packageName, app.info.flags); 7820 skipCurrentReceiverLocked(app); 7821 } 7822 7823 void skipCurrentReceiverLocked(ProcessRecord app) { 7824 for (BroadcastQueue queue : mBroadcastQueues) { 7825 queue.skipCurrentReceiverLocked(app); 7826 } 7827 } 7828 7829 /** 7830 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7831 * The application process will exit immediately after this call returns. 7832 * @param app object of the crashing app, null for the system server 7833 * @param crashInfo describing the exception 7834 */ 7835 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7836 ProcessRecord r = findAppProcess(app, "Crash"); 7837 final String processName = app == null ? "system_server" 7838 : (r == null ? "unknown" : r.processName); 7839 7840 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7841 processName, 7842 r == null ? -1 : r.info.flags, 7843 crashInfo.exceptionClassName, 7844 crashInfo.exceptionMessage, 7845 crashInfo.throwFileName, 7846 crashInfo.throwLineNumber); 7847 7848 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7849 7850 crashApplication(r, crashInfo); 7851 } 7852 7853 public void handleApplicationStrictModeViolation( 7854 IBinder app, 7855 int violationMask, 7856 StrictMode.ViolationInfo info) { 7857 ProcessRecord r = findAppProcess(app, "StrictMode"); 7858 if (r == null) { 7859 return; 7860 } 7861 7862 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7863 Integer stackFingerprint = info.hashCode(); 7864 boolean logIt = true; 7865 synchronized (mAlreadyLoggedViolatedStacks) { 7866 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7867 logIt = false; 7868 // TODO: sub-sample into EventLog for these, with 7869 // the info.durationMillis? Then we'd get 7870 // the relative pain numbers, without logging all 7871 // the stack traces repeatedly. We'd want to do 7872 // likewise in the client code, which also does 7873 // dup suppression, before the Binder call. 7874 } else { 7875 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7876 mAlreadyLoggedViolatedStacks.clear(); 7877 } 7878 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7879 } 7880 } 7881 if (logIt) { 7882 logStrictModeViolationToDropBox(r, info); 7883 } 7884 } 7885 7886 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7887 AppErrorResult result = new AppErrorResult(); 7888 synchronized (this) { 7889 final long origId = Binder.clearCallingIdentity(); 7890 7891 Message msg = Message.obtain(); 7892 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7893 HashMap<String, Object> data = new HashMap<String, Object>(); 7894 data.put("result", result); 7895 data.put("app", r); 7896 data.put("violationMask", violationMask); 7897 data.put("info", info); 7898 msg.obj = data; 7899 mHandler.sendMessage(msg); 7900 7901 Binder.restoreCallingIdentity(origId); 7902 } 7903 int res = result.get(); 7904 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7905 } 7906 } 7907 7908 // Depending on the policy in effect, there could be a bunch of 7909 // these in quick succession so we try to batch these together to 7910 // minimize disk writes, number of dropbox entries, and maximize 7911 // compression, by having more fewer, larger records. 7912 private void logStrictModeViolationToDropBox( 7913 ProcessRecord process, 7914 StrictMode.ViolationInfo info) { 7915 if (info == null) { 7916 return; 7917 } 7918 final boolean isSystemApp = process == null || 7919 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7920 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7921 final String processName = process == null ? "unknown" : process.processName; 7922 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7923 final DropBoxManager dbox = (DropBoxManager) 7924 mContext.getSystemService(Context.DROPBOX_SERVICE); 7925 7926 // Exit early if the dropbox isn't configured to accept this report type. 7927 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7928 7929 boolean bufferWasEmpty; 7930 boolean needsFlush; 7931 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7932 synchronized (sb) { 7933 bufferWasEmpty = sb.length() == 0; 7934 appendDropBoxProcessHeaders(process, processName, sb); 7935 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7936 sb.append("System-App: ").append(isSystemApp).append("\n"); 7937 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7938 if (info.violationNumThisLoop != 0) { 7939 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7940 } 7941 if (info.numAnimationsRunning != 0) { 7942 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7943 } 7944 if (info.broadcastIntentAction != null) { 7945 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7946 } 7947 if (info.durationMillis != -1) { 7948 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7949 } 7950 if (info.numInstances != -1) { 7951 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7952 } 7953 if (info.tags != null) { 7954 for (String tag : info.tags) { 7955 sb.append("Span-Tag: ").append(tag).append("\n"); 7956 } 7957 } 7958 sb.append("\n"); 7959 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7960 sb.append(info.crashInfo.stackTrace); 7961 } 7962 sb.append("\n"); 7963 7964 // Only buffer up to ~64k. Various logging bits truncate 7965 // things at 128k. 7966 needsFlush = (sb.length() > 64 * 1024); 7967 } 7968 7969 // Flush immediately if the buffer's grown too large, or this 7970 // is a non-system app. Non-system apps are isolated with a 7971 // different tag & policy and not batched. 7972 // 7973 // Batching is useful during internal testing with 7974 // StrictMode settings turned up high. Without batching, 7975 // thousands of separate files could be created on boot. 7976 if (!isSystemApp || needsFlush) { 7977 new Thread("Error dump: " + dropboxTag) { 7978 @Override 7979 public void run() { 7980 String report; 7981 synchronized (sb) { 7982 report = sb.toString(); 7983 sb.delete(0, sb.length()); 7984 sb.trimToSize(); 7985 } 7986 if (report.length() != 0) { 7987 dbox.addText(dropboxTag, report); 7988 } 7989 } 7990 }.start(); 7991 return; 7992 } 7993 7994 // System app batching: 7995 if (!bufferWasEmpty) { 7996 // An existing dropbox-writing thread is outstanding, so 7997 // we don't need to start it up. The existing thread will 7998 // catch the buffer appends we just did. 7999 return; 8000 } 8001 8002 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8003 // (After this point, we shouldn't access AMS internal data structures.) 8004 new Thread("Error dump: " + dropboxTag) { 8005 @Override 8006 public void run() { 8007 // 5 second sleep to let stacks arrive and be batched together 8008 try { 8009 Thread.sleep(5000); // 5 seconds 8010 } catch (InterruptedException e) {} 8011 8012 String errorReport; 8013 synchronized (mStrictModeBuffer) { 8014 errorReport = mStrictModeBuffer.toString(); 8015 if (errorReport.length() == 0) { 8016 return; 8017 } 8018 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8019 mStrictModeBuffer.trimToSize(); 8020 } 8021 dbox.addText(dropboxTag, errorReport); 8022 } 8023 }.start(); 8024 } 8025 8026 /** 8027 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8028 * @param app object of the crashing app, null for the system server 8029 * @param tag reported by the caller 8030 * @param crashInfo describing the context of the error 8031 * @return true if the process should exit immediately (WTF is fatal) 8032 */ 8033 public boolean handleApplicationWtf(IBinder app, String tag, 8034 ApplicationErrorReport.CrashInfo crashInfo) { 8035 ProcessRecord r = findAppProcess(app, "WTF"); 8036 final String processName = app == null ? "system_server" 8037 : (r == null ? "unknown" : r.processName); 8038 8039 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8040 processName, 8041 r == null ? -1 : r.info.flags, 8042 tag, crashInfo.exceptionMessage); 8043 8044 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8045 8046 if (r != null && r.pid != Process.myPid() && 8047 Settings.Secure.getInt(mContext.getContentResolver(), 8048 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8049 crashApplication(r, crashInfo); 8050 return true; 8051 } else { 8052 return false; 8053 } 8054 } 8055 8056 /** 8057 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8058 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8059 */ 8060 private ProcessRecord findAppProcess(IBinder app, String reason) { 8061 if (app == null) { 8062 return null; 8063 } 8064 8065 synchronized (this) { 8066 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8067 final int NA = apps.size(); 8068 for (int ia=0; ia<NA; ia++) { 8069 ProcessRecord p = apps.valueAt(ia); 8070 if (p.thread != null && p.thread.asBinder() == app) { 8071 return p; 8072 } 8073 } 8074 } 8075 8076 Slog.w(TAG, "Can't find mystery application for " + reason 8077 + " from pid=" + Binder.getCallingPid() 8078 + " uid=" + Binder.getCallingUid() + ": " + app); 8079 return null; 8080 } 8081 } 8082 8083 /** 8084 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8085 * to append various headers to the dropbox log text. 8086 */ 8087 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8088 StringBuilder sb) { 8089 // Watchdog thread ends up invoking this function (with 8090 // a null ProcessRecord) to add the stack file to dropbox. 8091 // Do not acquire a lock on this (am) in such cases, as it 8092 // could cause a potential deadlock, if and when watchdog 8093 // is invoked due to unavailability of lock on am and it 8094 // would prevent watchdog from killing system_server. 8095 if (process == null) { 8096 sb.append("Process: ").append(processName).append("\n"); 8097 return; 8098 } 8099 // Note: ProcessRecord 'process' is guarded by the service 8100 // instance. (notably process.pkgList, which could otherwise change 8101 // concurrently during execution of this method) 8102 synchronized (this) { 8103 sb.append("Process: ").append(processName).append("\n"); 8104 int flags = process.info.flags; 8105 IPackageManager pm = AppGlobals.getPackageManager(); 8106 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8107 for (String pkg : process.pkgList) { 8108 sb.append("Package: ").append(pkg); 8109 try { 8110 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8111 if (pi != null) { 8112 sb.append(" v").append(pi.versionCode); 8113 if (pi.versionName != null) { 8114 sb.append(" (").append(pi.versionName).append(")"); 8115 } 8116 } 8117 } catch (RemoteException e) { 8118 Slog.e(TAG, "Error getting package info: " + pkg, e); 8119 } 8120 sb.append("\n"); 8121 } 8122 } 8123 } 8124 8125 private static String processClass(ProcessRecord process) { 8126 if (process == null || process.pid == MY_PID) { 8127 return "system_server"; 8128 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8129 return "system_app"; 8130 } else { 8131 return "data_app"; 8132 } 8133 } 8134 8135 /** 8136 * Write a description of an error (crash, WTF, ANR) to the drop box. 8137 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8138 * @param process which caused the error, null means the system server 8139 * @param activity which triggered the error, null if unknown 8140 * @param parent activity related to the error, null if unknown 8141 * @param subject line related to the error, null if absent 8142 * @param report in long form describing the error, null if absent 8143 * @param logFile to include in the report, null if none 8144 * @param crashInfo giving an application stack trace, null if absent 8145 */ 8146 public void addErrorToDropBox(String eventType, 8147 ProcessRecord process, String processName, ActivityRecord activity, 8148 ActivityRecord parent, String subject, 8149 final String report, final File logFile, 8150 final ApplicationErrorReport.CrashInfo crashInfo) { 8151 // NOTE -- this must never acquire the ActivityManagerService lock, 8152 // otherwise the watchdog may be prevented from resetting the system. 8153 8154 final String dropboxTag = processClass(process) + "_" + eventType; 8155 final DropBoxManager dbox = (DropBoxManager) 8156 mContext.getSystemService(Context.DROPBOX_SERVICE); 8157 8158 // Exit early if the dropbox isn't configured to accept this report type. 8159 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8160 8161 final StringBuilder sb = new StringBuilder(1024); 8162 appendDropBoxProcessHeaders(process, processName, sb); 8163 if (activity != null) { 8164 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8165 } 8166 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8167 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8168 } 8169 if (parent != null && parent != activity) { 8170 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8171 } 8172 if (subject != null) { 8173 sb.append("Subject: ").append(subject).append("\n"); 8174 } 8175 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8176 if (Debug.isDebuggerConnected()) { 8177 sb.append("Debugger: Connected\n"); 8178 } 8179 sb.append("\n"); 8180 8181 // Do the rest in a worker thread to avoid blocking the caller on I/O 8182 // (After this point, we shouldn't access AMS internal data structures.) 8183 Thread worker = new Thread("Error dump: " + dropboxTag) { 8184 @Override 8185 public void run() { 8186 if (report != null) { 8187 sb.append(report); 8188 } 8189 if (logFile != null) { 8190 try { 8191 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8192 } catch (IOException e) { 8193 Slog.e(TAG, "Error reading " + logFile, e); 8194 } 8195 } 8196 if (crashInfo != null && crashInfo.stackTrace != null) { 8197 sb.append(crashInfo.stackTrace); 8198 } 8199 8200 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8201 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8202 if (lines > 0) { 8203 sb.append("\n"); 8204 8205 // Merge several logcat streams, and take the last N lines 8206 InputStreamReader input = null; 8207 try { 8208 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8209 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8210 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8211 8212 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8213 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8214 input = new InputStreamReader(logcat.getInputStream()); 8215 8216 int num; 8217 char[] buf = new char[8192]; 8218 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8219 } catch (IOException e) { 8220 Slog.e(TAG, "Error running logcat", e); 8221 } finally { 8222 if (input != null) try { input.close(); } catch (IOException e) {} 8223 } 8224 } 8225 8226 dbox.addText(dropboxTag, sb.toString()); 8227 } 8228 }; 8229 8230 if (process == null) { 8231 // If process is null, we are being called from some internal code 8232 // and may be about to die -- run this synchronously. 8233 worker.run(); 8234 } else { 8235 worker.start(); 8236 } 8237 } 8238 8239 /** 8240 * Bring up the "unexpected error" dialog box for a crashing app. 8241 * Deal with edge cases (intercepts from instrumented applications, 8242 * ActivityController, error intent receivers, that sort of thing). 8243 * @param r the application crashing 8244 * @param crashInfo describing the failure 8245 */ 8246 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8247 long timeMillis = System.currentTimeMillis(); 8248 String shortMsg = crashInfo.exceptionClassName; 8249 String longMsg = crashInfo.exceptionMessage; 8250 String stackTrace = crashInfo.stackTrace; 8251 if (shortMsg != null && longMsg != null) { 8252 longMsg = shortMsg + ": " + longMsg; 8253 } else if (shortMsg != null) { 8254 longMsg = shortMsg; 8255 } 8256 8257 AppErrorResult result = new AppErrorResult(); 8258 synchronized (this) { 8259 if (mController != null) { 8260 try { 8261 String name = r != null ? r.processName : null; 8262 int pid = r != null ? r.pid : Binder.getCallingPid(); 8263 if (!mController.appCrashed(name, pid, 8264 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8265 Slog.w(TAG, "Force-killing crashed app " + name 8266 + " at watcher's request"); 8267 Process.killProcess(pid); 8268 return; 8269 } 8270 } catch (RemoteException e) { 8271 mController = null; 8272 } 8273 } 8274 8275 final long origId = Binder.clearCallingIdentity(); 8276 8277 // If this process is running instrumentation, finish it. 8278 if (r != null && r.instrumentationClass != null) { 8279 Slog.w(TAG, "Error in app " + r.processName 8280 + " running instrumentation " + r.instrumentationClass + ":"); 8281 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8282 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8283 Bundle info = new Bundle(); 8284 info.putString("shortMsg", shortMsg); 8285 info.putString("longMsg", longMsg); 8286 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8287 Binder.restoreCallingIdentity(origId); 8288 return; 8289 } 8290 8291 // If we can't identify the process or it's already exceeded its crash quota, 8292 // quit right away without showing a crash dialog. 8293 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8294 Binder.restoreCallingIdentity(origId); 8295 return; 8296 } 8297 8298 Message msg = Message.obtain(); 8299 msg.what = SHOW_ERROR_MSG; 8300 HashMap data = new HashMap(); 8301 data.put("result", result); 8302 data.put("app", r); 8303 msg.obj = data; 8304 mHandler.sendMessage(msg); 8305 8306 Binder.restoreCallingIdentity(origId); 8307 } 8308 8309 int res = result.get(); 8310 8311 Intent appErrorIntent = null; 8312 synchronized (this) { 8313 if (r != null && !r.isolated) { 8314 // XXX Can't keep track of crash time for isolated processes, 8315 // since they don't have a persistent identity. 8316 mProcessCrashTimes.put(r.info.processName, r.uid, 8317 SystemClock.uptimeMillis()); 8318 } 8319 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8320 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8321 } 8322 } 8323 8324 if (appErrorIntent != null) { 8325 try { 8326 mContext.startActivity(appErrorIntent); 8327 } catch (ActivityNotFoundException e) { 8328 Slog.w(TAG, "bug report receiver dissappeared", e); 8329 } 8330 } 8331 } 8332 8333 Intent createAppErrorIntentLocked(ProcessRecord r, 8334 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8335 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8336 if (report == null) { 8337 return null; 8338 } 8339 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8340 result.setComponent(r.errorReportReceiver); 8341 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8342 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8343 return result; 8344 } 8345 8346 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8347 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8348 if (r.errorReportReceiver == null) { 8349 return null; 8350 } 8351 8352 if (!r.crashing && !r.notResponding) { 8353 return null; 8354 } 8355 8356 ApplicationErrorReport report = new ApplicationErrorReport(); 8357 report.packageName = r.info.packageName; 8358 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8359 report.processName = r.processName; 8360 report.time = timeMillis; 8361 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8362 8363 if (r.crashing) { 8364 report.type = ApplicationErrorReport.TYPE_CRASH; 8365 report.crashInfo = crashInfo; 8366 } else if (r.notResponding) { 8367 report.type = ApplicationErrorReport.TYPE_ANR; 8368 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8369 8370 report.anrInfo.activity = r.notRespondingReport.tag; 8371 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8372 report.anrInfo.info = r.notRespondingReport.longMsg; 8373 } 8374 8375 return report; 8376 } 8377 8378 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8379 enforceNotIsolatedCaller("getProcessesInErrorState"); 8380 // assume our apps are happy - lazy create the list 8381 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8382 8383 synchronized (this) { 8384 8385 // iterate across all processes 8386 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8387 ProcessRecord app = mLruProcesses.get(i); 8388 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8389 // This one's in trouble, so we'll generate a report for it 8390 // crashes are higher priority (in case there's a crash *and* an anr) 8391 ActivityManager.ProcessErrorStateInfo report = null; 8392 if (app.crashing) { 8393 report = app.crashingReport; 8394 } else if (app.notResponding) { 8395 report = app.notRespondingReport; 8396 } 8397 8398 if (report != null) { 8399 if (errList == null) { 8400 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8401 } 8402 errList.add(report); 8403 } else { 8404 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8405 " crashing = " + app.crashing + 8406 " notResponding = " + app.notResponding); 8407 } 8408 } 8409 } 8410 } 8411 8412 return errList; 8413 } 8414 8415 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8416 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8417 if (currApp != null) { 8418 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8419 } 8420 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8421 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8422 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8423 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8424 if (currApp != null) { 8425 currApp.lru = 0; 8426 } 8427 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8428 } else if (adj >= ProcessList.SERVICE_ADJ) { 8429 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8430 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8431 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8432 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8433 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8434 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8435 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8436 } else { 8437 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8438 } 8439 } 8440 8441 private void fillInProcMemInfo(ProcessRecord app, 8442 ActivityManager.RunningAppProcessInfo outInfo) { 8443 outInfo.pid = app.pid; 8444 outInfo.uid = app.info.uid; 8445 if (mHeavyWeightProcess == app) { 8446 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8447 } 8448 if (app.persistent) { 8449 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8450 } 8451 outInfo.lastTrimLevel = app.trimMemoryLevel; 8452 int adj = app.curAdj; 8453 outInfo.importance = oomAdjToImportance(adj, outInfo); 8454 outInfo.importanceReasonCode = app.adjTypeCode; 8455 } 8456 8457 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8458 enforceNotIsolatedCaller("getRunningAppProcesses"); 8459 // Lazy instantiation of list 8460 List<ActivityManager.RunningAppProcessInfo> runList = null; 8461 synchronized (this) { 8462 // Iterate across all processes 8463 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8464 ProcessRecord app = mLruProcesses.get(i); 8465 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8466 // Generate process state info for running application 8467 ActivityManager.RunningAppProcessInfo currApp = 8468 new ActivityManager.RunningAppProcessInfo(app.processName, 8469 app.pid, app.getPackageList()); 8470 fillInProcMemInfo(app, currApp); 8471 if (app.adjSource instanceof ProcessRecord) { 8472 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8473 currApp.importanceReasonImportance = oomAdjToImportance( 8474 app.adjSourceOom, null); 8475 } else if (app.adjSource instanceof ActivityRecord) { 8476 ActivityRecord r = (ActivityRecord)app.adjSource; 8477 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8478 } 8479 if (app.adjTarget instanceof ComponentName) { 8480 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8481 } 8482 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8483 // + " lru=" + currApp.lru); 8484 if (runList == null) { 8485 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8486 } 8487 runList.add(currApp); 8488 } 8489 } 8490 } 8491 return runList; 8492 } 8493 8494 public List<ApplicationInfo> getRunningExternalApplications() { 8495 enforceNotIsolatedCaller("getRunningExternalApplications"); 8496 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8497 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8498 if (runningApps != null && runningApps.size() > 0) { 8499 Set<String> extList = new HashSet<String>(); 8500 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8501 if (app.pkgList != null) { 8502 for (String pkg : app.pkgList) { 8503 extList.add(pkg); 8504 } 8505 } 8506 } 8507 IPackageManager pm = AppGlobals.getPackageManager(); 8508 for (String pkg : extList) { 8509 try { 8510 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8511 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8512 retList.add(info); 8513 } 8514 } catch (RemoteException e) { 8515 } 8516 } 8517 } 8518 return retList; 8519 } 8520 8521 @Override 8522 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8523 enforceNotIsolatedCaller("getMyMemoryState"); 8524 synchronized (this) { 8525 ProcessRecord proc; 8526 synchronized (mPidsSelfLocked) { 8527 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8528 } 8529 fillInProcMemInfo(proc, outInfo); 8530 } 8531 } 8532 8533 @Override 8534 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8535 if (checkCallingPermission(android.Manifest.permission.DUMP) 8536 != PackageManager.PERMISSION_GRANTED) { 8537 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8538 + Binder.getCallingPid() 8539 + ", uid=" + Binder.getCallingUid() 8540 + " without permission " 8541 + android.Manifest.permission.DUMP); 8542 return; 8543 } 8544 8545 boolean dumpAll = false; 8546 boolean dumpClient = false; 8547 String dumpPackage = null; 8548 8549 int opti = 0; 8550 while (opti < args.length) { 8551 String opt = args[opti]; 8552 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8553 break; 8554 } 8555 opti++; 8556 if ("-a".equals(opt)) { 8557 dumpAll = true; 8558 } else if ("-c".equals(opt)) { 8559 dumpClient = true; 8560 } else if ("-h".equals(opt)) { 8561 pw.println("Activity manager dump options:"); 8562 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8563 pw.println(" cmd may be one of:"); 8564 pw.println(" a[ctivities]: activity stack state"); 8565 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8566 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8567 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8568 pw.println(" o[om]: out of memory management"); 8569 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8570 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8571 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8572 pw.println(" service [COMP_SPEC]: service client-side state"); 8573 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8574 pw.println(" all: dump all activities"); 8575 pw.println(" top: dump the top activity"); 8576 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8577 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8578 pw.println(" a partial substring in a component name, a"); 8579 pw.println(" hex object identifier."); 8580 pw.println(" -a: include all available server state."); 8581 pw.println(" -c: include client state."); 8582 return; 8583 } else { 8584 pw.println("Unknown argument: " + opt + "; use -h for help"); 8585 } 8586 } 8587 8588 long origId = Binder.clearCallingIdentity(); 8589 boolean more = false; 8590 // Is the caller requesting to dump a particular piece of data? 8591 if (opti < args.length) { 8592 String cmd = args[opti]; 8593 opti++; 8594 if ("activities".equals(cmd) || "a".equals(cmd)) { 8595 synchronized (this) { 8596 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8597 } 8598 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8599 String[] newArgs; 8600 String name; 8601 if (opti >= args.length) { 8602 name = null; 8603 newArgs = EMPTY_STRING_ARRAY; 8604 } else { 8605 name = args[opti]; 8606 opti++; 8607 newArgs = new String[args.length - opti]; 8608 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8609 args.length - opti); 8610 } 8611 synchronized (this) { 8612 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8613 } 8614 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8615 String[] newArgs; 8616 String name; 8617 if (opti >= args.length) { 8618 name = null; 8619 newArgs = EMPTY_STRING_ARRAY; 8620 } else { 8621 name = args[opti]; 8622 opti++; 8623 newArgs = new String[args.length - opti]; 8624 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8625 args.length - opti); 8626 } 8627 synchronized (this) { 8628 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8629 } 8630 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8631 String[] newArgs; 8632 String name; 8633 if (opti >= args.length) { 8634 name = null; 8635 newArgs = EMPTY_STRING_ARRAY; 8636 } else { 8637 name = args[opti]; 8638 opti++; 8639 newArgs = new String[args.length - opti]; 8640 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8641 args.length - opti); 8642 } 8643 synchronized (this) { 8644 dumpProcessesLocked(fd, pw, args, opti, true, name); 8645 } 8646 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8647 synchronized (this) { 8648 dumpOomLocked(fd, pw, args, opti, true); 8649 } 8650 } else if ("provider".equals(cmd)) { 8651 String[] newArgs; 8652 String name; 8653 if (opti >= args.length) { 8654 name = null; 8655 newArgs = EMPTY_STRING_ARRAY; 8656 } else { 8657 name = args[opti]; 8658 opti++; 8659 newArgs = new String[args.length - opti]; 8660 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8661 } 8662 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8663 pw.println("No providers match: " + name); 8664 pw.println("Use -h for help."); 8665 } 8666 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8667 synchronized (this) { 8668 dumpProvidersLocked(fd, pw, args, opti, true, null); 8669 } 8670 } else if ("service".equals(cmd)) { 8671 String[] newArgs; 8672 String name; 8673 if (opti >= args.length) { 8674 name = null; 8675 newArgs = EMPTY_STRING_ARRAY; 8676 } else { 8677 name = args[opti]; 8678 opti++; 8679 newArgs = new String[args.length - opti]; 8680 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8681 args.length - opti); 8682 } 8683 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8684 pw.println("No services match: " + name); 8685 pw.println("Use -h for help."); 8686 } 8687 } else if ("package".equals(cmd)) { 8688 String[] newArgs; 8689 if (opti >= args.length) { 8690 pw.println("package: no package name specified"); 8691 pw.println("Use -h for help."); 8692 } else { 8693 dumpPackage = args[opti]; 8694 opti++; 8695 newArgs = new String[args.length - opti]; 8696 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8697 args.length - opti); 8698 args = newArgs; 8699 opti = 0; 8700 more = true; 8701 } 8702 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8703 synchronized (this) { 8704 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8705 } 8706 } else { 8707 // Dumping a single activity? 8708 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8709 pw.println("Bad activity command, or no activities match: " + cmd); 8710 pw.println("Use -h for help."); 8711 } 8712 } 8713 if (!more) { 8714 Binder.restoreCallingIdentity(origId); 8715 return; 8716 } 8717 } 8718 8719 // No piece of data specified, dump everything. 8720 synchronized (this) { 8721 boolean needSep; 8722 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8723 if (needSep) { 8724 pw.println(" "); 8725 } 8726 if (dumpAll) { 8727 pw.println("-------------------------------------------------------------------------------"); 8728 } 8729 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8730 if (needSep) { 8731 pw.println(" "); 8732 } 8733 if (dumpAll) { 8734 pw.println("-------------------------------------------------------------------------------"); 8735 } 8736 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8737 if (needSep) { 8738 pw.println(" "); 8739 } 8740 if (dumpAll) { 8741 pw.println("-------------------------------------------------------------------------------"); 8742 } 8743 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8744 if (needSep) { 8745 pw.println(" "); 8746 } 8747 if (dumpAll) { 8748 pw.println("-------------------------------------------------------------------------------"); 8749 } 8750 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8751 if (needSep) { 8752 pw.println(" "); 8753 } 8754 if (dumpAll) { 8755 pw.println("-------------------------------------------------------------------------------"); 8756 } 8757 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8758 } 8759 Binder.restoreCallingIdentity(origId); 8760 } 8761 8762 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8763 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8764 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8765 pw.println(" Main stack:"); 8766 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8767 dumpPackage); 8768 pw.println(" "); 8769 pw.println(" Running activities (most recent first):"); 8770 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8771 dumpPackage); 8772 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8773 pw.println(" "); 8774 pw.println(" Activities waiting for another to become visible:"); 8775 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8776 !dumpAll, false, dumpPackage); 8777 } 8778 if (mMainStack.mStoppingActivities.size() > 0) { 8779 pw.println(" "); 8780 pw.println(" Activities waiting to stop:"); 8781 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8782 !dumpAll, false, dumpPackage); 8783 } 8784 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8785 pw.println(" "); 8786 pw.println(" Activities waiting to sleep:"); 8787 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8788 !dumpAll, false, dumpPackage); 8789 } 8790 if (mMainStack.mFinishingActivities.size() > 0) { 8791 pw.println(" "); 8792 pw.println(" Activities waiting to finish:"); 8793 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8794 !dumpAll, false, dumpPackage); 8795 } 8796 8797 pw.println(" "); 8798 if (mMainStack.mPausingActivity != null) { 8799 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8800 } 8801 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8802 pw.println(" mFocusedActivity: " + mFocusedActivity); 8803 if (dumpAll) { 8804 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8805 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8806 pw.println(" mDismissKeyguardOnNextActivity: " 8807 + mMainStack.mDismissKeyguardOnNextActivity); 8808 } 8809 8810 if (mRecentTasks.size() > 0) { 8811 pw.println(); 8812 pw.println(" Recent tasks:"); 8813 8814 final int N = mRecentTasks.size(); 8815 for (int i=0; i<N; i++) { 8816 TaskRecord tr = mRecentTasks.get(i); 8817 if (dumpPackage != null) { 8818 if (tr.realActivity == null || 8819 !dumpPackage.equals(tr.realActivity)) { 8820 continue; 8821 } 8822 } 8823 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8824 pw.println(tr); 8825 if (dumpAll) { 8826 mRecentTasks.get(i).dump(pw, " "); 8827 } 8828 } 8829 } 8830 8831 if (dumpAll) { 8832 pw.println(" "); 8833 pw.println(" mCurTask: " + mCurTask); 8834 } 8835 8836 return true; 8837 } 8838 8839 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8840 int opti, boolean dumpAll, String dumpPackage) { 8841 boolean needSep = false; 8842 int numPers = 0; 8843 8844 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8845 8846 if (dumpAll) { 8847 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8848 final int NA = procs.size(); 8849 for (int ia=0; ia<NA; ia++) { 8850 ProcessRecord r = procs.valueAt(ia); 8851 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8852 continue; 8853 } 8854 if (!needSep) { 8855 pw.println(" All known processes:"); 8856 needSep = true; 8857 } 8858 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8859 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8860 pw.print(" "); pw.println(r); 8861 r.dump(pw, " "); 8862 if (r.persistent) { 8863 numPers++; 8864 } 8865 } 8866 } 8867 } 8868 8869 if (mIsolatedProcesses.size() > 0) { 8870 if (needSep) pw.println(" "); 8871 needSep = true; 8872 pw.println(" Isolated process list (sorted by uid):"); 8873 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8874 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8875 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8876 continue; 8877 } 8878 pw.println(String.format("%sIsolated #%2d: %s", 8879 " ", i, r.toString())); 8880 } 8881 } 8882 8883 if (mLruProcesses.size() > 0) { 8884 if (needSep) pw.println(" "); 8885 needSep = true; 8886 pw.println(" Process LRU list (sorted by oom_adj):"); 8887 dumpProcessOomList(pw, this, mLruProcesses, " ", 8888 "Proc", "PERS", false, dumpPackage); 8889 needSep = true; 8890 } 8891 8892 if (dumpAll) { 8893 synchronized (mPidsSelfLocked) { 8894 boolean printed = false; 8895 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8896 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8897 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8898 continue; 8899 } 8900 if (!printed) { 8901 if (needSep) pw.println(" "); 8902 needSep = true; 8903 pw.println(" PID mappings:"); 8904 printed = true; 8905 } 8906 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8907 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8908 } 8909 } 8910 } 8911 8912 if (mForegroundProcesses.size() > 0) { 8913 synchronized (mPidsSelfLocked) { 8914 boolean printed = false; 8915 for (int i=0; i<mForegroundProcesses.size(); i++) { 8916 ProcessRecord r = mPidsSelfLocked.get( 8917 mForegroundProcesses.valueAt(i).pid); 8918 if (dumpPackage != null && (r == null 8919 || !dumpPackage.equals(r.info.packageName))) { 8920 continue; 8921 } 8922 if (!printed) { 8923 if (needSep) pw.println(" "); 8924 needSep = true; 8925 pw.println(" Foreground Processes:"); 8926 printed = true; 8927 } 8928 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8929 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8930 } 8931 } 8932 } 8933 8934 if (mPersistentStartingProcesses.size() > 0) { 8935 if (needSep) pw.println(" "); 8936 needSep = true; 8937 pw.println(" Persisent processes that are starting:"); 8938 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8939 "Starting Norm", "Restarting PERS", dumpPackage); 8940 } 8941 8942 if (mRemovedProcesses.size() > 0) { 8943 if (needSep) pw.println(" "); 8944 needSep = true; 8945 pw.println(" Processes that are being removed:"); 8946 dumpProcessList(pw, this, mRemovedProcesses, " ", 8947 "Removed Norm", "Removed PERS", dumpPackage); 8948 } 8949 8950 if (mProcessesOnHold.size() > 0) { 8951 if (needSep) pw.println(" "); 8952 needSep = true; 8953 pw.println(" Processes that are on old until the system is ready:"); 8954 dumpProcessList(pw, this, mProcessesOnHold, " ", 8955 "OnHold Norm", "OnHold PERS", dumpPackage); 8956 } 8957 8958 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8959 8960 if (mProcessCrashTimes.getMap().size() > 0) { 8961 boolean printed = false; 8962 long now = SystemClock.uptimeMillis(); 8963 for (Map.Entry<String, SparseArray<Long>> procs 8964 : mProcessCrashTimes.getMap().entrySet()) { 8965 String pname = procs.getKey(); 8966 SparseArray<Long> uids = procs.getValue(); 8967 final int N = uids.size(); 8968 for (int i=0; i<N; i++) { 8969 int puid = uids.keyAt(i); 8970 ProcessRecord r = mProcessNames.get(pname, puid); 8971 if (dumpPackage != null && (r == null 8972 || !dumpPackage.equals(r.info.packageName))) { 8973 continue; 8974 } 8975 if (!printed) { 8976 if (needSep) pw.println(" "); 8977 needSep = true; 8978 pw.println(" Time since processes crashed:"); 8979 printed = true; 8980 } 8981 pw.print(" Process "); pw.print(pname); 8982 pw.print(" uid "); pw.print(puid); 8983 pw.print(": last crashed "); 8984 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8985 pw.println(" ago"); 8986 } 8987 } 8988 } 8989 8990 if (mBadProcesses.getMap().size() > 0) { 8991 boolean printed = false; 8992 for (Map.Entry<String, SparseArray<Long>> procs 8993 : mBadProcesses.getMap().entrySet()) { 8994 String pname = procs.getKey(); 8995 SparseArray<Long> uids = procs.getValue(); 8996 final int N = uids.size(); 8997 for (int i=0; i<N; i++) { 8998 int puid = uids.keyAt(i); 8999 ProcessRecord r = mProcessNames.get(pname, puid); 9000 if (dumpPackage != null && (r == null 9001 || !dumpPackage.equals(r.info.packageName))) { 9002 continue; 9003 } 9004 if (!printed) { 9005 if (needSep) pw.println(" "); 9006 needSep = true; 9007 pw.println(" Bad processes:"); 9008 } 9009 pw.print(" Bad process "); pw.print(pname); 9010 pw.print(" uid "); pw.print(puid); 9011 pw.print(": crashed at time "); 9012 pw.println(uids.valueAt(i)); 9013 } 9014 } 9015 } 9016 9017 pw.println(); 9018 pw.println(" mHomeProcess: " + mHomeProcess); 9019 pw.println(" mPreviousProcess: " + mPreviousProcess); 9020 if (dumpAll) { 9021 StringBuilder sb = new StringBuilder(128); 9022 sb.append(" mPreviousProcessVisibleTime: "); 9023 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9024 pw.println(sb); 9025 } 9026 if (mHeavyWeightProcess != null) { 9027 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9028 } 9029 pw.println(" mConfiguration: " + mConfiguration); 9030 if (dumpAll) { 9031 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9032 if (mCompatModePackages.getPackages().size() > 0) { 9033 boolean printed = false; 9034 for (Map.Entry<String, Integer> entry 9035 : mCompatModePackages.getPackages().entrySet()) { 9036 String pkg = entry.getKey(); 9037 int mode = entry.getValue(); 9038 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9039 continue; 9040 } 9041 if (!printed) { 9042 pw.println(" mScreenCompatPackages:"); 9043 printed = true; 9044 } 9045 pw.print(" "); pw.print(pkg); pw.print(": "); 9046 pw.print(mode); pw.println(); 9047 } 9048 } 9049 } 9050 if (mSleeping || mWentToSleep || mLockScreenShown) { 9051 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9052 + " mLockScreenShown " + mLockScreenShown); 9053 } 9054 if (mShuttingDown) { 9055 pw.println(" mShuttingDown=" + mShuttingDown); 9056 } 9057 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9058 || mOrigWaitForDebugger) { 9059 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9060 + " mDebugTransient=" + mDebugTransient 9061 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9062 } 9063 if (mOpenGlTraceApp != null) { 9064 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9065 } 9066 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9067 || mProfileFd != null) { 9068 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9069 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9070 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9071 + mAutoStopProfiler); 9072 } 9073 if (mAlwaysFinishActivities || mController != null) { 9074 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9075 + " mController=" + mController); 9076 } 9077 if (dumpAll) { 9078 pw.println(" Total persistent processes: " + numPers); 9079 pw.println(" mStartRunning=" + mStartRunning 9080 + " mProcessesReady=" + mProcessesReady 9081 + " mSystemReady=" + mSystemReady); 9082 pw.println(" mBooting=" + mBooting 9083 + " mBooted=" + mBooted 9084 + " mFactoryTest=" + mFactoryTest); 9085 pw.print(" mLastPowerCheckRealtime="); 9086 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9087 pw.println(""); 9088 pw.print(" mLastPowerCheckUptime="); 9089 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9090 pw.println(""); 9091 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9092 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9093 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9094 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9095 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9096 } 9097 9098 return true; 9099 } 9100 9101 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9102 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9103 if (mProcessesToGc.size() > 0) { 9104 boolean printed = false; 9105 long now = SystemClock.uptimeMillis(); 9106 for (int i=0; i<mProcessesToGc.size(); i++) { 9107 ProcessRecord proc = mProcessesToGc.get(i); 9108 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9109 continue; 9110 } 9111 if (!printed) { 9112 if (needSep) pw.println(" "); 9113 needSep = true; 9114 pw.println(" Processes that are waiting to GC:"); 9115 printed = true; 9116 } 9117 pw.print(" Process "); pw.println(proc); 9118 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9119 pw.print(", last gced="); 9120 pw.print(now-proc.lastRequestedGc); 9121 pw.print(" ms ago, last lowMem="); 9122 pw.print(now-proc.lastLowMemory); 9123 pw.println(" ms ago"); 9124 9125 } 9126 } 9127 return needSep; 9128 } 9129 9130 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9131 int opti, boolean dumpAll) { 9132 boolean needSep = false; 9133 9134 if (mLruProcesses.size() > 0) { 9135 if (needSep) pw.println(" "); 9136 needSep = true; 9137 pw.println(" OOM levels:"); 9138 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9139 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9140 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9141 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9142 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9143 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9144 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9145 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9146 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9147 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9148 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9149 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9150 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9151 9152 if (needSep) pw.println(" "); 9153 needSep = true; 9154 pw.println(" Process OOM control:"); 9155 dumpProcessOomList(pw, this, mLruProcesses, " ", 9156 "Proc", "PERS", true, null); 9157 needSep = true; 9158 } 9159 9160 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9161 9162 pw.println(); 9163 pw.println(" mHomeProcess: " + mHomeProcess); 9164 pw.println(" mPreviousProcess: " + mPreviousProcess); 9165 if (mHeavyWeightProcess != null) { 9166 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9167 } 9168 9169 return true; 9170 } 9171 9172 /** 9173 * There are three ways to call this: 9174 * - no provider specified: dump all the providers 9175 * - a flattened component name that matched an existing provider was specified as the 9176 * first arg: dump that one provider 9177 * - the first arg isn't the flattened component name of an existing provider: 9178 * dump all providers whose component contains the first arg as a substring 9179 */ 9180 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9181 int opti, boolean dumpAll) { 9182 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9183 } 9184 9185 static class ItemMatcher { 9186 ArrayList<ComponentName> components; 9187 ArrayList<String> strings; 9188 ArrayList<Integer> objects; 9189 boolean all; 9190 9191 ItemMatcher() { 9192 all = true; 9193 } 9194 9195 void build(String name) { 9196 ComponentName componentName = ComponentName.unflattenFromString(name); 9197 if (componentName != null) { 9198 if (components == null) { 9199 components = new ArrayList<ComponentName>(); 9200 } 9201 components.add(componentName); 9202 all = false; 9203 } else { 9204 int objectId = 0; 9205 // Not a '/' separated full component name; maybe an object ID? 9206 try { 9207 objectId = Integer.parseInt(name, 16); 9208 if (objects == null) { 9209 objects = new ArrayList<Integer>(); 9210 } 9211 objects.add(objectId); 9212 all = false; 9213 } catch (RuntimeException e) { 9214 // Not an integer; just do string match. 9215 if (strings == null) { 9216 strings = new ArrayList<String>(); 9217 } 9218 strings.add(name); 9219 all = false; 9220 } 9221 } 9222 } 9223 9224 int build(String[] args, int opti) { 9225 for (; opti<args.length; opti++) { 9226 String name = args[opti]; 9227 if ("--".equals(name)) { 9228 return opti+1; 9229 } 9230 build(name); 9231 } 9232 return opti; 9233 } 9234 9235 boolean match(Object object, ComponentName comp) { 9236 if (all) { 9237 return true; 9238 } 9239 if (components != null) { 9240 for (int i=0; i<components.size(); i++) { 9241 if (components.get(i).equals(comp)) { 9242 return true; 9243 } 9244 } 9245 } 9246 if (objects != null) { 9247 for (int i=0; i<objects.size(); i++) { 9248 if (System.identityHashCode(object) == objects.get(i)) { 9249 return true; 9250 } 9251 } 9252 } 9253 if (strings != null) { 9254 String flat = comp.flattenToString(); 9255 for (int i=0; i<strings.size(); i++) { 9256 if (flat.contains(strings.get(i))) { 9257 return true; 9258 } 9259 } 9260 } 9261 return false; 9262 } 9263 } 9264 9265 /** 9266 * There are three things that cmd can be: 9267 * - a flattened component name that matches an existing activity 9268 * - the cmd arg isn't the flattened component name of an existing activity: 9269 * dump all activity whose component contains the cmd as a substring 9270 * - A hex number of the ActivityRecord object instance. 9271 */ 9272 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9273 int opti, boolean dumpAll) { 9274 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9275 9276 if ("all".equals(name)) { 9277 synchronized (this) { 9278 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9279 activities.add(r1); 9280 } 9281 } 9282 } else if ("top".equals(name)) { 9283 synchronized (this) { 9284 final int N = mMainStack.mHistory.size(); 9285 if (N > 0) { 9286 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9287 } 9288 } 9289 } else { 9290 ItemMatcher matcher = new ItemMatcher(); 9291 matcher.build(name); 9292 9293 synchronized (this) { 9294 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9295 if (matcher.match(r1, r1.intent.getComponent())) { 9296 activities.add(r1); 9297 } 9298 } 9299 } 9300 } 9301 9302 if (activities.size() <= 0) { 9303 return false; 9304 } 9305 9306 String[] newArgs = new String[args.length - opti]; 9307 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9308 9309 TaskRecord lastTask = null; 9310 boolean needSep = false; 9311 for (int i=activities.size()-1; i>=0; i--) { 9312 ActivityRecord r = (ActivityRecord)activities.get(i); 9313 if (needSep) { 9314 pw.println(); 9315 } 9316 needSep = true; 9317 synchronized (this) { 9318 if (lastTask != r.task) { 9319 lastTask = r.task; 9320 pw.print("TASK "); pw.print(lastTask.affinity); 9321 pw.print(" id="); pw.println(lastTask.taskId); 9322 if (dumpAll) { 9323 lastTask.dump(pw, " "); 9324 } 9325 } 9326 } 9327 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9328 } 9329 return true; 9330 } 9331 9332 /** 9333 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9334 * there is a thread associated with the activity. 9335 */ 9336 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9337 final ActivityRecord r, String[] args, boolean dumpAll) { 9338 String innerPrefix = prefix + " "; 9339 synchronized (this) { 9340 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9341 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9342 pw.print(" pid="); 9343 if (r.app != null) pw.println(r.app.pid); 9344 else pw.println("(not running)"); 9345 if (dumpAll) { 9346 r.dump(pw, innerPrefix); 9347 } 9348 } 9349 if (r.app != null && r.app.thread != null) { 9350 // flush anything that is already in the PrintWriter since the thread is going 9351 // to write to the file descriptor directly 9352 pw.flush(); 9353 try { 9354 TransferPipe tp = new TransferPipe(); 9355 try { 9356 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9357 r.appToken, innerPrefix, args); 9358 tp.go(fd); 9359 } finally { 9360 tp.kill(); 9361 } 9362 } catch (IOException e) { 9363 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9364 } catch (RemoteException e) { 9365 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9366 } 9367 } 9368 } 9369 9370 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9371 int opti, boolean dumpAll, String dumpPackage) { 9372 boolean needSep = false; 9373 9374 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9375 if (dumpAll) { 9376 if (mRegisteredReceivers.size() > 0) { 9377 boolean printed = false; 9378 Iterator it = mRegisteredReceivers.values().iterator(); 9379 while (it.hasNext()) { 9380 ReceiverList r = (ReceiverList)it.next(); 9381 if (dumpPackage != null && (r.app == null || 9382 !dumpPackage.equals(r.app.info.packageName))) { 9383 continue; 9384 } 9385 if (!printed) { 9386 pw.println(" Registered Receivers:"); 9387 needSep = true; 9388 printed = true; 9389 } 9390 pw.print(" * "); pw.println(r); 9391 r.dump(pw, " "); 9392 } 9393 } 9394 9395 if (mReceiverResolver.dump(pw, needSep ? 9396 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9397 " ", dumpPackage, false)) { 9398 needSep = true; 9399 } 9400 } 9401 9402 for (BroadcastQueue q : mBroadcastQueues) { 9403 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9404 } 9405 9406 needSep = true; 9407 9408 if (mStickyBroadcasts != null && dumpPackage == null) { 9409 if (needSep) { 9410 pw.println(); 9411 } 9412 needSep = true; 9413 pw.println(" Sticky broadcasts:"); 9414 StringBuilder sb = new StringBuilder(128); 9415 for (Map.Entry<String, ArrayList<Intent>> ent 9416 : mStickyBroadcasts.entrySet()) { 9417 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9418 if (dumpAll) { 9419 pw.println(":"); 9420 ArrayList<Intent> intents = ent.getValue(); 9421 final int N = intents.size(); 9422 for (int i=0; i<N; i++) { 9423 sb.setLength(0); 9424 sb.append(" Intent: "); 9425 intents.get(i).toShortString(sb, false, true, false, false); 9426 pw.println(sb.toString()); 9427 Bundle bundle = intents.get(i).getExtras(); 9428 if (bundle != null) { 9429 pw.print(" "); 9430 pw.println(bundle.toString()); 9431 } 9432 } 9433 } else { 9434 pw.println(""); 9435 } 9436 } 9437 needSep = true; 9438 } 9439 9440 if (dumpAll) { 9441 pw.println(); 9442 for (BroadcastQueue queue : mBroadcastQueues) { 9443 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9444 + queue.mBroadcastsScheduled); 9445 } 9446 pw.println(" mHandler:"); 9447 mHandler.dump(new PrintWriterPrinter(pw), " "); 9448 needSep = true; 9449 } 9450 9451 return needSep; 9452 } 9453 9454 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9455 int opti, boolean dumpAll, String dumpPackage) { 9456 boolean needSep = true; 9457 9458 ItemMatcher matcher = new ItemMatcher(); 9459 matcher.build(args, opti); 9460 9461 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9462 9463 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9464 9465 if (mLaunchingProviders.size() > 0) { 9466 boolean printed = false; 9467 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9468 ContentProviderRecord r = mLaunchingProviders.get(i); 9469 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9470 continue; 9471 } 9472 if (!printed) { 9473 if (needSep) pw.println(" "); 9474 needSep = true; 9475 pw.println(" Launching content providers:"); 9476 printed = true; 9477 } 9478 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9479 pw.println(r); 9480 } 9481 } 9482 9483 if (mGrantedUriPermissions.size() > 0) { 9484 if (needSep) pw.println(); 9485 needSep = true; 9486 pw.println("Granted Uri Permissions:"); 9487 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9488 int uid = mGrantedUriPermissions.keyAt(i); 9489 HashMap<Uri, UriPermission> perms 9490 = mGrantedUriPermissions.valueAt(i); 9491 pw.print(" * UID "); pw.print(uid); 9492 pw.println(" holds:"); 9493 for (UriPermission perm : perms.values()) { 9494 pw.print(" "); pw.println(perm); 9495 if (dumpAll) { 9496 perm.dump(pw, " "); 9497 } 9498 } 9499 } 9500 needSep = true; 9501 } 9502 9503 return needSep; 9504 } 9505 9506 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9507 int opti, boolean dumpAll, String dumpPackage) { 9508 boolean needSep = false; 9509 9510 if (mIntentSenderRecords.size() > 0) { 9511 boolean printed = false; 9512 Iterator<WeakReference<PendingIntentRecord>> it 9513 = mIntentSenderRecords.values().iterator(); 9514 while (it.hasNext()) { 9515 WeakReference<PendingIntentRecord> ref = it.next(); 9516 PendingIntentRecord rec = ref != null ? ref.get(): null; 9517 if (dumpPackage != null && (rec == null 9518 || !dumpPackage.equals(rec.key.packageName))) { 9519 continue; 9520 } 9521 if (!printed) { 9522 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9523 printed = true; 9524 } 9525 needSep = true; 9526 if (rec != null) { 9527 pw.print(" * "); pw.println(rec); 9528 if (dumpAll) { 9529 rec.dump(pw, " "); 9530 } 9531 } else { 9532 pw.print(" * "); pw.println(ref); 9533 } 9534 } 9535 } 9536 9537 return needSep; 9538 } 9539 9540 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9541 String prefix, String label, boolean complete, boolean brief, boolean client, 9542 String dumpPackage) { 9543 TaskRecord lastTask = null; 9544 boolean needNL = false; 9545 final String innerPrefix = prefix + " "; 9546 final String[] args = new String[0]; 9547 for (int i=list.size()-1; i>=0; i--) { 9548 final ActivityRecord r = (ActivityRecord)list.get(i); 9549 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9550 continue; 9551 } 9552 final boolean full = !brief && (complete || !r.isInHistory()); 9553 if (needNL) { 9554 pw.println(" "); 9555 needNL = false; 9556 } 9557 if (lastTask != r.task) { 9558 lastTask = r.task; 9559 pw.print(prefix); 9560 pw.print(full ? "* " : " "); 9561 pw.println(lastTask); 9562 if (full) { 9563 lastTask.dump(pw, prefix + " "); 9564 } else if (complete) { 9565 // Complete + brief == give a summary. Isn't that obvious?!? 9566 if (lastTask.intent != null) { 9567 pw.print(prefix); pw.print(" "); 9568 pw.println(lastTask.intent.toInsecureStringWithClip()); 9569 } 9570 } 9571 } 9572 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9573 pw.print(" #"); pw.print(i); pw.print(": "); 9574 pw.println(r); 9575 if (full) { 9576 r.dump(pw, innerPrefix); 9577 } else if (complete) { 9578 // Complete + brief == give a summary. Isn't that obvious?!? 9579 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9580 if (r.app != null) { 9581 pw.print(innerPrefix); pw.println(r.app); 9582 } 9583 } 9584 if (client && r.app != null && r.app.thread != null) { 9585 // flush anything that is already in the PrintWriter since the thread is going 9586 // to write to the file descriptor directly 9587 pw.flush(); 9588 try { 9589 TransferPipe tp = new TransferPipe(); 9590 try { 9591 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9592 r.appToken, innerPrefix, args); 9593 // Short timeout, since blocking here can 9594 // deadlock with the application. 9595 tp.go(fd, 2000); 9596 } finally { 9597 tp.kill(); 9598 } 9599 } catch (IOException e) { 9600 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9601 } catch (RemoteException e) { 9602 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9603 } 9604 needNL = true; 9605 } 9606 } 9607 } 9608 9609 private static String buildOomTag(String prefix, String space, int val, int base) { 9610 if (val == base) { 9611 if (space == null) return prefix; 9612 return prefix + " "; 9613 } 9614 return prefix + "+" + Integer.toString(val-base); 9615 } 9616 9617 private static final int dumpProcessList(PrintWriter pw, 9618 ActivityManagerService service, List list, 9619 String prefix, String normalLabel, String persistentLabel, 9620 String dumpPackage) { 9621 int numPers = 0; 9622 final int N = list.size()-1; 9623 for (int i=N; i>=0; i--) { 9624 ProcessRecord r = (ProcessRecord)list.get(i); 9625 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9626 continue; 9627 } 9628 pw.println(String.format("%s%s #%2d: %s", 9629 prefix, (r.persistent ? persistentLabel : normalLabel), 9630 i, r.toString())); 9631 if (r.persistent) { 9632 numPers++; 9633 } 9634 } 9635 return numPers; 9636 } 9637 9638 private static final boolean dumpProcessOomList(PrintWriter pw, 9639 ActivityManagerService service, List<ProcessRecord> origList, 9640 String prefix, String normalLabel, String persistentLabel, 9641 boolean inclDetails, String dumpPackage) { 9642 9643 ArrayList<Pair<ProcessRecord, Integer>> list 9644 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9645 for (int i=0; i<origList.size(); i++) { 9646 ProcessRecord r = origList.get(i); 9647 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9648 continue; 9649 } 9650 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9651 } 9652 9653 if (list.size() <= 0) { 9654 return false; 9655 } 9656 9657 Comparator<Pair<ProcessRecord, Integer>> comparator 9658 = new Comparator<Pair<ProcessRecord, Integer>>() { 9659 @Override 9660 public int compare(Pair<ProcessRecord, Integer> object1, 9661 Pair<ProcessRecord, Integer> object2) { 9662 if (object1.first.setAdj != object2.first.setAdj) { 9663 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9664 } 9665 if (object1.second.intValue() != object2.second.intValue()) { 9666 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9667 } 9668 return 0; 9669 } 9670 }; 9671 9672 Collections.sort(list, comparator); 9673 9674 final long curRealtime = SystemClock.elapsedRealtime(); 9675 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9676 final long curUptime = SystemClock.uptimeMillis(); 9677 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9678 9679 for (int i=list.size()-1; i>=0; i--) { 9680 ProcessRecord r = list.get(i).first; 9681 String oomAdj; 9682 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9683 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9684 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9685 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9686 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9687 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9688 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9689 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9690 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9691 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9692 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9693 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9694 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9695 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9696 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9697 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9698 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9699 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9700 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9701 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9702 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9703 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9704 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9705 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9706 } else { 9707 oomAdj = Integer.toString(r.setAdj); 9708 } 9709 String schedGroup; 9710 switch (r.setSchedGroup) { 9711 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9712 schedGroup = "B"; 9713 break; 9714 case Process.THREAD_GROUP_DEFAULT: 9715 schedGroup = "F"; 9716 break; 9717 default: 9718 schedGroup = Integer.toString(r.setSchedGroup); 9719 break; 9720 } 9721 String foreground; 9722 if (r.foregroundActivities) { 9723 foreground = "A"; 9724 } else if (r.foregroundServices) { 9725 foreground = "S"; 9726 } else { 9727 foreground = " "; 9728 } 9729 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9730 prefix, (r.persistent ? persistentLabel : normalLabel), 9731 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9732 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9733 if (r.adjSource != null || r.adjTarget != null) { 9734 pw.print(prefix); 9735 pw.print(" "); 9736 if (r.adjTarget instanceof ComponentName) { 9737 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9738 } else if (r.adjTarget != null) { 9739 pw.print(r.adjTarget.toString()); 9740 } else { 9741 pw.print("{null}"); 9742 } 9743 pw.print("<="); 9744 if (r.adjSource instanceof ProcessRecord) { 9745 pw.print("Proc{"); 9746 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9747 pw.println("}"); 9748 } else if (r.adjSource != null) { 9749 pw.println(r.adjSource.toString()); 9750 } else { 9751 pw.println("{null}"); 9752 } 9753 } 9754 if (inclDetails) { 9755 pw.print(prefix); 9756 pw.print(" "); 9757 pw.print("oom: max="); pw.print(r.maxAdj); 9758 pw.print(" hidden="); pw.print(r.hiddenAdj); 9759 pw.print(" curRaw="); pw.print(r.curRawAdj); 9760 pw.print(" setRaw="); pw.print(r.setRawAdj); 9761 pw.print(" cur="); pw.print(r.curAdj); 9762 pw.print(" set="); pw.println(r.setAdj); 9763 pw.print(prefix); 9764 pw.print(" "); 9765 pw.print("keeping="); pw.print(r.keeping); 9766 pw.print(" hidden="); pw.print(r.hidden); 9767 pw.print(" empty="); pw.print(r.empty); 9768 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9769 9770 if (!r.keeping) { 9771 if (r.lastWakeTime != 0) { 9772 long wtime; 9773 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9774 synchronized (stats) { 9775 wtime = stats.getProcessWakeTime(r.info.uid, 9776 r.pid, curRealtime); 9777 } 9778 long timeUsed = wtime - r.lastWakeTime; 9779 pw.print(prefix); 9780 pw.print(" "); 9781 pw.print("keep awake over "); 9782 TimeUtils.formatDuration(realtimeSince, pw); 9783 pw.print(" used "); 9784 TimeUtils.formatDuration(timeUsed, pw); 9785 pw.print(" ("); 9786 pw.print((timeUsed*100)/realtimeSince); 9787 pw.println("%)"); 9788 } 9789 if (r.lastCpuTime != 0) { 9790 long timeUsed = r.curCpuTime - r.lastCpuTime; 9791 pw.print(prefix); 9792 pw.print(" "); 9793 pw.print("run cpu over "); 9794 TimeUtils.formatDuration(uptimeSince, pw); 9795 pw.print(" used "); 9796 TimeUtils.formatDuration(timeUsed, pw); 9797 pw.print(" ("); 9798 pw.print((timeUsed*100)/uptimeSince); 9799 pw.println("%)"); 9800 } 9801 } 9802 } 9803 } 9804 return true; 9805 } 9806 9807 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9808 ArrayList<ProcessRecord> procs; 9809 synchronized (this) { 9810 if (args != null && args.length > start 9811 && args[start].charAt(0) != '-') { 9812 procs = new ArrayList<ProcessRecord>(); 9813 int pid = -1; 9814 try { 9815 pid = Integer.parseInt(args[start]); 9816 } catch (NumberFormatException e) { 9817 9818 } 9819 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9820 ProcessRecord proc = mLruProcesses.get(i); 9821 if (proc.pid == pid) { 9822 procs.add(proc); 9823 } else if (proc.processName.equals(args[start])) { 9824 procs.add(proc); 9825 } 9826 } 9827 if (procs.size() <= 0) { 9828 pw.println("No process found for: " + args[start]); 9829 return null; 9830 } 9831 } else { 9832 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9833 } 9834 } 9835 return procs; 9836 } 9837 9838 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9839 PrintWriter pw, String[] args) { 9840 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9841 if (procs == null) { 9842 return; 9843 } 9844 9845 long uptime = SystemClock.uptimeMillis(); 9846 long realtime = SystemClock.elapsedRealtime(); 9847 pw.println("Applications Graphics Acceleration Info:"); 9848 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9849 9850 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9851 ProcessRecord r = procs.get(i); 9852 if (r.thread != null) { 9853 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9854 pw.flush(); 9855 try { 9856 TransferPipe tp = new TransferPipe(); 9857 try { 9858 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9859 tp.go(fd); 9860 } finally { 9861 tp.kill(); 9862 } 9863 } catch (IOException e) { 9864 pw.println("Failure while dumping the app: " + r); 9865 pw.flush(); 9866 } catch (RemoteException e) { 9867 pw.println("Got a RemoteException while dumping the app " + r); 9868 pw.flush(); 9869 } 9870 } 9871 } 9872 } 9873 9874 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9875 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9876 if (procs == null) { 9877 return; 9878 } 9879 9880 pw.println("Applications Database Info:"); 9881 9882 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9883 ProcessRecord r = procs.get(i); 9884 if (r.thread != null) { 9885 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9886 pw.flush(); 9887 try { 9888 TransferPipe tp = new TransferPipe(); 9889 try { 9890 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9891 tp.go(fd); 9892 } finally { 9893 tp.kill(); 9894 } 9895 } catch (IOException e) { 9896 pw.println("Failure while dumping the app: " + r); 9897 pw.flush(); 9898 } catch (RemoteException e) { 9899 pw.println("Got a RemoteException while dumping the app " + r); 9900 pw.flush(); 9901 } 9902 } 9903 } 9904 } 9905 9906 final static class MemItem { 9907 final String label; 9908 final String shortLabel; 9909 final long pss; 9910 final int id; 9911 ArrayList<MemItem> subitems; 9912 9913 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9914 label = _label; 9915 shortLabel = _shortLabel; 9916 pss = _pss; 9917 id = _id; 9918 } 9919 } 9920 9921 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9922 boolean sort) { 9923 if (sort) { 9924 Collections.sort(items, new Comparator<MemItem>() { 9925 @Override 9926 public int compare(MemItem lhs, MemItem rhs) { 9927 if (lhs.pss < rhs.pss) { 9928 return 1; 9929 } else if (lhs.pss > rhs.pss) { 9930 return -1; 9931 } 9932 return 0; 9933 } 9934 }); 9935 } 9936 9937 for (int i=0; i<items.size(); i++) { 9938 MemItem mi = items.get(i); 9939 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9940 if (mi.subitems != null) { 9941 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9942 } 9943 } 9944 } 9945 9946 // These are in KB. 9947 static final long[] DUMP_MEM_BUCKETS = new long[] { 9948 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9949 120*1024, 160*1024, 200*1024, 9950 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9951 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9952 }; 9953 9954 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9955 boolean stackLike) { 9956 int start = label.lastIndexOf('.'); 9957 if (start >= 0) start++; 9958 else start = 0; 9959 int end = label.length(); 9960 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9961 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9962 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9963 out.append(bucket); 9964 out.append(stackLike ? "MB." : "MB "); 9965 out.append(label, start, end); 9966 return; 9967 } 9968 } 9969 out.append(memKB/1024); 9970 out.append(stackLike ? "MB." : "MB "); 9971 out.append(label, start, end); 9972 } 9973 9974 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9975 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9976 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9977 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9978 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9979 }; 9980 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9981 "System", "Persistent", "Foreground", 9982 "Visible", "Perceptible", "Heavy Weight", 9983 "Backup", "A Services", "Home", "Previous", 9984 "B Services", "Background" 9985 }; 9986 9987 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9988 PrintWriter pw, String prefix, String[] args, boolean brief, 9989 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9990 boolean dumpAll = false; 9991 boolean oomOnly = false; 9992 9993 int opti = 0; 9994 while (opti < args.length) { 9995 String opt = args[opti]; 9996 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9997 break; 9998 } 9999 opti++; 10000 if ("-a".equals(opt)) { 10001 dumpAll = true; 10002 } else if ("--oom".equals(opt)) { 10003 oomOnly = true; 10004 } else if ("-h".equals(opt)) { 10005 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10006 pw.println(" -a: include all available information for each process."); 10007 pw.println(" --oom: only show processes organized by oom adj."); 10008 pw.println("If [process] is specified it can be the name or "); 10009 pw.println("pid of a specific process to dump."); 10010 return; 10011 } else { 10012 pw.println("Unknown argument: " + opt + "; use -h for help"); 10013 } 10014 } 10015 10016 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10017 if (procs == null) { 10018 return; 10019 } 10020 10021 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10022 long uptime = SystemClock.uptimeMillis(); 10023 long realtime = SystemClock.elapsedRealtime(); 10024 10025 if (procs.size() == 1 || isCheckinRequest) { 10026 dumpAll = true; 10027 } 10028 10029 if (isCheckinRequest) { 10030 // short checkin version 10031 pw.println(uptime + "," + realtime); 10032 pw.flush(); 10033 } else { 10034 pw.println("Applications Memory Usage (kB):"); 10035 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10036 } 10037 10038 String[] innerArgs = new String[args.length-opti]; 10039 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10040 10041 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10042 long nativePss=0, dalvikPss=0, otherPss=0; 10043 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10044 10045 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10046 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10047 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10048 10049 long totalPss = 0; 10050 10051 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10052 ProcessRecord r = procs.get(i); 10053 if (r.thread != null) { 10054 if (!isCheckinRequest && dumpAll) { 10055 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10056 pw.flush(); 10057 } 10058 Debug.MemoryInfo mi = null; 10059 if (dumpAll) { 10060 try { 10061 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10062 } catch (RemoteException e) { 10063 if (!isCheckinRequest) { 10064 pw.println("Got RemoteException!"); 10065 pw.flush(); 10066 } 10067 } 10068 } else { 10069 mi = new Debug.MemoryInfo(); 10070 Debug.getMemoryInfo(r.pid, mi); 10071 } 10072 10073 if (!isCheckinRequest && mi != null) { 10074 long myTotalPss = mi.getTotalPss(); 10075 totalPss += myTotalPss; 10076 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10077 r.processName, myTotalPss, 0); 10078 procMems.add(pssItem); 10079 10080 nativePss += mi.nativePss; 10081 dalvikPss += mi.dalvikPss; 10082 otherPss += mi.otherPss; 10083 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10084 long mem = mi.getOtherPss(j); 10085 miscPss[j] += mem; 10086 otherPss -= mem; 10087 } 10088 10089 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10090 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10091 || oomIndex == (oomPss.length-1)) { 10092 oomPss[oomIndex] += myTotalPss; 10093 if (oomProcs[oomIndex] == null) { 10094 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10095 } 10096 oomProcs[oomIndex].add(pssItem); 10097 break; 10098 } 10099 } 10100 } 10101 } 10102 } 10103 10104 if (!isCheckinRequest && procs.size() > 1) { 10105 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10106 10107 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10108 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10109 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10110 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10111 String label = Debug.MemoryInfo.getOtherLabel(j); 10112 catMems.add(new MemItem(label, label, miscPss[j], j)); 10113 } 10114 10115 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10116 for (int j=0; j<oomPss.length; j++) { 10117 if (oomPss[j] != 0) { 10118 String label = DUMP_MEM_OOM_LABEL[j]; 10119 MemItem item = new MemItem(label, label, oomPss[j], 10120 DUMP_MEM_OOM_ADJ[j]); 10121 item.subitems = oomProcs[j]; 10122 oomMems.add(item); 10123 } 10124 } 10125 10126 if (outTag != null || outStack != null) { 10127 if (outTag != null) { 10128 appendMemBucket(outTag, totalPss, "total", false); 10129 } 10130 if (outStack != null) { 10131 appendMemBucket(outStack, totalPss, "total", true); 10132 } 10133 boolean firstLine = true; 10134 for (int i=0; i<oomMems.size(); i++) { 10135 MemItem miCat = oomMems.get(i); 10136 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10137 continue; 10138 } 10139 if (miCat.id < ProcessList.SERVICE_ADJ 10140 || miCat.id == ProcessList.HOME_APP_ADJ 10141 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10142 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10143 outTag.append(" / "); 10144 } 10145 if (outStack != null) { 10146 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10147 if (firstLine) { 10148 outStack.append(":"); 10149 firstLine = false; 10150 } 10151 outStack.append("\n\t at "); 10152 } else { 10153 outStack.append("$"); 10154 } 10155 } 10156 for (int j=0; j<miCat.subitems.size(); j++) { 10157 MemItem mi = miCat.subitems.get(j); 10158 if (j > 0) { 10159 if (outTag != null) { 10160 outTag.append(" "); 10161 } 10162 if (outStack != null) { 10163 outStack.append("$"); 10164 } 10165 } 10166 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10167 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10168 } 10169 if (outStack != null) { 10170 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10171 } 10172 } 10173 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10174 outStack.append("("); 10175 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10176 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10177 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10178 outStack.append(":"); 10179 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10180 } 10181 } 10182 outStack.append(")"); 10183 } 10184 } 10185 } 10186 } 10187 10188 if (!brief && !oomOnly) { 10189 pw.println(); 10190 pw.println("Total PSS by process:"); 10191 dumpMemItems(pw, " ", procMems, true); 10192 pw.println(); 10193 } 10194 pw.println("Total PSS by OOM adjustment:"); 10195 dumpMemItems(pw, " ", oomMems, false); 10196 if (!oomOnly) { 10197 PrintWriter out = categoryPw != null ? categoryPw : pw; 10198 out.println(); 10199 out.println("Total PSS by category:"); 10200 dumpMemItems(out, " ", catMems, true); 10201 } 10202 pw.println(); 10203 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10204 final int[] SINGLE_LONG_FORMAT = new int[] { 10205 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10206 }; 10207 long[] longOut = new long[1]; 10208 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10209 SINGLE_LONG_FORMAT, null, longOut, null); 10210 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10211 longOut[0] = 0; 10212 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10213 SINGLE_LONG_FORMAT, null, longOut, null); 10214 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10215 longOut[0] = 0; 10216 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10217 SINGLE_LONG_FORMAT, null, longOut, null); 10218 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10219 longOut[0] = 0; 10220 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10221 SINGLE_LONG_FORMAT, null, longOut, null); 10222 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10223 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10224 pw.print(shared); pw.println(" kB"); 10225 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10226 pw.print(voltile); pw.println(" kB volatile"); 10227 } 10228 } 10229 10230 /** 10231 * Searches array of arguments for the specified string 10232 * @param args array of argument strings 10233 * @param value value to search for 10234 * @return true if the value is contained in the array 10235 */ 10236 private static boolean scanArgs(String[] args, String value) { 10237 if (args != null) { 10238 for (String arg : args) { 10239 if (value.equals(arg)) { 10240 return true; 10241 } 10242 } 10243 } 10244 return false; 10245 } 10246 10247 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10248 ContentProviderRecord cpr, boolean always) { 10249 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10250 10251 if (!inLaunching || always) { 10252 synchronized (cpr) { 10253 cpr.launchingApp = null; 10254 cpr.notifyAll(); 10255 } 10256 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10257 String names[] = cpr.info.authority.split(";"); 10258 for (int j = 0; j < names.length; j++) { 10259 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10260 } 10261 } 10262 10263 for (int i=0; i<cpr.connections.size(); i++) { 10264 ContentProviderConnection conn = cpr.connections.get(i); 10265 if (conn.waiting) { 10266 // If this connection is waiting for the provider, then we don't 10267 // need to mess with its process unless we are always removing 10268 // or for some reason the provider is not currently launching. 10269 if (inLaunching && !always) { 10270 continue; 10271 } 10272 } 10273 ProcessRecord capp = conn.client; 10274 conn.dead = true; 10275 if (conn.stableCount > 0) { 10276 if (!capp.persistent && capp.thread != null 10277 && capp.pid != 0 10278 && capp.pid != MY_PID) { 10279 Slog.i(TAG, "Kill " + capp.processName 10280 + " (pid " + capp.pid + "): provider " + cpr.info.name 10281 + " in dying process " + (proc != null ? proc.processName : "??")); 10282 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10283 capp.processName, capp.setAdj, "dying provider " 10284 + cpr.name.toShortString()); 10285 Process.killProcessQuiet(capp.pid); 10286 } 10287 } else if (capp.thread != null && conn.provider.provider != null) { 10288 try { 10289 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10290 } catch (RemoteException e) { 10291 } 10292 // In the protocol here, we don't expect the client to correctly 10293 // clean up this connection, we'll just remove it. 10294 cpr.connections.remove(i); 10295 conn.client.conProviders.remove(conn); 10296 } 10297 } 10298 10299 if (inLaunching && always) { 10300 mLaunchingProviders.remove(cpr); 10301 } 10302 return inLaunching; 10303 } 10304 10305 /** 10306 * Main code for cleaning up a process when it has gone away. This is 10307 * called both as a result of the process dying, or directly when stopping 10308 * a process when running in single process mode. 10309 */ 10310 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10311 boolean restarting, boolean allowRestart, int index) { 10312 if (index >= 0) { 10313 mLruProcesses.remove(index); 10314 } 10315 10316 mProcessesToGc.remove(app); 10317 10318 // Dismiss any open dialogs. 10319 if (app.crashDialog != null) { 10320 app.crashDialog.dismiss(); 10321 app.crashDialog = null; 10322 } 10323 if (app.anrDialog != null) { 10324 app.anrDialog.dismiss(); 10325 app.anrDialog = null; 10326 } 10327 if (app.waitDialog != null) { 10328 app.waitDialog.dismiss(); 10329 app.waitDialog = null; 10330 } 10331 10332 app.crashing = false; 10333 app.notResponding = false; 10334 10335 app.resetPackageList(); 10336 app.unlinkDeathRecipient(); 10337 app.thread = null; 10338 app.forcingToForeground = null; 10339 app.foregroundServices = false; 10340 app.foregroundActivities = false; 10341 app.hasShownUi = false; 10342 app.hasAboveClient = false; 10343 10344 mServices.killServicesLocked(app, allowRestart); 10345 10346 boolean restart = false; 10347 10348 // Remove published content providers. 10349 if (!app.pubProviders.isEmpty()) { 10350 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10351 while (it.hasNext()) { 10352 ContentProviderRecord cpr = it.next(); 10353 10354 final boolean always = app.bad || !allowRestart; 10355 if (removeDyingProviderLocked(app, cpr, always) || always) { 10356 // We left the provider in the launching list, need to 10357 // restart it. 10358 restart = true; 10359 } 10360 10361 cpr.provider = null; 10362 cpr.proc = null; 10363 } 10364 app.pubProviders.clear(); 10365 } 10366 10367 // Take care of any launching providers waiting for this process. 10368 if (checkAppInLaunchingProvidersLocked(app, false)) { 10369 restart = true; 10370 } 10371 10372 // Unregister from connected content providers. 10373 if (!app.conProviders.isEmpty()) { 10374 for (int i=0; i<app.conProviders.size(); i++) { 10375 ContentProviderConnection conn = app.conProviders.get(i); 10376 conn.provider.connections.remove(conn); 10377 } 10378 app.conProviders.clear(); 10379 } 10380 10381 // At this point there may be remaining entries in mLaunchingProviders 10382 // where we were the only one waiting, so they are no longer of use. 10383 // Look for these and clean up if found. 10384 // XXX Commented out for now. Trying to figure out a way to reproduce 10385 // the actual situation to identify what is actually going on. 10386 if (false) { 10387 for (int i=0; i<mLaunchingProviders.size(); i++) { 10388 ContentProviderRecord cpr = (ContentProviderRecord) 10389 mLaunchingProviders.get(i); 10390 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10391 synchronized (cpr) { 10392 cpr.launchingApp = null; 10393 cpr.notifyAll(); 10394 } 10395 } 10396 } 10397 } 10398 10399 skipCurrentReceiverLocked(app); 10400 10401 // Unregister any receivers. 10402 if (app.receivers.size() > 0) { 10403 Iterator<ReceiverList> it = app.receivers.iterator(); 10404 while (it.hasNext()) { 10405 removeReceiverLocked(it.next()); 10406 } 10407 app.receivers.clear(); 10408 } 10409 10410 // If the app is undergoing backup, tell the backup manager about it 10411 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10412 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10413 try { 10414 IBackupManager bm = IBackupManager.Stub.asInterface( 10415 ServiceManager.getService(Context.BACKUP_SERVICE)); 10416 bm.agentDisconnected(app.info.packageName); 10417 } catch (RemoteException e) { 10418 // can't happen; backup manager is local 10419 } 10420 } 10421 10422 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10423 ProcessChangeItem item = mPendingProcessChanges.get(i); 10424 if (item.pid == app.pid) { 10425 mPendingProcessChanges.remove(i); 10426 mAvailProcessChanges.add(item); 10427 } 10428 } 10429 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10430 10431 // If the caller is restarting this app, then leave it in its 10432 // current lists and let the caller take care of it. 10433 if (restarting) { 10434 return; 10435 } 10436 10437 if (!app.persistent || app.isolated) { 10438 if (DEBUG_PROCESSES) Slog.v(TAG, 10439 "Removing non-persistent process during cleanup: " + app); 10440 mProcessNames.remove(app.processName, app.uid); 10441 mIsolatedProcesses.remove(app.uid); 10442 if (mHeavyWeightProcess == app) { 10443 mHeavyWeightProcess = null; 10444 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10445 } 10446 } else if (!app.removed) { 10447 // This app is persistent, so we need to keep its record around. 10448 // If it is not already on the pending app list, add it there 10449 // and start a new process for it. 10450 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10451 mPersistentStartingProcesses.add(app); 10452 restart = true; 10453 } 10454 } 10455 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10456 "Clean-up removing on hold: " + app); 10457 mProcessesOnHold.remove(app); 10458 10459 if (app == mHomeProcess) { 10460 mHomeProcess = null; 10461 } 10462 if (app == mPreviousProcess) { 10463 mPreviousProcess = null; 10464 } 10465 10466 if (restart && !app.isolated) { 10467 // We have components that still need to be running in the 10468 // process, so re-launch it. 10469 mProcessNames.put(app.processName, app.uid, app); 10470 startProcessLocked(app, "restart", app.processName); 10471 } else if (app.pid > 0 && app.pid != MY_PID) { 10472 // Goodbye! 10473 synchronized (mPidsSelfLocked) { 10474 mPidsSelfLocked.remove(app.pid); 10475 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10476 } 10477 app.setPid(0); 10478 } 10479 } 10480 10481 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10482 // Look through the content providers we are waiting to have launched, 10483 // and if any run in this process then either schedule a restart of 10484 // the process or kill the client waiting for it if this process has 10485 // gone bad. 10486 int NL = mLaunchingProviders.size(); 10487 boolean restart = false; 10488 for (int i=0; i<NL; i++) { 10489 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10490 if (cpr.launchingApp == app) { 10491 if (!alwaysBad && !app.bad) { 10492 restart = true; 10493 } else { 10494 removeDyingProviderLocked(app, cpr, true); 10495 NL = mLaunchingProviders.size(); 10496 } 10497 } 10498 } 10499 return restart; 10500 } 10501 10502 // ========================================================= 10503 // SERVICES 10504 // ========================================================= 10505 10506 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10507 int flags) { 10508 enforceNotIsolatedCaller("getServices"); 10509 synchronized (this) { 10510 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10511 } 10512 } 10513 10514 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10515 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10516 synchronized (this) { 10517 return mServices.getRunningServiceControlPanelLocked(name); 10518 } 10519 } 10520 10521 public ComponentName startService(IApplicationThread caller, Intent service, 10522 String resolvedType) { 10523 enforceNotIsolatedCaller("startService"); 10524 // Refuse possible leaked file descriptors 10525 if (service != null && service.hasFileDescriptors() == true) { 10526 throw new IllegalArgumentException("File descriptors passed in Intent"); 10527 } 10528 10529 if (DEBUG_SERVICE) 10530 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10531 synchronized(this) { 10532 final int callingPid = Binder.getCallingPid(); 10533 final int callingUid = Binder.getCallingUid(); 10534 final long origId = Binder.clearCallingIdentity(); 10535 ComponentName res = mServices.startServiceLocked(caller, service, 10536 resolvedType, callingPid, callingUid); 10537 Binder.restoreCallingIdentity(origId); 10538 return res; 10539 } 10540 } 10541 10542 ComponentName startServiceInPackage(int uid, 10543 Intent service, String resolvedType) { 10544 synchronized(this) { 10545 if (DEBUG_SERVICE) 10546 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10547 final long origId = Binder.clearCallingIdentity(); 10548 ComponentName res = mServices.startServiceLocked(null, service, 10549 resolvedType, -1, uid); 10550 Binder.restoreCallingIdentity(origId); 10551 return res; 10552 } 10553 } 10554 10555 public int stopService(IApplicationThread caller, Intent service, 10556 String resolvedType) { 10557 enforceNotIsolatedCaller("stopService"); 10558 // Refuse possible leaked file descriptors 10559 if (service != null && service.hasFileDescriptors() == true) { 10560 throw new IllegalArgumentException("File descriptors passed in Intent"); 10561 } 10562 10563 synchronized(this) { 10564 return mServices.stopServiceLocked(caller, service, resolvedType); 10565 } 10566 } 10567 10568 public IBinder peekService(Intent service, String resolvedType) { 10569 enforceNotIsolatedCaller("peekService"); 10570 // Refuse possible leaked file descriptors 10571 if (service != null && service.hasFileDescriptors() == true) { 10572 throw new IllegalArgumentException("File descriptors passed in Intent"); 10573 } 10574 synchronized(this) { 10575 return mServices.peekServiceLocked(service, resolvedType); 10576 } 10577 } 10578 10579 public boolean stopServiceToken(ComponentName className, IBinder token, 10580 int startId) { 10581 synchronized(this) { 10582 return mServices.stopServiceTokenLocked(className, token, startId); 10583 } 10584 } 10585 10586 public void setServiceForeground(ComponentName className, IBinder token, 10587 int id, Notification notification, boolean removeNotification) { 10588 synchronized(this) { 10589 mServices.setServiceForegroundLocked(className, token, id, notification, 10590 removeNotification); 10591 } 10592 } 10593 10594 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10595 String className, int flags) { 10596 boolean result = false; 10597 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10598 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10599 if (ActivityManager.checkUidPermission( 10600 android.Manifest.permission.INTERACT_ACROSS_USERS, 10601 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10602 ComponentName comp = new ComponentName(aInfo.packageName, className); 10603 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10604 + " requests FLAG_SINGLE_USER, but app does not hold " 10605 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10606 Slog.w(TAG, msg); 10607 throw new SecurityException(msg); 10608 } 10609 result = true; 10610 } 10611 } else if (componentProcessName == aInfo.packageName) { 10612 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10613 } else if ("system".equals(componentProcessName)) { 10614 result = true; 10615 } 10616 if (DEBUG_MU) { 10617 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10618 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10619 } 10620 return result; 10621 } 10622 10623 public int bindService(IApplicationThread caller, IBinder token, 10624 Intent service, String resolvedType, 10625 IServiceConnection connection, int flags, int userId) { 10626 enforceNotIsolatedCaller("bindService"); 10627 // Refuse possible leaked file descriptors 10628 if (service != null && service.hasFileDescriptors() == true) { 10629 throw new IllegalArgumentException("File descriptors passed in Intent"); 10630 } 10631 10632 checkValidCaller(Binder.getCallingUid(), userId); 10633 10634 synchronized(this) { 10635 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10636 connection, flags, userId); 10637 } 10638 } 10639 10640 public boolean unbindService(IServiceConnection connection) { 10641 synchronized (this) { 10642 return mServices.unbindServiceLocked(connection); 10643 } 10644 } 10645 10646 public void publishService(IBinder token, Intent intent, IBinder service) { 10647 // Refuse possible leaked file descriptors 10648 if (intent != null && intent.hasFileDescriptors() == true) { 10649 throw new IllegalArgumentException("File descriptors passed in Intent"); 10650 } 10651 10652 synchronized(this) { 10653 if (!(token instanceof ServiceRecord)) { 10654 throw new IllegalArgumentException("Invalid service token"); 10655 } 10656 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10657 } 10658 } 10659 10660 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10661 // Refuse possible leaked file descriptors 10662 if (intent != null && intent.hasFileDescriptors() == true) { 10663 throw new IllegalArgumentException("File descriptors passed in Intent"); 10664 } 10665 10666 synchronized(this) { 10667 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10668 } 10669 } 10670 10671 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10672 synchronized(this) { 10673 if (!(token instanceof ServiceRecord)) { 10674 throw new IllegalArgumentException("Invalid service token"); 10675 } 10676 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10677 } 10678 } 10679 10680 // ========================================================= 10681 // BACKUP AND RESTORE 10682 // ========================================================= 10683 10684 // Cause the target app to be launched if necessary and its backup agent 10685 // instantiated. The backup agent will invoke backupAgentCreated() on the 10686 // activity manager to announce its creation. 10687 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10688 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10689 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10690 10691 synchronized(this) { 10692 // !!! TODO: currently no check here that we're already bound 10693 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10694 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10695 synchronized (stats) { 10696 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10697 } 10698 10699 // Backup agent is now in use, its package can't be stopped. 10700 try { 10701 AppGlobals.getPackageManager().setPackageStoppedState( 10702 app.packageName, false, UserId.getUserId(app.uid)); 10703 } catch (RemoteException e) { 10704 } catch (IllegalArgumentException e) { 10705 Slog.w(TAG, "Failed trying to unstop package " 10706 + app.packageName + ": " + e); 10707 } 10708 10709 BackupRecord r = new BackupRecord(ss, app, backupMode); 10710 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10711 ? new ComponentName(app.packageName, app.backupAgentName) 10712 : new ComponentName("android", "FullBackupAgent"); 10713 // startProcessLocked() returns existing proc's record if it's already running 10714 ProcessRecord proc = startProcessLocked(app.processName, app, 10715 false, 0, "backup", hostingName, false, false); 10716 if (proc == null) { 10717 Slog.e(TAG, "Unable to start backup agent process " + r); 10718 return false; 10719 } 10720 10721 r.app = proc; 10722 mBackupTarget = r; 10723 mBackupAppName = app.packageName; 10724 10725 // Try not to kill the process during backup 10726 updateOomAdjLocked(proc); 10727 10728 // If the process is already attached, schedule the creation of the backup agent now. 10729 // If it is not yet live, this will be done when it attaches to the framework. 10730 if (proc.thread != null) { 10731 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10732 try { 10733 proc.thread.scheduleCreateBackupAgent(app, 10734 compatibilityInfoForPackageLocked(app), backupMode); 10735 } catch (RemoteException e) { 10736 // Will time out on the backup manager side 10737 } 10738 } else { 10739 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10740 } 10741 // Invariants: at this point, the target app process exists and the application 10742 // is either already running or in the process of coming up. mBackupTarget and 10743 // mBackupAppName describe the app, so that when it binds back to the AM we 10744 // know that it's scheduled for a backup-agent operation. 10745 } 10746 10747 return true; 10748 } 10749 10750 // A backup agent has just come up 10751 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10752 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10753 + " = " + agent); 10754 10755 synchronized(this) { 10756 if (!agentPackageName.equals(mBackupAppName)) { 10757 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10758 return; 10759 } 10760 } 10761 10762 long oldIdent = Binder.clearCallingIdentity(); 10763 try { 10764 IBackupManager bm = IBackupManager.Stub.asInterface( 10765 ServiceManager.getService(Context.BACKUP_SERVICE)); 10766 bm.agentConnected(agentPackageName, agent); 10767 } catch (RemoteException e) { 10768 // can't happen; the backup manager service is local 10769 } catch (Exception e) { 10770 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10771 e.printStackTrace(); 10772 } finally { 10773 Binder.restoreCallingIdentity(oldIdent); 10774 } 10775 } 10776 10777 // done with this agent 10778 public void unbindBackupAgent(ApplicationInfo appInfo) { 10779 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10780 if (appInfo == null) { 10781 Slog.w(TAG, "unbind backup agent for null app"); 10782 return; 10783 } 10784 10785 synchronized(this) { 10786 if (mBackupAppName == null) { 10787 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10788 return; 10789 } 10790 10791 if (!mBackupAppName.equals(appInfo.packageName)) { 10792 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10793 return; 10794 } 10795 10796 ProcessRecord proc = mBackupTarget.app; 10797 mBackupTarget = null; 10798 mBackupAppName = null; 10799 10800 // Not backing this app up any more; reset its OOM adjustment 10801 updateOomAdjLocked(proc); 10802 10803 // If the app crashed during backup, 'thread' will be null here 10804 if (proc.thread != null) { 10805 try { 10806 proc.thread.scheduleDestroyBackupAgent(appInfo, 10807 compatibilityInfoForPackageLocked(appInfo)); 10808 } catch (Exception e) { 10809 Slog.e(TAG, "Exception when unbinding backup agent:"); 10810 e.printStackTrace(); 10811 } 10812 } 10813 } 10814 } 10815 // ========================================================= 10816 // BROADCASTS 10817 // ========================================================= 10818 10819 private final List getStickiesLocked(String action, IntentFilter filter, 10820 List cur) { 10821 final ContentResolver resolver = mContext.getContentResolver(); 10822 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10823 if (list == null) { 10824 return cur; 10825 } 10826 int N = list.size(); 10827 for (int i=0; i<N; i++) { 10828 Intent intent = list.get(i); 10829 if (filter.match(resolver, intent, true, TAG) >= 0) { 10830 if (cur == null) { 10831 cur = new ArrayList<Intent>(); 10832 } 10833 cur.add(intent); 10834 } 10835 } 10836 return cur; 10837 } 10838 10839 boolean isPendingBroadcastProcessLocked(int pid) { 10840 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10841 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10842 } 10843 10844 void skipPendingBroadcastLocked(int pid) { 10845 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10846 for (BroadcastQueue queue : mBroadcastQueues) { 10847 queue.skipPendingBroadcastLocked(pid); 10848 } 10849 } 10850 10851 // The app just attached; send any pending broadcasts that it should receive 10852 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10853 boolean didSomething = false; 10854 for (BroadcastQueue queue : mBroadcastQueues) { 10855 didSomething |= queue.sendPendingBroadcastsLocked(app); 10856 } 10857 return didSomething; 10858 } 10859 10860 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10861 IIntentReceiver receiver, IntentFilter filter, String permission) { 10862 enforceNotIsolatedCaller("registerReceiver"); 10863 int callingUid; 10864 synchronized(this) { 10865 ProcessRecord callerApp = null; 10866 if (caller != null) { 10867 callerApp = getRecordForAppLocked(caller); 10868 if (callerApp == null) { 10869 throw new SecurityException( 10870 "Unable to find app for caller " + caller 10871 + " (pid=" + Binder.getCallingPid() 10872 + ") when registering receiver " + receiver); 10873 } 10874 if (callerApp.info.uid != Process.SYSTEM_UID && 10875 !callerApp.pkgList.contains(callerPackage)) { 10876 throw new SecurityException("Given caller package " + callerPackage 10877 + " is not running in process " + callerApp); 10878 } 10879 callingUid = callerApp.info.uid; 10880 } else { 10881 callerPackage = null; 10882 callingUid = Binder.getCallingUid(); 10883 } 10884 10885 List allSticky = null; 10886 10887 // Look for any matching sticky broadcasts... 10888 Iterator actions = filter.actionsIterator(); 10889 if (actions != null) { 10890 while (actions.hasNext()) { 10891 String action = (String)actions.next(); 10892 allSticky = getStickiesLocked(action, filter, allSticky); 10893 } 10894 } else { 10895 allSticky = getStickiesLocked(null, filter, allSticky); 10896 } 10897 10898 // The first sticky in the list is returned directly back to 10899 // the client. 10900 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10901 10902 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10903 + ": " + sticky); 10904 10905 if (receiver == null) { 10906 return sticky; 10907 } 10908 10909 ReceiverList rl 10910 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10911 if (rl == null) { 10912 rl = new ReceiverList(this, callerApp, 10913 Binder.getCallingPid(), 10914 Binder.getCallingUid(), receiver); 10915 if (rl.app != null) { 10916 rl.app.receivers.add(rl); 10917 } else { 10918 try { 10919 receiver.asBinder().linkToDeath(rl, 0); 10920 } catch (RemoteException e) { 10921 return sticky; 10922 } 10923 rl.linkedToDeath = true; 10924 } 10925 mRegisteredReceivers.put(receiver.asBinder(), rl); 10926 } 10927 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10928 permission, callingUid); 10929 rl.add(bf); 10930 if (!bf.debugCheck()) { 10931 Slog.w(TAG, "==> For Dynamic broadast"); 10932 } 10933 mReceiverResolver.addFilter(bf); 10934 10935 // Enqueue broadcasts for all existing stickies that match 10936 // this filter. 10937 if (allSticky != null) { 10938 ArrayList receivers = new ArrayList(); 10939 receivers.add(bf); 10940 10941 int N = allSticky.size(); 10942 for (int i=0; i<N; i++) { 10943 Intent intent = (Intent)allSticky.get(i); 10944 BroadcastQueue queue = broadcastQueueForIntent(intent); 10945 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10946 null, -1, -1, null, receivers, null, 0, null, null, 10947 false, true, true, false); 10948 queue.enqueueParallelBroadcastLocked(r); 10949 queue.scheduleBroadcastsLocked(); 10950 } 10951 } 10952 10953 return sticky; 10954 } 10955 } 10956 10957 public void unregisterReceiver(IIntentReceiver receiver) { 10958 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10959 10960 final long origId = Binder.clearCallingIdentity(); 10961 try { 10962 boolean doTrim = false; 10963 10964 synchronized(this) { 10965 ReceiverList rl 10966 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10967 if (rl != null) { 10968 if (rl.curBroadcast != null) { 10969 BroadcastRecord r = rl.curBroadcast; 10970 final boolean doNext = finishReceiverLocked( 10971 receiver.asBinder(), r.resultCode, r.resultData, 10972 r.resultExtras, r.resultAbort, true); 10973 if (doNext) { 10974 doTrim = true; 10975 r.queue.processNextBroadcast(false); 10976 } 10977 } 10978 10979 if (rl.app != null) { 10980 rl.app.receivers.remove(rl); 10981 } 10982 removeReceiverLocked(rl); 10983 if (rl.linkedToDeath) { 10984 rl.linkedToDeath = false; 10985 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10986 } 10987 } 10988 } 10989 10990 // If we actually concluded any broadcasts, we might now be able 10991 // to trim the recipients' apps from our working set 10992 if (doTrim) { 10993 trimApplications(); 10994 return; 10995 } 10996 10997 } finally { 10998 Binder.restoreCallingIdentity(origId); 10999 } 11000 } 11001 11002 void removeReceiverLocked(ReceiverList rl) { 11003 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11004 int N = rl.size(); 11005 for (int i=0; i<N; i++) { 11006 mReceiverResolver.removeFilter(rl.get(i)); 11007 } 11008 } 11009 11010 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11011 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11012 ProcessRecord r = mLruProcesses.get(i); 11013 if (r.thread != null) { 11014 try { 11015 r.thread.dispatchPackageBroadcast(cmd, packages); 11016 } catch (RemoteException ex) { 11017 } 11018 } 11019 } 11020 } 11021 11022 private final int broadcastIntentLocked(ProcessRecord callerApp, 11023 String callerPackage, Intent intent, String resolvedType, 11024 IIntentReceiver resultTo, int resultCode, String resultData, 11025 Bundle map, String requiredPermission, 11026 boolean ordered, boolean sticky, int callingPid, int callingUid, 11027 int userId) { 11028 intent = new Intent(intent); 11029 11030 // By default broadcasts do not go to stopped apps. 11031 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11032 11033 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11034 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11035 + " ordered=" + ordered + " userid=" + userId); 11036 if ((resultTo != null) && !ordered) { 11037 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11038 } 11039 11040 boolean onlySendToCaller = false; 11041 11042 // If the caller is trying to send this broadcast to a different 11043 // user, verify that is allowed. 11044 if (UserId.getUserId(callingUid) != userId) { 11045 if (checkComponentPermission( 11046 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11047 callingPid, callingUid, -1, true) 11048 != PackageManager.PERMISSION_GRANTED) { 11049 if (checkComponentPermission( 11050 android.Manifest.permission.INTERACT_ACROSS_USERS, 11051 callingPid, callingUid, -1, true) 11052 == PackageManager.PERMISSION_GRANTED) { 11053 onlySendToCaller = true; 11054 } else { 11055 String msg = "Permission Denial: " + intent.getAction() 11056 + " broadcast from " + callerPackage 11057 + " asks to send as user " + userId 11058 + " but is calling from user " + UserId.getUserId(callingUid) 11059 + "; this requires " 11060 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11061 Slog.w(TAG, msg); 11062 throw new SecurityException(msg); 11063 } 11064 } 11065 } 11066 11067 // Handle special intents: if this broadcast is from the package 11068 // manager about a package being removed, we need to remove all of 11069 // its activities from the history stack. 11070 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11071 intent.getAction()); 11072 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11073 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11074 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11075 || uidRemoved) { 11076 if (checkComponentPermission( 11077 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11078 callingPid, callingUid, -1, true) 11079 == PackageManager.PERMISSION_GRANTED) { 11080 if (uidRemoved) { 11081 final Bundle intentExtras = intent.getExtras(); 11082 final int uid = intentExtras != null 11083 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11084 if (uid >= 0) { 11085 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11086 synchronized (bs) { 11087 bs.removeUidStatsLocked(uid); 11088 } 11089 } 11090 } else { 11091 // If resources are unvailble just force stop all 11092 // those packages and flush the attribute cache as well. 11093 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11094 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11095 if (list != null && (list.length > 0)) { 11096 for (String pkg : list) { 11097 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11098 } 11099 sendPackageBroadcastLocked( 11100 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11101 } 11102 } else { 11103 Uri data = intent.getData(); 11104 String ssp; 11105 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11106 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11107 forceStopPackageLocked(ssp, 11108 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11109 false, userId); 11110 } 11111 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11112 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11113 new String[] {ssp}); 11114 } 11115 } 11116 } 11117 } 11118 } else { 11119 String msg = "Permission Denial: " + intent.getAction() 11120 + " broadcast from " + callerPackage + " (pid=" + callingPid 11121 + ", uid=" + callingUid + ")" 11122 + " requires " 11123 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11124 Slog.w(TAG, msg); 11125 throw new SecurityException(msg); 11126 } 11127 11128 // Special case for adding a package: by default turn on compatibility 11129 // mode. 11130 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11131 Uri data = intent.getData(); 11132 String ssp; 11133 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11134 mCompatModePackages.handlePackageAddedLocked(ssp, 11135 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11136 } 11137 } 11138 11139 /* 11140 * If this is the time zone changed action, queue up a message that will reset the timezone 11141 * of all currently running processes. This message will get queued up before the broadcast 11142 * happens. 11143 */ 11144 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11145 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11146 } 11147 11148 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11149 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11150 } 11151 11152 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11153 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11154 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11155 } 11156 11157 /* 11158 * Prevent non-system code (defined here to be non-persistent 11159 * processes) from sending protected broadcasts. 11160 */ 11161 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11162 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11163 callingUid == 0) { 11164 // Always okay. 11165 } else if (callerApp == null || !callerApp.persistent) { 11166 try { 11167 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11168 intent.getAction())) { 11169 String msg = "Permission Denial: not allowed to send broadcast " 11170 + intent.getAction() + " from pid=" 11171 + callingPid + ", uid=" + callingUid; 11172 Slog.w(TAG, msg); 11173 throw new SecurityException(msg); 11174 } 11175 } catch (RemoteException e) { 11176 Slog.w(TAG, "Remote exception", e); 11177 return ActivityManager.BROADCAST_SUCCESS; 11178 } 11179 } 11180 11181 // Add to the sticky list if requested. 11182 if (sticky) { 11183 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11184 callingPid, callingUid) 11185 != PackageManager.PERMISSION_GRANTED) { 11186 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11187 + callingPid + ", uid=" + callingUid 11188 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11189 Slog.w(TAG, msg); 11190 throw new SecurityException(msg); 11191 } 11192 if (requiredPermission != null) { 11193 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11194 + " and enforce permission " + requiredPermission); 11195 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11196 } 11197 if (intent.getComponent() != null) { 11198 throw new SecurityException( 11199 "Sticky broadcasts can't target a specific component"); 11200 } 11201 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11202 if (list == null) { 11203 list = new ArrayList<Intent>(); 11204 mStickyBroadcasts.put(intent.getAction(), list); 11205 } 11206 int N = list.size(); 11207 int i; 11208 for (i=0; i<N; i++) { 11209 if (intent.filterEquals(list.get(i))) { 11210 // This sticky already exists, replace it. 11211 list.set(i, new Intent(intent)); 11212 break; 11213 } 11214 } 11215 if (i >= N) { 11216 list.add(new Intent(intent)); 11217 } 11218 } 11219 11220 // Figure out who all will receive this broadcast. 11221 List receivers = null; 11222 List<BroadcastFilter> registeredReceivers = null; 11223 try { 11224 // Need to resolve the intent to interested receivers... 11225 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11226 == 0) { 11227 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11228 intent, resolvedType, STOCK_PM_FLAGS, userId); 11229 } 11230 if (intent.getComponent() == null) { 11231 registeredReceivers = mReceiverResolver.queryIntent(intent, 11232 resolvedType, false, userId); 11233 } 11234 } catch (RemoteException ex) { 11235 // pm is in same process, this will never happen. 11236 } 11237 11238 final boolean replacePending = 11239 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11240 11241 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11242 + " replacePending=" + replacePending); 11243 11244 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11245 if (!ordered && NR > 0) { 11246 // If we are not serializing this broadcast, then send the 11247 // registered receivers separately so they don't wait for the 11248 // components to be launched. 11249 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11250 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11251 callerPackage, callingPid, callingUid, requiredPermission, 11252 registeredReceivers, resultTo, resultCode, resultData, map, 11253 ordered, sticky, false, onlySendToCaller); 11254 if (DEBUG_BROADCAST) Slog.v( 11255 TAG, "Enqueueing parallel broadcast " + r); 11256 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11257 if (!replaced) { 11258 queue.enqueueParallelBroadcastLocked(r); 11259 queue.scheduleBroadcastsLocked(); 11260 } 11261 registeredReceivers = null; 11262 NR = 0; 11263 } 11264 11265 // Merge into one list. 11266 int ir = 0; 11267 if (receivers != null) { 11268 // A special case for PACKAGE_ADDED: do not allow the package 11269 // being added to see this broadcast. This prevents them from 11270 // using this as a back door to get run as soon as they are 11271 // installed. Maybe in the future we want to have a special install 11272 // broadcast or such for apps, but we'd like to deliberately make 11273 // this decision. 11274 String skipPackages[] = null; 11275 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11276 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11277 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11278 Uri data = intent.getData(); 11279 if (data != null) { 11280 String pkgName = data.getSchemeSpecificPart(); 11281 if (pkgName != null) { 11282 skipPackages = new String[] { pkgName }; 11283 } 11284 } 11285 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11286 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11287 } 11288 if (skipPackages != null && (skipPackages.length > 0)) { 11289 for (String skipPackage : skipPackages) { 11290 if (skipPackage != null) { 11291 int NT = receivers.size(); 11292 for (int it=0; it<NT; it++) { 11293 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11294 if (curt.activityInfo.packageName.equals(skipPackage)) { 11295 receivers.remove(it); 11296 it--; 11297 NT--; 11298 } 11299 } 11300 } 11301 } 11302 } 11303 11304 int NT = receivers != null ? receivers.size() : 0; 11305 int it = 0; 11306 ResolveInfo curt = null; 11307 BroadcastFilter curr = null; 11308 while (it < NT && ir < NR) { 11309 if (curt == null) { 11310 curt = (ResolveInfo)receivers.get(it); 11311 } 11312 if (curr == null) { 11313 curr = registeredReceivers.get(ir); 11314 } 11315 if (curr.getPriority() >= curt.priority) { 11316 // Insert this broadcast record into the final list. 11317 receivers.add(it, curr); 11318 ir++; 11319 curr = null; 11320 it++; 11321 NT++; 11322 } else { 11323 // Skip to the next ResolveInfo in the final list. 11324 it++; 11325 curt = null; 11326 } 11327 } 11328 } 11329 while (ir < NR) { 11330 if (receivers == null) { 11331 receivers = new ArrayList(); 11332 } 11333 receivers.add(registeredReceivers.get(ir)); 11334 ir++; 11335 } 11336 11337 if ((receivers != null && receivers.size() > 0) 11338 || resultTo != null) { 11339 BroadcastQueue queue = broadcastQueueForIntent(intent); 11340 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11341 callerPackage, callingPid, callingUid, requiredPermission, 11342 receivers, resultTo, resultCode, resultData, map, ordered, 11343 sticky, false, onlySendToCaller); 11344 if (DEBUG_BROADCAST) Slog.v( 11345 TAG, "Enqueueing ordered broadcast " + r 11346 + ": prev had " + queue.mOrderedBroadcasts.size()); 11347 if (DEBUG_BROADCAST) { 11348 int seq = r.intent.getIntExtra("seq", -1); 11349 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11350 } 11351 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11352 if (!replaced) { 11353 queue.enqueueOrderedBroadcastLocked(r); 11354 queue.scheduleBroadcastsLocked(); 11355 } 11356 } 11357 11358 return ActivityManager.BROADCAST_SUCCESS; 11359 } 11360 11361 final Intent verifyBroadcastLocked(Intent intent) { 11362 // Refuse possible leaked file descriptors 11363 if (intent != null && intent.hasFileDescriptors() == true) { 11364 throw new IllegalArgumentException("File descriptors passed in Intent"); 11365 } 11366 11367 int flags = intent.getFlags(); 11368 11369 if (!mProcessesReady) { 11370 // if the caller really truly claims to know what they're doing, go 11371 // ahead and allow the broadcast without launching any receivers 11372 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11373 intent = new Intent(intent); 11374 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11375 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11376 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11377 + " before boot completion"); 11378 throw new IllegalStateException("Cannot broadcast before boot completed"); 11379 } 11380 } 11381 11382 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11383 throw new IllegalArgumentException( 11384 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11385 } 11386 11387 return intent; 11388 } 11389 11390 public final int broadcastIntent(IApplicationThread caller, 11391 Intent intent, String resolvedType, IIntentReceiver resultTo, 11392 int resultCode, String resultData, Bundle map, 11393 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11394 enforceNotIsolatedCaller("broadcastIntent"); 11395 synchronized(this) { 11396 intent = verifyBroadcastLocked(intent); 11397 11398 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11399 final int callingPid = Binder.getCallingPid(); 11400 final int callingUid = Binder.getCallingUid(); 11401 final long origId = Binder.clearCallingIdentity(); 11402 int res = broadcastIntentLocked(callerApp, 11403 callerApp != null ? callerApp.info.packageName : null, 11404 intent, resolvedType, resultTo, 11405 resultCode, resultData, map, requiredPermission, serialized, sticky, 11406 callingPid, callingUid, userId); 11407 Binder.restoreCallingIdentity(origId); 11408 return res; 11409 } 11410 } 11411 11412 int broadcastIntentInPackage(String packageName, int uid, 11413 Intent intent, String resolvedType, IIntentReceiver resultTo, 11414 int resultCode, String resultData, Bundle map, 11415 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11416 synchronized(this) { 11417 intent = verifyBroadcastLocked(intent); 11418 11419 final long origId = Binder.clearCallingIdentity(); 11420 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11421 resultTo, resultCode, resultData, map, requiredPermission, 11422 serialized, sticky, -1, uid, userId); 11423 Binder.restoreCallingIdentity(origId); 11424 return res; 11425 } 11426 } 11427 11428 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11429 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11430 // Refuse possible leaked file descriptors 11431 if (intent != null && intent.hasFileDescriptors() == true) { 11432 throw new IllegalArgumentException("File descriptors passed in Intent"); 11433 } 11434 11435 synchronized(this) { 11436 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11437 != PackageManager.PERMISSION_GRANTED) { 11438 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11439 + Binder.getCallingPid() 11440 + ", uid=" + Binder.getCallingUid() 11441 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11442 Slog.w(TAG, msg); 11443 throw new SecurityException(msg); 11444 } 11445 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11446 if (list != null) { 11447 int N = list.size(); 11448 int i; 11449 for (i=0; i<N; i++) { 11450 if (intent.filterEquals(list.get(i))) { 11451 list.remove(i); 11452 break; 11453 } 11454 } 11455 } 11456 } 11457 } 11458 11459 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11460 String resultData, Bundle resultExtras, boolean resultAbort, 11461 boolean explicit) { 11462 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11463 if (r == null) { 11464 Slog.w(TAG, "finishReceiver called but not found on queue"); 11465 return false; 11466 } 11467 11468 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11469 explicit); 11470 } 11471 11472 public void finishReceiver(IBinder who, int resultCode, String resultData, 11473 Bundle resultExtras, boolean resultAbort) { 11474 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11475 11476 // Refuse possible leaked file descriptors 11477 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11478 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11479 } 11480 11481 final long origId = Binder.clearCallingIdentity(); 11482 try { 11483 boolean doNext = false; 11484 BroadcastRecord r = null; 11485 11486 synchronized(this) { 11487 r = broadcastRecordForReceiverLocked(who); 11488 if (r != null) { 11489 doNext = r.queue.finishReceiverLocked(r, resultCode, 11490 resultData, resultExtras, resultAbort, true); 11491 } 11492 } 11493 11494 if (doNext) { 11495 r.queue.processNextBroadcast(false); 11496 } 11497 trimApplications(); 11498 } finally { 11499 Binder.restoreCallingIdentity(origId); 11500 } 11501 } 11502 11503 // ========================================================= 11504 // INSTRUMENTATION 11505 // ========================================================= 11506 11507 public boolean startInstrumentation(ComponentName className, 11508 String profileFile, int flags, Bundle arguments, 11509 IInstrumentationWatcher watcher) { 11510 enforceNotIsolatedCaller("startInstrumentation"); 11511 // Refuse possible leaked file descriptors 11512 if (arguments != null && arguments.hasFileDescriptors()) { 11513 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11514 } 11515 11516 synchronized(this) { 11517 InstrumentationInfo ii = null; 11518 ApplicationInfo ai = null; 11519 try { 11520 ii = mContext.getPackageManager().getInstrumentationInfo( 11521 className, STOCK_PM_FLAGS); 11522 ai = mContext.getPackageManager().getApplicationInfo( 11523 ii.targetPackage, STOCK_PM_FLAGS); 11524 } catch (PackageManager.NameNotFoundException e) { 11525 } 11526 if (ii == null) { 11527 reportStartInstrumentationFailure(watcher, className, 11528 "Unable to find instrumentation info for: " + className); 11529 return false; 11530 } 11531 if (ai == null) { 11532 reportStartInstrumentationFailure(watcher, className, 11533 "Unable to find instrumentation target package: " + ii.targetPackage); 11534 return false; 11535 } 11536 11537 int match = mContext.getPackageManager().checkSignatures( 11538 ii.targetPackage, ii.packageName); 11539 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11540 String msg = "Permission Denial: starting instrumentation " 11541 + className + " from pid=" 11542 + Binder.getCallingPid() 11543 + ", uid=" + Binder.getCallingPid() 11544 + " not allowed because package " + ii.packageName 11545 + " does not have a signature matching the target " 11546 + ii.targetPackage; 11547 reportStartInstrumentationFailure(watcher, className, msg); 11548 throw new SecurityException(msg); 11549 } 11550 11551 int userId = UserId.getCallingUserId(); 11552 final long origId = Binder.clearCallingIdentity(); 11553 // Instrumentation can kill and relaunch even persistent processes 11554 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11555 ProcessRecord app = addAppLocked(ai, false); 11556 app.instrumentationClass = className; 11557 app.instrumentationInfo = ai; 11558 app.instrumentationProfileFile = profileFile; 11559 app.instrumentationArguments = arguments; 11560 app.instrumentationWatcher = watcher; 11561 app.instrumentationResultClass = className; 11562 Binder.restoreCallingIdentity(origId); 11563 } 11564 11565 return true; 11566 } 11567 11568 /** 11569 * Report errors that occur while attempting to start Instrumentation. Always writes the 11570 * error to the logs, but if somebody is watching, send the report there too. This enables 11571 * the "am" command to report errors with more information. 11572 * 11573 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11574 * @param cn The component name of the instrumentation. 11575 * @param report The error report. 11576 */ 11577 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11578 ComponentName cn, String report) { 11579 Slog.w(TAG, report); 11580 try { 11581 if (watcher != null) { 11582 Bundle results = new Bundle(); 11583 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11584 results.putString("Error", report); 11585 watcher.instrumentationStatus(cn, -1, results); 11586 } 11587 } catch (RemoteException e) { 11588 Slog.w(TAG, e); 11589 } 11590 } 11591 11592 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11593 if (app.instrumentationWatcher != null) { 11594 try { 11595 // NOTE: IInstrumentationWatcher *must* be oneway here 11596 app.instrumentationWatcher.instrumentationFinished( 11597 app.instrumentationClass, 11598 resultCode, 11599 results); 11600 } catch (RemoteException e) { 11601 } 11602 } 11603 app.instrumentationWatcher = null; 11604 app.instrumentationClass = null; 11605 app.instrumentationInfo = null; 11606 app.instrumentationProfileFile = null; 11607 app.instrumentationArguments = null; 11608 11609 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11610 } 11611 11612 public void finishInstrumentation(IApplicationThread target, 11613 int resultCode, Bundle results) { 11614 int userId = UserId.getCallingUserId(); 11615 // Refuse possible leaked file descriptors 11616 if (results != null && results.hasFileDescriptors()) { 11617 throw new IllegalArgumentException("File descriptors passed in Intent"); 11618 } 11619 11620 synchronized(this) { 11621 ProcessRecord app = getRecordForAppLocked(target); 11622 if (app == null) { 11623 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11624 return; 11625 } 11626 final long origId = Binder.clearCallingIdentity(); 11627 finishInstrumentationLocked(app, resultCode, results); 11628 Binder.restoreCallingIdentity(origId); 11629 } 11630 } 11631 11632 // ========================================================= 11633 // CONFIGURATION 11634 // ========================================================= 11635 11636 public ConfigurationInfo getDeviceConfigurationInfo() { 11637 ConfigurationInfo config = new ConfigurationInfo(); 11638 synchronized (this) { 11639 config.reqTouchScreen = mConfiguration.touchscreen; 11640 config.reqKeyboardType = mConfiguration.keyboard; 11641 config.reqNavigation = mConfiguration.navigation; 11642 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11643 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11644 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11645 } 11646 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11647 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11648 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11649 } 11650 config.reqGlEsVersion = GL_ES_VERSION; 11651 } 11652 return config; 11653 } 11654 11655 public Configuration getConfiguration() { 11656 Configuration ci; 11657 synchronized(this) { 11658 ci = new Configuration(mConfiguration); 11659 } 11660 return ci; 11661 } 11662 11663 public void updatePersistentConfiguration(Configuration values) { 11664 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11665 "updateConfiguration()"); 11666 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11667 "updateConfiguration()"); 11668 if (values == null) { 11669 throw new NullPointerException("Configuration must not be null"); 11670 } 11671 11672 synchronized(this) { 11673 final long origId = Binder.clearCallingIdentity(); 11674 updateConfigurationLocked(values, null, true, false); 11675 Binder.restoreCallingIdentity(origId); 11676 } 11677 } 11678 11679 public void updateConfiguration(Configuration values) { 11680 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11681 "updateConfiguration()"); 11682 11683 synchronized(this) { 11684 if (values == null && mWindowManager != null) { 11685 // sentinel: fetch the current configuration from the window manager 11686 values = mWindowManager.computeNewConfiguration(); 11687 } 11688 11689 if (mWindowManager != null) { 11690 mProcessList.applyDisplaySize(mWindowManager); 11691 } 11692 11693 final long origId = Binder.clearCallingIdentity(); 11694 if (values != null) { 11695 Settings.System.clearConfiguration(values); 11696 } 11697 updateConfigurationLocked(values, null, false, false); 11698 Binder.restoreCallingIdentity(origId); 11699 } 11700 } 11701 11702 /** 11703 * Do either or both things: (1) change the current configuration, and (2) 11704 * make sure the given activity is running with the (now) current 11705 * configuration. Returns true if the activity has been left running, or 11706 * false if <var>starting</var> is being destroyed to match the new 11707 * configuration. 11708 * @param persistent TODO 11709 */ 11710 boolean updateConfigurationLocked(Configuration values, 11711 ActivityRecord starting, boolean persistent, boolean initLocale) { 11712 // do nothing if we are headless 11713 if (mHeadless) return true; 11714 11715 int changes = 0; 11716 11717 boolean kept = true; 11718 11719 if (values != null) { 11720 Configuration newConfig = new Configuration(mConfiguration); 11721 changes = newConfig.updateFrom(values); 11722 if (changes != 0) { 11723 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11724 Slog.i(TAG, "Updating configuration to: " + values); 11725 } 11726 11727 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11728 11729 if (values.locale != null && !initLocale) { 11730 saveLocaleLocked(values.locale, 11731 !values.locale.equals(mConfiguration.locale), 11732 values.userSetLocale); 11733 } 11734 11735 mConfigurationSeq++; 11736 if (mConfigurationSeq <= 0) { 11737 mConfigurationSeq = 1; 11738 } 11739 newConfig.seq = mConfigurationSeq; 11740 mConfiguration = newConfig; 11741 Slog.i(TAG, "Config changed: " + newConfig); 11742 11743 final Configuration configCopy = new Configuration(mConfiguration); 11744 11745 // TODO: If our config changes, should we auto dismiss any currently 11746 // showing dialogs? 11747 mShowDialogs = shouldShowDialogs(newConfig); 11748 11749 AttributeCache ac = AttributeCache.instance(); 11750 if (ac != null) { 11751 ac.updateConfiguration(configCopy); 11752 } 11753 11754 // Make sure all resources in our process are updated 11755 // right now, so that anyone who is going to retrieve 11756 // resource values after we return will be sure to get 11757 // the new ones. This is especially important during 11758 // boot, where the first config change needs to guarantee 11759 // all resources have that config before following boot 11760 // code is executed. 11761 mSystemThread.applyConfigurationToResources(configCopy); 11762 11763 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11764 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11765 msg.obj = new Configuration(configCopy); 11766 mHandler.sendMessage(msg); 11767 } 11768 11769 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11770 ProcessRecord app = mLruProcesses.get(i); 11771 try { 11772 if (app.thread != null) { 11773 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11774 + app.processName + " new config " + mConfiguration); 11775 app.thread.scheduleConfigurationChanged(configCopy); 11776 } 11777 } catch (Exception e) { 11778 } 11779 } 11780 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11781 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11782 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11783 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11784 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11785 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11786 broadcastIntentLocked(null, null, 11787 new Intent(Intent.ACTION_LOCALE_CHANGED), 11788 null, null, 0, null, null, 11789 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11790 } 11791 } 11792 } 11793 11794 if (changes != 0 && starting == null) { 11795 // If the configuration changed, and the caller is not already 11796 // in the process of starting an activity, then find the top 11797 // activity to check if its configuration needs to change. 11798 starting = mMainStack.topRunningActivityLocked(null); 11799 } 11800 11801 if (starting != null) { 11802 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11803 // And we need to make sure at this point that all other activities 11804 // are made visible with the correct configuration. 11805 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11806 } 11807 11808 if (values != null && mWindowManager != null) { 11809 mWindowManager.setNewConfiguration(mConfiguration); 11810 } 11811 11812 return kept; 11813 } 11814 11815 /** 11816 * Decide based on the configuration whether we should shouw the ANR, 11817 * crash, etc dialogs. The idea is that if there is no affordnace to 11818 * press the on-screen buttons, we shouldn't show the dialog. 11819 * 11820 * A thought: SystemUI might also want to get told about this, the Power 11821 * dialog / global actions also might want different behaviors. 11822 */ 11823 private static final boolean shouldShowDialogs(Configuration config) { 11824 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11825 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11826 } 11827 11828 /** 11829 * Save the locale. You must be inside a synchronized (this) block. 11830 */ 11831 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11832 if(isDiff) { 11833 SystemProperties.set("user.language", l.getLanguage()); 11834 SystemProperties.set("user.region", l.getCountry()); 11835 } 11836 11837 if(isPersist) { 11838 SystemProperties.set("persist.sys.language", l.getLanguage()); 11839 SystemProperties.set("persist.sys.country", l.getCountry()); 11840 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11841 } 11842 } 11843 11844 @Override 11845 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11846 ActivityRecord srec = ActivityRecord.forToken(token); 11847 return srec != null && srec.task.affinity != null && 11848 srec.task.affinity.equals(destAffinity); 11849 } 11850 11851 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11852 Intent resultData) { 11853 ComponentName dest = destIntent.getComponent(); 11854 11855 synchronized (this) { 11856 ActivityRecord srec = ActivityRecord.forToken(token); 11857 if (srec == null) { 11858 return false; 11859 } 11860 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11861 final int start = history.indexOf(srec); 11862 if (start < 0) { 11863 // Current activity is not in history stack; do nothing. 11864 return false; 11865 } 11866 int finishTo = start - 1; 11867 ActivityRecord parent = null; 11868 boolean foundParentInTask = false; 11869 if (dest != null) { 11870 TaskRecord tr = srec.task; 11871 for (int i = start - 1; i >= 0; i--) { 11872 ActivityRecord r = history.get(i); 11873 if (tr != r.task) { 11874 // Couldn't find parent in the same task; stop at the one above this. 11875 // (Root of current task; in-app "home" behavior) 11876 // Always at least finish the current activity. 11877 finishTo = Math.min(start - 1, i + 1); 11878 parent = history.get(finishTo); 11879 break; 11880 } else if (r.info.packageName.equals(dest.getPackageName()) && 11881 r.info.name.equals(dest.getClassName())) { 11882 finishTo = i; 11883 parent = r; 11884 foundParentInTask = true; 11885 break; 11886 } 11887 } 11888 } 11889 11890 if (mController != null) { 11891 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11892 if (next != null) { 11893 // ask watcher if this is allowed 11894 boolean resumeOK = true; 11895 try { 11896 resumeOK = mController.activityResuming(next.packageName); 11897 } catch (RemoteException e) { 11898 mController = null; 11899 } 11900 11901 if (!resumeOK) { 11902 return false; 11903 } 11904 } 11905 } 11906 final long origId = Binder.clearCallingIdentity(); 11907 for (int i = start; i > finishTo; i--) { 11908 ActivityRecord r = history.get(i); 11909 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11910 "navigate-up"); 11911 // Only return the supplied result for the first activity finished 11912 resultCode = Activity.RESULT_CANCELED; 11913 resultData = null; 11914 } 11915 11916 if (parent != null && foundParentInTask) { 11917 final int parentLaunchMode = parent.info.launchMode; 11918 final int destIntentFlags = destIntent.getFlags(); 11919 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11920 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11921 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11922 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11923 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11924 } else { 11925 try { 11926 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11927 destIntent.getComponent(), 0, UserId.getCallingUserId()); 11928 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11929 null, aInfo, parent.appToken, null, 11930 0, -1, parent.launchedFromUid, 0, null, true, null); 11931 foundParentInTask = res == ActivityManager.START_SUCCESS; 11932 } catch (RemoteException e) { 11933 foundParentInTask = false; 11934 } 11935 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11936 resultData, "navigate-up"); 11937 } 11938 } 11939 Binder.restoreCallingIdentity(origId); 11940 return foundParentInTask; 11941 } 11942 } 11943 11944 public int getLaunchedFromUid(IBinder activityToken) { 11945 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11946 if (srec == null) { 11947 return -1; 11948 } 11949 return srec.launchedFromUid; 11950 } 11951 11952 // ========================================================= 11953 // LIFETIME MANAGEMENT 11954 // ========================================================= 11955 11956 // Returns which broadcast queue the app is the current [or imminent] receiver 11957 // on, or 'null' if the app is not an active broadcast recipient. 11958 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11959 BroadcastRecord r = app.curReceiver; 11960 if (r != null) { 11961 return r.queue; 11962 } 11963 11964 // It's not the current receiver, but it might be starting up to become one 11965 synchronized (this) { 11966 for (BroadcastQueue queue : mBroadcastQueues) { 11967 r = queue.mPendingBroadcast; 11968 if (r != null && r.curApp == app) { 11969 // found it; report which queue it's in 11970 return queue; 11971 } 11972 } 11973 } 11974 11975 return null; 11976 } 11977 11978 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11979 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11980 if (mAdjSeq == app.adjSeq) { 11981 // This adjustment has already been computed. If we are calling 11982 // from the top, we may have already computed our adjustment with 11983 // an earlier hidden adjustment that isn't really for us... if 11984 // so, use the new hidden adjustment. 11985 if (!recursed && app.hidden) { 11986 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 11987 } 11988 return app.curRawAdj; 11989 } 11990 11991 if (app.thread == null) { 11992 app.adjSeq = mAdjSeq; 11993 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 11994 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 11995 } 11996 11997 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 11998 app.adjSource = null; 11999 app.adjTarget = null; 12000 app.empty = false; 12001 app.hidden = false; 12002 12003 final int activitiesSize = app.activities.size(); 12004 12005 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12006 // The max adjustment doesn't allow this app to be anything 12007 // below foreground, so it is not worth doing work for it. 12008 app.adjType = "fixed"; 12009 app.adjSeq = mAdjSeq; 12010 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12011 app.foregroundActivities = false; 12012 app.keeping = true; 12013 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12014 // System process can do UI, and when they do we want to have 12015 // them trim their memory after the user leaves the UI. To 12016 // facilitate this, here we need to determine whether or not it 12017 // is currently showing UI. 12018 app.systemNoUi = true; 12019 if (app == TOP_APP) { 12020 app.systemNoUi = false; 12021 } else if (activitiesSize > 0) { 12022 for (int j = 0; j < activitiesSize; j++) { 12023 final ActivityRecord r = app.activities.get(j); 12024 if (r.visible) { 12025 app.systemNoUi = false; 12026 break; 12027 } 12028 } 12029 } 12030 return (app.curAdj=app.maxAdj); 12031 } 12032 12033 app.keeping = false; 12034 app.systemNoUi = false; 12035 12036 // Determine the importance of the process, starting with most 12037 // important to least, and assign an appropriate OOM adjustment. 12038 int adj; 12039 int schedGroup; 12040 boolean foregroundActivities = false; 12041 boolean interesting = false; 12042 BroadcastQueue queue; 12043 if (app == TOP_APP) { 12044 // The last app on the list is the foreground app. 12045 adj = ProcessList.FOREGROUND_APP_ADJ; 12046 schedGroup = Process.THREAD_GROUP_DEFAULT; 12047 app.adjType = "top-activity"; 12048 foregroundActivities = true; 12049 interesting = true; 12050 } else if (app.instrumentationClass != null) { 12051 // Don't want to kill running instrumentation. 12052 adj = ProcessList.FOREGROUND_APP_ADJ; 12053 schedGroup = Process.THREAD_GROUP_DEFAULT; 12054 app.adjType = "instrumentation"; 12055 interesting = true; 12056 } else if ((queue = isReceivingBroadcast(app)) != null) { 12057 // An app that is currently receiving a broadcast also 12058 // counts as being in the foreground for OOM killer purposes. 12059 // It's placed in a sched group based on the nature of the 12060 // broadcast as reflected by which queue it's active in. 12061 adj = ProcessList.FOREGROUND_APP_ADJ; 12062 schedGroup = (queue == mFgBroadcastQueue) 12063 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12064 app.adjType = "broadcast"; 12065 } else if (app.executingServices.size() > 0) { 12066 // An app that is currently executing a service callback also 12067 // counts as being in the foreground. 12068 adj = ProcessList.FOREGROUND_APP_ADJ; 12069 schedGroup = Process.THREAD_GROUP_DEFAULT; 12070 app.adjType = "exec-service"; 12071 } else if (activitiesSize > 0) { 12072 // This app is in the background with paused activities. 12073 // We inspect activities to potentially upgrade adjustment further below. 12074 adj = hiddenAdj; 12075 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12076 app.hidden = true; 12077 app.adjType = "bg-activities"; 12078 } else { 12079 // A very not-needed process. If this is lower in the lru list, 12080 // we will push it in to the empty bucket. 12081 adj = hiddenAdj; 12082 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12083 app.hidden = true; 12084 app.empty = true; 12085 app.adjType = "bg-empty"; 12086 } 12087 12088 boolean hasStoppingActivities = false; 12089 12090 // Examine all activities if not already foreground. 12091 if (!foregroundActivities && activitiesSize > 0) { 12092 for (int j = 0; j < activitiesSize; j++) { 12093 final ActivityRecord r = app.activities.get(j); 12094 if (r.visible) { 12095 // App has a visible activity; only upgrade adjustment. 12096 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12097 adj = ProcessList.VISIBLE_APP_ADJ; 12098 app.adjType = "visible"; 12099 } 12100 schedGroup = Process.THREAD_GROUP_DEFAULT; 12101 app.hidden = false; 12102 foregroundActivities = true; 12103 break; 12104 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12105 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12106 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12107 app.adjType = "pausing"; 12108 } 12109 app.hidden = false; 12110 foregroundActivities = true; 12111 } else if (r.state == ActivityState.STOPPING) { 12112 // We will apply the actual adjustment later, because 12113 // we want to allow this process to immediately go through 12114 // any memory trimming that is in effect. 12115 app.hidden = false; 12116 foregroundActivities = true; 12117 hasStoppingActivities = true; 12118 } 12119 } 12120 } 12121 12122 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12123 if (app.foregroundServices) { 12124 // The user is aware of this app, so make it visible. 12125 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12126 app.hidden = false; 12127 app.adjType = "foreground-service"; 12128 schedGroup = Process.THREAD_GROUP_DEFAULT; 12129 } else if (app.forcingToForeground != null) { 12130 // The user is aware of this app, so make it visible. 12131 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12132 app.hidden = false; 12133 app.adjType = "force-foreground"; 12134 app.adjSource = app.forcingToForeground; 12135 schedGroup = Process.THREAD_GROUP_DEFAULT; 12136 } 12137 } 12138 12139 if (app.foregroundServices) { 12140 interesting = true; 12141 } 12142 12143 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12144 // We don't want to kill the current heavy-weight process. 12145 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12146 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12147 app.hidden = false; 12148 app.adjType = "heavy"; 12149 } 12150 12151 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12152 // This process is hosting what we currently consider to be the 12153 // home app, so we don't want to let it go into the background. 12154 adj = ProcessList.HOME_APP_ADJ; 12155 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12156 app.hidden = false; 12157 app.adjType = "home"; 12158 } 12159 12160 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12161 && app.activities.size() > 0) { 12162 // This was the previous process that showed UI to the user. 12163 // We want to try to keep it around more aggressively, to give 12164 // a good experience around switching between two apps. 12165 adj = ProcessList.PREVIOUS_APP_ADJ; 12166 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12167 app.hidden = false; 12168 app.adjType = "previous"; 12169 } 12170 12171 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12172 + " reason=" + app.adjType); 12173 12174 // By default, we use the computed adjustment. It may be changed if 12175 // there are applications dependent on our services or providers, but 12176 // this gives us a baseline and makes sure we don't get into an 12177 // infinite recursion. 12178 app.adjSeq = mAdjSeq; 12179 app.curRawAdj = app.nonStoppingAdj = adj; 12180 12181 if (mBackupTarget != null && app == mBackupTarget.app) { 12182 // If possible we want to avoid killing apps while they're being backed up 12183 if (adj > ProcessList.BACKUP_APP_ADJ) { 12184 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12185 adj = ProcessList.BACKUP_APP_ADJ; 12186 app.adjType = "backup"; 12187 app.hidden = false; 12188 } 12189 } 12190 12191 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12192 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12193 final long now = SystemClock.uptimeMillis(); 12194 // This process is more important if the top activity is 12195 // bound to the service. 12196 Iterator<ServiceRecord> jt = app.services.iterator(); 12197 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12198 ServiceRecord s = jt.next(); 12199 if (s.startRequested) { 12200 if (app.hasShownUi && app != mHomeProcess) { 12201 // If this process has shown some UI, let it immediately 12202 // go to the LRU list because it may be pretty heavy with 12203 // UI stuff. We'll tag it with a label just to help 12204 // debug and understand what is going on. 12205 if (adj > ProcessList.SERVICE_ADJ) { 12206 app.adjType = "started-bg-ui-services"; 12207 } 12208 } else { 12209 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12210 // This service has seen some activity within 12211 // recent memory, so we will keep its process ahead 12212 // of the background processes. 12213 if (adj > ProcessList.SERVICE_ADJ) { 12214 adj = ProcessList.SERVICE_ADJ; 12215 app.adjType = "started-services"; 12216 app.hidden = false; 12217 } 12218 } 12219 // If we have let the service slide into the background 12220 // state, still have some text describing what it is doing 12221 // even though the service no longer has an impact. 12222 if (adj > ProcessList.SERVICE_ADJ) { 12223 app.adjType = "started-bg-services"; 12224 } 12225 } 12226 // Don't kill this process because it is doing work; it 12227 // has said it is doing work. 12228 app.keeping = true; 12229 } 12230 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12231 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12232 Iterator<ArrayList<ConnectionRecord>> kt 12233 = s.connections.values().iterator(); 12234 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12235 ArrayList<ConnectionRecord> clist = kt.next(); 12236 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12237 // XXX should compute this based on the max of 12238 // all connected clients. 12239 ConnectionRecord cr = clist.get(i); 12240 if (cr.binding.client == app) { 12241 // Binding to ourself is not interesting. 12242 continue; 12243 } 12244 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12245 ProcessRecord client = cr.binding.client; 12246 int clientAdj = adj; 12247 int myHiddenAdj = hiddenAdj; 12248 if (myHiddenAdj > client.hiddenAdj) { 12249 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12250 myHiddenAdj = client.hiddenAdj; 12251 } else { 12252 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12253 } 12254 } 12255 clientAdj = computeOomAdjLocked( 12256 client, myHiddenAdj, TOP_APP, true, doingAll); 12257 String adjType = null; 12258 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12259 // Not doing bind OOM management, so treat 12260 // this guy more like a started service. 12261 if (app.hasShownUi && app != mHomeProcess) { 12262 // If this process has shown some UI, let it immediately 12263 // go to the LRU list because it may be pretty heavy with 12264 // UI stuff. We'll tag it with a label just to help 12265 // debug and understand what is going on. 12266 if (adj > clientAdj) { 12267 adjType = "bound-bg-ui-services"; 12268 } 12269 app.hidden = false; 12270 clientAdj = adj; 12271 } else { 12272 if (now >= (s.lastActivity 12273 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12274 // This service has not seen activity within 12275 // recent memory, so allow it to drop to the 12276 // LRU list if there is no other reason to keep 12277 // it around. We'll also tag it with a label just 12278 // to help debug and undertand what is going on. 12279 if (adj > clientAdj) { 12280 adjType = "bound-bg-services"; 12281 } 12282 clientAdj = adj; 12283 } 12284 } 12285 } 12286 if (adj > clientAdj) { 12287 // If this process has recently shown UI, and 12288 // the process that is binding to it is less 12289 // important than being visible, then we don't 12290 // care about the binding as much as we care 12291 // about letting this process get into the LRU 12292 // list to be killed and restarted if needed for 12293 // memory. 12294 if (app.hasShownUi && app != mHomeProcess 12295 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12296 adjType = "bound-bg-ui-services"; 12297 } else { 12298 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12299 |Context.BIND_IMPORTANT)) != 0) { 12300 adj = clientAdj; 12301 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12302 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12303 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12304 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12305 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12306 adj = clientAdj; 12307 } else { 12308 app.pendingUiClean = true; 12309 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12310 adj = ProcessList.VISIBLE_APP_ADJ; 12311 } 12312 } 12313 if (!client.hidden) { 12314 app.hidden = false; 12315 } 12316 if (client.keeping) { 12317 app.keeping = true; 12318 } 12319 adjType = "service"; 12320 } 12321 } 12322 if (adjType != null) { 12323 app.adjType = adjType; 12324 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12325 .REASON_SERVICE_IN_USE; 12326 app.adjSource = cr.binding.client; 12327 app.adjSourceOom = clientAdj; 12328 app.adjTarget = s.name; 12329 } 12330 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12331 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12332 schedGroup = Process.THREAD_GROUP_DEFAULT; 12333 } 12334 } 12335 } 12336 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12337 ActivityRecord a = cr.activity; 12338 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12339 (a.visible || a.state == ActivityState.RESUMED 12340 || a.state == ActivityState.PAUSING)) { 12341 adj = ProcessList.FOREGROUND_APP_ADJ; 12342 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12343 schedGroup = Process.THREAD_GROUP_DEFAULT; 12344 } 12345 app.hidden = false; 12346 app.adjType = "service"; 12347 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12348 .REASON_SERVICE_IN_USE; 12349 app.adjSource = a; 12350 app.adjSourceOom = adj; 12351 app.adjTarget = s.name; 12352 } 12353 } 12354 } 12355 } 12356 } 12357 } 12358 12359 // Finally, if this process has active services running in it, we 12360 // would like to avoid killing it unless it would prevent the current 12361 // application from running. By default we put the process in 12362 // with the rest of the background processes; as we scan through 12363 // its services we may bump it up from there. 12364 if (adj > hiddenAdj) { 12365 adj = hiddenAdj; 12366 app.hidden = false; 12367 app.adjType = "bg-services"; 12368 } 12369 } 12370 12371 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12372 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12373 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12374 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12375 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12376 ContentProviderRecord cpr = jt.next(); 12377 for (int i = cpr.connections.size()-1; 12378 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12379 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12380 i--) { 12381 ContentProviderConnection conn = cpr.connections.get(i); 12382 ProcessRecord client = conn.client; 12383 if (client == app) { 12384 // Being our own client is not interesting. 12385 continue; 12386 } 12387 int myHiddenAdj = hiddenAdj; 12388 if (myHiddenAdj > client.hiddenAdj) { 12389 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12390 myHiddenAdj = client.hiddenAdj; 12391 } else { 12392 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12393 } 12394 } 12395 int clientAdj = computeOomAdjLocked( 12396 client, myHiddenAdj, TOP_APP, true, doingAll); 12397 if (adj > clientAdj) { 12398 if (app.hasShownUi && app != mHomeProcess 12399 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12400 app.adjType = "bg-ui-provider"; 12401 } else { 12402 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12403 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12404 app.adjType = "provider"; 12405 } 12406 if (!client.hidden) { 12407 app.hidden = false; 12408 } 12409 if (client.keeping) { 12410 app.keeping = true; 12411 } 12412 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12413 .REASON_PROVIDER_IN_USE; 12414 app.adjSource = client; 12415 app.adjSourceOom = clientAdj; 12416 app.adjTarget = cpr.name; 12417 } 12418 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12419 schedGroup = Process.THREAD_GROUP_DEFAULT; 12420 } 12421 } 12422 // If the provider has external (non-framework) process 12423 // dependencies, ensure that its adjustment is at least 12424 // FOREGROUND_APP_ADJ. 12425 if (cpr.hasExternalProcessHandles()) { 12426 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12427 adj = ProcessList.FOREGROUND_APP_ADJ; 12428 schedGroup = Process.THREAD_GROUP_DEFAULT; 12429 app.hidden = false; 12430 app.keeping = true; 12431 app.adjType = "provider"; 12432 app.adjTarget = cpr.name; 12433 } 12434 } 12435 } 12436 } 12437 12438 if (adj == ProcessList.SERVICE_ADJ) { 12439 if (doingAll) { 12440 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12441 mNewNumServiceProcs++; 12442 } 12443 if (app.serviceb) { 12444 adj = ProcessList.SERVICE_B_ADJ; 12445 } 12446 } else { 12447 app.serviceb = false; 12448 } 12449 12450 app.nonStoppingAdj = adj; 12451 12452 if (hasStoppingActivities) { 12453 // Only upgrade adjustment. 12454 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12455 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12456 app.adjType = "stopping"; 12457 } 12458 } 12459 12460 app.curRawAdj = adj; 12461 12462 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12463 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12464 if (adj > app.maxAdj) { 12465 adj = app.maxAdj; 12466 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12467 schedGroup = Process.THREAD_GROUP_DEFAULT; 12468 } 12469 } 12470 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12471 app.keeping = true; 12472 } 12473 12474 if (app.hasAboveClient) { 12475 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12476 // then we need to drop its adjustment to be lower than the service's 12477 // in order to honor the request. We want to drop it by one adjustment 12478 // level... but there is special meaning applied to various levels so 12479 // we will skip some of them. 12480 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12481 // System process will not get dropped, ever 12482 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12483 adj = ProcessList.VISIBLE_APP_ADJ; 12484 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12485 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12486 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12487 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12488 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12489 adj++; 12490 } 12491 } 12492 12493 int importance = app.memImportance; 12494 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12495 app.curAdj = adj; 12496 app.curSchedGroup = schedGroup; 12497 if (!interesting) { 12498 // For this reporting, if there is not something explicitly 12499 // interesting in this process then we will push it to the 12500 // background importance. 12501 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12502 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12503 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12504 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12505 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12506 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12507 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12508 } else if (adj >= ProcessList.SERVICE_ADJ) { 12509 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12510 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12511 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12512 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12513 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12514 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12515 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12516 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12517 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12518 } else { 12519 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12520 } 12521 } 12522 12523 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12524 if (foregroundActivities != app.foregroundActivities) { 12525 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12526 } 12527 if (changes != 0) { 12528 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12529 app.memImportance = importance; 12530 app.foregroundActivities = foregroundActivities; 12531 int i = mPendingProcessChanges.size()-1; 12532 ProcessChangeItem item = null; 12533 while (i >= 0) { 12534 item = mPendingProcessChanges.get(i); 12535 if (item.pid == app.pid) { 12536 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12537 break; 12538 } 12539 i--; 12540 } 12541 if (i < 0) { 12542 // No existing item in pending changes; need a new one. 12543 final int NA = mAvailProcessChanges.size(); 12544 if (NA > 0) { 12545 item = mAvailProcessChanges.remove(NA-1); 12546 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12547 } else { 12548 item = new ProcessChangeItem(); 12549 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12550 } 12551 item.changes = 0; 12552 item.pid = app.pid; 12553 item.uid = app.info.uid; 12554 if (mPendingProcessChanges.size() == 0) { 12555 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12556 "*** Enqueueing dispatch processes changed!"); 12557 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12558 } 12559 mPendingProcessChanges.add(item); 12560 } 12561 item.changes |= changes; 12562 item.importance = importance; 12563 item.foregroundActivities = foregroundActivities; 12564 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12565 + Integer.toHexString(System.identityHashCode(item)) 12566 + " " + app.toShortString() + ": changes=" + item.changes 12567 + " importance=" + item.importance 12568 + " foreground=" + item.foregroundActivities 12569 + " type=" + app.adjType + " source=" + app.adjSource 12570 + " target=" + app.adjTarget); 12571 } 12572 12573 return app.curRawAdj; 12574 } 12575 12576 /** 12577 * Ask a given process to GC right now. 12578 */ 12579 final void performAppGcLocked(ProcessRecord app) { 12580 try { 12581 app.lastRequestedGc = SystemClock.uptimeMillis(); 12582 if (app.thread != null) { 12583 if (app.reportLowMemory) { 12584 app.reportLowMemory = false; 12585 app.thread.scheduleLowMemory(); 12586 } else { 12587 app.thread.processInBackground(); 12588 } 12589 } 12590 } catch (Exception e) { 12591 // whatever. 12592 } 12593 } 12594 12595 /** 12596 * Returns true if things are idle enough to perform GCs. 12597 */ 12598 private final boolean canGcNowLocked() { 12599 boolean processingBroadcasts = false; 12600 for (BroadcastQueue q : mBroadcastQueues) { 12601 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12602 processingBroadcasts = true; 12603 } 12604 } 12605 return !processingBroadcasts 12606 && (mSleeping || (mMainStack.mResumedActivity != null && 12607 mMainStack.mResumedActivity.idle)); 12608 } 12609 12610 /** 12611 * Perform GCs on all processes that are waiting for it, but only 12612 * if things are idle. 12613 */ 12614 final void performAppGcsLocked() { 12615 final int N = mProcessesToGc.size(); 12616 if (N <= 0) { 12617 return; 12618 } 12619 if (canGcNowLocked()) { 12620 while (mProcessesToGc.size() > 0) { 12621 ProcessRecord proc = mProcessesToGc.remove(0); 12622 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12623 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12624 <= SystemClock.uptimeMillis()) { 12625 // To avoid spamming the system, we will GC processes one 12626 // at a time, waiting a few seconds between each. 12627 performAppGcLocked(proc); 12628 scheduleAppGcsLocked(); 12629 return; 12630 } else { 12631 // It hasn't been long enough since we last GCed this 12632 // process... put it in the list to wait for its time. 12633 addProcessToGcListLocked(proc); 12634 break; 12635 } 12636 } 12637 } 12638 12639 scheduleAppGcsLocked(); 12640 } 12641 } 12642 12643 /** 12644 * If all looks good, perform GCs on all processes waiting for them. 12645 */ 12646 final void performAppGcsIfAppropriateLocked() { 12647 if (canGcNowLocked()) { 12648 performAppGcsLocked(); 12649 return; 12650 } 12651 // Still not idle, wait some more. 12652 scheduleAppGcsLocked(); 12653 } 12654 12655 /** 12656 * Schedule the execution of all pending app GCs. 12657 */ 12658 final void scheduleAppGcsLocked() { 12659 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12660 12661 if (mProcessesToGc.size() > 0) { 12662 // Schedule a GC for the time to the next process. 12663 ProcessRecord proc = mProcessesToGc.get(0); 12664 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12665 12666 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12667 long now = SystemClock.uptimeMillis(); 12668 if (when < (now+GC_TIMEOUT)) { 12669 when = now + GC_TIMEOUT; 12670 } 12671 mHandler.sendMessageAtTime(msg, when); 12672 } 12673 } 12674 12675 /** 12676 * Add a process to the array of processes waiting to be GCed. Keeps the 12677 * list in sorted order by the last GC time. The process can't already be 12678 * on the list. 12679 */ 12680 final void addProcessToGcListLocked(ProcessRecord proc) { 12681 boolean added = false; 12682 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12683 if (mProcessesToGc.get(i).lastRequestedGc < 12684 proc.lastRequestedGc) { 12685 added = true; 12686 mProcessesToGc.add(i+1, proc); 12687 break; 12688 } 12689 } 12690 if (!added) { 12691 mProcessesToGc.add(0, proc); 12692 } 12693 } 12694 12695 /** 12696 * Set up to ask a process to GC itself. This will either do it 12697 * immediately, or put it on the list of processes to gc the next 12698 * time things are idle. 12699 */ 12700 final void scheduleAppGcLocked(ProcessRecord app) { 12701 long now = SystemClock.uptimeMillis(); 12702 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12703 return; 12704 } 12705 if (!mProcessesToGc.contains(app)) { 12706 addProcessToGcListLocked(app); 12707 scheduleAppGcsLocked(); 12708 } 12709 } 12710 12711 final void checkExcessivePowerUsageLocked(boolean doKills) { 12712 updateCpuStatsNow(); 12713 12714 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12715 boolean doWakeKills = doKills; 12716 boolean doCpuKills = doKills; 12717 if (mLastPowerCheckRealtime == 0) { 12718 doWakeKills = false; 12719 } 12720 if (mLastPowerCheckUptime == 0) { 12721 doCpuKills = false; 12722 } 12723 if (stats.isScreenOn()) { 12724 doWakeKills = false; 12725 } 12726 final long curRealtime = SystemClock.elapsedRealtime(); 12727 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12728 final long curUptime = SystemClock.uptimeMillis(); 12729 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12730 mLastPowerCheckRealtime = curRealtime; 12731 mLastPowerCheckUptime = curUptime; 12732 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12733 doWakeKills = false; 12734 } 12735 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12736 doCpuKills = false; 12737 } 12738 int i = mLruProcesses.size(); 12739 while (i > 0) { 12740 i--; 12741 ProcessRecord app = mLruProcesses.get(i); 12742 if (!app.keeping) { 12743 long wtime; 12744 synchronized (stats) { 12745 wtime = stats.getProcessWakeTime(app.info.uid, 12746 app.pid, curRealtime); 12747 } 12748 long wtimeUsed = wtime - app.lastWakeTime; 12749 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12750 if (DEBUG_POWER) { 12751 StringBuilder sb = new StringBuilder(128); 12752 sb.append("Wake for "); 12753 app.toShortString(sb); 12754 sb.append(": over "); 12755 TimeUtils.formatDuration(realtimeSince, sb); 12756 sb.append(" used "); 12757 TimeUtils.formatDuration(wtimeUsed, sb); 12758 sb.append(" ("); 12759 sb.append((wtimeUsed*100)/realtimeSince); 12760 sb.append("%)"); 12761 Slog.i(TAG, sb.toString()); 12762 sb.setLength(0); 12763 sb.append("CPU for "); 12764 app.toShortString(sb); 12765 sb.append(": over "); 12766 TimeUtils.formatDuration(uptimeSince, sb); 12767 sb.append(" used "); 12768 TimeUtils.formatDuration(cputimeUsed, sb); 12769 sb.append(" ("); 12770 sb.append((cputimeUsed*100)/uptimeSince); 12771 sb.append("%)"); 12772 Slog.i(TAG, sb.toString()); 12773 } 12774 // If a process has held a wake lock for more 12775 // than 50% of the time during this period, 12776 // that sounds bad. Kill! 12777 if (doWakeKills && realtimeSince > 0 12778 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12779 synchronized (stats) { 12780 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12781 realtimeSince, wtimeUsed); 12782 } 12783 Slog.w(TAG, "Excessive wake lock in " + app.processName 12784 + " (pid " + app.pid + "): held " + wtimeUsed 12785 + " during " + realtimeSince); 12786 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12787 app.processName, app.setAdj, "excessive wake lock"); 12788 Process.killProcessQuiet(app.pid); 12789 } else if (doCpuKills && uptimeSince > 0 12790 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12791 synchronized (stats) { 12792 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12793 uptimeSince, cputimeUsed); 12794 } 12795 Slog.w(TAG, "Excessive CPU in " + app.processName 12796 + " (pid " + app.pid + "): used " + cputimeUsed 12797 + " during " + uptimeSince); 12798 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12799 app.processName, app.setAdj, "excessive cpu"); 12800 Process.killProcessQuiet(app.pid); 12801 } else { 12802 app.lastWakeTime = wtime; 12803 app.lastCpuTime = app.curCpuTime; 12804 } 12805 } 12806 } 12807 } 12808 12809 private final boolean updateOomAdjLocked( 12810 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 12811 app.hiddenAdj = hiddenAdj; 12812 12813 if (app.thread == null) { 12814 return false; 12815 } 12816 12817 final boolean wasKeeping = app.keeping; 12818 12819 boolean success = true; 12820 12821 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 12822 12823 if (app.curRawAdj != app.setRawAdj) { 12824 if (wasKeeping && !app.keeping) { 12825 // This app is no longer something we want to keep. Note 12826 // its current wake lock time to later know to kill it if 12827 // it is not behaving well. 12828 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12829 synchronized (stats) { 12830 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12831 app.pid, SystemClock.elapsedRealtime()); 12832 } 12833 app.lastCpuTime = app.curCpuTime; 12834 } 12835 12836 app.setRawAdj = app.curRawAdj; 12837 } 12838 12839 if (app.curAdj != app.setAdj) { 12840 if (Process.setOomAdj(app.pid, app.curAdj)) { 12841 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12842 TAG, "Set " + app.pid + " " + app.processName + 12843 " adj " + app.curAdj + ": " + app.adjType); 12844 app.setAdj = app.curAdj; 12845 } else { 12846 success = false; 12847 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12848 } 12849 } 12850 if (app.setSchedGroup != app.curSchedGroup) { 12851 app.setSchedGroup = app.curSchedGroup; 12852 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12853 "Setting process group of " + app.processName 12854 + " to " + app.curSchedGroup); 12855 if (app.waitingToKill != null && 12856 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12857 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12858 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12859 app.processName, app.setAdj, app.waitingToKill); 12860 app.killedBackground = true; 12861 Process.killProcessQuiet(app.pid); 12862 success = false; 12863 } else { 12864 if (true) { 12865 long oldId = Binder.clearCallingIdentity(); 12866 try { 12867 Process.setProcessGroup(app.pid, app.curSchedGroup); 12868 } catch (Exception e) { 12869 Slog.w(TAG, "Failed setting process group of " + app.pid 12870 + " to " + app.curSchedGroup); 12871 e.printStackTrace(); 12872 } finally { 12873 Binder.restoreCallingIdentity(oldId); 12874 } 12875 } else { 12876 if (app.thread != null) { 12877 try { 12878 app.thread.setSchedulingGroup(app.curSchedGroup); 12879 } catch (RemoteException e) { 12880 } 12881 } 12882 } 12883 } 12884 } 12885 return success; 12886 } 12887 12888 private final ActivityRecord resumedAppLocked() { 12889 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12890 if (resumedActivity == null || resumedActivity.app == null) { 12891 resumedActivity = mMainStack.mPausingActivity; 12892 if (resumedActivity == null || resumedActivity.app == null) { 12893 resumedActivity = mMainStack.topRunningActivityLocked(null); 12894 } 12895 } 12896 return resumedActivity; 12897 } 12898 12899 final boolean updateOomAdjLocked(ProcessRecord app) { 12900 final ActivityRecord TOP_ACT = resumedAppLocked(); 12901 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12902 int curAdj = app.curAdj; 12903 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12904 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12905 12906 mAdjSeq++; 12907 12908 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 12909 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12910 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12911 if (nowHidden != wasHidden) { 12912 // Changed to/from hidden state, so apps after it in the LRU 12913 // list may also be changed. 12914 updateOomAdjLocked(); 12915 } 12916 return success; 12917 } 12918 12919 final void updateOomAdjLocked() { 12920 final ActivityRecord TOP_ACT = resumedAppLocked(); 12921 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12922 12923 if (false) { 12924 RuntimeException e = new RuntimeException(); 12925 e.fillInStackTrace(); 12926 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12927 } 12928 12929 mAdjSeq++; 12930 mNewNumServiceProcs = 0; 12931 12932 // Let's determine how many processes we have running vs. 12933 // how many slots we have for background processes; we may want 12934 // to put multiple processes in a slot of there are enough of 12935 // them. 12936 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 12937 int factor = (mLruProcesses.size()-4)/numSlots; 12938 if (factor < 1) factor = 1; 12939 int step = 0; 12940 int numHidden = 0; 12941 int numTrimming = 0; 12942 12943 // First update the OOM adjustment for each of the 12944 // application processes based on their current state. 12945 int i = mLruProcesses.size(); 12946 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12947 while (i > 0) { 12948 i--; 12949 ProcessRecord app = mLruProcesses.get(i); 12950 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 12951 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 12952 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 12953 && app.curAdj == curHiddenAdj) { 12954 step++; 12955 if (step >= factor) { 12956 step = 0; 12957 curHiddenAdj++; 12958 } 12959 } 12960 if (!app.killedBackground) { 12961 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12962 numHidden++; 12963 if (numHidden > mProcessLimit) { 12964 Slog.i(TAG, "No longer want " + app.processName 12965 + " (pid " + app.pid + "): hidden #" + numHidden); 12966 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12967 app.processName, app.setAdj, "too many background"); 12968 app.killedBackground = true; 12969 Process.killProcessQuiet(app.pid); 12970 } 12971 } 12972 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 12973 // If this is an isolated process, and there are no 12974 // services running in it, then the process is no longer 12975 // needed. We agressively kill these because we can by 12976 // definition not re-use the same process again, and it is 12977 // good to avoid having whatever code was running in them 12978 // left sitting around after no longer needed. 12979 Slog.i(TAG, "Isolated process " + app.processName 12980 + " (pid " + app.pid + ") no longer needed"); 12981 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12982 app.processName, app.setAdj, "isolated not needed"); 12983 app.killedBackground = true; 12984 Process.killProcessQuiet(app.pid); 12985 } 12986 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12987 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12988 && !app.killedBackground) { 12989 numTrimming++; 12990 } 12991 } 12992 } 12993 12994 mNumServiceProcs = mNewNumServiceProcs; 12995 12996 // Now determine the memory trimming level of background processes. 12997 // Unfortunately we need to start at the back of the list to do this 12998 // properly. We only do this if the number of background apps we 12999 // are managing to keep around is less than half the maximum we desire; 13000 // if we are keeping a good number around, we'll let them use whatever 13001 // memory they want. 13002 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 13003 final int N = mLruProcesses.size(); 13004 factor = numTrimming/3; 13005 int minFactor = 2; 13006 if (mHomeProcess != null) minFactor++; 13007 if (mPreviousProcess != null) minFactor++; 13008 if (factor < minFactor) factor = minFactor; 13009 step = 0; 13010 int fgTrimLevel; 13011 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13012 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13013 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13014 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13015 } else { 13016 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13017 } 13018 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13019 for (i=0; i<N; i++) { 13020 ProcessRecord app = mLruProcesses.get(i); 13021 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13022 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13023 && !app.killedBackground) { 13024 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13025 try { 13026 app.thread.scheduleTrimMemory(curLevel); 13027 } catch (RemoteException e) { 13028 } 13029 if (false) { 13030 // For now we won't do this; our memory trimming seems 13031 // to be good enough at this point that destroying 13032 // activities causes more harm than good. 13033 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13034 && app != mHomeProcess && app != mPreviousProcess) { 13035 // Need to do this on its own message because the stack may not 13036 // be in a consistent state at this point. 13037 // For these apps we will also finish their activities 13038 // to help them free memory. 13039 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13040 } 13041 } 13042 } 13043 app.trimMemoryLevel = curLevel; 13044 step++; 13045 if (step >= factor) { 13046 step = 0; 13047 switch (curLevel) { 13048 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13049 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13050 break; 13051 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13052 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13053 break; 13054 } 13055 } 13056 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13057 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13058 && app.thread != null) { 13059 try { 13060 app.thread.scheduleTrimMemory( 13061 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13062 } catch (RemoteException e) { 13063 } 13064 } 13065 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13066 } else { 13067 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13068 && app.pendingUiClean) { 13069 // If this application is now in the background and it 13070 // had done UI, then give it the special trim level to 13071 // have it free UI resources. 13072 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13073 if (app.trimMemoryLevel < level && app.thread != null) { 13074 try { 13075 app.thread.scheduleTrimMemory(level); 13076 } catch (RemoteException e) { 13077 } 13078 } 13079 app.pendingUiClean = false; 13080 } 13081 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13082 try { 13083 app.thread.scheduleTrimMemory(fgTrimLevel); 13084 } catch (RemoteException e) { 13085 } 13086 } 13087 app.trimMemoryLevel = fgTrimLevel; 13088 } 13089 } 13090 } else { 13091 final int N = mLruProcesses.size(); 13092 for (i=0; i<N; i++) { 13093 ProcessRecord app = mLruProcesses.get(i); 13094 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13095 && app.pendingUiClean) { 13096 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13097 && app.thread != null) { 13098 try { 13099 app.thread.scheduleTrimMemory( 13100 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13101 } catch (RemoteException e) { 13102 } 13103 } 13104 app.pendingUiClean = false; 13105 } 13106 app.trimMemoryLevel = 0; 13107 } 13108 } 13109 13110 if (mAlwaysFinishActivities) { 13111 // Need to do this on its own message because the stack may not 13112 // be in a consistent state at this point. 13113 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13114 } 13115 } 13116 13117 final void trimApplications() { 13118 synchronized (this) { 13119 int i; 13120 13121 // First remove any unused application processes whose package 13122 // has been removed. 13123 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13124 final ProcessRecord app = mRemovedProcesses.get(i); 13125 if (app.activities.size() == 0 13126 && app.curReceiver == null && app.services.size() == 0) { 13127 Slog.i( 13128 TAG, "Exiting empty application process " 13129 + app.processName + " (" 13130 + (app.thread != null ? app.thread.asBinder() : null) 13131 + ")\n"); 13132 if (app.pid > 0 && app.pid != MY_PID) { 13133 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13134 app.processName, app.setAdj, "empty"); 13135 Process.killProcessQuiet(app.pid); 13136 } else { 13137 try { 13138 app.thread.scheduleExit(); 13139 } catch (Exception e) { 13140 // Ignore exceptions. 13141 } 13142 } 13143 cleanUpApplicationRecordLocked(app, false, true, -1); 13144 mRemovedProcesses.remove(i); 13145 13146 if (app.persistent) { 13147 if (app.persistent) { 13148 addAppLocked(app.info, false); 13149 } 13150 } 13151 } 13152 } 13153 13154 // Now update the oom adj for all processes. 13155 updateOomAdjLocked(); 13156 } 13157 } 13158 13159 /** This method sends the specified signal to each of the persistent apps */ 13160 public void signalPersistentProcesses(int sig) throws RemoteException { 13161 if (sig != Process.SIGNAL_USR1) { 13162 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13163 } 13164 13165 synchronized (this) { 13166 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13167 != PackageManager.PERMISSION_GRANTED) { 13168 throw new SecurityException("Requires permission " 13169 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13170 } 13171 13172 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13173 ProcessRecord r = mLruProcesses.get(i); 13174 if (r.thread != null && r.persistent) { 13175 Process.sendSignal(r.pid, sig); 13176 } 13177 } 13178 } 13179 } 13180 13181 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13182 if (proc == null || proc == mProfileProc) { 13183 proc = mProfileProc; 13184 path = mProfileFile; 13185 profileType = mProfileType; 13186 clearProfilerLocked(); 13187 } 13188 if (proc == null) { 13189 return; 13190 } 13191 try { 13192 proc.thread.profilerControl(false, path, null, profileType); 13193 } catch (RemoteException e) { 13194 throw new IllegalStateException("Process disappeared"); 13195 } 13196 } 13197 13198 private void clearProfilerLocked() { 13199 if (mProfileFd != null) { 13200 try { 13201 mProfileFd.close(); 13202 } catch (IOException e) { 13203 } 13204 } 13205 mProfileApp = null; 13206 mProfileProc = null; 13207 mProfileFile = null; 13208 mProfileType = 0; 13209 mAutoStopProfiler = false; 13210 } 13211 13212 public boolean profileControl(String process, boolean start, 13213 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13214 13215 try { 13216 synchronized (this) { 13217 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13218 // its own permission. 13219 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13220 != PackageManager.PERMISSION_GRANTED) { 13221 throw new SecurityException("Requires permission " 13222 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13223 } 13224 13225 if (start && fd == null) { 13226 throw new IllegalArgumentException("null fd"); 13227 } 13228 13229 ProcessRecord proc = null; 13230 if (process != null) { 13231 try { 13232 int pid = Integer.parseInt(process); 13233 synchronized (mPidsSelfLocked) { 13234 proc = mPidsSelfLocked.get(pid); 13235 } 13236 } catch (NumberFormatException e) { 13237 } 13238 13239 if (proc == null) { 13240 HashMap<String, SparseArray<ProcessRecord>> all 13241 = mProcessNames.getMap(); 13242 SparseArray<ProcessRecord> procs = all.get(process); 13243 if (procs != null && procs.size() > 0) { 13244 proc = procs.valueAt(0); 13245 } 13246 } 13247 } 13248 13249 if (start && (proc == null || proc.thread == null)) { 13250 throw new IllegalArgumentException("Unknown process: " + process); 13251 } 13252 13253 if (start) { 13254 stopProfilerLocked(null, null, 0); 13255 setProfileApp(proc.info, proc.processName, path, fd, false); 13256 mProfileProc = proc; 13257 mProfileType = profileType; 13258 try { 13259 fd = fd.dup(); 13260 } catch (IOException e) { 13261 fd = null; 13262 } 13263 proc.thread.profilerControl(start, path, fd, profileType); 13264 fd = null; 13265 mProfileFd = null; 13266 } else { 13267 stopProfilerLocked(proc, path, profileType); 13268 if (fd != null) { 13269 try { 13270 fd.close(); 13271 } catch (IOException e) { 13272 } 13273 } 13274 } 13275 13276 return true; 13277 } 13278 } catch (RemoteException e) { 13279 throw new IllegalStateException("Process disappeared"); 13280 } finally { 13281 if (fd != null) { 13282 try { 13283 fd.close(); 13284 } catch (IOException e) { 13285 } 13286 } 13287 } 13288 } 13289 13290 public boolean dumpHeap(String process, boolean managed, 13291 String path, ParcelFileDescriptor fd) throws RemoteException { 13292 13293 try { 13294 synchronized (this) { 13295 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13296 // its own permission (same as profileControl). 13297 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13298 != PackageManager.PERMISSION_GRANTED) { 13299 throw new SecurityException("Requires permission " 13300 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13301 } 13302 13303 if (fd == null) { 13304 throw new IllegalArgumentException("null fd"); 13305 } 13306 13307 ProcessRecord proc = null; 13308 try { 13309 int pid = Integer.parseInt(process); 13310 synchronized (mPidsSelfLocked) { 13311 proc = mPidsSelfLocked.get(pid); 13312 } 13313 } catch (NumberFormatException e) { 13314 } 13315 13316 if (proc == null) { 13317 HashMap<String, SparseArray<ProcessRecord>> all 13318 = mProcessNames.getMap(); 13319 SparseArray<ProcessRecord> procs = all.get(process); 13320 if (procs != null && procs.size() > 0) { 13321 proc = procs.valueAt(0); 13322 } 13323 } 13324 13325 if (proc == null || proc.thread == null) { 13326 throw new IllegalArgumentException("Unknown process: " + process); 13327 } 13328 13329 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13330 if (!isDebuggable) { 13331 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13332 throw new SecurityException("Process not debuggable: " + proc); 13333 } 13334 } 13335 13336 proc.thread.dumpHeap(managed, path, fd); 13337 fd = null; 13338 return true; 13339 } 13340 } catch (RemoteException e) { 13341 throw new IllegalStateException("Process disappeared"); 13342 } finally { 13343 if (fd != null) { 13344 try { 13345 fd.close(); 13346 } catch (IOException e) { 13347 } 13348 } 13349 } 13350 } 13351 13352 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13353 public void monitor() { 13354 synchronized (this) { } 13355 } 13356 13357 void onCoreSettingsChange(Bundle settings) { 13358 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13359 ProcessRecord processRecord = mLruProcesses.get(i); 13360 try { 13361 if (processRecord.thread != null) { 13362 processRecord.thread.setCoreSettings(settings); 13363 } 13364 } catch (RemoteException re) { 13365 /* ignore */ 13366 } 13367 } 13368 } 13369 13370 // Multi-user methods 13371 13372 public boolean switchUser(int userId) { 13373 final int callingUid = Binder.getCallingUid(); 13374 if (callingUid != 0 && callingUid != Process.myUid()) { 13375 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13376 return false; 13377 } 13378 if (mCurrentUserId == userId) 13379 return true; 13380 13381 synchronized (this) { 13382 // Check if user is already logged in, otherwise check if user exists first before 13383 // adding to the list of logged in users. 13384 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13385 if (!userExists(userId)) { 13386 return false; 13387 } 13388 mLoggedInUsers.append(userId, userId); 13389 } 13390 13391 mCurrentUserId = userId; 13392 boolean haveActivities = mMainStack.switchUser(userId); 13393 if (!haveActivities) { 13394 startHomeActivityLocked(userId); 13395 } 13396 13397 } 13398 13399 // Inform of user switch 13400 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13401 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 13402 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13403 13404 return true; 13405 } 13406 13407 @Override 13408 public UserInfo getCurrentUser() throws RemoteException { 13409 final int callingUid = Binder.getCallingUid(); 13410 if (callingUid != 0 && callingUid != Process.myUid()) { 13411 Slog.e(TAG, "Trying to get user from unauthorized app"); 13412 return null; 13413 } 13414 return getUserManager().getUserInfo(mCurrentUserId); 13415 } 13416 13417 private void onUserRemoved(Intent intent) { 13418 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 13419 if (extraUserId < 1) return; 13420 13421 // Kill all the processes for the user 13422 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13423 synchronized (this) { 13424 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13425 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13426 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13427 for (int i = 0; i < uids.size(); i++) { 13428 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 13429 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13430 } 13431 } 13432 } 13433 13434 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13435 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13436 false, false, true, true, extraUserId); 13437 } 13438 } 13439 } 13440 13441 private boolean userExists(int userId) { 13442 UserInfo user = getUserManager().getUserInfo(userId); 13443 return user != null; 13444 } 13445 13446 UserManager getUserManager() { 13447 if (mUserManager == null) { 13448 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13449 } 13450 return mUserManager; 13451 } 13452 13453 private void checkValidCaller(int uid, int userId) { 13454 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13455 13456 throw new SecurityException("Caller uid=" + uid 13457 + " is not privileged to communicate with user=" + userId); 13458 } 13459 13460 private int applyUserId(int uid, int userId) { 13461 return UserId.getUid(userId, uid); 13462 } 13463 13464 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13465 if (info == null) return null; 13466 ApplicationInfo newInfo = new ApplicationInfo(info); 13467 newInfo.uid = applyUserId(info.uid, userId); 13468 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13469 + info.packageName; 13470 return newInfo; 13471 } 13472 13473 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13474 if (aInfo == null 13475 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 13476 return aInfo; 13477 } 13478 13479 ActivityInfo info = new ActivityInfo(aInfo); 13480 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13481 return info; 13482 } 13483} 13484